diff --git a/[refs] b/[refs] index 05431e917227..f3348cb32cd0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 940389b8afad6495211614c13eb91ef7001773ec +refs/heads/master: e6bb83fd2f39eff3ae3e5ad6cac91d154d7ef3b1 diff --git a/trunk/Documentation/DMA-API.txt b/trunk/Documentation/DMA-API.txt index d8b63d164e41..80d150458c80 100644 --- a/trunk/Documentation/DMA-API.txt +++ b/trunk/Documentation/DMA-API.txt @@ -298,10 +298,10 @@ recommended that you never use these unless you really know what the cache width is. int -dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +dma_mapping_error(dma_addr_t dma_addr) int -pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr) +pci_dma_mapping_error(dma_addr_t dma_addr) In some circumstances dma_map_single and dma_map_page will fail to create a mapping. A driver can check for these errors by testing the returned diff --git a/trunk/Documentation/Intel-IOMMU.txt b/trunk/Documentation/Intel-IOMMU.txt index 21bc416d887e..c2321903aa09 100644 --- a/trunk/Documentation/Intel-IOMMU.txt +++ b/trunk/Documentation/Intel-IOMMU.txt @@ -48,7 +48,7 @@ IOVA generation is pretty generic. We used the same technique as vmalloc() but these are not global address spaces, but separate for each domain. Different DMA engines may support different number of domains. -We also allocate guard pages with each mapping, so we can attempt to catch +We also allocate gaurd pages with each mapping, so we can attempt to catch any overflow that might happen. @@ -112,4 +112,4 @@ TBD - For compatibility testing, could use unity map domain for all devices, just provide a 1-1 for all useful memory under a single domain for all devices. -- API for paravirt ops for abstracting functionality for VMM folks. +- API for paravirt ops for abstracting functionlity for VMM folks. diff --git a/trunk/Documentation/accounting/taskstats-struct.txt b/trunk/Documentation/accounting/taskstats-struct.txt index e7512c061c15..b988d110db59 100644 --- a/trunk/Documentation/accounting/taskstats-struct.txt +++ b/trunk/Documentation/accounting/taskstats-struct.txt @@ -6,7 +6,7 @@ This document contains an explanation of the struct taskstats fields. There are three different groups of fields in the struct taskstats: 1) Common and basic accounting fields - If CONFIG_TASKSTATS is set, the taskstats interface is enabled and + If CONFIG_TASKSTATS is set, the taskstats inteface is enabled and the common fields and basic accounting fields are collected for delivery at do_exit() of a task. 2) Delay accounting fields diff --git a/trunk/Documentation/cpu-freq/governors.txt b/trunk/Documentation/cpu-freq/governors.txt index 5b0cfa67aff9..dcec0564d040 100644 --- a/trunk/Documentation/cpu-freq/governors.txt +++ b/trunk/Documentation/cpu-freq/governors.txt @@ -122,7 +122,7 @@ around '10000' or more. show_sampling_rate_(min|max): the minimum and maximum sampling rates available that you may set 'sampling_rate' to. -up_threshold: defines what the average CPU usage between the samplings +up_threshold: defines what the average CPU usaged between the samplings of 'sampling_rate' needs to be for the kernel to make a decision on whether it should increase the frequency. For example when it is set to its default value of '80' it means that between the checking diff --git a/trunk/Documentation/edac.txt b/trunk/Documentation/edac.txt index 8eda3fb66416..ced527388001 100644 --- a/trunk/Documentation/edac.txt +++ b/trunk/Documentation/edac.txt @@ -327,7 +327,7 @@ Sdram memory scrubbing rate: 'sdram_scrub_rate' Read/Write attribute file that controls memory scrubbing. The scrubbing - rate is set by writing a minimum bandwidth in bytes/sec to the attribute + rate is set by writing a minimum bandwith in bytes/sec to the attribute file. The rate will be translated to an internal value that gives at least the specified rate. diff --git a/trunk/Documentation/filesystems/omfs.txt b/trunk/Documentation/filesystems/omfs.txt deleted file mode 100644 index 1d0d41ff5c65..000000000000 --- a/trunk/Documentation/filesystems/omfs.txt +++ /dev/null @@ -1,106 +0,0 @@ -Optimized MPEG Filesystem (OMFS) - -Overview -======== - -OMFS is a filesystem created by SonicBlue for use in the ReplayTV DVR -and Rio Karma MP3 player. The filesystem is extent-based, utilizing -block sizes from 2k to 8k, with hash-based directories. This -filesystem driver may be used to read and write disks from these -devices. - -Note, it is not recommended that this FS be used in place of a general -filesystem for your own streaming media device. Native Linux filesystems -will likely perform better. - -More information is available at: - - http://linux-karma.sf.net/ - -Various utilities, including mkomfs and omfsck, are included with -omfsprogs, available at: - - http://bobcopeland.com/karma/ - -Instructions are included in its README. - -Options -======= - -OMFS supports the following mount-time options: - - uid=n - make all files owned by specified user - gid=n - make all files owned by specified group - umask=xxx - set permission umask to xxx - fmask=xxx - set umask to xxx for files - dmask=xxx - set umask to xxx for directories - -Disk format -=========== - -OMFS discriminates between "sysblocks" and normal data blocks. The sysblock -group consists of super block information, file metadata, directory structures, -and extents. Each sysblock has a header containing CRCs of the entire -sysblock, and may be mirrored in successive blocks on the disk. A sysblock may -have a smaller size than a data block, but since they are both addressed by the -same 64-bit block number, any remaining space in the smaller sysblock is -unused. - -Sysblock header information: - -struct omfs_header { - __be64 h_self; /* FS block where this is located */ - __be32 h_body_size; /* size of useful data after header */ - __be16 h_crc; /* crc-ccitt of body_size bytes */ - char h_fill1[2]; - u8 h_version; /* version, always 1 */ - char h_type; /* OMFS_INODE_X */ - u8 h_magic; /* OMFS_IMAGIC */ - u8 h_check_xor; /* XOR of header bytes before this */ - __be32 h_fill2; -}; - -Files and directories are both represented by omfs_inode: - -struct omfs_inode { - struct omfs_header i_head; /* header */ - __be64 i_parent; /* parent containing this inode */ - __be64 i_sibling; /* next inode in hash bucket */ - __be64 i_ctime; /* ctime, in milliseconds */ - char i_fill1[35]; - char i_type; /* OMFS_[DIR,FILE] */ - __be32 i_fill2; - char i_fill3[64]; - char i_name[OMFS_NAMELEN]; /* filename */ - __be64 i_size; /* size of file, in bytes */ -}; - -Directories in OMFS are implemented as a large hash table. Filenames are -hashed then prepended into the bucket list beginning at OMFS_DIR_START. -Lookup requires hashing the filename, then seeking across i_sibling pointers -until a match is found on i_name. Empty buckets are represented by block -pointers with all-1s (~0). - -A file is an omfs_inode structure followed by an extent table beginning at -OMFS_EXTENT_START: - -struct omfs_extent_entry { - __be64 e_cluster; /* start location of a set of blocks */ - __be64 e_blocks; /* number of blocks after e_cluster */ -}; - -struct omfs_extent { - __be64 e_next; /* next extent table location */ - __be32 e_extent_count; /* total # extents in this table */ - __be32 e_fill; - struct omfs_extent_entry e_entry; /* start of extent entries */ -}; - -Each extent holds the block offset followed by number of blocks allocated to -the extent. The final extent in each table is a terminator with e_cluster -being ~0 and e_blocks being ones'-complement of the total number of blocks -in the table. - -If this table overflows, a continuation inode is written and pointed to by -e_next. These have a header but lack the rest of the inode structure. - diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index 64557821ee59..8c6384bdfed4 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -931,7 +931,7 @@ group_prealloc max_to_scan mb_groups mb_history min_to_scan order2_req stats stream_req mb_groups: -This file gives the details of multiblock allocator buddy cache of free blocks +This file gives the details of mutiblock allocator buddy cache of free blocks mb_history: Multiblock allocation history. @@ -1474,7 +1474,7 @@ used because pages_free(1355) is smaller than watermark + protection[2] normal page requirement. If requirement is DMA zone(index=0), protection[0] (=0) is used. -zone[i]'s protection[j] is calculated by following expression. +zone[i]'s protection[j] is calculated by following exprssion. (i < j): zone[i]->protection[j] diff --git a/trunk/Documentation/filesystems/relay.txt b/trunk/Documentation/filesystems/relay.txt index 510b722667ac..094f2d2f38b1 100644 --- a/trunk/Documentation/filesystems/relay.txt +++ b/trunk/Documentation/filesystems/relay.txt @@ -294,16 +294,6 @@ user-defined data with a channel, and is immediately available (including in create_buf_file()) via chan->private_data or buf->chan->private_data. -Buffer-only channels --------------------- - -These channels have no files associated and can be created with -relay_open(NULL, NULL, ...). Such channels are useful in scenarios such -as when doing early tracing in the kernel, before the VFS is up. In these -cases, one may open a buffer-only channel and then call -relay_late_setup_files() when the kernel is ready to handle files, -to expose the buffered data to the userspace. - Channel 'modes' --------------- diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index c4d348dabe94..b7522c6cbae3 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -143,7 +143,7 @@ struct file_system_type { The get_sb() method has the following arguments: - struct file_system_type *fs_type: describes the filesystem, partly initialized + struct file_system_type *fs_type: decribes the filesystem, partly initialized by the specific filesystem code int flags: mount flags @@ -895,9 +895,9 @@ struct dentry_operations { iput() yourself d_dname: called when the pathname of a dentry should be generated. - Useful for some pseudo filesystems (sockfs, pipefs, ...) to delay + Usefull for some pseudo filesystems (sockfs, pipefs, ...) to delay pathname generation. (Instead of doing it when dentry is created, - it's done only when the path is needed.). Real filesystems probably + its done only when the path is needed.). Real filesystems probably dont want to use it, because their dentries are present in global dcache hash, so their hash should be an invariant. As no lock is held, d_dname() should not try to modify the dentry itself, unless diff --git a/trunk/Documentation/ia64/kvm.txt b/trunk/Documentation/ia64/kvm.txt index 914d07f49268..bec9d815da33 100644 --- a/trunk/Documentation/ia64/kvm.txt +++ b/trunk/Documentation/ia64/kvm.txt @@ -50,9 +50,9 @@ Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qe /usr/local/bin/qemu-system-ia64 -smp xx -m 512 -hda $your_image (xx is the number of virtual processors for the guest, now the maximum value is 4) -5. Known possible issue on some platforms with old Firmware. +5. Known possibile issue on some platforms with old Firmware. -In the event of strange host crash issues, try to solve it through either of the following ways: +If meet strange host crashe issues, try to solve it through either of the following ways: (1): Upgrade your Firmware to the latest one. @@ -65,8 +65,8 @@ index 0b53344..f02b0f7 100644 mov ar.pfs = loc1 mov rp = loc0 ;; -- srlz.d // serialize restoration of psr.l -+ srlz.i // serialize restoration of psr.l +- srlz.d // seralize restoration of psr.l ++ srlz.i // seralize restoration of psr.l + ;; br.ret.sptk.many b0 END(ia64_pal_call_static) diff --git a/trunk/Documentation/input/cs461x.txt b/trunk/Documentation/input/cs461x.txt index 202e9dbacec3..afe0d6543e09 100644 --- a/trunk/Documentation/input/cs461x.txt +++ b/trunk/Documentation/input/cs461x.txt @@ -31,7 +31,7 @@ The driver works with ALSA drivers simultaneously. For example, the xracer uses joystick as input device and PCM device as sound output in one time. There are no sound or input collisions detected. The source code have comments about them; but I've found the joystick can be initialized -separately of ALSA modules. So, you can use only one joystick driver +separately of ALSA modules. So, you canm use only one joystick driver without ALSA drivers. The ALSA drivers are not needed to compile or run this driver. diff --git a/trunk/Documentation/ioctl/ioctl-decoding.txt b/trunk/Documentation/ioctl/ioctl-decoding.txt index e35efb0cec2e..bfdf7f3ee4f0 100644 --- a/trunk/Documentation/ioctl/ioctl-decoding.txt +++ b/trunk/Documentation/ioctl/ioctl-decoding.txt @@ -1,6 +1,6 @@ To decode a hex IOCTL code: -Most architectures use this generic format, but check +Most architecures use this generic format, but check include/ARCH/ioctl.h for specifics, e.g. powerpc uses 3 bits to encode read/write and 13 bits for size. @@ -18,7 +18,7 @@ uses 3 bits to encode read/write and 13 bits for size. 7-0 function # -So for example 0x82187201 is a read with arg length of 0x218, + So for example 0x82187201 is a read with arg length of 0x218, character 'r' function 1. Grepping the source reveals this is: #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) diff --git a/trunk/Documentation/iostats.txt b/trunk/Documentation/iostats.txt index 59a69ec67c40..5925c3cd030d 100644 --- a/trunk/Documentation/iostats.txt +++ b/trunk/Documentation/iostats.txt @@ -143,7 +143,7 @@ disk and partition statistics are consistent again. Since we still don't keep record of the partition-relative address, an operation is attributed to the partition which contains the first sector of the request after the eventual merges. As requests can be merged across partition, this could lead -to some (probably insignificant) inaccuracy. +to some (probably insignificant) innacuracy. Additional notes ---------------- diff --git a/trunk/Documentation/isdn/README.mISDN b/trunk/Documentation/isdn/README.mISDN deleted file mode 100644 index cd8bf920e77b..000000000000 --- a/trunk/Documentation/isdn/README.mISDN +++ /dev/null @@ -1,6 +0,0 @@ -mISDN is a new modular ISDN driver, in the long term it should replace -the old I4L driver architecture for passiv ISDN cards. -It was designed to allow a broad range of applications and interfaces -but only have the basic function in kernel, the interface to the user -space is based on sockets with a own address family AF_ISDN. - diff --git a/trunk/Documentation/keys.txt b/trunk/Documentation/keys.txt index b56aacc1fff8..d5c7a57d1700 100644 --- a/trunk/Documentation/keys.txt +++ b/trunk/Documentation/keys.txt @@ -864,7 +864,7 @@ payload contents" for more information. request_key_with_auxdata() respectively. These two functions return with the key potentially still under - construction. To wait for construction completion, the following should be + construction. To wait for contruction completion, the following should be called: int wait_for_key_construction(struct key *key, bool intr); diff --git a/trunk/Documentation/leds-class.txt b/trunk/Documentation/leds-class.txt index 6399557cdab3..18860ad9935a 100644 --- a/trunk/Documentation/leds-class.txt +++ b/trunk/Documentation/leds-class.txt @@ -59,7 +59,7 @@ Hardware accelerated blink of LEDs Some LEDs can be programmed to blink without any CPU interaction. To support this feature, a LED driver can optionally implement the -blink_set() function (see ). If implemented, triggers can +blink_set() function (see ). If implemeted, triggers can attempt to use it before falling back to software timers. The blink_set() function should return 0 if the blink setting is supported, or -EINVAL otherwise, which means that LED blinking will be handled by software. diff --git a/trunk/Documentation/local_ops.txt b/trunk/Documentation/local_ops.txt index f4f8b1c6c8ba..4269a1105b37 100644 --- a/trunk/Documentation/local_ops.txt +++ b/trunk/Documentation/local_ops.txt @@ -36,7 +36,7 @@ It can be done by slightly modifying the standard atomic operations : only their UP variant must be kept. It typically means removing LOCK prefix (on i386 and x86_64) and any SMP sychronization barrier. If the architecture does not have a different behavior between SMP and UP, including asm-generic/local.h -in your architecture's local.h is sufficient. +in your archtecture's local.h is sufficient. The local_t type is defined as an opaque signed long by embedding an atomic_long_t inside a structure. This is made so a cast from this type to a diff --git a/trunk/Documentation/networking/bonding.txt b/trunk/Documentation/networking/bonding.txt index 688dfe1e6b70..7fa7fe71d7a8 100644 --- a/trunk/Documentation/networking/bonding.txt +++ b/trunk/Documentation/networking/bonding.txt @@ -631,7 +631,7 @@ xmit_hash_policy in environments where a layer3 gateway device is required to reach most destinations. - This algorithm is 802.3ad compliant. + This algorithm is 802.3ad complient. layer3+4 diff --git a/trunk/Documentation/networking/can.txt b/trunk/Documentation/networking/can.txt index 297ba7b1ccaf..641d2afacffa 100644 --- a/trunk/Documentation/networking/can.txt +++ b/trunk/Documentation/networking/can.txt @@ -186,7 +186,7 @@ solution for a couple of reasons: The Linux network devices (by default) just can handle the transmission and reception of media dependent frames. Due to the - arbitration on the CAN bus the transmission of a low prio CAN-ID + arbritration on the CAN bus the transmission of a low prio CAN-ID may be delayed by the reception of a high prio CAN frame. To reflect the correct* traffic on the node the loopback of the sent data has to be performed right after a successful transmission. If @@ -481,7 +481,7 @@ solution for a couple of reasons: - stats_timer: To calculate the Socket CAN core statistics (e.g. current/maximum frames per second) this 1 second timer is invoked at can.ko module start time by default. This timer can be - disabled by using stattimer=0 on the module commandline. + disabled by using stattimer=0 on the module comandline. - debug: (removed since SocketCAN SVN r546) diff --git a/trunk/Documentation/networking/packet_mmap.txt b/trunk/Documentation/networking/packet_mmap.txt index 07c53d596035..db0cd5169581 100644 --- a/trunk/Documentation/networking/packet_mmap.txt +++ b/trunk/Documentation/networking/packet_mmap.txt @@ -326,7 +326,7 @@ just one call to mmap is needed: mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); If tp_frame_size is a divisor of tp_block_size frames will be -contiguously spaced by tp_frame_size bytes. If not, each +contiguosly spaced by tp_frame_size bytes. If not, each tp_block_size/tp_frame_size frames there will be a gap between the frames. This is because a frame cannot be spawn across two blocks. diff --git a/trunk/Documentation/networking/tc-actions-env-rules.txt b/trunk/Documentation/networking/tc-actions-env-rules.txt index dcadf6f88e34..01e716d185f4 100644 --- a/trunk/Documentation/networking/tc-actions-env-rules.txt +++ b/trunk/Documentation/networking/tc-actions-env-rules.txt @@ -4,27 +4,26 @@ The "enviromental" rules for authors of any new tc actions are: 1) If you stealeth or borroweth any packet thou shalt be branching from the righteous path and thou shalt cloneth. -For example if your action queues a packet to be processed later, -or intentionally branches by redirecting a packet, then you need to +For example if your action queues a packet to be processed later +or intentionaly branches by redirecting a packet then you need to clone the packet. - There are certain fields in the skb tc_verd that need to be reset so we -avoid loops, etc. A few are generic enough that skb_act_clone() -resets them for you, so invoke skb_act_clone() rather than skb_clone(). +avoid loops etc. A few are generic enough so much so that skb_act_clone() +resets them for you. So invoke skb_act_clone() rather than skb_clone() 2) If you munge any packet thou shalt call pskb_expand_head in the case someone else is referencing the skb. After that you "own" the skb. You must also tell us if it is ok to munge the packet (TC_OK2MUNGE), this way any action downstream can stomp on the packet. -3) Dropping packets you don't own is a no-no. You simply return +3) dropping packets you dont own is a nono. You simply return TC_ACT_SHOT to the caller and they will drop it. The "enviromental" rules for callers of actions (qdiscs etc) are: -*) Thou art responsible for freeing anything returned as being +*) thou art responsible for freeing anything returned as being TC_ACT_SHOT/STOLEN/QUEUED. If none of TC_ACT_SHOT/STOLEN/QUEUED is -returned, then all is great and you don't need to do anything. +returned then all is great and you dont need to do anything. Post on netdev if something is unclear. diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt index 928a79ceb7aa..99514ced82c5 100644 --- a/trunk/Documentation/powerpc/booting-without-of.txt +++ b/trunk/Documentation/powerpc/booting-without-of.txt @@ -708,7 +708,7 @@ device or bus to be described by the device tree. In general, the format of an address for a device is defined by the parent bus type, based on the #address-cells and #size-cells properties. Note that the parent's parent definitions of #address-cells -and #size-cells are not inherited so every node with children must specify +and #size-cells are not inhereted so every node with children must specify them. The kernel requires the root node to have those properties defining addresses format for devices directly mapped on the processor bus. @@ -1777,7 +1777,7 @@ platforms are moved over to use the flattened-device-tree model. Xilinx uartlite devices are simple fixed speed serial ports. - Required properties: + Requred properties: - current-speed : Baud rate of uartlite v) Xilinx hwicap @@ -1799,7 +1799,7 @@ platforms are moved over to use the flattened-device-tree model. Xilinx UART 16550 devices are very similar to the NS16550 but with different register spacing and an offset from the base address. - Required properties: + Requred properties: - clock-frequency : Frequency of the clock input - reg-offset : A value of 3 is required - reg-shift : A value of 2 is required @@ -1953,7 +1953,7 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. 1) The /system-controller node This node is used to represent the system-controller and must be - present when the system uses a system controller chip. The top-level + present when the system uses a system contller chip. The top-level system-controller node contains information that is global to all devices within the system controller chip. The node name begins with "system-controller" followed by the unit address, which is diff --git a/trunk/Documentation/powerpc/qe_firmware.txt b/trunk/Documentation/powerpc/qe_firmware.txt index 06da4d4b44f9..896266432d33 100644 --- a/trunk/Documentation/powerpc/qe_firmware.txt +++ b/trunk/Documentation/powerpc/qe_firmware.txt @@ -217,7 +217,7 @@ Although it is not recommended, you can specify '0' in the soc.model field to skip matching SOCs altogether. The 'model' field is a 16-bit number that matches the actual SOC. The -'major' and 'minor' fields are the major and minor revision numbers, +'major' and 'minor' fields are the major and minor revision numbrs, respectively, of the SOC. For example, to match the 8323, revision 1.0: diff --git a/trunk/Documentation/s390/driver-model.txt b/trunk/Documentation/s390/driver-model.txt index bde473df748d..e938c442277d 100644 --- a/trunk/Documentation/s390/driver-model.txt +++ b/trunk/Documentation/s390/driver-model.txt @@ -25,7 +25,7 @@ device 4711 via subchannel 1 in subchannel set 0, and subchannel 2 is a non-I/O subchannel. Device 1234 is accessed via subchannel 0 in subchannel set 1. The subchannel named 'defunct' does not represent any real subchannel on the -system; it is a pseudo subchannel where disconnected ccw devices are moved to +system; it is a pseudo subchannel where disconnnected ccw devices are moved to if they are displaced by another ccw device becoming operational on their former subchannel. The ccw devices will be moved again to a proper subchannel if they become operational again on that subchannel. diff --git a/trunk/Documentation/scsi/ibmmca.txt b/trunk/Documentation/scsi/ibmmca.txt index 3920f28710c4..a810421f1fb3 100644 --- a/trunk/Documentation/scsi/ibmmca.txt +++ b/trunk/Documentation/scsi/ibmmca.txt @@ -524,7 +524,7 @@ - Michael Lang June 25 1997: (v1.8b) - 1) Some cosmetic changes for the handling of SCSI-device-types. + 1) Some cosmetical changes for the handling of SCSI-device-types. Now, also CD-Burners / WORMs and SCSI-scanners should work. For MO-drives I have no experience, therefore not yet supported. In logical_devices I changed from different type-variables to one @@ -914,7 +914,7 @@ in version 4.0. This was never really necessary, as all troubles were based on non-command related reasons up to now, so bypassing commands did not help to avoid any bugs. It is kept in 3.2X for debugging reasons. - 5) Dynamic reassignment of ldns was again verified and analyzed to be + 5) Dynamical reassignment of ldns was again verified and analyzed to be completely inoperational. This is corrected and should work now. 6) All commands that get sent to the SCSI adapter were verified and completed in such a way, that they are now completely conform to the @@ -1386,7 +1386,7 @@ concerning the Linux-kernel in special, this SCSI-driver comes without any warranty. Its functionality is tested as good as possible on certain machines and combinations of computer hardware, which does not exclude, - that data loss or severe damage of hardware is possible while using this + that dataloss or severe damage of hardware is possible while using this part of software on some arbitrary computer hardware or in combination with other software packages. It is highly recommended to make backup copies of your data before using this software. Furthermore, personal diff --git a/trunk/Documentation/scsi/lpfc.txt b/trunk/Documentation/scsi/lpfc.txt index 5741ea8aa88a..4dbe41370a6d 100644 --- a/trunk/Documentation/scsi/lpfc.txt +++ b/trunk/Documentation/scsi/lpfc.txt @@ -36,7 +36,7 @@ Cable pull and temporary device Loss: being removed, a switch rebooting, or a device reboot), the driver could hide the disappearance of the device from the midlayer. I/O's issued to the LLDD would simply be queued for a short duration, allowing the device - to reappear or link come back alive, with no inadvertent side effects + to reappear or link come back alive, with no inadvertant side effects to the system. If the driver did not hide these conditions, i/o would be errored by the driver, the mid-layer would exhaust its retries, and the device would be taken offline. Manual intervention would be required to diff --git a/trunk/Documentation/scsi/scsi_fc_transport.txt b/trunk/Documentation/scsi/scsi_fc_transport.txt index 75143f0c23b6..d403e46d8463 100644 --- a/trunk/Documentation/scsi/scsi_fc_transport.txt +++ b/trunk/Documentation/scsi/scsi_fc_transport.txt @@ -65,7 +65,7 @@ Overview: discussion will concentrate on NPIV. Note: World Wide Name assignment (and uniqueness guarantees) are left - up to an administrative entity controlling the vport. For example, + up to an administrative entity controling the vport. For example, if vports are to be associated with virtual machines, a XEN mgmt utility would be responsible for creating wwpn/wwnn's for the vport, using it's own naming authority and OUI. (Note: it already does this @@ -91,7 +91,7 @@ Device Trees and Vport Objects: Here's what to expect in the device tree : The typical Physical Port's Scsi_Host: /sys/devices/.../host17/ - and it has the typical descendant tree: + and it has the typical decendent tree: /sys/devices/.../host17/rport-17:0-0/target17:0:0/17:0:0:0: and then the vport is created on the Physical Port: /sys/devices/.../host17/vport-17:0-0 @@ -192,7 +192,7 @@ Vport States: independent of the adapter's link state. - Instantiation of the vport on the FC link via ELS traffic, etc. This is equivalent to a "link up" and successfull link initialization. - Further information can be found in the interfaces section below for + Futher information can be found in the interfaces section below for Vport Creation. Once a vport has been instantiated with the kernel/LLDD, a vport state diff --git a/trunk/Documentation/sh/clk.txt b/trunk/Documentation/sh/clk.txt index 114b595cfa97..9aef710e9a4b 100644 --- a/trunk/Documentation/sh/clk.txt +++ b/trunk/Documentation/sh/clk.txt @@ -12,7 +12,7 @@ means no changes to adjanced clock Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method, if it is present in ops structure. The method should set the clock rate and adjust all needed clocks according to the passed algo_id. -Exact values for algo_id are machine-dependent. For the sh7722, the following +Exact values for algo_id are machine-dependend. For the sh7722, the following values are defined: NO_CHANGE = 0, diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 6f6d117ac7e2..72aff61e7315 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1024,7 +1024,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. intel-mac-v3 Intel Mac Type 3 intel-mac-v4 Intel Mac Type 4 intel-mac-v5 Intel Mac Type 5 - intel-mac-auto Intel Mac (detect type according to subsystem id) macmini Intel Mac Mini (equivalent with type 3) macbook Intel Mac Book (eq. type 5) macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3) diff --git a/trunk/Documentation/sound/alsa/Audiophile-Usb.txt b/trunk/Documentation/sound/alsa/Audiophile-Usb.txt index a4c53d8961e1..2ad5e6306c44 100644 --- a/trunk/Documentation/sound/alsa/Audiophile-Usb.txt +++ b/trunk/Documentation/sound/alsa/Audiophile-Usb.txt @@ -236,15 +236,15 @@ The parameter can be given: alias snd-card-1 snd-usb-audio options snd-usb-audio index=1 device_setup=0x09 -CAUTION when initializing the device +CAUTION when initializaing the device ------------------------------------- * Correct initialization on the device requires that device_setup is given to the module BEFORE the device is turned on. So, if you use the "manual probing" method described above, take care to power-on the device AFTER this initialization. - * Failing to respect this will lead to a misconfiguration of the device. In this case - turn off the device, unprobe the snd-usb-audio module, then probe it again with + * Failing to respect this will lead in a misconfiguration of the device. In this case + turn off the device, unproble the snd-usb-audio module, then probe it again with correct device_setup parameter and then (and only then) turn on the device again. * If you've correctly initialized the device in a valid mode and then want to switch @@ -388,9 +388,9 @@ There are 2 main potential issues when using Jackd with the device: Jack supports big endian devices only in recent versions (thanks to Andreas Steinmetz for his first big-endian patch). I can't remember -exactly when this support was released into jackd, let's just say that +extacly when this support was released into jackd, let's just say that with jackd version 0.103.0 it's almost ok (just a small bug is affecting -16bits Big-Endian devices, but since you've read carefully the above +16bits Big-Endian devices, but since you've read carefully the above paragraphs, you're now using kernel >= 2.6.23 and your 16bits devices are now Little Endians ;-) ). diff --git a/trunk/Documentation/sound/alsa/hda_codec.txt b/trunk/Documentation/sound/alsa/hda_codec.txt index 34e87ec1379c..8e1b02526698 100644 --- a/trunk/Documentation/sound/alsa/hda_codec.txt +++ b/trunk/Documentation/sound/alsa/hda_codec.txt @@ -67,7 +67,7 @@ CONFIG_SND_HDA_POWER_SAVE kconfig. It's called when the codec needs to power up or may power down. The controller should check the all belonging codecs on the bus whether they are actually powered off (check codec->power_on), and optionally the driver may power down the -controller side, too. +contoller side, too. The bus instance is created via snd_hda_bus_new(). You need to pass the card instance, the template, and the pointer to store the diff --git a/trunk/Documentation/sound/alsa/soc/dapm.txt b/trunk/Documentation/sound/alsa/soc/dapm.txt index b2ed6983f40d..c784a18b94dc 100644 --- a/trunk/Documentation/sound/alsa/soc/dapm.txt +++ b/trunk/Documentation/sound/alsa/soc/dapm.txt @@ -68,7 +68,7 @@ Audio DAPM widgets fall into a number of types:- (Widgets are defined in include/sound/soc-dapm.h) Widgets are usually added in the codec driver and the machine driver. There are -convenience macros defined in soc-dapm.h that can be used to quickly build a +convience macros defined in soc-dapm.h that can be used to quickly build a list of widgets of the codecs and machines DAPM widgets. Most widgets have a name, register, shift and invert. Some widgets have extra diff --git a/trunk/Documentation/sparse.txt b/trunk/Documentation/sparse.txt index 42f43fa59f24..1a3bdc27d95e 100644 --- a/trunk/Documentation/sparse.txt +++ b/trunk/Documentation/sparse.txt @@ -73,10 +73,10 @@ recompiled, or use "make C=2" to run sparse on the files whether they need to be recompiled or not. The latter is a fast way to check the whole tree if you have already built it. -The optional make variable CF can be used to pass arguments to sparse. The -build system passes -Wbitwise to sparse automatically. To perform endianness -checks, you may define __CHECK_ENDIAN__: +The optional make variable CHECKFLAGS can be used to pass arguments to sparse. +The build system passes -Wbitwise to sparse automatically. To perform +endianness checks, you may define __CHECK_ENDIAN__: - make C=2 CF="-D__CHECK_ENDIAN__" + make C=2 CHECKFLAGS="-D__CHECK_ENDIAN__" These checks are disabled by default as they generate a host of warnings. diff --git a/trunk/Documentation/sysctl/vm.txt b/trunk/Documentation/sysctl/vm.txt index d79eeda7a699..8a4863c4edd4 100644 --- a/trunk/Documentation/sysctl/vm.txt +++ b/trunk/Documentation/sysctl/vm.txt @@ -116,7 +116,7 @@ of kilobytes free. The VM uses this number to compute a pages_min value for each lowmem zone in the system. Each lowmem zone gets a number of reserved free pages based proportionally on its size. -Some minimal amount of memory is needed to satisfy PF_MEMALLOC +Some minimal ammount of memory is needed to satisfy PF_MEMALLOC allocations; if you set this to lower than 1024KB, your system will become subtly broken, and prone to deadlock under high loads. diff --git a/trunk/Documentation/timers/highres.txt b/trunk/Documentation/timers/highres.txt index 21332233cef1..a73ecf5b4bdb 100644 --- a/trunk/Documentation/timers/highres.txt +++ b/trunk/Documentation/timers/highres.txt @@ -125,7 +125,7 @@ increase of flexibility and the avoidance of duplicated code across architectures justifies the slight increase of the binary size. The conversion of an architecture has no functional impact, but allows to -utilize the high resolution and dynamic tick functionalities without any change +utilize the high resolution and dynamic tick functionalites without any change to the clock event device and timer interrupt code. After the conversion the enabling of high resolution timers and dynamic ticks is simply provided by adding the kernel/time/Kconfig file to the architecture specific Kconfig and diff --git a/trunk/Documentation/usb/authorization.txt b/trunk/Documentation/usb/authorization.txt index 381b22ee7834..2af400609498 100644 --- a/trunk/Documentation/usb/authorization.txt +++ b/trunk/Documentation/usb/authorization.txt @@ -8,7 +8,7 @@ not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. As of now, when a USB device is connected it is configured and -its interfaces are immediately made available to the users. With this +it's interfaces inmediately made available to the users. With this modification, only if root authorizes the device to be configured will then it be possible to use it. diff --git a/trunk/Documentation/video4linux/sn9c102.txt b/trunk/Documentation/video4linux/sn9c102.txt index 73de4050d637..b26f5195af51 100644 --- a/trunk/Documentation/video4linux/sn9c102.txt +++ b/trunk/Documentation/video4linux/sn9c102.txt @@ -157,7 +157,7 @@ Loading can be done as shown below: [root@localhost home]# modprobe sn9c102 -Note that the module is called "sn9c102" for historic reasons, although it +Note that the module is called "sn9c102" for historic reasons, althought it does not just support the SN9C102. At this point all the devices supported by the driver and connected to the USB diff --git a/trunk/Documentation/vm/hugetlbpage.txt b/trunk/Documentation/vm/hugetlbpage.txt index ea8714fcc3ad..8a5b5763f0fe 100644 --- a/trunk/Documentation/vm/hugetlbpage.txt +++ b/trunk/Documentation/vm/hugetlbpage.txt @@ -77,7 +77,7 @@ memory that is preset in system at this time. System administrators may want to put this command in one of the local rc init files. This will enable the kernel to request huge pages early in the boot process (when the possibility of getting physical contiguous pages is still very high). In either -case, administrators will want to verify the number of hugepages actually +case, adminstrators will want to verify the number of hugepages actually allocated by checking the sysctl or meminfo. /proc/sys/vm/nr_overcommit_hugepages indicates how large the pool of diff --git a/trunk/Documentation/vm/numa_memory_policy.txt b/trunk/Documentation/vm/numa_memory_policy.txt index 6aaaeb38730c..bad16d3f6a47 100644 --- a/trunk/Documentation/vm/numa_memory_policy.txt +++ b/trunk/Documentation/vm/numa_memory_policy.txt @@ -58,7 +58,7 @@ most general to most specific: the policy at the time they were allocated. VMA Policy: A "VMA" or "Virtual Memory Area" refers to a range of a task's - virtual address space. A task may define a specific policy for a range + virtual adddress space. A task may define a specific policy for a range of its virtual address space. See the MEMORY POLICIES APIS section, below, for an overview of the mbind() system call used to set a VMA policy. @@ -353,7 +353,7 @@ follows: Because of this extra reference counting, and because we must lookup shared policies in a tree structure under spinlock, shared policies are - more expensive to use in the page allocation path. This is especially + more expensive to use in the page allocation path. This is expecially true for shared policies on shared memory regions shared by tasks running on different NUMA nodes. This extra overhead can be avoided by always falling back to task or system default policy for shared memory regions, diff --git a/trunk/Documentation/volatile-considered-harmful.txt b/trunk/Documentation/volatile-considered-harmful.txt index 991c26a6ef64..10c2e411cca8 100644 --- a/trunk/Documentation/volatile-considered-harmful.txt +++ b/trunk/Documentation/volatile-considered-harmful.txt @@ -114,6 +114,6 @@ CREDITS Original impetus and research by Randy Dunlap Written by Jonathan Corbet -Improvements via comments from Satyam Sharma, Johannes Stezenbach, Jesper +Improvements via coments from Satyam Sharma, Johannes Stezenbach, Jesper Juhl, Heikki Orsila, H. Peter Anvin, Philipp Hahn, and Stefan Richter. diff --git a/trunk/Kbuild b/trunk/Kbuild index f056b4feee51..e750e9c3fe59 100644 --- a/trunk/Kbuild +++ b/trunk/Kbuild @@ -43,7 +43,7 @@ $(obj)/$(bounds-file): kernel/bounds.s Kbuild # 2) Generate asm-offsets.h # -offsets-file := include/asm/asm-offsets.h +offsets-file := include/asm-$(SRCARCH)/asm-offsets.h always += $(offsets-file) targets += $(offsets-file) @@ -81,6 +81,7 @@ arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \ $(call if_changed_dep,cc_s_c) $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild + $(Q)mkdir -p $(dir $@) $(call cmd,offsets) ##### diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 03c5d6ccb9f8..4cbf6016a9b9 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3123,12 +3123,6 @@ W: http://oss.oracle.com/projects/ocfs2/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2.git S: Supported -OMFS FILESYSTEM -P: Bob Copeland -M: me@bobcopeland.com -L: linux-karma-devel@lists.sourceforge.net -S: Maintained - OMNIKEY CARDMAN 4000 DRIVER P: Harald Welte M: laforge@gnumonks.org diff --git a/trunk/Makefile b/trunk/Makefile index 40f24810116c..3cad7db5eba7 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -205,9 +205,6 @@ ifeq ($(ARCH),x86_64) SRCARCH := x86 endif -# Where to locate arch specific headers -hdr-arch := $(SRCARCH) - KCONFIG_CONFIG ?= .config # SHELL used by kbuild @@ -329,8 +326,7 @@ AFLAGS_KERNEL = # Needed to be compatible with the O= option LINUXINCLUDE := -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ - -I$(srctree)/arch/$(hdr-arch)/include \ - -include include/linux/autoconf.h + -include include/linux/autoconf.h KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) @@ -926,9 +922,7 @@ ifneq ($(KBUILD_SRC),) /bin/false; \ fi; $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi; - $(Q)if [ -e $(srctree)/include/asm-$(SRCARCH)/system.h ]; then \ - ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ - fi + $(Q)ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm endif # prepare2 creates a makefile if using a separate output directory @@ -954,34 +948,22 @@ export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) # The asm symlink changes when $(ARCH) changes. # Detect this and ask user to run make mrproper -define check-symlink - set -e; \ - if [ -L include/asm ]; then \ - asmlink=`readlink include/asm | cut -d '-' -f 2`; \ - if [ "$$asmlink" != "$(SRCARCH)" ]; then \ + +include/asm: FORCE + $(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`; \ + if [ -L include/asm ]; then \ + if [ "$$asmlink" != "$(SRCARCH)" ]; then \ echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \ echo " set ARCH or save .config and run 'make mrproper' to fix it"; \ - exit 1; \ - fi; \ + exit 1; \ + fi; \ + else \ + echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ + if [ ! -d include ]; then \ + mkdir -p include; \ + fi; \ + ln -fsn asm-$(SRCARCH) $@; \ fi -endef - -# We create the target directory of the symlink if it does -# not exist so the test in chack-symlink works and we have a -# directory for generated filesas used by some architectures. -define create-symlink - if [ ! -L include/asm ]; then \ - echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ - if [ ! -d include/asm-$(SRCARCH) ]; then \ - mkdir -p include/asm-$(SRCARCH); \ - fi; \ - ln -fsn asm-$(SRCARCH) $@; \ - fi -endef - -include/asm: FORCE - $(Q)$(check-symlink) - $(Q)$(create-symlink) # Generate some files # --------------------------------------------------------------------------- @@ -1028,43 +1010,36 @@ firmware_install: FORCE # --------------------------------------------------------------------------- # Kernel headers +INSTALL_HDR_PATH=$(objtree)/usr +export INSTALL_HDR_PATH -#Default location for installed headers -export INSTALL_HDR_PATH = $(objtree)/usr - -hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj -# Find out where the Kbuild file is located to support -# arch/$(ARCH)/include/asm -hdr-dir = $(strip \ - $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild), \ - arch/$(hdr-arch)/include/asm, include/asm-$(hdr-arch))) - -# If we do an all arch process set dst to asm-$(hdr-arch) -hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) - -PHONY += __headers -__headers: include/linux/version.h scripts_basic FORCE - $(Q)$(MAKE) $(build)=scripts scripts/unifdef +HDRFILTER=generic i386 x86_64 +HDRARCHES=$(filter-out $(HDRFILTER),$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild))) PHONY += headers_install_all -headers_install_all: - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/headers.sh install +headers_install_all: include/linux/version.h scripts_basic FORCE + $(Q)$(MAKE) $(build)=scripts scripts/unifdef + $(Q)for arch in $(HDRARCHES); do \ + $(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch ;\ + done PHONY += headers_install -headers_install: __headers - $(if $(wildcard $(srctree)/$(hdr-dir)/Kbuild),, \ - $(error Headers not exportable for the $(SRCARCH) architecture)) - $(Q)$(MAKE) $(hdr-inst)=include - $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) +headers_install: include/linux/version.h scripts_basic FORCE + @if [ ! -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \ + echo '*** Error: Headers not exportable for this architecture ($(SRCARCH))'; \ + exit 1 ; fi + $(Q)$(MAKE) $(build)=scripts scripts/unifdef + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include PHONY += headers_check_all headers_check_all: headers_install_all - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/headers.sh check + $(Q)for arch in $(HDRARCHES); do \ + $(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch HDRCHECK=1 ;\ + done PHONY += headers_check headers_check: headers_install - $(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1 - $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) HDRCHECK=1 + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include HDRCHECK=1 # --------------------------------------------------------------------------- # Modules @@ -1156,7 +1131,7 @@ MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ include/linux/bounds.h include/asm*/asm-offsets.h \ - Module.symvers Module.markers tags TAGS cscope* + Module.symvers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules # @@ -1175,7 +1150,7 @@ clean: archclean $(clean-dirs) \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o -name 'Module.markers' -o -name '.tmp_*.o.*' \) \ + -o -name 'Module.markers' \) \ -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config @@ -1249,17 +1224,21 @@ help: @echo ' cscope - Generate cscope index' @echo ' kernelrelease - Output the release version string' @echo ' kernelversion - Output the version stored in Makefile' - @echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \ + @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \ + echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \ echo ' (default: $(INSTALL_HDR_PATH))'; \ - echo '' + fi + @echo '' @echo 'Static analysers' @echo ' checkstack - Generate a list of stack hogs' @echo ' namespacecheck - Name space analysis on compiled kernel' @echo ' versioncheck - Sanity check on version.h usage' @echo ' includecheck - Check for duplicate included header files' @echo ' export_report - List the usages of all exported symbols' - @echo ' headers_check - Sanity check on exported headers'; \ - echo '' + @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \ + echo ' headers_check - Sanity check on exported headers'; \ + fi + @echo '' @echo 'Kernel packaging:' @$(MAKE) $(build)=$(package-dir) help @echo '' @@ -1432,11 +1411,7 @@ define find-sources \( -name config -o -name 'asm-*' \) -prune \ -o -name $1 -print; \ for arch in $(ALLINCLUDE_ARCHS) ; do \ - test -e $(__srctree)include/asm-$${arch} && \ - find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \ - -name $1 -print; \ - test -e $(__srctree)arch/$${arch}/include/asm && \ - find $(__srctree)arch/$${arch}/include/asm $(RCS_FIND_IGNORE) \ + find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \ -name $1 -print; \ done ; \ find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 364c6dadde0a..b0fabfa864ff 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -59,24 +59,6 @@ config HAVE_KPROBES config HAVE_KRETPROBES def_bool n -# -# An arch should select this if it provides all these things: -# -# task_pt_regs() in asm/processor.h or asm/ptrace.h -# arch_has_single_step() if there is hardware single-step support -# arch_has_block_step() if there is hardware block-step support -# arch_ptrace() and not #define __ARCH_SYS_PTRACE -# compat_arch_ptrace() and #define __ARCH_WANT_COMPAT_SYS_PTRACE -# asm/syscall.h supplying asm-generic/syscall.h interface -# linux/regset.h user_regset interfaces -# CORE_DUMP_USE_REGSET #define'd in linux/elf.h -# TIF_SYSCALL_TRACE calls tracehook_report_syscall_{entry,exit} -# TIF_NOTIFY_RESUME calls tracehook_notify_resume() -# signal delivery calls tracehook_signal_handler() -# -config HAVE_ARCH_TRACEHOOK - def_bool n - config HAVE_DMA_ATTRS def_bool n diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index 6e943135f0e0..32ca1b927307 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -253,15 +253,15 @@ do_osf_statfs(struct dentry * dentry, struct osf_statfs __user *buffer, } asmlinkage int -osf_statfs(char __user *pathname, struct osf_statfs __user *buffer, unsigned long bufsiz) +osf_statfs(char __user *path, struct osf_statfs __user *buffer, unsigned long bufsiz) { - struct path path; + struct nameidata nd; int retval; - retval = user_path(pathname, &path); + retval = user_path_walk(path, &nd); if (!retval) { - retval = do_osf_statfs(path.dentry, buffer, bufsiz); - path_put(&path); + retval = do_osf_statfs(nd.path.dentry, buffer, bufsiz); + path_put(&nd.path); } return retval; } diff --git a/trunk/arch/alpha/mm/init.c b/trunk/arch/alpha/mm/init.c index 234e42b8ee74..40c15e7301de 100644 --- a/trunk/arch/alpha/mm/init.c +++ b/trunk/arch/alpha/mm/init.c @@ -94,6 +94,36 @@ __bad_page(void) return pte_mkdirty(mk_pte(virt_to_page(EMPTY_PGE), PAGE_SHARED)); } +#ifndef CONFIG_DISCONTIGMEM +void +show_mem(void) +{ + long i,free = 0,total = 0,reserved = 0; + long shared = 0, cached = 0; + + printk("\nMem-info:\n"); + show_free_areas(); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (!page_count(mem_map+i)) + free++; + else + shared += page_count(mem_map + i) - 1; + } + printk("%ld pages of RAM\n",total); + printk("%ld free pages\n",free); + printk("%ld reserved pages\n",reserved); + printk("%ld pages shared\n",shared); + printk("%ld pages swap cached\n",cached); +} +#endif + static inline unsigned long load_PCB(struct pcb_struct *pcb) { diff --git a/trunk/arch/alpha/mm/numa.c b/trunk/arch/alpha/mm/numa.c index a13de49d1265..d8c4ceaf00b9 100644 --- a/trunk/arch/alpha/mm/numa.c +++ b/trunk/arch/alpha/mm/numa.c @@ -359,3 +359,38 @@ void __init mem_init(void) mem_stress(); #endif } + +void +show_mem(void) +{ + long i,free = 0,total = 0,reserved = 0; + long shared = 0, cached = 0; + int nid; + + printk("\nMem-info:\n"); + show_free_areas(); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + for_each_online_node(nid) { + unsigned long flags; + pgdat_resize_lock(NODE_DATA(nid), &flags); + i = node_spanned_pages(nid); + while (i-- > 0) { + struct page *page = nid_page_nr(nid, i); + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (!page_count(page)) + free++; + else + shared += page_count(page) - 1; + } + pgdat_resize_unlock(NODE_DATA(nid), &flags); + } + printk("%ld pages of RAM\n",total); + printk("%ld free pages\n",free); + printk("%ld reserved pages\n",reserved); + printk("%ld pages shared\n",shared); + printk("%ld pages swap cached\n",cached); +} diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index b20995a82e04..2f0747744236 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -67,7 +67,7 @@ tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi -tune-$(CONFIG_CPU_ARM946T) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) +tune-$(CONFIG_CPU_ARM946E) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index 69130f365904..dd2947342604 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -280,7 +280,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, /* * Trying to unmap an invalid mapping */ - if (dma_mapping_error(dev, dma_addr)) { + if (dma_mapping_error(dma_addr)) { dev_err(dev, "Trying to unmap invalid mapping\n"); return; } diff --git a/trunk/arch/arm/mach-at91/at91cap9_devices.c b/trunk/arch/arm/mach-at91/at91cap9_devices.c index dc8b40783d94..747b9dedab88 100644 --- a/trunk/arch/arm/mach-at91/at91cap9_devices.c +++ b/trunk/arch/arm/mach-at91/at91cap9_devices.c @@ -377,7 +377,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct atmel_nand_data nand_data; +static struct at91_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -395,7 +395,7 @@ static struct resource nand_resources[] = { }; static struct platform_device at91cap9_nand_device = { - .name = "atmel_nand", + .name = "at91_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -404,7 +404,7 @@ static struct platform_device at91cap9_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct atmel_nand_data *data) +void __init at91_add_device_nand(struct at91_nand_data *data) { unsigned long csa, mode; @@ -445,7 +445,7 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) platform_device_register(&at91cap9_nand_device); } #else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} +void __init at91_add_device_nand(struct at91_nand_data *data) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91rm9200_devices.c b/trunk/arch/arm/mach-at91/at91rm9200_devices.c index 8ced9bc82099..de19bee83f75 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_devices.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_devices.c @@ -369,7 +369,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct atmel_nand_data nand_data; +static struct at91_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -382,7 +382,7 @@ static struct resource nand_resources[] = { }; static struct platform_device at91rm9200_nand_device = { - .name = "atmel_nand", + .name = "at91_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -391,7 +391,7 @@ static struct platform_device at91rm9200_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct atmel_nand_data *data) +void __init at91_add_device_nand(struct at91_nand_data *data) { unsigned int csa; @@ -429,7 +429,7 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) platform_device_register(&at91rm9200_nand_device); } #else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} +void __init at91_add_device_nand(struct at91_nand_data *data) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9260_devices.c b/trunk/arch/arm/mach-at91/at91sam9260_devices.c index cae5f52f1278..86cba4ac29b1 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9260_devices.c @@ -284,7 +284,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct atmel_nand_data nand_data; +static struct at91_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -302,7 +302,7 @@ static struct resource nand_resources[] = { }; static struct platform_device at91sam9260_nand_device = { - .name = "atmel_nand", + .name = "at91_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -311,7 +311,7 @@ static struct platform_device at91sam9260_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct atmel_nand_data *data) +void __init at91_add_device_nand(struct at91_nand_data *data) { unsigned long csa, mode; @@ -373,7 +373,7 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) platform_device_register(&at91sam9260_nand_device); } #else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} +void __init at91_add_device_nand(struct at91_nand_data *data) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9261_devices.c b/trunk/arch/arm/mach-at91/at91sam9261_devices.c index 483d436af22d..ec1891375dfb 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9261_devices.c @@ -199,7 +199,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct atmel_nand_data nand_data; +static struct at91_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -211,8 +211,8 @@ static struct resource nand_resources[] = { } }; -static struct platform_device atmel_nand_device = { - .name = "atmel_nand", +static struct platform_device at91_nand_device = { + .name = "at91_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -221,7 +221,7 @@ static struct platform_device atmel_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct atmel_nand_data *data) +void __init at91_add_device_nand(struct at91_nand_data *data) { unsigned long csa, mode; @@ -262,11 +262,11 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */ nand_data = *data; - platform_device_register(&atmel_nand_device); + platform_device_register(&at91_nand_device); } #else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} +void __init at91_add_device_nand(struct at91_nand_data *data) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9263_devices.c b/trunk/arch/arm/mach-at91/at91sam9263_devices.c index 9762b15f658a..8a81f76f0200 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9263_devices.c @@ -353,7 +353,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct atmel_nand_data nand_data; +static struct at91_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -371,7 +371,7 @@ static struct resource nand_resources[] = { }; static struct platform_device at91sam9263_nand_device = { - .name = "atmel_nand", + .name = "at91_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -380,7 +380,7 @@ static struct platform_device at91sam9263_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct atmel_nand_data *data) +void __init at91_add_device_nand(struct at91_nand_data *data) { unsigned long csa, mode; @@ -421,7 +421,7 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) platform_device_register(&at91sam9263_nand_device); } #else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} +void __init at91_add_device_nand(struct at91_nand_data *data) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c index 5f3094870cad..ae28101e7542 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c @@ -195,7 +195,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct atmel_nand_data nand_data; +static struct at91_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -212,8 +212,8 @@ static struct resource nand_resources[] = { } }; -static struct platform_device atmel_nand_device = { - .name = "atmel_nand", +static struct platform_device at91_nand_device = { + .name = "at91_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -222,7 +222,7 @@ static struct platform_device atmel_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct atmel_nand_data *data) +void __init at91_add_device_nand(struct at91_nand_data *data) { unsigned long csa; @@ -259,11 +259,11 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_set_A_periph(AT91_PIN_PB5, 0); /* NANDWE */ nand_data = *data; - platform_device_register(&atmel_nand_device); + platform_device_register(&at91_nand_device); } #else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} +void __init at91_add_device_nand(struct at91_nand_data *data) {} #endif diff --git a/trunk/arch/arm/mach-at91/board-cam60.c b/trunk/arch/arm/mach-at91/board-cam60.c index af2c33aff1a8..b22a1a004055 100644 --- a/trunk/arch/arm/mach-at91/board-cam60.c +++ b/trunk/arch/arm/mach-at91/board-cam60.c @@ -142,7 +142,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return cam60_nand_partition; } -static struct atmel_nand_data __initdata cam60_nand_data = { +static struct at91_nand_data __initdata cam60_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not there diff --git a/trunk/arch/arm/mach-at91/board-cap9adk.c b/trunk/arch/arm/mach-at91/board-cap9adk.c index a1c41d7c0be9..8a2a958639db 100644 --- a/trunk/arch/arm/mach-at91/board-cap9adk.c +++ b/trunk/arch/arm/mach-at91/board-cap9adk.c @@ -181,7 +181,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return cap9adk_nand_partitions; } -static struct atmel_nand_data __initdata cap9adk_nand_data = { +static struct at91_nand_data __initdata cap9adk_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/trunk/arch/arm/mach-at91/board-dk.c b/trunk/arch/arm/mach-at91/board-dk.c index 02a70b2f355b..dab958d25926 100644 --- a/trunk/arch/arm/mach-at91/board-dk.c +++ b/trunk/arch/arm/mach-at91/board-dk.c @@ -147,7 +147,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return dk_nand_partition; } -static struct atmel_nand_data __initdata dk_nand_data = { +static struct at91_nand_data __initdata dk_nand_data = { .ale = 22, .cle = 21, .det_pin = AT91_PIN_PB1, diff --git a/trunk/arch/arm/mach-at91/board-kb9202.c b/trunk/arch/arm/mach-at91/board-kb9202.c index 082ed59365a4..cb065febd95e 100644 --- a/trunk/arch/arm/mach-at91/board-kb9202.c +++ b/trunk/arch/arm/mach-at91/board-kb9202.c @@ -105,7 +105,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return kb9202_nand_partition; } -static struct atmel_nand_data __initdata kb9202_nand_data = { +static struct at91_nand_data __initdata kb9202_nand_data = { .ale = 22, .cle = 21, // .det_pin = ... not there diff --git a/trunk/arch/arm/mach-at91/board-sam9-l9260.c b/trunk/arch/arm/mach-at91/board-sam9-l9260.c index 57a6221943ed..8f76af5e219a 100644 --- a/trunk/arch/arm/mach-at91/board-sam9-l9260.c +++ b/trunk/arch/arm/mach-at91/board-sam9-l9260.c @@ -141,7 +141,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct atmel_nand_data __initdata ek_nand_data = { +static struct at91_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/trunk/arch/arm/mach-at91/board-sam9260ek.c b/trunk/arch/arm/mach-at91/board-sam9260ek.c index 6a680795c3c8..4d1d9c777084 100644 --- a/trunk/arch/arm/mach-at91/board-sam9260ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9260ek.c @@ -178,7 +178,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct atmel_nand_data __initdata ek_nand_data = { +static struct at91_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/trunk/arch/arm/mach-at91/board-sam9261ek.c b/trunk/arch/arm/mach-at91/board-sam9261ek.c index 43dfbd0d543a..08382c0df221 100644 --- a/trunk/arch/arm/mach-at91/board-sam9261ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9261ek.c @@ -183,7 +183,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct atmel_nand_data __initdata ek_nand_data = { +static struct at91_nand_data __initdata ek_nand_data = { .ale = 22, .cle = 21, // .det_pin = ... not connected diff --git a/trunk/arch/arm/mach-at91/board-sam9263ek.c b/trunk/arch/arm/mach-at91/board-sam9263ek.c index 6605a0980117..b4cd5d0ed597 100644 --- a/trunk/arch/arm/mach-at91/board-sam9263ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9263ek.c @@ -187,7 +187,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct atmel_nand_data __initdata ek_nand_data = { +static struct at91_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/trunk/arch/arm/mach-at91/board-sam9rlek.c b/trunk/arch/arm/mach-at91/board-sam9rlek.c index 66e77bb2e079..b6a70fc735c3 100644 --- a/trunk/arch/arm/mach-at91/board-sam9rlek.c +++ b/trunk/arch/arm/mach-at91/board-sam9rlek.c @@ -96,7 +96,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct atmel_nand_data __initdata ek_nand_data = { +static struct at91_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/trunk/arch/arm/mach-at91/board-yl-9200.c b/trunk/arch/arm/mach-at91/board-yl-9200.c index bbbfd06f5e0c..7079050ab88d 100755 --- a/trunk/arch/arm/mach-at91/board-yl-9200.c +++ b/trunk/arch/arm/mach-at91/board-yl-9200.c @@ -180,7 +180,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return yl9200_nand_partition; } -static struct atmel_nand_data __initdata yl9200_nand_data = { +static struct at91_nand_data __initdata yl9200_nand_data = { .ale = 6, .cle = 7, // .det_pin = ... not connected diff --git a/trunk/arch/arm/plat-s3c24xx/dma.c b/trunk/arch/arm/plat-s3c24xx/dma.c index 8c5e656d5d8c..60f162dc4fad 100644 --- a/trunk/arch/arm/plat-s3c24xx/dma.c +++ b/trunk/arch/arm/plat-s3c24xx/dma.c @@ -1304,7 +1304,7 @@ struct sysdev_class dma_sysclass = { /* kmem cache implementation */ -static void s3c2410_dma_cache_ctor(void *p) +static void s3c2410_dma_cache_ctor(struct kmem_cache *c, void *p) { memset(p, 0, sizeof(struct s3c2410_dma_buf)); } diff --git a/trunk/arch/avr32/boards/atstk1000/Kconfig b/trunk/arch/avr32/boards/atstk1000/Kconfig index 8dc48214f0b7..af90b00100fd 100644 --- a/trunk/arch/avr32/boards/atstk1000/Kconfig +++ b/trunk/arch/avr32/boards/atstk1000/Kconfig @@ -18,10 +18,6 @@ config BOARD_ATSTK1004 bool "ATSTK1004" select CPU_AT32AP7002 -config BOARD_ATSTK1006 - bool "ATSTK1006" - select CPU_AT32AP7000 - endchoice diff --git a/trunk/arch/avr32/boards/atstk1000/Makefile b/trunk/arch/avr32/boards/atstk1000/Makefile index edecee03742d..beead86462e8 100644 --- a/trunk/arch/avr32/boards/atstk1000/Makefile +++ b/trunk/arch/avr32/boards/atstk1000/Makefile @@ -2,4 +2,3 @@ obj-y += setup.o flash.o obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o obj-$(CONFIG_BOARD_ATSTK1003) += atstk1003.o obj-$(CONFIG_BOARD_ATSTK1004) += atstk1004.o -obj-$(CONFIG_BOARD_ATSTK1006) += atstk1002.o diff --git a/trunk/arch/avr32/boards/atstk1000/atstk1002.c b/trunk/arch/avr32/boards/atstk1000/atstk1002.c index 8538ba75ef92..e11659b732fa 100644 --- a/trunk/arch/avr32/boards/atstk1000/atstk1002.c +++ b/trunk/arch/avr32/boards/atstk1000/atstk1002.c @@ -1,7 +1,7 @@ /* - * ATSTK1002/ATSTK1006 daughterboard-specific init code + * ATSTK1002 daughterboard-specific init code * - * Copyright (C) 2005-2007 Atmel Corporation + * Copyright (C) 2005-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 @@ -21,8 +21,6 @@ #include #include -#include - #include #include #include @@ -37,74 +35,6 @@ unsigned long at32_board_osc_rates[3] = { [2] = 12000000, /* 12 MHz on osc1 */ }; -/* - * The ATSTK1006 daughterboard is very similar to the ATSTK1002. Both - * have the AT32AP7000 chip on board; the difference is that the - * STK1006 has 128 MB SDRAM (the STK1002 uses the 8 MB SDRAM chip on - * the STK1000 motherboard) and 256 MB NAND flash (the STK1002 has - * none.) - * - * The RAM difference is handled by the boot loader, so the only - * difference we end up handling here is the NAND flash. - */ -#ifdef CONFIG_BOARD_ATSTK1006 -#include -#include - -static struct smc_timing nand_timing __initdata = { - .ncs_read_setup = 0, - .nrd_setup = 10, - .ncs_write_setup = 0, - .nwe_setup = 10, - - .ncs_read_pulse = 30, - .nrd_pulse = 15, - .ncs_write_pulse = 30, - .nwe_pulse = 15, - - .read_cycle = 30, - .write_cycle = 30, - - .ncs_read_recover = 0, - .nrd_recover = 15, - .ncs_write_recover = 0, - /* WE# high -> RE# low min 60 ns */ - .nwe_recover = 50, -}; - -static struct smc_config nand_config __initdata = { - .bus_width = 1, - .nrd_controlled = 1, - .nwe_controlled = 1, - .nwait_mode = 0, - .byte_write = 0, - .tdf_cycles = 2, - .tdf_mode = 0, -}; - -static struct mtd_partition nand_partitions[] = { - { - .name = "main", - .offset = 0x00000000, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct mtd_partition *nand_part_info(int size, int *num_partitions) -{ - *num_partitions = ARRAY_SIZE(nand_partitions); - return nand_partitions; -} - -struct atmel_nand_data atstk1006_nand_data __initdata = { - .cle = 21, - .ale = 22, - .rdy_pin = GPIO_PIN_PB(30), - .enable_pin = GPIO_PIN_PB(29), - .partition_info = nand_part_info, -}; -#endif - struct eth_addr { u8 addr[6]; }; @@ -262,21 +192,6 @@ void __init setup_board(void) at32_setup_serial_console(0); } -#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - -/* MMC card detect requires MACB0 *NOT* be used */ -#ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM -static struct mci_platform_data __initdata mci0_data = { - .detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */ - .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */ -}; -#define MCI_PDATA &mci0_data -#else -#define MCI_PDATA NULL -#endif /* SW6 for sd{cd,wp} routing */ - -#endif /* SW2 for MMC signal routing */ - static int __init atstk1002_init(void) { /* @@ -303,12 +218,6 @@ static int __init atstk1002_init(void) at32_add_system_devices(); -#ifdef CONFIG_BOARD_ATSTK1006 - smc_set_timing(&nand_config, &nand_timing); - smc_set_configuration(3, &nand_config); - at32_add_device_nand(0, &atstk1006_nand_data); -#endif - #ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM at32_add_device_usart(1); #else @@ -326,7 +235,7 @@ static int __init atstk1002_init(void) at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); #endif #ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM - at32_add_device_mci(0, MCI_PDATA); + at32_add_device_mci(0, NULL); #endif #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM set_hw_addr(at32_add_device_eth(1, ð_data[1])); diff --git a/trunk/arch/avr32/boards/atstk1000/atstk1003.c b/trunk/arch/avr32/boards/atstk1000/atstk1003.c index 591fc73b554a..ea109f435a83 100644 --- a/trunk/arch/avr32/boards/atstk1000/atstk1003.c +++ b/trunk/arch/avr32/boards/atstk1000/atstk1003.c @@ -154,7 +154,7 @@ static int __init atstk1003_init(void) at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); #endif #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_mci(0, NULL); + at32_add_device_mci(0); #endif at32_add_device_usba(0, NULL); #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM diff --git a/trunk/arch/avr32/boards/atstk1000/atstk1004.c b/trunk/arch/avr32/boards/atstk1000/atstk1004.c index d9c5e0a21256..c7236df74d74 100644 --- a/trunk/arch/avr32/boards/atstk1000/atstk1004.c +++ b/trunk/arch/avr32/boards/atstk1000/atstk1004.c @@ -137,7 +137,7 @@ static int __init atstk1004_init(void) at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); #endif #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_mci(0, NULL); + at32_add_device_mci(0); #endif at32_add_device_lcdc(0, &atstk1000_lcdc_data, fbmem_start, fbmem_size, 0); diff --git a/trunk/arch/avr32/kernel/time.c b/trunk/arch/avr32/kernel/time.c index 7e7f32771ae1..abd954fb7ba0 100644 --- a/trunk/arch/avr32/kernel/time.c +++ b/trunk/arch/avr32/kernel/time.c @@ -43,9 +43,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evdev = dev_id; - if (unlikely(!(intc_get_pending(0) & 1))) - return IRQ_NONE; - /* * Disable the interrupt until the clockevent subsystem * reprograms it. @@ -58,8 +55,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction timer_irqaction = { .handler = timer_interrupt, - /* Oprofile uses the same irq as the timer, so allow it to be shared */ - .flags = IRQF_TIMER | IRQF_DISABLED | IRQF_SHARED, + .flags = IRQF_TIMER | IRQF_DISABLED, .name = "avr32_comparator", }; diff --git a/trunk/arch/avr32/mach-at32ap/at32ap700x.c b/trunk/arch/avr32/mach-at32ap/at32ap700x.c index 1617048c86c5..604f44f5dd16 100644 --- a/trunk/arch/avr32/mach-at32ap/at32ap700x.c +++ b/trunk/arch/avr32/mach-at32ap/at32ap700x.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -1286,6 +1285,7 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) { struct mci_platform_data _data; struct platform_device *pdev; + struct dw_dma_slave *dws; if (id != 0) return NULL; @@ -1300,9 +1300,7 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) if (!data) { data = &_data; - memset(data, -1, sizeof(struct mci_platform_data)); - data->detect_pin = GPIO_PIN_NONE; - data->wp_pin = GPIO_PIN_NONE; + memset(data, 0, sizeof(struct mci_platform_data)); } if (platform_device_add_data(pdev, data, @@ -1316,10 +1314,12 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ - if (gpio_is_valid(data->detect_pin)) - at32_select_gpio(data->detect_pin, 0); - if (gpio_is_valid(data->wp_pin)) - at32_select_gpio(data->wp_pin, 0); + if (data) { + if (data->detect_pin != GPIO_PIN_NONE) + at32_select_gpio(data->detect_pin, 0); + if (data->wp_pin != GPIO_PIN_NONE) + at32_select_gpio(data->wp_pin, 0); + } atmel_mci0_pclk.dev = &pdev->dev; @@ -1853,11 +1853,11 @@ at32_add_device_cf(unsigned int id, unsigned int extint, if (at32_init_ide_or_cf(pdev, data->cs, extint)) goto fail; - if (gpio_is_valid(data->detect_pin)) + if (data->detect_pin != GPIO_PIN_NONE) at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH); - if (gpio_is_valid(data->reset_pin)) + if (data->reset_pin != GPIO_PIN_NONE) at32_select_gpio(data->reset_pin, 0); - if (gpio_is_valid(data->vcc_pin)) + if (data->vcc_pin != GPIO_PIN_NONE) at32_select_gpio(data->vcc_pin, 0); /* READY is used as extint, so we can't select it as gpio */ @@ -1870,58 +1870,6 @@ at32_add_device_cf(unsigned int id, unsigned int extint, } #endif -/* -------------------------------------------------------------------- - * NAND Flash / SmartMedia - * -------------------------------------------------------------------- */ -static struct resource smc_cs3_resource[] __initdata = { - { - .start = 0x0c000000, - .end = 0x0fffffff, - .flags = IORESOURCE_MEM, - }, { - .start = 0xfff03c00, - .end = 0xfff03fff, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device *__init -at32_add_device_nand(unsigned int id, struct atmel_nand_data *data) -{ - struct platform_device *pdev; - - if (id != 0 || !data) - return NULL; - - pdev = platform_device_alloc("atmel_nand", id); - if (!pdev) - goto fail; - - if (platform_device_add_resources(pdev, smc_cs3_resource, - ARRAY_SIZE(smc_cs3_resource))) - goto fail; - - if (platform_device_add_data(pdev, data, - sizeof(struct atmel_nand_data))) - goto fail; - - set_ebi_sfr_bits(HMATRIX_BIT(CS3A)); - if (data->enable_pin) - at32_select_gpio(data->enable_pin, - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - if (data->rdy_pin) - at32_select_gpio(data->rdy_pin, 0); - if (data->det_pin) - at32_select_gpio(data->det_pin, 0); - - platform_device_add(pdev); - return pdev; - -fail: - platform_device_put(pdev); - return NULL; -} - /* -------------------------------------------------------------------- * AC97C * -------------------------------------------------------------------- */ @@ -1937,11 +1885,9 @@ static struct clk atmel_ac97c0_pclk = { .index = 10, }; -struct platform_device *__init -at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data) +struct platform_device *__init at32_add_device_ac97c(unsigned int id) { struct platform_device *pdev; - struct ac97c_platform_data _data; if (id != 0) return NULL; @@ -1952,37 +1898,19 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data) if (platform_device_add_resources(pdev, atmel_ac97c0_resource, ARRAY_SIZE(atmel_ac97c0_resource))) - goto fail; - - if (!data) { - data = &_data; - memset(data, 0, sizeof(struct ac97c_platform_data)); - data->reset_pin = GPIO_PIN_NONE; - } - - data->dma_rx_periph_id = 3; - data->dma_tx_periph_id = 4; - data->dma_controller_id = 0; - - if (platform_device_add_data(pdev, data, - sizeof(struct ac97c_platform_data))) - goto fail; - - select_peripheral(PB(20), PERIPH_B, 0); /* SDO */ - select_peripheral(PB(21), PERIPH_B, 0); /* SYNC */ - select_peripheral(PB(22), PERIPH_B, 0); /* SCLK */ - select_peripheral(PB(23), PERIPH_B, 0); /* SDI */ + goto err_add_resources; - /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ - if (data->reset_pin != GPIO_PIN_NONE) - at32_select_gpio(data->reset_pin, 0); + select_peripheral(PB(20), PERIPH_B, 0); /* SYNC */ + select_peripheral(PB(21), PERIPH_B, 0); /* SDO */ + select_peripheral(PB(22), PERIPH_B, 0); /* SDI */ + select_peripheral(PB(23), PERIPH_B, 0); /* SCLK */ atmel_ac97c0_pclk.dev = &pdev->dev; platform_device_add(pdev); return pdev; -fail: +err_add_resources: platform_device_put(pdev); return NULL; } diff --git a/trunk/arch/avr32/mach-at32ap/hsmc.c b/trunk/arch/avr32/mach-at32ap/hsmc.c index b2d9bc61a35c..fa427ed42787 100644 --- a/trunk/arch/avr32/mach-at32ap/hsmc.c +++ b/trunk/arch/avr32/mach-at32ap/hsmc.c @@ -278,4 +278,4 @@ static int __init hsmc_init(void) { return platform_driver_register(&hsmc_driver); } -core_initcall(hsmc_init); +arch_initcall(hsmc_init); diff --git a/trunk/arch/avr32/mm/init.c b/trunk/arch/avr32/mm/init.c index fa92ff6d95f7..3c85fdaa9487 100644 --- a/trunk/arch/avr32/mm/init.c +++ b/trunk/arch/avr32/mm/init.c @@ -38,6 +38,45 @@ EXPORT_SYMBOL(empty_zero_page); */ unsigned long mmu_context_cache = NO_CONTEXT; +void show_mem(void) +{ + int total = 0, reserved = 0, cached = 0; + int slab = 0, free = 0, shared = 0; + pg_data_t *pgdat; + + printk("Mem-info:\n"); + show_free_areas(); + + for_each_online_pgdat(pgdat) { + struct page *page, *end; + + page = pgdat->node_mem_map; + end = page + pgdat->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); + printk ("%d free pages\n", free); + printk ("%d reserved pages\n", reserved); + printk ("%d slab pages\n", slab); + printk ("%d pages shared\n", shared); + printk ("%d pages swap cached\n", cached); +} + /* * paging_init() sets up the page tables * diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index 5a097c46bc46..b83b8ef84e91 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -234,7 +234,7 @@ config MEM_MT48LC16M16A2TG_75 bool depends on (BFIN533_EZKIT || BFIN561_EZKIT \ || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM \ - || H8606_HVSISTEMAS || BFIN527_BLUETECHNIX_CM) + || H8606_HVSISTEMAS) default y config MEM_MT48LC32M8A2_75 @@ -310,6 +310,25 @@ config BFIN_KERNEL_CLOCK are also not changed, and the Bootloader does 100% of the hardware configuration. +config MEM_SIZE + int "SDRAM Memory Size in MBytes" + depends on BFIN_KERNEL_CLOCK + default 64 + +config MEM_ADD_WIDTH + int "Memory Address Width" + depends on BFIN_KERNEL_CLOCK + depends on (!BF54x) + range 8 11 + default 9 if BFIN533_EZKIT + default 9 if BFIN561_EZKIT + default 9 if H8606_HVSISTEMAS + default 10 if BFIN527_EZKIT + default 10 if BFIN537_STAMP + default 11 if BFIN533_STAMP + default 10 if PNAV10 + default 10 if BFIN532_IP0X + config PLL_BYPASS bool "Bypass PLL" depends on BFIN_KERNEL_CLOCK @@ -330,7 +349,8 @@ config VCO_MULT default "45" if BFIN533_STAMP default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM) default "22" if BFIN533_BLUETECHNIX_CM - default "20" if (BFIN537_BLUETECHNIX_CM || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) + default "20" if BFIN537_BLUETECHNIX_CM + default "20" if BFIN561_BLUETECHNIX_CM default "20" if BFIN561_EZKIT default "16" if H8606_HVSISTEMAS help @@ -370,7 +390,7 @@ config SCLK_DIV config MAX_MEM_SIZE int "Max SDRAM Memory Size in MBytes" - depends on !MPU + depends on !BFIN_KERNEL_CLOCK && !MPU default 512 help This is the max memory size that the kernel will create CPLB @@ -728,6 +748,14 @@ config BFIN_WT endchoice +config L1_MAX_PIECE + int "Set the max L1 SRAM pieces" + default 16 + help + Set the max memory pieces for the L1 SRAM allocation algorithm. + Min value is 16. Max value is 1024. + + config MPU bool "Enable the memory protection unit (EXPERIMENTAL)" default n @@ -871,7 +899,7 @@ config ARCH_SUSPEND_POSSIBLE depends on !SMP choice - prompt "Standby Power Saving Mode" + prompt "Default Power Saving Mode" depends on PM default PM_BFIN_SLEEP_DEEPER config PM_BFIN_SLEEP_DEEPER @@ -890,8 +918,6 @@ config PM_BFIN_SLEEP_DEEPER normal during Sleep Deeper, due to the reduced SCLK frequency. When in the sleep mode, system DMA access to L1 memory is not supported. - If unsure, select "Sleep Deeper". - config PM_BFIN_SLEEP bool "Sleep" help @@ -899,17 +925,15 @@ config PM_BFIN_SLEEP dissipation by disabling the clock to the processor core (CCLK). The PLL and system clock (SCLK), however, continue to operate in this mode. Typically an external event or RTC activity will wake - up the processor. When in the sleep mode, system DMA access to L1 - memory is not supported. - - If unsure, select "Sleep Deeper". + up the processor. When in the sleep mode, + system DMA access to L1 memory is not supported. endchoice config PM_WAKEUP_BY_GPIO - bool "Allow Wakeup from Standby by GPIO" + bool "Cause Wakeup Event by GPIO" config PM_WAKEUP_GPIO_NUMBER - int "GPIO number" + int "Wakeup GPIO number" range 0 47 depends on PM_WAKEUP_BY_GPIO default 2 if BFIN537_STAMP @@ -930,58 +954,6 @@ config PM_WAKEUP_GPIO_POLAR_EDGE_B bool "Both EDGE" endchoice -comment "Possible Suspend Mem / Hibernate Wake-Up Sources" - depends on PM - -config PM_BFIN_WAKE_RTC - bool "Allow Wake-Up from RESET and on-chip RTC" - depends on PM - default n - help - Enable RTC Wake-Up (Voltage Regulator Power-Up) - -config PM_BFIN_WAKE_PH6 - bool "Allow Wake-Up from on-chip PHY or PH6 GP" - depends on PM && (BF52x || BF534 || BF536 || BF537) - default n - help - Enable PHY and PH6 GP Wake-Up (Voltage Regulator Power-Up) - -config PM_BFIN_WAKE_CAN - bool "Allow Wake-Up from on-chip CAN0/1" - depends on PM && (BF54x || BF534 || BF536 || BF537) - default n - help - Enable CAN0/1 Wake-Up (Voltage Regulator Power-Up) - -config PM_BFIN_WAKE_GP - bool "Allow Wake-Up from GPIOs" - depends on PM && BF54x - default n - help - Enable General-Purpose Wake-Up (Voltage Regulator Power-Up) - -config PM_BFIN_WAKE_USB - bool "Allow Wake-Up from on-chip USB" - depends on PM && (BF54x || BF52x) - default n - help - Enable USB Wake-Up (Voltage Regulator Power-Up) - -config PM_BFIN_WAKE_KEYPAD - bool "Allow Wake-Up from on-chip Keypad" - depends on PM && BF54x - default n - help - Enable Keypad Wake-Up (Voltage Regulator Power-Up) - -config PM_BFIN_WAKE_ROTARY - bool "Allow Wake-Up from on-chip Rotary" - depends on PM && BF54x - default n - help - Enable Rotary Wake-Up (Voltage Regulator Power-Up) - endmenu menu "CPU Frequency scaling" diff --git a/trunk/arch/blackfin/Kconfig.debug b/trunk/arch/blackfin/Kconfig.debug index c468624d55f0..c61bdebb9974 100644 --- a/trunk/arch/blackfin/Kconfig.debug +++ b/trunk/arch/blackfin/Kconfig.debug @@ -154,6 +154,13 @@ config EARLY_PRINTK all of this lives in the init section and is thrown away after the kernel boots completely. +config DUAL_CORE_TEST_MODULE + tristate "Dual Core Test Module" + depends on (BF561) + default n + help + Say Y here to build-in dual core test module for dual core test. + config CPLB_INFO bool "Display the CPLB information" help diff --git a/trunk/arch/blackfin/Makefile b/trunk/arch/blackfin/Makefile index 9564731ad3a8..3cbe16caad4b 100644 --- a/trunk/arch/blackfin/Makefile +++ b/trunk/arch/blackfin/Makefile @@ -6,9 +6,8 @@ # for more details. # -ifeq ($(CROSS_COMPILE),) -CROSS_COMPILE := bfin-uclinux- -endif + +CROSS_COMPILE ?= bfin-uclinux- LDFLAGS_vmlinux := -X OBJCOPYFLAGS := -O binary -R .note -R .comment -S GZFLAGS := -9 diff --git a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig index 66854a83c0de..5e6fb9d8e50f 100644 --- a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -1,6 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.24.7 +# Fri May 16 10:02:29 2008 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -289,7 +290,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y -CONFIG_BFIN_GPTIMERS=y +# CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set @@ -429,58 +430,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -CONFIG_IRDA=m - -# -# IrDA protocols -# -CONFIG_IRLAN=m -CONFIG_IRCOMM=m -# CONFIG_IRDA_ULTRA is not set - -# -# IrDA options -# -# CONFIG_IRDA_CACHE_LAST_LSAP is not set -# CONFIG_IRDA_FAST_RR is not set -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# - -# -# SIR device drivers -# -CONFIG_IRTTY_SIR=m -CONFIG_BFIN_SIR=m -CONFIG_BFIN_SIR0=y -CONFIG_SIR_BFIN_DMA=y -# CONFIG_SIR_BFIN_PIO is not set - -# -# Dongle support -# -# CONFIG_DONGLE is not set -# CONFIG_KINGSUN_DONGLE is not set -# CONFIG_KSDAZZLE_DONGLE is not set -# CONFIG_KS959_DONGLE is not set - -# -# Old SIR device drivers -# -# CONFIG_IRPORT_SIR is not set - -# -# Old Serial dongle support -# - -# -# FIR device drivers -# -# CONFIG_USB_IRDA is not set -# CONFIG_SIGMATEL_FIR is not set -# CONFIG_MCS_FIR is not set +# CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -739,11 +689,8 @@ CONFIG_BFIN_OTP=y # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SIMPLE_GPIO is not set +# CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -925,136 +872,18 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y -# CONFIG_FB_SVGALIB is not set -# 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 - -# -# Frame buffer hardware drivers -# -CONFIG_FB_BFIN_T350MCQB=y -# CONFIG_FB_BFIN_7393 is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_VIRTUAL is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=m -CONFIG_LCD_LTV350QV=m -CONFIG_BACKLIGHT_CLASS_DEVICE=m -# CONFIG_BACKLIGHT_CORGI is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_BLACKFIN_VGA16 is not set -CONFIG_LOGO_BLACKFIN_CLUT224=y - # # Sound # -CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_PCM_OSS is not set -# 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_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# SPI devices -# - -# -# ALSA Blackfin devices -# -# CONFIG_SND_BLACKFIN_AD1836 is not set -# CONFIG_SND_BLACKFIN_AD1836_TDM is not set -# CONFIG_SND_BLACKFIN_AD1836_I2S is not set -# CONFIG_SND_BLACKFIN_AD1836_MULSUB is not set -# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set -# CONFIG_SND_BFIN_AD73311 is not set -# CONFIG_SND_BFIN_AD73322 is not set - -# -# USB devices -# -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set - -# -# System on Chip audio support -# -CONFIG_SND_SOC_AC97_BUS=y -CONFIG_SND_SOC=m -CONFIG_SND_BF5XX_SOC=m -CONFIG_SND_MMAP_SUPPORT=y -CONFIG_SND_BF5XX_SOC_I2S=m -CONFIG_SND_BF5XX_SOC_AC97=m -# CONFIG_SND_BF5XX_SOC_WM8750 is not set -# CONFIG_SND_BF5XX_SOC_WM8731 is not set -CONFIG_SND_BF5XX_SOC_SSM2602=m -CONFIG_SND_BF5XX_SOC_BF5xx=m -CONFIG_SND_BF5XX_SPORT_NUM=0 -# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set - -# -# SoC Audio support for SuperH -# -CONFIG_SND_SOC_SSM2602=m -# CONFIG_SND_SOC_SSM2602_SPI is not set -CONFIG_SND_SOC_AD1980=m - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set -CONFIG_AC97_BUS=m +# CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set diff --git a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig index 6bc11db12690..8d817ba01945 100644 --- a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24.7 +# Linux kernel version: 2.6.22.16 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,34 +13,35 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# General setup +# 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_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -63,24 +64,32 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 +# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # 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 -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -132,12 +141,12 @@ CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF53x=y +CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC16M16A2TG_75=y CONFIG_BFIN533_EZKIT=y # CONFIG_BFIN533_STAMP is not set # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_H8606_HVSISTEMAS is not set -# CONFIG_BFIN532_IP0X is not set # CONFIG_GENERIC_BF533_BOARD is not set # @@ -180,14 +189,12 @@ CONFIG_WDTIMER=13 # Board customizations # # CONFIG_CMDLINE_BOOL is not set -CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=27000000 # CONFIG_BFIN_KERNEL_CLOCK is not set -CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=750000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -201,17 +208,13 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -# CONFIG_CYCLES_CLOCKSOURCE is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Misc +# Memory Setup # +CONFIG_MAX_MEM_SIZE=512 +CONFIG_MEM_ADD_WIDTH=9 +CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -247,14 +250,12 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_VIRT_TO_BUS=y +CONFIG_LARGE_ALLOCS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y -# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -292,13 +293,17 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xAAC2 +CONFIG_BANK_3=0xAAC3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# # CONFIG_PCCARD is not set # @@ -316,9 +321,7 @@ CONFIG_BINFMT_ZFLAT=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -CONFIG_PM_SLEEP=y -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_SUSPEND=y +# CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set @@ -364,7 +367,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -391,6 +393,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # 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 # @@ -422,7 +428,6 @@ CONFIG_IRDA_CACHE_LAST_LSAP=y # SIR device drivers # CONFIG_IRTTY_SIR=m -# CONFIG_BFIN_SIR is not set # # Dongle support @@ -452,7 +457,6 @@ CONFIG_IRTTY_SIR=m # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set # # Device Drivers @@ -461,11 +465,14 @@ CONFIG_IRTTY_SIR=m # # Generic Driver Options # -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -485,7 +492,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -542,8 +548,20 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -553,8 +571,10 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set + +# +# Misc devices +# # CONFIG_IDE is not set # @@ -562,29 +582,32 @@ CONFIG_MISC_DEVICES=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# # CONFIG_MD is not set + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_VETH is not set # CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -601,7 +624,15 @@ CONFIG_NETDEV_10000=y # 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 # @@ -616,6 +647,7 @@ CONFIG_INPUT=m # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set @@ -640,12 +672,13 @@ CONFIG_INPUT_EVDEV=m # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set +# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set CONFIG_BFIN_SPORT=y # CONFIG_BFIN_TIMER_LATENCY is not set -CONFIG_SIMPLE_GPIO=m +# CONFIG_AD5304 is not set # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -673,11 +706,28 @@ CONFIG_UNIX98_PTYS=y # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set +CONFIG_BLACKFIN_DPMC=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set @@ -698,37 +748,22 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set + +# +# Dallas's 1-wire bus +# # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set # # Multifunction device drivers @@ -745,27 +780,72 @@ CONFIG_DAB=y # # Graphics support # -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_FB is not set # # Sound # # CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y + +# +# HID Devices +# CONFIG_HID=m # CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set -# CONFIG_USB_SUPPORT 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 + +# +# Enable Host or Gadget support to see Inventra options +# + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set # 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_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -781,6 +861,10 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set # CONFIG_RTC_DRV_TEST is not set +# +# I2C RTC drivers +# + # # SPI RTC drivers # @@ -791,10 +875,8 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -803,9 +885,22 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_BFIN=y # -# Userspace I/O +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices # -# CONFIG_UIO is not set + +# +# PBX support +# +# CONFIG_PBX is not set # # File systems @@ -850,6 +945,7 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -875,12 +971,10 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # 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_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -889,7 +983,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y + +# +# Network File Systems +# CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -909,12 +1006,17 @@ CONFIG_SMB_FS=m # 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_MSDOS_PARTITION=y + +# +# Native Language Support +# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -955,16 +1057,21 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y + +# +# Profiling support +# # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -972,7 +1079,6 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -992,7 +1098,11 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_CAPABILITIES is not set +CONFIG_SECURITY_CAPABILITIES=m + +# +# Cryptographic options +# # CONFIG_CRYPTO is not set # @@ -1003,7 +1113,6 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig index d77d991a1f61..20d598d17bd1 100644 --- a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24.7 +# Linux kernel version: 2.6.22.16 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,34 +13,35 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# General setup +# 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_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -63,24 +64,32 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 +# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # 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 -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -132,12 +141,12 @@ CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF53x=y +CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC64M4A2FB_7E=y # CONFIG_BFIN533_EZKIT is not set CONFIG_BFIN533_STAMP=y # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_H8606_HVSISTEMAS is not set -# CONFIG_BFIN532_IP0X is not set # CONFIG_GENERIC_BF533_BOARD is not set # @@ -180,14 +189,12 @@ CONFIG_WDTIMER=13 # Board customizations # # CONFIG_CMDLINE_BOOL is not set -CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=11059200 # CONFIG_BFIN_KERNEL_CLOCK is not set -CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=750000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -201,17 +208,14 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -# CONFIG_CYCLES_CLOCKSOURCE is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Misc +# Memory Setup # +CONFIG_MAX_MEM_SIZE=512 +CONFIG_MEM_ADD_WIDTH=11 +CONFIG_ENET_FLASH_PIN=0 +CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -247,14 +251,12 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_VIRT_TO_BUS=y +CONFIG_LARGE_ALLOCS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y -# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -292,13 +294,17 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xAAC2 +CONFIG_BANK_3=0xAAC3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# # CONFIG_PCCARD is not set # @@ -316,9 +322,7 @@ CONFIG_BINFMT_ZFLAT=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -CONFIG_PM_SLEEP=y -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_SUSPEND=y +# CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set @@ -364,7 +368,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -391,6 +394,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # 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 # @@ -422,9 +429,6 @@ CONFIG_IRDA_CACHE_LAST_LSAP=y # SIR device drivers # CONFIG_IRTTY_SIR=m -CONFIG_BFIN_SIR=m -CONFIG_SIR_BFIN_DMA=y -# CONFIG_SIR_BFIN_PIO is not set # # Dongle support @@ -454,7 +458,6 @@ CONFIG_SIR_BFIN_DMA=y # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set # # Device Drivers @@ -463,11 +466,14 @@ CONFIG_SIR_BFIN_DMA=y # # Generic Driver Options # -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -487,7 +493,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -519,7 +524,11 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_BFIN_ASYNC=m +CONFIG_MTD_BF5xx=m +CONFIG_BFIN_FLASH_BANK_0=0x7BB0 +CONFIG_BFIN_FLASH_BANK_1=0x7BB0 +CONFIG_BFIN_FLASH_BANK_2=0x7BB0 +CONFIG_BFIN_FLASH_BANK_3=0x7BB0 # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -546,8 +555,20 @@ CONFIG_MTD_BFIN_ASYNC=m # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -557,8 +578,10 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set + +# +# Misc devices +# # CONFIG_IDE is not set # @@ -566,29 +589,32 @@ CONFIG_MISC_DEVICES=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# # CONFIG_MD is not set + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_VETH is not set # CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -605,7 +631,15 @@ CONFIG_NETDEV_10000=y # 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 # @@ -620,6 +654,7 @@ CONFIG_INPUT=y # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set @@ -632,8 +667,14 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_UINPUT is not set CONFIG_TWI_KEYPAD=m +CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39 # # Hardware I/O ports @@ -646,13 +687,15 @@ CONFIG_TWI_KEYPAD=m # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set +# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set CONFIG_BFIN_SPORT=y # CONFIG_BFIN_TIMER_LATENCY is not set CONFIG_TWI_LCD=m -CONFIG_SIMPLE_GPIO=m +CONFIG_TWI_LCD_SLAVE_ADDR=34 +# CONFIG_AD5304 is not set # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -680,11 +723,28 @@ CONFIG_UNIX98_PTYS=y # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set +CONFIG_BLACKFIN_DPMC=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y @@ -704,7 +764,6 @@ CONFIG_I2C_ALGOBIT=m # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_STUB is not set # @@ -712,15 +771,14 @@ CONFIG_I2C_ALGOBIT=m # # CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_DS1374 is not set -# CONFIG_DS1682 is not set # CONFIG_SENSORS_AD5252 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8575 is not set +# CONFIG_SENSORS_PCA9543 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -743,11 +801,14 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set + +# +# Dallas's 1-wire bus +# # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -755,12 +816,12 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S 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 @@ -775,16 +836,13 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -794,20 +852,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set # # Multifunction device drivers @@ -819,20 +863,24 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support # +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_FB=m CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=m CONFIG_FB_CFB_COPYAREA=m CONFIG_FB_CFB_IMAGEBLIT=m -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set @@ -847,7 +895,7 @@ CONFIG_FB_DEFERRED_IO=y # # Frame buffer hardware drivers # -# CONFIG_FB_BFIN_T350MCQB is not set +CONFIG_FB_BFIN_7171=m CONFIG_FB_BFIN_7393=m CONFIG_NTSC=y # CONFIG_PAL is not set @@ -857,14 +905,9 @@ CONFIG_NTSC=y # CONFIG_PAL_YCBCR is not set CONFIG_ADV7393_1XMEM=y # CONFIG_ADV7393_2XMEM is not set +# CONFIG_FB_BFIN_T350MCQB is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_LOGO is not set # @@ -897,10 +940,6 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set -# -# SPI devices -# - # # ALSA Blackfin devices # @@ -914,43 +953,69 @@ CONFIG_SND_BLACKFIN_SPI_PFBIT=4 CONFIG_SND_BFIN_AD73311=m CONFIG_SND_BFIN_SPORT=0 CONFIG_SND_BFIN_AD73311_SE=4 -CONFIG_SND_BFIN_AD73322=m -CONFIG_SND_BFIN_AD73322_SPORT0_SE=10 -CONFIG_SND_BFIN_AD73322_SPORT1_SE=14 -CONFIG_SND_BFIN_AD73322_RESET=12 # # System on Chip audio support # -CONFIG_SND_SOC_AC97_BUS=y -CONFIG_SND_SOC=m -CONFIG_SND_BF5XX_SOC=m -CONFIG_SND_MMAP_SUPPORT=y -CONFIG_SND_BF5XX_SOC_AC97=m -# CONFIG_SND_BF5XX_SOC_WM8750 is not set -# CONFIG_SND_BF5XX_SOC_WM8731 is not set -# CONFIG_SND_BF5XX_SOC_SSM2602 is not set -CONFIG_SND_BF5XX_SOC_BF5xx=m -CONFIG_SND_BF5XX_SPORT_NUM=0 -# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set +# CONFIG_SND_SOC is not set # -# SoC Audio support for SuperH +# Open Sound System # -CONFIG_SND_SOC_AD1980=m +# CONFIG_SOUND_PRIME is not set # -# Open Sound System +# HID Devices # -# CONFIG_SOUND_PRIME is not set -CONFIG_AC97_BUS=m -CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set -# CONFIG_USB_SUPPORT 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 + +# +# Enable Host or Gadget support to see Inventra options +# + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set # 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_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -970,7 +1035,6 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_RS5C372 is not set @@ -978,7 +1042,6 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set # # SPI RTC drivers @@ -990,10 +1053,8 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1002,9 +1063,22 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_BFIN=y # -# Userspace I/O +# DMA Engine support # -# CONFIG_UIO is not set +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# PBX support +# +# CONFIG_PBX is not set # # File systems @@ -1049,6 +1123,7 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1074,12 +1149,10 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # 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_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -1088,7 +1161,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y + +# +# Network File Systems +# CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1108,12 +1184,17 @@ CONFIG_SMB_FS=m # 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_MSDOS_PARTITION=y + +# +# Native Language Support +# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1154,16 +1235,21 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y + +# +# Profiling support +# # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1171,7 +1257,6 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1191,7 +1276,11 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_CAPABILITIES is not set +CONFIG_SECURITY_CAPABILITIES=m + +# +# Cryptographic options +# # CONFIG_CRYPTO is not set # @@ -1202,7 +1291,6 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig index 5fd7c4b143df..b5189c8ba263 100644 --- a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24.7 +# Linux kernel version: 2.6.22.16 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,34 +13,35 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# General setup +# 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_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -63,24 +64,32 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 +# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # 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 -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -132,6 +141,7 @@ CONFIG_BF_REV_0_2=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF53x=y +CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC32M8A2_75=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_RTC=8 @@ -187,14 +197,12 @@ CONFIG_IRQ_PROG_INTA=12 # Board customizations # # CONFIG_CMDLINE_BOOL is not set -CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=25000000 # CONFIG_BFIN_KERNEL_CLOCK is not set -CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=600000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -208,17 +216,13 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -# CONFIG_CYCLES_CLOCKSOURCE is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Misc +# Memory Setup # +CONFIG_MAX_MEM_SIZE=512 +CONFIG_MEM_ADD_WIDTH=10 +CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -254,14 +258,12 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_VIRT_TO_BUS=y +CONFIG_LARGE_ALLOCS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y -# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -299,13 +301,17 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0x99B2 +CONFIG_BANK_3=0x99B3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# # CONFIG_PCCARD is not set # @@ -323,9 +329,7 @@ CONFIG_BINFMT_ZFLAT=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -CONFIG_PM_SLEEP=y -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_SUSPEND=y +# CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set @@ -371,7 +375,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -398,6 +401,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # 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 # @@ -429,10 +436,6 @@ CONFIG_IRDA_CACHE_LAST_LSAP=y # SIR device drivers # CONFIG_IRTTY_SIR=m -CONFIG_BFIN_SIR=m -CONFIG_BFIN_SIR1=y -CONFIG_SIR_BFIN_DMA=y -# CONFIG_SIR_BFIN_PIO is not set # # Dongle support @@ -462,7 +465,6 @@ CONFIG_SIR_BFIN_DMA=y # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set # # Device Drivers @@ -471,11 +473,14 @@ CONFIG_SIR_BFIN_DMA=y # # Generic Driver Options # -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -495,7 +500,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -568,8 +572,20 @@ CONFIG_MTD_NAND_IDS=m # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -579,8 +595,10 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set + +# +# Misc devices +# # CONFIG_IDE is not set # @@ -588,18 +606,22 @@ CONFIG_MISC_DEVICES=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# # CONFIG_MD is not set + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_VETH is not set CONFIG_PHYLIB=y # @@ -613,24 +635,21 @@ CONFIG_PHYLIB=y # CONFIG_VITESSE_PHY is not set CONFIG_SMSC_PHY=y # CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set # CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_SMC91X is not set CONFIG_BFIN_MAC=y CONFIG_BFIN_MAC_USE_L1=y CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 # CONFIG_BFIN_MAC_RMII is not set -# CONFIG_SMC91X is not set # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -647,7 +666,15 @@ CONFIG_NETDEV_10000=y # 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 # @@ -662,6 +689,7 @@ CONFIG_INPUT=y # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set @@ -674,8 +702,14 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_UINPUT is not set CONFIG_TWI_KEYPAD=m +CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72 # # Hardware I/O ports @@ -688,13 +722,15 @@ CONFIG_TWI_KEYPAD=m # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set +# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set CONFIG_BFIN_SPORT=y # CONFIG_BFIN_TIMER_LATENCY is not set CONFIG_TWI_LCD=m -CONFIG_SIMPLE_GPIO=m +CONFIG_TWI_LCD_SLAVE_ADDR=34 +# CONFIG_AD5304 is not set # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -730,11 +766,28 @@ CONFIG_CAN4LINUX=y # CONFIG_CAN_MCF5282 is not set # CONFIG_CAN_UNCTWINCAN is not set CONFIG_CAN_BLACKFIN=m + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set +CONFIG_BLACKFIN_DPMC=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y @@ -756,7 +809,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_STUB is not set # @@ -764,15 +816,14 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # # CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_DS1374 is not set -# CONFIG_DS1682 is not set CONFIG_SENSORS_AD5252=m # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8575 is not set +# CONFIG_SENSORS_PCA9543 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -795,11 +846,14 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set + +# +# Dallas's 1-wire bus +# # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -807,12 +861,12 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S 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 @@ -827,16 +881,13 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -846,20 +897,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set # # Multifunction device drivers @@ -876,15 +913,21 @@ CONFIG_DAB=y # # Graphics support # +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_LCD_CLASS_DEVICE=m + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_FB=m CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=m CONFIG_FB_CFB_COPYAREA=m CONFIG_FB_CFB_IMAGEBLIT=m -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set @@ -899,8 +942,7 @@ CONFIG_FB_DEFERRED_IO=y # # Frame buffer hardware drivers # -# CONFIG_FB_HITACHI_TX09 is not set -# CONFIG_FB_BFIN_T350MCQB is not set +CONFIG_FB_BFIN_7171=m CONFIG_FB_BFIN_7393=m CONFIG_NTSC=y # CONFIG_PAL is not set @@ -914,18 +956,10 @@ CONFIG_FB_BF537_LQ035=m CONFIG_LQ035_SLAVE_ADDR=0x58 # CONFIG_FB_BFIN_LANDSCAPE is not set # CONFIG_FB_BFIN_BGR is not set +# CONFIG_FB_BFIN_T350MCQB is not set +# CONFIG_FB_HITACHI_TX09 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_LTV350QV is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=m -CONFIG_BACKLIGHT_CORGI=m - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_LOGO is not set # @@ -958,10 +992,6 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set -# -# SPI devices -# - # # ALSA Blackfin devices # @@ -975,10 +1005,6 @@ CONFIG_SND_BLACKFIN_SPI_PFBIT=4 CONFIG_SND_BFIN_AD73311=m CONFIG_SND_BFIN_SPORT=0 CONFIG_SND_BFIN_AD73311_SE=4 -CONFIG_SND_BFIN_AD73322=m -CONFIG_SND_BFIN_AD73322_SPORT0_SE=10 -CONFIG_SND_BFIN_AD73322_SPORT1_SE=14 -CONFIG_SND_BFIN_AD73322_RESET=12 # # System on Chip audio support @@ -990,14 +1016,9 @@ CONFIG_SND_MMAP_SUPPORT=y CONFIG_SND_BF5XX_SOC_AC97=m # CONFIG_SND_BF5XX_SOC_WM8750 is not set # CONFIG_SND_BF5XX_SOC_WM8731 is not set -# CONFIG_SND_BF5XX_SOC_SSM2602 is not set CONFIG_SND_BF5XX_SOC_BF5xx=m CONFIG_SND_BF5XX_SPORT_NUM=0 # CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set - -# -# SoC Audio support for SuperH -# CONFIG_SND_SOC_AD1980=m # @@ -1005,18 +1026,59 @@ CONFIG_SND_SOC_AD1980=m # # CONFIG_SOUND_PRIME is not set CONFIG_AC97_BUS=m -CONFIG_HID_SUPPORT=y + +# +# HID Devices +# CONFIG_HID=y # CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_NO_DUMMY_DELAY is not set -# CONFIG_DUMMY_DELAY_BANK0 is not set -# CONFIG_DUMMY_DELAY_BANK1 is not set -# CONFIG_DUMMY_DELAY_BANK2 is not set -# CONFIG_DUMMY_DELAY_BANK3 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 + +# +# Enable Host or Gadget support to see Inventra options +# + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set # 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_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -1036,7 +1098,6 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_RS5C372 is not set @@ -1044,7 +1105,6 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set # # SPI RTC drivers @@ -1056,10 +1116,8 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1068,9 +1126,22 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_BFIN=y # -# Userspace I/O +# DMA Engine support # -# CONFIG_UIO is not set +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# PBX support +# +# CONFIG_PBX is not set # # File systems @@ -1115,6 +1186,7 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1140,12 +1212,10 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # 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_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -1154,7 +1224,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y + +# +# Network File Systems +# CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1174,12 +1247,17 @@ CONFIG_SMB_FS=m # 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_MSDOS_PARTITION=y + +# +# Native Language Support +# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1220,16 +1298,21 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y + +# +# Profiling support +# # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1237,7 +1320,6 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1257,7 +1339,11 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_CAPABILITIES is not set +CONFIG_SECURITY_CAPABILITIES=m + +# +# Cryptographic options +# # CONFIG_CRYPTO is not set # @@ -1268,7 +1354,6 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig index 390669e8668e..1ff2ff4b49aa 100644 --- a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -365,7 +365,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x5554 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0x99B2 +CONFIG_BANK_3=0x99B3 CONFIG_EBIU_MBSCTLVAL=0x0 CONFIG_EBIU_MODEVAL=0x1 CONFIG_EBIU_FCTLVAL=0x6 @@ -468,60 +468,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -CONFIG_IRDA=m - -# -# IrDA protocols -# -CONFIG_IRLAN=m -CONFIG_IRCOMM=m -# CONFIG_IRDA_ULTRA is not set - -# -# IrDA options -# -# CONFIG_IRDA_CACHE_LAST_LSAP is not set -# CONFIG_IRDA_FAST_RR is not set -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# - -# -# SIR device drivers -# -CONFIG_IRTTY_SIR=m -CONFIG_BFIN_SIR=m -# CONFIG_BFIN_SIR0 is not set -# CONFIG_BFIN_SIR2 is not set -CONFIG_BFIN_SIR3=y -CONFIG_SIR_BFIN_DMA=y -# CONFIG_SIR_BFIN_PIO is not set - -# -# Dongle support -# -# CONFIG_DONGLE is not set -# CONFIG_KINGSUN_DONGLE is not set -# CONFIG_KSDAZZLE_DONGLE is not set -# CONFIG_KS959_DONGLE is not set - -# -# Old SIR device drivers -# -# CONFIG_IRPORT_SIR is not set - -# -# Old Serial dongle support -# - -# -# FIR device drivers -# -# CONFIG_USB_IRDA is not set -# CONFIG_SIGMATEL_FIR is not set -# CONFIG_MCS_FIR is not set +# CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -628,7 +575,6 @@ CONFIG_MTD_NAND=y CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_BF5XX=y CONFIG_MTD_NAND_BF5XX_HWECC=y -# CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC is not set # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set @@ -820,7 +766,7 @@ CONFIG_BFIN_OTP=y # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m +# CONFIG_SIMPLE_GPIO is not set CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y @@ -1125,7 +1071,6 @@ CONFIG_SND_BF5XX_SOC_AC97=y CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y # CONFIG_SND_BF5XX_SOC_WM8750 is not set # CONFIG_SND_BF5XX_SOC_WM8731 is not set -# CONFIG_SND_BF5XX_SOC_SSM2602 is not set CONFIG_SND_BF5XX_SPORT_NUM=0 CONFIG_SND_BF5XX_HAVE_COLD_RESET=y CONFIG_SND_BF5XX_RESET_GPIO_NUM=19 @@ -1188,7 +1133,7 @@ CONFIG_USB_MUSB_HOST=y # CONFIG_USB_MUSB_OTG is not set CONFIG_USB_MUSB_HDRC_HCD=y # CONFIG_MUSB_PIO_ONLY is not set -CONFIG_USB_INVENTRA_DMA=y +# CONFIG_USB_INVENTRA_DMA is not set # CONFIG_USB_TI_CPPI_DMA is not set CONFIG_USB_MUSB_LOGLEVEL=0 @@ -1367,7 +1312,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig index 976a4d7ba175..b4a20c890816 100644 --- a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24.7 +# Linux kernel version: 2.6.22.16 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,34 +13,35 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# General setup +# 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_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -63,24 +64,32 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 +# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # 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 -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -131,6 +140,7 @@ CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_0_5 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set +CONFIG_BFIN_DUAL_CORE=y CONFIG_MEM_MT48LC16M16A2TG_75=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_SPORT0_ERROR=7 @@ -223,14 +233,12 @@ CONFIG_IRQ_WDTIMER=13 # Board customizations # # CONFIG_CMDLINE_BOOL is not set -CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=30000000 # CONFIG_BFIN_KERNEL_CLOCK is not set -CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=600000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -244,17 +252,13 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -# CONFIG_CYCLES_CLOCKSOURCE is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Misc +# Memory Setup # +CONFIG_MAX_MEM_SIZE=512 +CONFIG_MEM_ADD_WIDTH=9 +CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -290,14 +294,12 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_VIRT_TO_BUS=y +CONFIG_LARGE_ALLOCS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y -# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -339,13 +341,17 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xAAC2 +CONFIG_BANK_3=0xAAC3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# # CONFIG_PCCARD is not set # @@ -361,14 +367,8 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y # CONFIG_PM_WAKEUP_BY_GPIO is not set -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - # # Networking # @@ -405,7 +405,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -432,6 +431,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # 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 # @@ -463,7 +466,6 @@ CONFIG_IRDA_CACHE_LAST_LSAP=y # SIR device drivers # CONFIG_IRTTY_SIR=m -# CONFIG_BFIN_SIR is not set # # Dongle support @@ -493,7 +495,6 @@ CONFIG_IRTTY_SIR=m # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set # # Device Drivers @@ -502,11 +503,14 @@ CONFIG_IRTTY_SIR=m # # Generic Driver Options # -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -526,7 +530,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -587,8 +590,20 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -598,8 +613,10 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set + +# +# Misc devices +# # CONFIG_IDE is not set # @@ -607,29 +624,32 @@ CONFIG_MISC_DEVICES=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# # CONFIG_MD is not set + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_VETH is not set # CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -646,7 +666,15 @@ CONFIG_NETDEV_10000=y # 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 # @@ -661,6 +689,7 @@ CONFIG_INPUT=m # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set @@ -685,12 +714,13 @@ CONFIG_INPUT_EVDEV=m # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set +# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set -CONFIG_SIMPLE_GPIO=m +# CONFIG_AD5304 is not set # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -718,11 +748,27 @@ CONFIG_UNIX98_PTYS=y # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set @@ -743,37 +789,22 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set + +# +# Dallas's 1-wire bus +# # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set # # Multifunction device drivers @@ -790,33 +821,91 @@ CONFIG_DAB=y # # Graphics support # -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_FB is not set # # Sound # # CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y + +# +# HID Devices +# CONFIG_HID=m # CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set -# CONFIG_USB_SUPPORT 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 + +# +# Enable Host or Gadget support to see Inventra options +# + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set # 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 # -# Userspace I/O +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices # -# CONFIG_UIO is not set + +# +# PBX support +# +# CONFIG_PBX is not set # # File systems @@ -861,6 +950,7 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -886,12 +976,10 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # 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_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -900,7 +988,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y + +# +# Network File Systems +# CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -920,12 +1011,17 @@ CONFIG_SMB_FS=m # 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_MSDOS_PARTITION=y + +# +# Native Language Support +# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -966,16 +1062,21 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y + +# +# Profiling support +# # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -983,7 +1084,6 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1004,7 +1104,11 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_CAPABILITIES is not set +CONFIG_SECURITY_CAPABILITIES=m + +# +# Cryptographic options +# # CONFIG_CRYPTO is not set # @@ -1015,7 +1119,6 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/trunk/arch/blackfin/configs/CM-BF527_defconfig b/trunk/arch/blackfin/configs/CM-BF527_defconfig deleted file mode 100644 index 0799aa9bba9d..000000000000 --- a/trunk/arch/blackfin/configs/CM-BF527_defconfig +++ /dev/null @@ -1,1185 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.24.7 -# Fri Jul 18 18:00:41 2008 -# -# CONFIG_MMU is not set -# CONFIG_FPU is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_BLACKFIN=y -CONFIG_ZONE_DMA=y -CONFIG_SEMAPHORE_SLEEPERS=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_GPIO=y -CONFIG_FORCE_MAX_ZONEORDER=14 -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -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_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_EVENTFD=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set - -# -# Blackfin Processor Options -# - -# -# Processor and Board Settings -# -# CONFIG_BF522 is not set -# CONFIG_BF523 is not set -# CONFIG_BF524 is not set -# CONFIG_BF525 is not set -# CONFIG_BF526 is not set -CONFIG_BF527=y -# CONFIG_BF531 is not set -# CONFIG_BF532 is not set -# CONFIG_BF533 is not set -# CONFIG_BF534 is not set -# CONFIG_BF536 is not set -# CONFIG_BF537 is not set -# CONFIG_BF542 is not set -# CONFIG_BF544 is not set -# CONFIG_BF547 is not set -# CONFIG_BF548 is not set -# CONFIG_BF549 is not set -# CONFIG_BF561 is not set -# CONFIG_BF_REV_0_0 is not set -CONFIG_BF_REV_0_1=y -# CONFIG_BF_REV_0_2 is not set -# CONFIG_BF_REV_0_3 is not set -# CONFIG_BF_REV_0_4 is not set -# CONFIG_BF_REV_0_5 is not set -# CONFIG_BF_REV_ANY is not set -# CONFIG_BF_REV_NONE is not set -CONFIG_BF52x=y -CONFIG_MEM_MT48LC16M16A2TG_75=y -# CONFIG_BFIN527_EZKIT is not set -CONFIG_BFIN527_BLUETECHNIX_CM=y - -# -# BF527 Specific Configuration -# - -# -# Alternative Multiplexing Scheme -# -# CONFIG_BF527_SPORT0_PORTF is not set -CONFIG_BF527_SPORT0_PORTG=y -CONFIG_BF527_SPORT0_TSCLK_PG10=y -# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set -CONFIG_BF527_UART1_PORTF=y -# CONFIG_BF527_UART1_PORTG is not set -# CONFIG_BF527_NAND_D_PORTF is not set -CONFIG_BF527_NAND_D_PORTH=y - -# -# Interrupt Priority Assignment -# - -# -# Priority -# -CONFIG_IRQ_PLL_WAKEUP=7 -CONFIG_IRQ_DMA0_ERROR=7 -CONFIG_IRQ_DMAR0_BLK=7 -CONFIG_IRQ_DMAR1_BLK=7 -CONFIG_IRQ_DMAR0_OVR=7 -CONFIG_IRQ_DMAR1_OVR=7 -CONFIG_IRQ_PPI_ERROR=7 -CONFIG_IRQ_MAC_ERROR=7 -CONFIG_IRQ_SPORT0_ERROR=7 -CONFIG_IRQ_SPORT1_ERROR=7 -CONFIG_IRQ_UART0_ERROR=7 -CONFIG_IRQ_UART1_ERROR=7 -CONFIG_IRQ_RTC=8 -CONFIG_IRQ_PPI=8 -CONFIG_IRQ_SPORT0_RX=9 -CONFIG_IRQ_SPORT0_TX=9 -CONFIG_IRQ_SPORT1_RX=9 -CONFIG_IRQ_SPORT1_TX=9 -CONFIG_IRQ_TWI=10 -CONFIG_IRQ_SPI=10 -CONFIG_IRQ_UART0_RX=10 -CONFIG_IRQ_UART0_TX=10 -CONFIG_IRQ_UART1_RX=10 -CONFIG_IRQ_UART1_TX=10 -CONFIG_IRQ_OPTSEC=11 -CONFIG_IRQ_CNT=11 -CONFIG_IRQ_MAC_RX=11 -CONFIG_IRQ_PORTH_INTA=11 -CONFIG_IRQ_MAC_TX=11 -CONFIG_IRQ_PORTH_INTB=11 -CONFIG_IRQ_TMR0=12 -CONFIG_IRQ_TMR1=12 -CONFIG_IRQ_TMR2=12 -CONFIG_IRQ_TMR3=12 -CONFIG_IRQ_TMR4=12 -CONFIG_IRQ_TMR5=12 -CONFIG_IRQ_TMR6=12 -CONFIG_IRQ_TMR7=12 -CONFIG_IRQ_PORTG_INTA=12 -CONFIG_IRQ_PORTG_INTB=12 -CONFIG_IRQ_MEM_DMA0=13 -CONFIG_IRQ_MEM_DMA1=13 -CONFIG_IRQ_WATCH=13 -CONFIG_IRQ_PORTF_INTA=13 -CONFIG_IRQ_PORTF_INTB=13 -CONFIG_IRQ_SPI_ERROR=7 -CONFIG_IRQ_NFC_ERROR=7 -CONFIG_IRQ_HDMA_ERROR=7 -CONFIG_IRQ_HDMA=7 -CONFIG_IRQ_USB_EINT=10 -CONFIG_IRQ_USB_INT0=11 -CONFIG_IRQ_USB_INT1=11 -CONFIG_IRQ_USB_INT2=11 -CONFIG_IRQ_USB_DMA=11 - -# -# Board customizations -# -# CONFIG_CMDLINE_BOOL is not set -CONFIG_BOOT_LOAD=0x1000 - -# -# Clock/PLL Setup -# -CONFIG_CLKIN_HZ=25000000 -# CONFIG_BFIN_KERNEL_CLOCK is not set -CONFIG_MAX_MEM_SIZE=512 -CONFIG_MAX_VCO_HZ=600000000 -CONFIG_MIN_VCO_HZ=50000000 -CONFIG_MAX_SCLK_HZ=133333333 -CONFIG_MIN_SCLK_HZ=27000000 - -# -# Kernel Timer/Scheduler -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -# CONFIG_CYCLES_CLOCKSOURCE is not set -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y - -# -# Misc -# -CONFIG_BFIN_SCRATCH_REG_RETN=y -# CONFIG_BFIN_SCRATCH_REG_RETE is not set -# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set - -# -# Blackfin Kernel Optimizations -# - -# -# Memory Optimizations -# -CONFIG_I_ENTRY_L1=y -CONFIG_EXCPT_IRQ_SYSC_L1=y -CONFIG_DO_IRQ_L1=y -CONFIG_CORE_TIMER_IRQ_L1=y -CONFIG_IDLE_L1=y -# CONFIG_SCHEDULE_L1 is not set -CONFIG_ARITHMETIC_OPS_L1=y -CONFIG_ACCESS_OK_L1=y -# CONFIG_MEMSET_L1 is not set -# CONFIG_MEMCPY_L1 is not set -# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set -# CONFIG_IP_CHECKSUM_L1 is not set -CONFIG_CACHELINE_ALIGNED_L1=y -# CONFIG_SYSCALL_TAB_L1 is not set -# CONFIG_CPLB_SWITCH_TAB_L1 is not set -CONFIG_RAMKERNEL=y -# CONFIG_ROMKERNEL 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_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_VIRT_TO_BUS=y -CONFIG_BFIN_GPTIMERS=y -CONFIG_BFIN_DMA_5XX=y -# CONFIG_DMA_UNCACHED_4M is not set -# CONFIG_DMA_UNCACHED_2M is not set -CONFIG_DMA_UNCACHED_1M=y -# CONFIG_DMA_UNCACHED_NONE is not set - -# -# Cache Support -# -CONFIG_BFIN_ICACHE=y -CONFIG_BFIN_DCACHE=y -# CONFIG_BFIN_DCACHE_BANKA is not set -# CONFIG_BFIN_ICACHE_LOCK is not set -# CONFIG_BFIN_WB is not set -CONFIG_BFIN_WT=y -# CONFIG_MPU is not set - -# -# Asynchonous Memory Configuration -# - -# -# EBIU_AMGCTL Global Control -# -CONFIG_C_AMCKEN=y -CONFIG_C_CDPRIO=y -# CONFIG_C_AMBEN is not set -# CONFIG_C_AMBEN_B0 is not set -# CONFIG_C_AMBEN_B0_B1 is not set -# CONFIG_C_AMBEN_B0_B1_B2 is not set -CONFIG_C_AMBEN_ALL=y - -# -# EBIU_AMBCTL Control -# -CONFIG_BANK_0=0x7BB0 -CONFIG_BANK_1=0x5554 -CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC0 - -# -# Bus options (PCI, PCMCIA, EISA, MCA, ISA) -# -# CONFIG_PCI is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF_FDPIC=y -CONFIG_BINFMT_FLAT=y -CONFIG_BINFMT_ZFLAT=y -# CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options -# -# CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -# CONFIG_PM_BFIN_SLEEP_DEEPER is not set -# CONFIG_PM_BFIN_SLEEP is not set -# CONFIG_PM_WAKEUP_BY_GPIO is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# 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 is not set -# CONFIG_IP_PNP_BOOTP is not set -# 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=y -# 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=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO 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_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETLABEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# 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 -# 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_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -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 is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLKDEVS=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 -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=m -CONFIG_MTD_GEN_PROBE=m -# 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 is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_RAM=y -CONFIG_MTD_ROM=m -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -CONFIG_MTD_COMPLEX_MAPPINGS=y -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_UCLINUX is not set -# CONFIG_MTD_PLATRAM is not set - -# -# 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 -# 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 -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# 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_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MISC_DEVICES is not set -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_BFIN_MAC=y -CONFIG_BFIN_MAC_USE_L1=y -CONFIG_BFIN_TX_DESC_NUM=10 -CONFIG_BFIN_RX_DESC_NUM=20 -CONFIG_BFIN_MAC_RMII=y -# CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set -# CONFIG_DM9000 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 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_WAN 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 -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PPIFCD is not set -# CONFIG_BFIN_SIMPLE_TIMER is not set -# CONFIG_BF5xx_PPI is not set -CONFIG_BFIN_OTP=y -# CONFIG_BFIN_OTP_WRITE_ENABLE is not set -# CONFIG_BFIN_SPORT is not set -# CONFIG_BFIN_TIMER_LATENCY is not set -# CONFIG_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_BFIN=y -CONFIG_SERIAL_BFIN_CONSOLE=y -CONFIG_SERIAL_BFIN_DMA=y -# CONFIG_SERIAL_BFIN_PIO is not set -CONFIG_SERIAL_BFIN_UART0=y -# CONFIG_BFIN_UART0_CTSRTS is not set -CONFIG_SERIAL_BFIN_UART1=y -# CONFIG_BFIN_UART1_CTSRTS is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_BFIN_SPORT is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=m - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -CONFIG_I2C_BLACKFIN_TWI=m -CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 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 - -# -# SPI support -# -CONFIG_SPI=y -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -CONFIG_SPI_BFIN=y -# CONFIG_SPI_BITBANG is not set - -# -# SPI Protocol Masters -# -# CONFIG_SPI_AT25 is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S 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_LM70 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_THMC50 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 -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -CONFIG_USB_OTG_BLACKLIST_HUB=y - -# -# USB Host Controller Drivers -# -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1362_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_MUSB_HDRC=y -CONFIG_USB_MUSB_SOC=y - -# -# Blackfin high speed USB support -# -CONFIG_USB_MUSB_HOST=y -# CONFIG_USB_MUSB_PERIPHERAL is not set -# CONFIG_USB_MUSB_OTG is not set -CONFIG_USB_MUSB_HDRC_HCD=y -CONFIG_MUSB_PIO_ONLY=y -CONFIG_USB_MUSB_LOGLEVEL=0 - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER 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_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 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_BERRY_CHARGE 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_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set -# CONFIG_NEW_LEDS is not set -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 -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_MAX6902 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_BFIN=y - -# -# Userspace I/O -# -# CONFIG_UIO is not set - -# -# File systems -# -# CONFIG_EXT2_FS 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 -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_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_PROC_SYSCTL=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# 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_YAFFS_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 -CONFIG_NETWORK_FILESYSTEMS=y -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 is not set -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT 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 is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=m -CONFIG_NLS_DEFAULT="iso8859-1" -# 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 -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# 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 -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set -# CONFIG_DLM is not set -# CONFIG_INSTRUMENTATION is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set -CONFIG_DEBUG_MMRS=y -CONFIG_DEBUG_HUNT_FOR_ZERO=y -CONFIG_DEBUG_BFIN_HWTRACE_ON=y -CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y -# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set -# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set -CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 -# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set -# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -CONFIG_EARLY_PRINTK=y -# CONFIG_CPLB_INFO is not set -CONFIG_ACCESS_CHECK=y - -# -# Security options -# -# CONFIG_KEYS is not set -CONFIG_SECURITY=y -# CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_CAPABILITIES is not set -# CONFIG_SECURITY_ROOTPLUG is not set -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/trunk/arch/blackfin/configs/CM-BF533_defconfig b/trunk/arch/blackfin/configs/CM-BF533_defconfig index 09deea44480b..560890fe0d30 100644 --- a/trunk/arch/blackfin/configs/CM-BF533_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF533_defconfig @@ -39,8 +39,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y +# CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set @@ -292,7 +291,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC2 +CONFIG_BANK_3=0xFFC3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -618,7 +617,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # # CAN, the car bus and industrial fieldbus @@ -778,7 +778,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -866,11 +866,11 @@ CONFIG_MSDOS_PARTITION=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_MMRS=y +# CONFIG_DEBUG_MMRS is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y diff --git a/trunk/arch/blackfin/configs/CM-BF537E_defconfig b/trunk/arch/blackfin/configs/CM-BF537E_defconfig index 219fc345a5f5..9f66d2de1007 100644 --- a/trunk/arch/blackfin/configs/CM-BF537E_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF537E_defconfig @@ -39,8 +39,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y +# CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set @@ -300,7 +299,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC2 +CONFIG_BANK_3=0xFFC3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -352,10 +351,7 @@ 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 is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_ARPD is not set @@ -649,7 +645,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # # CAN, the car bus and industrial fieldbus @@ -809,7 +806,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -897,12 +894,12 @@ CONFIG_MSDOS_PARTITION=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_MMRS=y -CONFIG_DEBUG_HUNT_FOR_ZERO=y +# CONFIG_DEBUG_MMRS is not set +# CONFIG_DEBUG_HUNT_FOR_ZERO is not set CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y # CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set diff --git a/trunk/arch/blackfin/configs/CM-BF537U_defconfig b/trunk/arch/blackfin/configs/CM-BF537U_defconfig index 9873d586fc77..2694d06c5bde 100644 --- a/trunk/arch/blackfin/configs/CM-BF537U_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF537U_defconfig @@ -39,8 +39,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y +# CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set @@ -299,8 +298,8 @@ CONFIG_C_AMBEN_ALL=y # CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 -CONFIG_BANK_2=0xFFC2 -CONFIG_BANK_3=0xFFC2 +CONFIG_BANK_2=0xFFC3 +CONFIG_BANK_3=0xFFC3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -629,7 +628,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # # CAN, the car bus and industrial fieldbus @@ -806,7 +806,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -894,12 +894,12 @@ CONFIG_MSDOS_PARTITION=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_MMRS=y -CONFIG_DEBUG_HUNT_FOR_ZERO=y +# CONFIG_DEBUG_MMRS is not set +# CONFIG_DEBUG_HUNT_FOR_ZERO is not set CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y # CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set diff --git a/trunk/arch/blackfin/configs/CM-BF548_defconfig b/trunk/arch/blackfin/configs/CM-BF548_defconfig index 0e3605fdb7b0..90207251c533 100644 --- a/trunk/arch/blackfin/configs/CM-BF548_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF548_defconfig @@ -363,7 +363,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x5554 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0x99B2 +CONFIG_BANK_3=0x99B3 CONFIG_EBIU_MBSCTLVAL=0x0 CONFIG_EBIU_MODEVAL=0x1 CONFIG_EBIU_FCTLVAL=0x6 @@ -744,8 +744,8 @@ CONFIG_BFIN_OTP=y # CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y -CONFIG_SERIAL_BFIN_DMA=y -# CONFIG_SERIAL_BFIN_PIO is not set +# CONFIG_SERIAL_BFIN_DMA is not set +CONFIG_SERIAL_BFIN_PIO=y # CONFIG_SERIAL_BFIN_UART0 is not set CONFIG_SERIAL_BFIN_UART1=y # CONFIG_BFIN_UART1_CTSRTS is not set @@ -1149,7 +1149,7 @@ CONFIG_RTC_DRV_BFIN=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -1332,7 +1332,7 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_SAMPLES is not set -CONFIG_DEBUG_MMRS=y +# CONFIG_DEBUG_MMRS is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y diff --git a/trunk/arch/blackfin/configs/CM-BF561_defconfig b/trunk/arch/blackfin/configs/CM-BF561_defconfig index 59c7cdbee904..daf00906c1ef 100644 --- a/trunk/arch/blackfin/configs/CM-BF561_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF561_defconfig @@ -35,8 +35,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_USER_NS is not set # CONFIG_PID_NS is not set # CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y +# CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set CONFIG_FAIR_GROUP_SCHED=y @@ -342,7 +341,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC2 +CONFIG_BANK_3=0xFFC3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -632,7 +631,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # # CAN, the car bus and industrial fieldbus @@ -756,7 +756,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -830,12 +830,12 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_SAMPLES is not set -CONFIG_DEBUG_MMRS=y +# CONFIG_DEBUG_MMRS is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y diff --git a/trunk/arch/blackfin/configs/H8606_defconfig b/trunk/arch/blackfin/configs/H8606_defconfig index ba0bee90b7e1..679c7483ea71 100644 --- a/trunk/arch/blackfin/configs/H8606_defconfig +++ b/trunk/arch/blackfin/configs/H8606_defconfig @@ -967,7 +967,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/trunk/arch/blackfin/configs/IP0X_defconfig b/trunk/arch/blackfin/configs/IP0X_defconfig index 285d2241df26..4384a670a8b8 100644 --- a/trunk/arch/blackfin/configs/IP0X_defconfig +++ b/trunk/arch/blackfin/configs/IP0X_defconfig @@ -1066,7 +1066,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/trunk/arch/blackfin/configs/PNAV-10_defconfig b/trunk/arch/blackfin/configs/PNAV-10_defconfig index bffca7de65d4..87622ad9df47 100644 --- a/trunk/arch/blackfin/configs/PNAV-10_defconfig +++ b/trunk/arch/blackfin/configs/PNAV-10_defconfig @@ -294,7 +294,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x33B0 CONFIG_BANK_2=0x33B0 -CONFIG_BANK_3=0x99B2 +CONFIG_BANK_3=0x99B3 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -1080,7 +1080,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/trunk/arch/blackfin/configs/SRV1_defconfig b/trunk/arch/blackfin/configs/SRV1_defconfig index b1309f878fcd..951ea0412576 100644 --- a/trunk/arch/blackfin/configs/SRV1_defconfig +++ b/trunk/arch/blackfin/configs/SRV1_defconfig @@ -1067,7 +1067,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/trunk/arch/blackfin/kernel/Makefile b/trunk/arch/blackfin/kernel/Makefile index 606adc78aa85..6140cd69c782 100644 --- a/trunk/arch/blackfin/kernel/Makefile +++ b/trunk/arch/blackfin/kernel/Makefile @@ -18,5 +18,6 @@ endif obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o +obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c index 93229b3d6e3e..d54f19085f37 100644 --- a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c @@ -472,40 +472,6 @@ unsigned long get_dma_curr_addr(unsigned int channel) } EXPORT_SYMBOL(get_dma_curr_addr); -#ifdef CONFIG_PM -int blackfin_dma_suspend(void) -{ - int i; - -#ifdef CONFIG_BF561 /* IMDMA channels doesn't have a PERIPHERAL_MAP */ - for (i = 0; i <= CH_MEM_STREAM3_SRC; i++) { -#else - for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { -#endif - if (dma_ch[i].chan_status == DMA_CHANNEL_ENABLED) { - printk(KERN_ERR "DMA Channel %d failed to suspend\n", i); - return -EBUSY; - } - - dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map; - } - - return 0; -} - -void blackfin_dma_resume(void) -{ - int i; - -#ifdef CONFIG_BF561 /* IMDMA channels doesn't have a PERIPHERAL_MAP */ - for (i = 0; i <= CH_MEM_STREAM3_SRC; i++) -#else - for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) -#endif - dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; -} -#endif - static void *__dma_memcpy(void *dest, const void *src, size_t size) { int direction; /* 1 - address decrease, 0 - address increase */ diff --git a/trunk/arch/blackfin/kernel/bfin_gpio.c b/trunk/arch/blackfin/kernel/bfin_gpio.c index ecbd141e0ef2..b6d89d1644cc 100644 --- a/trunk/arch/blackfin/kernel/bfin_gpio.c +++ b/trunk/arch/blackfin/kernel/bfin_gpio.c @@ -186,10 +186,7 @@ static struct str_ident { char name[RESOURCE_LABEL_SIZE]; } str_ident[MAX_RESOURCES]; -#if defined(CONFIG_PM) -#if defined(CONFIG_BF54x) -static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; -#else +#if defined(CONFIG_PM) && !defined(CONFIG_BF54x) static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; @@ -209,7 +206,7 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PORTF_INT #ifdef BF561_FAMILY static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; #endif -#endif + #endif /* CONFIG_PM */ #if defined(BF548_FAMILY) @@ -670,7 +667,7 @@ static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) return 0; } -u32 bfin_pm_standby_setup(void) +u32 bfin_pm_setup(void) { u16 bank, mask, i, gpio; @@ -682,7 +679,7 @@ u32 bfin_pm_standby_setup(void) gpio_bankb[bank]->maskb = 0; if (mask) { -#if defined(BF527_FAMILY) || defined(BF537_FAMILY) +#ifdef BF537_FAMILY gpio_bank_saved[bank].fer = *port_fer[bank]; #endif gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; @@ -718,7 +715,7 @@ u32 bfin_pm_standby_setup(void) return 0; } -void bfin_pm_standby_restore(void) +void bfin_pm_restore(void) { u16 bank, mask, i; @@ -727,7 +724,7 @@ void bfin_pm_standby_restore(void) bank = gpio_bank(i); if (mask) { -#if defined(BF527_FAMILY) || defined(BF537_FAMILY) +#ifdef BF537_FAMILY *port_fer[bank] = gpio_bank_saved[bank].fer; #endif gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; @@ -746,111 +743,8 @@ void bfin_pm_standby_restore(void) AWA_DUMMY_READ(maskb); } -void bfin_gpio_pm_hibernate_suspend(void) -{ - int i, bank; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); - -#if defined(BF527_FAMILY) || defined(BF537_FAMILY) - gpio_bank_saved[bank].fer = *port_fer[bank]; -#ifdef BF527_FAMILY - gpio_bank_saved[bank].mux = *port_mux[bank]; -#else - if (bank == 0) - gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); -#endif -#endif - gpio_bank_saved[bank].data = gpio_bankb[bank]->data; - gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; - gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; - gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; - gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; - gpio_bank_saved[bank].both = gpio_bankb[bank]->both; - gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska; - } - - AWA_DUMMY_READ(maska); -} - -void bfin_gpio_pm_hibernate_restore(void) -{ - int i, bank; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); - -#if defined(BF527_FAMILY) || defined(BF537_FAMILY) -#ifdef BF527_FAMILY - *port_mux[bank] = gpio_bank_saved[bank].mux; -#else - if (bank == 0) - bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); -#endif - *port_fer[bank] = gpio_bank_saved[bank].fer; -#endif - gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; - gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; - gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; - gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; - gpio_bankb[bank]->both = gpio_bank_saved[bank].both; - - gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data - | gpio_bank_saved[bank].dir; - - gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska; - } - AWA_DUMMY_READ(maska); -} - - #endif #else /* BF548_FAMILY */ -#ifdef CONFIG_PM - -u32 bfin_pm_standby_setup(void) -{ - return 0; -} - -void bfin_pm_standby_restore(void) -{ - -} - -void bfin_gpio_pm_hibernate_suspend(void) -{ - int i, bank; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); - - gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; - gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; - gpio_bank_saved[bank].data = gpio_array[bank]->port_data; - gpio_bank_saved[bank].data = gpio_array[bank]->port_data; - gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen; - gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set; - } -} - -void bfin_gpio_pm_hibernate_restore(void) -{ - int i, bank; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); - - gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; - gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; - gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen; - gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir; - gpio_array[bank]->port_set = gpio_bank_saved[bank].data - | gpio_bank_saved[bank].dir; - } -} -#endif unsigned short get_gpio_dir(unsigned gpio) { diff --git a/trunk/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S b/trunk/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S index ecbabc0a1fed..2788532de72b 100644 --- a/trunk/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S +++ b/trunk/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S @@ -125,6 +125,6 @@ ENTRY(__cplb_hdr) SP += -12; call _panic_cplb_error; SP += 12; - JUMP.L _handle_bad_cplb; + JUMP _handle_bad_cplb; ENDPROC(__cplb_hdr) diff --git a/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 224e7cc30bc5..6be0c50122e8 100644 --- a/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -26,7 +26,11 @@ #include #include -#define CPLB_MEM CONFIG_MAX_MEM_SIZE +#ifdef CONFIG_MAX_MEM_SIZE +# define CPLB_MEM CONFIG_MAX_MEM_SIZE +#else +# define CPLB_MEM CONFIG_MEM_SIZE +#endif /* * Number of required data CPLB switchtable entries diff --git a/trunk/arch/blackfin/kernel/dualcore_test.c b/trunk/arch/blackfin/kernel/dualcore_test.c new file mode 100644 index 000000000000..0fcba74840b7 --- /dev/null +++ b/trunk/arch/blackfin/kernel/dualcore_test.c @@ -0,0 +1,49 @@ +/* + * File: arch/blackfin/kernel/dualcore_test.c + * Based on: + * Author: + * + * Created: + * Description: Small test code for CoreB on a BF561 + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.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 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +static int *testarg = (int *)0xfeb00000; + +static int test_init(void) +{ + *testarg = 1; + printk(KERN_INFO "Dual core test module inserted: set testarg = [%d]\n @ [%p]\n", + *testarg, testarg); + return 0; +} + +static void test_exit(void) +{ + printk(KERN_INFO "Dual core test module removed: testarg = [%d]\n", *testarg); +} + +module_init(test_init); +module_exit(test_exit); diff --git a/trunk/arch/blackfin/kernel/entry.S b/trunk/arch/blackfin/kernel/entry.S index 31bd9bf3efae..65f4e67a65c4 100644 --- a/trunk/arch/blackfin/kernel/entry.S +++ b/trunk/arch/blackfin/kernel/entry.S @@ -64,11 +64,6 @@ ENDPROC(_ret_from_fork) ENTRY(_sys_fork) r0 = -EINVAL; -#if (ANOMALY_05000371) - nop; - nop; - nop; -#endif rts; ENDPROC(_sys_fork) diff --git a/trunk/arch/blackfin/kernel/kgdb.c b/trunk/arch/blackfin/kernel/kgdb.c index a1f9641a6425..a9c15515bfd7 100644 --- a/trunk/arch/blackfin/kernel/kgdb.c +++ b/trunk/arch/blackfin/kernel/kgdb.c @@ -203,8 +203,6 @@ struct hw_breakpoint { int kgdb_arch_init(void) { - debugger_step = 0; - kgdb_remove_all_hw_break(); return 0; } @@ -370,7 +368,6 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo, char *ptr; int newPC; int wp_status; - int i; switch (remcom_in_buffer[0]) { case 'c': @@ -395,18 +392,7 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo, /* set the trace bit if we're stepping */ if (remcom_in_buffer[0] == 's') { linux_regs->syscfg |= 0x1; - debugger_step = linux_regs->ipend; - debugger_step >>= 6; - for (i = 10; i > 0; i--, debugger_step >>= 1) - if (debugger_step & 1) - break; - /* i indicate event priority of current stopped instruction - * user space instruction is 0, IVG15 is 1, IVTMR is 10. - * debugger_step > 0 means in single step mode - */ - debugger_step = i + 1; - } else { - debugger_step = 0; + debugger_step = 1; } wp_status = bfin_read_WPSTAT(); diff --git a/trunk/arch/blackfin/kernel/module.c b/trunk/arch/blackfin/kernel/module.c index e1bebc80a5bf..14a42848f37f 100644 --- a/trunk/arch/blackfin/kernel/module.c +++ b/trunk/arch/blackfin/kernel/module.c @@ -173,7 +173,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, for (s = sechdrs; s < sechdrs_end; ++s) { if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || ((strcmp(".text", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { dest = l1_inst_sram_alloc(s->sh_size); mod->arch.text_l1 = dest; if (dest == NULL) { @@ -188,7 +188,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, } if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || ((strcmp(".data", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { dest = l1_data_sram_alloc(s->sh_size); mod->arch.data_a_l1 = dest; if (dest == NULL) { @@ -203,7 +203,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, } if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || ((strcmp(".bss", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { dest = l1_data_sram_alloc(s->sh_size); mod->arch.bss_a_l1 = dest; if (dest == NULL) { @@ -242,51 +242,6 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, s->sh_flags &= ~SHF_ALLOC; s->sh_addr = (unsigned long)dest; } - if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) || - ((strcmp(".text", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) { - dest = l2_sram_alloc(s->sh_size); - mod->arch.text_l2 = dest; - if (dest == NULL) { - printk(KERN_ERR - "module %s: L2 SRAM allocation failed\n", - mod->name); - return -1; - } - memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) || - ((strcmp(".data", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { - dest = l2_sram_alloc(s->sh_size); - mod->arch.data_l2 = dest; - if (dest == NULL) { - printk(KERN_ERR - "module %s: L2 SRAM allocation failed\n", - mod->name); - return -1; - } - memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 || - ((strcmp(".bss", secstrings + s->sh_name) == 0) && - (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { - dest = l2_sram_alloc(s->sh_size); - mod->arch.bss_l2 = dest; - if (dest == NULL) { - printk(KERN_ERR - "module %s: L2 SRAM allocation failed\n", - mod->name); - return -1; - } - memset(dest, 0, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } } return 0; } @@ -456,10 +411,9 @@ module_finalize(const Elf_Ehdr * hdr, continue; if ((sechdrs[i].sh_type == SHT_RELA) && - ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) || - (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || + ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && - (hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) { + (hdr->e_flags & FLG_CODE_IN_L1)))) { apply_relocate_add((Elf_Shdr *) sechdrs, strtab, symindex, i, mod); } @@ -469,12 +423,14 @@ module_finalize(const Elf_Ehdr * hdr, void module_arch_cleanup(struct module *mod) { - l1_inst_sram_free(mod->arch.text_l1); - l1_data_A_sram_free(mod->arch.data_a_l1); - l1_data_A_sram_free(mod->arch.bss_a_l1); - l1_data_B_sram_free(mod->arch.data_b_l1); - l1_data_B_sram_free(mod->arch.bss_b_l1); - l2_sram_free(mod->arch.text_l2); - l2_sram_free(mod->arch.data_l2); - l2_sram_free(mod->arch.bss_l2); + if (mod->arch.text_l1) + l1_inst_sram_free((void *)mod->arch.text_l1); + if (mod->arch.data_a_l1) + l1_data_sram_free((void *)mod->arch.data_a_l1); + if (mod->arch.bss_a_l1) + l1_data_sram_free((void *)mod->arch.bss_a_l1); + if (mod->arch.data_b_l1) + l1_data_B_sram_free((void *)mod->arch.data_b_l1); + if (mod->arch.bss_b_l1) + l1_data_B_sram_free((void *)mod->arch.bss_b_l1); } diff --git a/trunk/arch/blackfin/kernel/ptrace.c b/trunk/arch/blackfin/kernel/ptrace.c index bf1a51d8e608..f51ab088098e 100644 --- a/trunk/arch/blackfin/kernel/ptrace.c +++ b/trunk/arch/blackfin/kernel/ptrace.c @@ -219,20 +219,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) safe_dma_memcpy (&tmp, (const void *)(addr + add), sizeof(tmp)); copied = sizeof(tmp); } else -#endif -#if L1_DATA_A_LENGTH != 0 - if (addr + add >= L1_DATA_A_START - && addr + add + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { - memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); - copied = sizeof(tmp); - } else -#endif -#if L1_DATA_B_LENGTH != 0 - if (addr + add >= L1_DATA_B_START - && addr + add + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { - memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); - copied = sizeof(tmp); - } else #endif if (addr + add >= FIXED_CODE_START && addr + add + sizeof(tmp) <= FIXED_CODE_END) { @@ -303,20 +289,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) safe_dma_memcpy ((void *)(addr + add), &data, sizeof(data)); copied = sizeof(data); } else -#endif -#if L1_DATA_A_LENGTH != 0 - if (addr + add >= L1_DATA_A_START - && addr + add + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { - memcpy((void *)(addr + add), &data, sizeof(data)); - copied = sizeof(data); - } else -#endif -#if L1_DATA_B_LENGTH != 0 - if (addr + add >= L1_DATA_B_START - && addr + add + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { - memcpy((void *)(addr + add), &data, sizeof(data)); - copied = sizeof(data); - } else #endif if (addr + add >= FIXED_CODE_START && addr + add + sizeof(data) <= FIXED_CODE_END) { diff --git a/trunk/arch/blackfin/kernel/setup.c b/trunk/arch/blackfin/kernel/setup.c index 23e637eb78da..8efea004aecb 100644 --- a/trunk/arch/blackfin/kernel/setup.c +++ b/trunk/arch/blackfin/kernel/setup.c @@ -104,7 +104,6 @@ void __init bf53x_relocate_l1_mem(void) unsigned long l1_code_length; unsigned long l1_data_a_length; unsigned long l1_data_b_length; - unsigned long l2_length; l1_code_length = _etext_l1 - _stext_l1; if (l1_code_length > L1_CODE_LENGTH) @@ -130,15 +129,6 @@ void __init bf53x_relocate_l1_mem(void) /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + l1_data_a_length, l1_data_b_length); - -#ifdef L2_LENGTH - l2_length = _ebss_l2 - _stext_l2; - if (l2_length > L2_LENGTH) - panic("L2 SRAM Overflow\n"); - - /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ - dma_memcpy(_stext_l2, _l2_lma_start, l2_length); -#endif } /* add_memory_region to memmap */ @@ -674,8 +664,11 @@ static __init void setup_bootmem_allocator(void) }) static inline int __init get_mem_size(void) { -#if defined(EBIU_SDBCTL) -# if defined(BF561_FAMILY) +#ifdef CONFIG_MEM_SIZE + return CONFIG_MEM_SIZE; +#else +# if defined(EBIU_SDBCTL) +# if defined(BF561_FAMILY) int ret = 0; u32 sdbctl = bfin_read_EBIU_SDBCTL(); ret += EBSZ_TO_MEG(sdbctl >> 0); @@ -683,10 +676,10 @@ static inline int __init get_mem_size(void) ret += EBSZ_TO_MEG(sdbctl >> 16); ret += EBSZ_TO_MEG(sdbctl >> 24); return ret; -# else +# else return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL()); -# endif -#elif defined(EBIU_DDRCTL1) +# endif +# elif defined(EBIU_DDRCTL1) u32 ddrctl = bfin_read_EBIU_DDRCTL1(); int ret = 0; switch (ddrctl & 0xc0000) { @@ -700,9 +693,8 @@ static inline int __init get_mem_size(void) case DEVWD_8: ret *= 2; case DEVWD_16: break; } - if ((ddrctl & 0xc000) == 0x4000) - ret *= 2; return ret; +# endif #endif BUG(); } @@ -771,9 +763,6 @@ void __init setup_arch(char **cmdline_p) _bfin_swrst = bfin_read_SWRST(); - /* If we double fault, reset the system - otherwise we hang forever */ - bfin_write_SWRST(DOUBLE_FAULT); - if (_bfin_swrst & RESET_DOUBLE) printk(KERN_INFO "Recovering from Double Fault event\n"); else if (_bfin_swrst & RESET_WDOG) @@ -853,55 +842,38 @@ static int __init topology_init(void) subsys_initcall(topology_init); -/* Get the voltage input multiplier */ -static u_long cached_vco_pll_ctl, cached_vco; static u_long get_vco(void) { u_long msel; + u_long vco; - u_long pll_ctl = bfin_read_PLL_CTL(); - if (pll_ctl == cached_vco_pll_ctl) - return cached_vco; - else - cached_vco_pll_ctl = pll_ctl; - - msel = (pll_ctl >> 9) & 0x3F; + msel = (bfin_read_PLL_CTL() >> 9) & 0x3F; if (0 == msel) msel = 64; - cached_vco = CONFIG_CLKIN_HZ; - cached_vco >>= (1 & pll_ctl); /* DF bit */ - cached_vco *= msel; - return cached_vco; + vco = CONFIG_CLKIN_HZ; + vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */ + vco = msel * vco; + return vco; } /* Get the Core clock */ -static u_long cached_cclk_pll_div, cached_cclk; u_long get_cclk(void) { u_long csel, ssel; - if (bfin_read_PLL_STAT() & 0x1) return CONFIG_CLKIN_HZ; ssel = bfin_read_PLL_DIV(); - if (ssel == cached_cclk_pll_div) - return cached_cclk; - else - cached_cclk_pll_div = ssel; - csel = ((ssel >> 4) & 0x03); ssel &= 0xf; if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ - cached_cclk = get_vco() / ssel; - else - cached_cclk = get_vco() >> csel; - return cached_cclk; + return get_vco() / ssel; + return get_vco() >> csel; } EXPORT_SYMBOL(get_cclk); /* Get the System clock */ -static u_long cached_sclk_pll_div, cached_sclk; u_long get_sclk(void) { u_long ssel; @@ -909,20 +881,13 @@ u_long get_sclk(void) if (bfin_read_PLL_STAT() & 0x1) return CONFIG_CLKIN_HZ; - ssel = bfin_read_PLL_DIV(); - if (ssel == cached_sclk_pll_div) - return cached_sclk; - else - cached_sclk_pll_div = ssel; - - ssel &= 0xf; + ssel = (bfin_read_PLL_DIV() & 0xf); if (0 == ssel) { printk(KERN_WARNING "Invalid System Clock\n"); ssel = 1; } - cached_sclk = get_vco() / ssel; - return cached_sclk; + return get_vco() / ssel; } EXPORT_SYMBOL(get_sclk); @@ -951,7 +916,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) uint32_t revid; u_long cclk = 0, sclk = 0; - u_int icache_size = BFIN_ICACHESIZE / 1024, dcache_size = 0, dsup_banks = 0; + u_int dcache_size = 0, dsup_banks = 0; cpu = CPU; mmu = "none"; @@ -1020,15 +985,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) } /* Is it turned on? */ - if ((bfin_read_DMEM_CONTROL() & (ENDCPLB | DMC_ENABLE)) != (ENDCPLB | DMC_ENABLE)) + if (!((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))) dcache_size = 0; - if ((bfin_read_IMEM_CONTROL() & (IMC | ENICPLB)) == (IMC | ENICPLB)) - icache_size = 0; - seq_printf(m, "cache size\t: %d KB(L1 icache) " "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", - icache_size, dcache_size, + BFIN_ICACHESIZE / 1024, dcache_size, #if defined CONFIG_BFIN_WB "wb" #elif defined CONFIG_BFIN_WT @@ -1038,12 +1000,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "%s\n", cache); - if (icache_size) - seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", - BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); - else - seq_printf(m, "icache setup\t: off\n"); - + seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", + BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); seq_printf(m, "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS, diff --git a/trunk/arch/blackfin/kernel/traps.c b/trunk/arch/blackfin/kernel/traps.c index ad922ab91543..f061f5181623 100644 --- a/trunk/arch/blackfin/kernel/traps.c +++ b/trunk/arch/blackfin/kernel/traps.c @@ -69,6 +69,8 @@ void __init trap_init(void) unsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr; +int kstack_depth_to_print = 48; + static void decode_address(char *buf, unsigned long address) { struct vm_list_struct *vml; @@ -161,9 +163,6 @@ static void decode_address(char *buf, unsigned long address) if (!in_atomic) mmput(mm); - if (!strlen(buf)) - sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name); - goto done; } @@ -174,7 +173,7 @@ static void decode_address(char *buf, unsigned long address) } /* we were unable to find this address anywhere */ - sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address); + sprintf(buf, "<0x%p> /* unknown address */", (void *)address); done: write_unlock_irqrestore(&tasklist_lock, flags); @@ -495,7 +494,7 @@ asmlinkage void trap_c(struct pt_regs *fp) BUG_ON(sig == 0); if (sig != SIGTRAP) { - unsigned long *stack; + unsigned long stack; dump_bfin_process(fp); dump_bfin_mem(fp); show_regs(fp); @@ -509,23 +508,14 @@ asmlinkage void trap_c(struct pt_regs *fp) else #endif dump_bfin_trace_buffer(); - + show_stack(current, &stack); if (oops_in_progress) { - /* Dump the current kernel stack */ - printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n"); - show_stack(current, NULL); - print_modules(); #ifndef CONFIG_ACCESS_CHECK printk(KERN_EMERG "Please turn on " "CONFIG_ACCESS_CHECK\n"); #endif panic("Kernel exception"); - } else { - /* Dump the user space stack */ - stack = (unsigned long *)rdusp(); - printk(KERN_NOTICE "Userspace Stack\n"); - show_stack(NULL, stack); } } @@ -542,71 +532,11 @@ asmlinkage void trap_c(struct pt_regs *fp) #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) -/* - * Similar to get_user, do some address checking, then dereference - * Return true on sucess, false on bad address - */ -bool get_instruction(unsigned short *val, unsigned short *address) -{ - - unsigned long addr; - - addr = (unsigned long)address; - - /* Check for odd addresses */ - if (addr & 0x1) - return false; - - /* Check that things do not wrap around */ - if (addr > (addr + 2)) - return false; - - /* - * Since we are in exception context, we need to do a little address checking - * We need to make sure we are only accessing valid memory, and - * we don't read something in the async space that can hang forever - */ - if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || -#ifdef L2_START - (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || -#endif - (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || -#if L1_DATA_A_LENGTH != 0 - (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) || -#endif -#if L1_DATA_B_LENGTH != 0 - (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) || -#endif - (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) || - (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) && - addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) || - (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) && - addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) || - (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) && - addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) || - (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) && - addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) { - *val = *address; - return true; - } - -#if L1_CODE_LENGTH != 0 - if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) { - dma_memcpy(val, address, 2); - return true; - } -#endif - - - return false; -} - void dump_bfin_trace_buffer(void) { #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int tflags, i = 0; char buf[150]; - unsigned short val = 0, *addr; #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND int j, index; #endif @@ -619,42 +549,8 @@ void dump_bfin_trace_buffer(void) for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { decode_address(buf, (unsigned long)bfin_read_TBUF()); printk(KERN_NOTICE "%4i Target : %s\n", i, buf); - addr = (unsigned short *)bfin_read_TBUF(); - decode_address(buf, (unsigned long)addr); - printk(KERN_NOTICE " Source : %s ", buf); - if (get_instruction(&val, addr)) { - if (val == 0x0010) - printk("RTS"); - else if (val == 0x0011) - printk("RTI"); - else if (val == 0x0012) - printk("RTX"); - else if (val >= 0x0050 && val <= 0x0057) - printk("JUMP (P%i)", val & 7); - else if (val >= 0x0060 && val <= 0x0067) - printk("CALL (P%i)", val & 7); - else if (val >= 0x0070 && val <= 0x0077) - printk("CALL (PC+P%i)", val & 7); - else if (val >= 0x0080 && val <= 0x0087) - printk("JUMP (PC+P%i)", val & 7); - else if ((val >= 0x1000 && val <= 0x13FF) || - (val >= 0x1800 && val <= 0x1BFF)) - printk("IF !CC JUMP"); - else if ((val >= 0x1400 && val <= 0x17ff) || - (val >= 0x1c00 && val <= 0x1fff)) - printk("IF CC JUMP"); - else if (val >= 0x2000 && val <= 0x2fff) - printk("JUMP.S"); - else if (val >= 0xe080 && val <= 0xe0ff) - printk("LSETUP"); - else if (val >= 0xe200 && val <= 0xe2ff) - printk("JUMP.L"); - else if (val >= 0xe300 && val <= 0xe3ff) - printk("CALL pcrel"); - else - printk("0x%04x", val); - } - printk("\n"); + decode_address(buf, (unsigned long)bfin_read_TBUF()); + printk(KERN_NOTICE " Source : %s\n", buf); } } @@ -686,151 +582,59 @@ void dump_bfin_trace_buffer(void) } EXPORT_SYMBOL(dump_bfin_trace_buffer); -/* - * Checks to see if the address pointed to is either a - * 16-bit CALL instruction, or a 32-bit CALL instruction - */ -bool is_bfin_call(unsigned short *addr) +static void show_trace(struct task_struct *tsk, unsigned long *sp) { - unsigned short opcode = 0, *ins_addr; - ins_addr = (unsigned short *)addr; - - if (!get_instruction(&opcode, ins_addr)) - return false; - - if ((opcode >= 0x0060 && opcode <= 0x0067) || - (opcode >= 0x0070 && opcode <= 0x0077)) - return true; - - ins_addr--; - if (!get_instruction(&opcode, ins_addr)) - return false; - - if (opcode >= 0xE300 && opcode <= 0xE3FF) - return true; + unsigned long addr; - return false; + printk(KERN_NOTICE "\n" KERN_NOTICE "Call Trace:\n"); + + while (!kstack_end(sp)) { + addr = *sp++; + /* + * If the address is either in the text segment of the + * kernel, or in the region which contains vmalloc'ed + * memory, it *may* be the address of a calling + * routine; if so, print it so that someone tracing + * down the cause of the crash will be able to figure + * out the call path that was taken. + */ + if (kernel_text_address(addr)) + print_ip_sym(addr); + } + printk(KERN_NOTICE "\n"); } + void show_stack(struct task_struct *task, unsigned long *stack) { - unsigned int *addr, *endstack, *fp = 0, *frame; - unsigned short *ins_addr; - char buf[150]; - unsigned int i, j, ret_addr, frame_no = 0; + unsigned long *endstack, addr; + int i; - /* - * If we have been passed a specific stack, use that one otherwise - * if we have been passed a task structure, use that, otherwise - * use the stack of where the variable "stack" exists + /* Cannot call dump_bfin_trace_buffer() here as show_stack() is + * called externally in some places in the kernel. */ - if (stack == NULL) { - if (task) { - /* We know this is a kernel stack, so this is the start/end */ + if (!stack) { + if (task) stack = (unsigned long *)task->thread.ksp; - endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); - } else { - /* print out the existing stack info */ + else stack = (unsigned long *)&stack; - endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); - } - } else - endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); - - decode_address(buf, (unsigned int)stack); - printk(KERN_NOTICE "Stack info:\n" KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); - addr = (unsigned int *)((unsigned int)stack & ~0x3F); - - /* First thing is to look for a frame pointer */ - for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; - addr < endstack; addr++, i++) { - if (*addr & 0x1) - continue; - ins_addr = (unsigned short *)*addr; - ins_addr--; - if (is_bfin_call(ins_addr)) - fp = addr - 1; - - if (fp) { - /* Let's check to see if it is a frame pointer */ - while (fp >= (addr - 1) && fp < endstack && fp) - fp = (unsigned int *)*fp; - if (fp == 0 || fp == endstack) { - fp = addr - 1; - break; - } - fp = 0; - } } - if (fp) { - frame = fp; - printk(" FP: (0x%p)\n", fp); - } else - frame = 0; - /* - * Now that we think we know where things are, we - * walk the stack again, this time printing things out - * incase there is no frame pointer, we still look for - * valid return addresses - */ + addr = (unsigned long)stack; + endstack = (unsigned long *)PAGE_ALIGN(addr); - /* First time print out data, next time, print out symbols */ - for (j = 0; j <= 1; j++) { - if (j) - printk(KERN_NOTICE "Return addresses in stack:\n"); - else - printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); - - fp = frame; - frame_no = 0; - - for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; - addr <= endstack; addr++, i++) { - - ret_addr = 0; - if (!j && i % 8 == 0) - printk("\n" KERN_NOTICE "%p:",addr); - - /* if it is an odd address, or zero, just skip it */ - if (*addr & 0x1 || !*addr) - goto print; - - ins_addr = (unsigned short *)*addr; - - /* Go back one instruction, and see if it is a CALL */ - ins_addr--; - ret_addr = is_bfin_call(ins_addr); - print: - if (!j && stack == (unsigned long *)addr) - printk("[%08x]", *addr); - else if (ret_addr) - if (j) { - decode_address(buf, (unsigned int)*addr); - if (frame == addr) { - printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); - continue; - } - printk(KERN_NOTICE " address : %s\n", buf); - } else - printk("<%08x>", *addr); - else if (fp == addr) { - if (j) - frame = addr+1; - else - printk("(%08x)", *addr); - - fp = (unsigned int *)*addr; - frame_no++; - - } else if (!j) - printk(" %08x ", *addr); - } - if (!j) - printk("\n"); + printk(KERN_NOTICE "Stack from %08lx:", (unsigned long)stack); + for (i = 0; i < kstack_depth_to_print; i++) { + if (stack + 1 > endstack) + break; + if (i % 8 == 0) + printk("\n" KERN_NOTICE " "); + printk(" %08lx", *stack++); } + printk("\n"); + show_trace(task, stack); } void dump_stack(void) @@ -911,9 +715,19 @@ void dump_bfin_mem(struct pt_regs *fp) if (!((unsigned long)addr & 0xF)) printk("\n" KERN_NOTICE "0x%p: ", addr); - if (get_instruction(&val, addr)) { + if (get_user(val, addr)) { + if (addr >= (unsigned short *)L1_CODE_START && + addr < (unsigned short *)(L1_CODE_START + L1_CODE_LENGTH)) { + dma_memcpy(&val, addr, sizeof(val)); + sprintf(buf, "%04x", val); + } else if (addr >= (unsigned short *)FIXED_CODE_START && + addr <= (unsigned short *)memory_start) { + val = bfin_read16(addr); + sprintf(buf, "%04x", val); + } else { val = 0; sprintf(buf, "????"); + } } else sprintf(buf, "%04x", val); diff --git a/trunk/arch/blackfin/kernel/vmlinux.lds.S b/trunk/arch/blackfin/kernel/vmlinux.lds.S index 0896e38d6108..3ecc64cab3be 100644 --- a/trunk/arch/blackfin/kernel/vmlinux.lds.S +++ b/trunk/arch/blackfin/kernel/vmlinux.lds.S @@ -101,11 +101,6 @@ SECTIONS #if !L1_DATA_B_LENGTH *(.l1.data.B) #endif -#ifndef L2_LENGTH - . = ALIGN(32); - *(.data_l2.cacheline_aligned) - *(.l2.data) -#endif DATA_DATA *(.data.*) @@ -187,12 +182,13 @@ SECTIONS *(.l1.data) __edata_l1 = .; - . = ALIGN(32); - *(.data_l1.cacheline_aligned) - . = ALIGN(4); __sbss_l1 = .; *(.l1.bss) + + . = ALIGN(32); + *(.data_l1.cacheline_aligned) + . = ALIGN(4); __ebss_l1 = .; } @@ -207,36 +203,10 @@ SECTIONS . = ALIGN(4); __sbss_b_l1 = .; *(.l1.bss.B) - . = ALIGN(4); - __ebss_b_l1 = .; - } - -#ifdef L2_LENGTH - __l2_lma_start = .; - .text_data_l2 L2_START : AT(LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1)) - { . = ALIGN(4); - __stext_l2 = .; - *(.l1.text) - . = ALIGN(4); - __etext_l2 = .; - - . = ALIGN(4); - __sdata_l2 = .; - *(.l1.data) - __edata_l2 = .; - - . = ALIGN(32); - *(.data_l2.cacheline_aligned) - - . = ALIGN(4); - __sbss_l2 = .; - *(.l1.bss) - . = ALIGN(4); - __ebss_l2 = .; + __ebss_b_l1 = .; } -#endif /* Force trailing alignment of our init section so that when we * free our init memory, we don't leave behind a partial page. diff --git a/trunk/arch/blackfin/mach-bf527/boards/Kconfig b/trunk/arch/blackfin/mach-bf527/boards/Kconfig index 8bf9e58f0148..6a570ad03746 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/Kconfig +++ b/trunk/arch/blackfin/mach-bf527/boards/Kconfig @@ -9,9 +9,4 @@ config BFIN527_EZKIT help BF527-EZKIT-LITE board support. -config BFIN527_BLUETECHNIX_CM - bool "Bluetechnix CM-BF527" - help - CM-BF527 support for EVAL- and DEV-Board. - endchoice diff --git a/trunk/arch/blackfin/mach-bf527/boards/Makefile b/trunk/arch/blackfin/mach-bf527/boards/Makefile index 7ba7d256bbb8..7277d35ef111 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/Makefile +++ b/trunk/arch/blackfin/mach-bf527/boards/Makefile @@ -3,4 +3,3 @@ # obj-$(CONFIG_BFIN527_EZKIT) += ezkit.o -obj-$(CONFIG_BFIN527_BLUETECHNIX_CM) += cm_bf527.o diff --git a/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c b/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c deleted file mode 100644 index 0b26ae2de5ee..000000000000 --- a/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ /dev/null @@ -1,1011 +0,0 @@ -/* - * File: arch/blackfin/mach-bf527/boards/cm-bf527.c - * Based on: arch/blackfin/mach-bf537/boards/stamp.c - * Author: Aidan Williams - * - * Created: - * Description: - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2008 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.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 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, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -#include -#endif -#include -#include -#include -#include -#include -#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -const char bfin_board_name[] = "Bluetechnix CM-BF527"; - -/* - * Driver needs to know address, irq and flag pin. - */ - -#define ISP1761_BASE 0x203C0000 -#define ISP1761_IRQ IRQ_PF7 - -#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) -static struct resource bfin_isp1761_resources[] = { - [0] = { - .name = "isp1761-regs", - .start = ISP1761_BASE + 0x00000000, - .end = ISP1761_BASE + 0x000fffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = ISP1761_IRQ, - .end = ISP1761_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_isp1761_device = { - .name = "isp1761", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_isp1761_resources), - .resource = bfin_isp1761_resources, -}; - -static struct platform_device *bfin_isp1761_devices[] = { - &bfin_isp1761_device, -}; - -int __init bfin_isp1761_init(void) -{ - unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices); - - printk(KERN_INFO "%s(): registering device resources\n", __func__); - set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING); - - return platform_add_devices(bfin_isp1761_devices, num_devices); -} - -void __exit bfin_isp1761_exit(void) -{ - platform_device_unregister(&bfin_isp1761_device); -} - -arch_initcall(bfin_isp1761_init); -#endif - -#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) -static struct resource musb_resources[] = { - [0] = { - .start = 0xffc03800, - .end = 0xffc03cff, - .flags = IORESOURCE_MEM, - }, - [1] = { /* general IRQ */ - .start = IRQ_USB_INT0, - .end = IRQ_USB_INT0, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, - [2] = { /* DMA IRQ */ - .start = IRQ_USB_DMA, - .end = IRQ_USB_DMA, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct musb_hdrc_platform_data musb_plat = { -#if defined(CONFIG_USB_MUSB_OTG) - .mode = MUSB_OTG, -#elif defined(CONFIG_USB_MUSB_HDRC_HCD) - .mode = MUSB_HOST, -#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) - .mode = MUSB_PERIPHERAL, -#endif - .multipoint = 0, -}; - -static u64 musb_dmamask = ~(u32)0; - -static struct platform_device musb_device = { - .name = "musb_hdrc", - .id = 0, - .dev = { - .dma_mask = &musb_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &musb_plat, - }, - .num_resources = ARRAY_SIZE(musb_resources), - .resource = musb_resources, -}; -#endif - -#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) -static struct mtd_partition ezkit_partitions[] = { - { - .name = "Bootloader", - .size = 0x40000, - .offset = 0, - }, { - .name = "Kernel", - .size = 0x1C0000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "RootFS", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - } -}; - -static struct physmap_flash_data ezkit_flash_data = { - .width = 2, - .parts = ezkit_partitions, - .nr_parts = ARRAY_SIZE(ezkit_partitions), -}; - -static struct resource ezkit_flash_resource = { - .start = 0x20000000, - .end = 0x201fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ezkit_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ezkit_flash_data, - }, - .num_resources = 1, - .resource = &ezkit_flash_resource, -}; -#endif - -#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) -static struct mtd_partition partition_info[] = { - { - .name = "Linux Kernel", - .offset = 0, - .size = 4 * SIZE_1M, - }, - { - .name = "File System", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct bf5xx_nand_platform bf5xx_nand_platform = { - .page_size = NFC_PG_SIZE_256, - .data_width = NFC_NWIDTH_8, - .partitions = partition_info, - .nr_partitions = ARRAY_SIZE(partition_info), - .rd_dly = 3, - .wr_dly = 3, -}; - -static struct resource bf5xx_nand_resources[] = { - { - .start = NFC_CTL, - .end = NFC_DATA_RD + 2, - .flags = IORESOURCE_MEM, - }, - { - .start = CH_NFC, - .end = CH_NFC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bf5xx_nand_device = { - .name = "bf5xx-nand", - .id = 0, - .num_resources = ARRAY_SIZE(bf5xx_nand_resources), - .resource = bf5xx_nand_resources, - .dev = { - .platform_data = &bf5xx_nand_platform, - }, -}; -#endif - -#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) -static struct resource bfin_pcmcia_cf_resources[] = { - { - .start = 0x20310000, /* IO PORT */ - .end = 0x20312000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20311000, /* Attribute Memory */ - .end = 0x20311FFF, - .flags = IORESOURCE_MEM, - }, { - .start = IRQ_PF4, - .end = IRQ_PF4, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, - }, { - .start = 6, /* Card Detect PF6 */ - .end = 6, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_pcmcia_cf_device = { - .name = "bfin_cf_pcmcia", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), - .resource = bfin_pcmcia_cf_resources, -}; -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .name = "smc91x-regs", - .start = 0x20300300, - .end = 0x20300300 + 16, - .flags = IORESOURCE_MEM, - }, { - - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) -static struct resource dm9000_resources[] = { - [0] = { - .start = 0x203FB800, - .end = 0x203FB800 + 8, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PF9, - .end = IRQ_PF9, - .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), - }, -}; - -static struct platform_device dm9000_device = { - .name = "dm9000", - .id = -1, - .num_resources = ARRAY_SIZE(dm9000_resources), - .resource = dm9000_resources, -}; -#endif - -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) -static struct resource sl811_hcd_resources[] = { - { - .start = 0x20340000, - .end = 0x20340000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20340004, - .end = 0x20340004, - .flags = IORESOURCE_MEM, - }, { - .start = CONFIG_USB_SL811_BFIN_IRQ, - .end = CONFIG_USB_SL811_BFIN_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) -void sl811_port_power(struct device *dev, int is_on) -{ - gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); - gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); -} -#endif - -static struct sl811_platform_data sl811_priv = { - .potpg = 10, - .power = 250, /* == 500mA */ -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) - .port_power = &sl811_port_power, -#endif -}; - -static struct platform_device sl811_hcd_device = { - .name = "sl811-hcd", - .id = 0, - .dev = { - .platform_data = &sl811_priv, - }, - .num_resources = ARRAY_SIZE(sl811_hcd_resources), - .resource = sl811_hcd_resources, -}; -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x20360000, - .end = 0x20360000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20360004, - .end = 0x20360004, - .flags = IORESOURCE_MEM, - }, { - .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mac_device = { - .name = "bfin_mac", -}; -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) -static struct resource net2272_bfin_resources[] = { - { - .start = 0x20300000, - .end = 0x20300000 + 0x100, - .flags = IORESOURCE_MEM, - }, { - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device net2272_bfin_device = { - .name = "net2272", - .id = -1, - .num_resources = ARRAY_SIZE(net2272_bfin_resources), - .resource = net2272_bfin_resources, -}; -#endif - -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader", - .size = 0x00040000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - }, { - .name = "linux kernel", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p16", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_SPI_ADC_BF533) \ - || defined(CONFIG_SPI_ADC_BF533_MODULE) -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) -static struct bfin5xx_spi_chip spi_mmc_chip_info = { - .enable_dma = 1, - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) -static struct bfin5xx_spi_chip spi_ad7877_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; - -static const struct ad7877_platform_data bfin_ad7877_ts_info = { - .model = 7877, - .vref_delay_usecs = 50, /* internal, no capacitor */ - .x_plate_ohms = 419, - .y_plate_ohms = 486, - .pressure_max = 1000, - .pressure_min = 0, - .stopacq_polarity = 1, - .first_conversion_delay = 3, - .acquisition_time = 1, - .averaging = 1, - .pen_down_acc_interval = 1, -}; -#endif - -#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ - && defined(CONFIG_SND_SOC_WM8731_SPI) -static struct bfin5xx_spi_chip spi_wm8731_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) -static struct bfin5xx_spi_chip spidev_chip_info = { - .enable_dma = 0, - .bits_per_word = 8, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_SPI_ADC_BF533) \ - || defined(CONFIG_SPI_ADC_BF533_MODULE) - { - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) - { - .modalias = "spi_mmc_dummy", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 0, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "spi_mmc", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = CONFIG_SPI_MMC_CS_CHAN, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J11_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J19_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) - { - .modalias = "ad7877", - .platform_data = &bfin_ad7877_ts_info, - .irq = IRQ_PF8, - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .controller_data = &spi_ad7877_chip_info, - }, -#endif -#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ - && defined(CONFIG_SND_SOC_WM8731_SPI) - { - .modalias = "wm8731", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 5, - .controller_data = &spi_wm8731_chip_info, - .mode = SPI_MODE_0, - }, -#endif -#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) - { - .modalias = "spidev", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &spidev_chip_info, - }, -#endif -}; - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* SPI controller data */ -static struct bfin5xx_spi_master bfin_spi0_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ - .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, -}; - -/* SPI (0) */ -static struct resource bfin_spi0_resource[] = { - [0] = { - .start = SPI0_REGBASE, - .end = SPI0_REGBASE + 0xFF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = CH_SPI, - .end = CH_SPI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_spi0_device = { - .name = "bfin-spi", - .id = 0, /* Bus number */ - .num_resources = ARRAY_SIZE(bfin_spi0_resource), - .resource = bfin_spi0_resource, - .dev = { - .platform_data = &bfin_spi0_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) -static struct platform_device bfin_fb_adv7393_device = { - .name = "bfin-adv7393", -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { -#ifdef CONFIG_SERIAL_BFIN_UART0 - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -#endif -#ifdef CONFIG_SERIAL_BFIN_UART1 - { - .start = 0xFFC02000, - .end = 0xFFC020FF, - .flags = IORESOURCE_MEM, - }, -#endif -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) -static struct resource bfin_sir_resources[] = { -#ifdef CONFIG_BFIN_SIR0 - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -#endif -#ifdef CONFIG_BFIN_SIR1 - { - .start = 0xFFC02000, - .end = 0xFFC020FF, - .flags = IORESOURCE_MEM, - }, -#endif -}; - -static struct platform_device bfin_sir_device = { - .name = "bfin_sir", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_sir_resources), - .resource = bfin_sir_resources, -}; -#endif - -#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static struct resource bfin_twi0_resource[] = { - [0] = { - .start = TWI0_REGBASE, - .end = TWI0_REGBASE, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TWI, - .end = IRQ_TWI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device i2c_bfin_twi_device = { - .name = "i2c-bfin-twi", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_twi0_resource), - .resource = bfin_twi0_resource, -}; -#endif - -#ifdef CONFIG_I2C_BOARDINFO -static struct i2c_board_info __initdata bfin_i2c_board_info[] = { -#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) - { - I2C_BOARD_INFO("pcf8574_lcd", 0x22), - .type = "pcf8574_lcd", - }, -#endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) - { - I2C_BOARD_INFO("pcf8574_keypad", 0x27), - .type = "pcf8574_keypad", - .irq = IRQ_PF8, - }, -#endif -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -static struct platform_device bfin_sport0_uart_device = { - .name = "bfin-sport-uart", - .id = 0, -}; - -static struct platform_device bfin_sport1_uart_device = { - .name = "bfin-sport-uart", - .id = 1, -}; -#endif - -#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) -#define PATA_INT 55 - -static struct pata_platform_info bfin_pata_platform_data = { - .ioport_shift = 1, - .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED, -}; - -static struct resource bfin_pata_resources[] = { - { - .start = 0x20314020, - .end = 0x2031403F, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x2031401C, - .end = 0x2031401F, - .flags = IORESOURCE_MEM, - }, - { - .start = PATA_INT, - .end = PATA_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_pata_device = { - .name = "pata_platform", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_pata_resources), - .resource = bfin_pata_resources, - .dev = { - .platform_data = &bfin_pata_platform_data, - } -}; -#endif - -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -#include -#include - -static struct gpio_keys_button bfin_gpio_keys_table[] = { - {BTN_0, GPIO_PF14, 1, "gpio-keys: BTN0"}, -}; - -static struct gpio_keys_platform_data bfin_gpio_keys_data = { - .buttons = bfin_gpio_keys_table, - .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), -}; - -static struct platform_device bfin_device_gpiokeys = { - .name = "gpio-keys", - .dev = { - .platform_data = &bfin_gpio_keys_data, - }, -}; -#endif - -static struct resource bfin_gpios_resources = { - .start = 0, - .end = MAX_BLACKFIN_GPIOS - 1, - .flags = IORESOURCE_IRQ, -}; - -static struct platform_device bfin_gpios_device = { - .name = "simple-gpio", - .id = -1, - .num_resources = 1, - .resource = &bfin_gpios_resources, -}; - -static const unsigned int cclk_vlev_datasheet[] = -{ - VRPAIR(VLEV_100, 400000000), - VRPAIR(VLEV_105, 426000000), - VRPAIR(VLEV_110, 500000000), - VRPAIR(VLEV_115, 533000000), - VRPAIR(VLEV_120, 600000000), -}; - -static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { - .tuple_tab = cclk_vlev_datasheet, - .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), - .vr_settling_time = 25 /* us */, -}; - -static struct platform_device bfin_dpmc = { - .name = "bfin dpmc", - .dev = { - .platform_data = &bfin_dmpc_vreg_data, - }, -}; - -static struct platform_device *stamp_devices[] __initdata = { - - &bfin_dpmc, - -#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) - &bf5xx_nand_device, -#endif - -#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) - &bfin_pcmcia_cf_device, -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) - &sl811_hcd_device, -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - -#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) - &musb_device, -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif - -#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) - &dm9000_device, -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mac_device, -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) - &net2272_bfin_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &bfin_spi0_device, -#endif - -#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) - &bfin_fb_adv7393_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif - -#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) - &bfin_sir_device, -#endif - -#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) - &i2c_bfin_twi_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) - &bfin_sport0_uart_device, - &bfin_sport1_uart_device, -#endif - -#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) - &bfin_pata_device, -#endif - -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) - &bfin_device_gpiokeys, -#endif - -#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) - &ezkit_flash_device, -#endif - - &bfin_gpios_device, -}; - -static int __init stamp_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __func__); - -#ifdef CONFIG_I2C_BOARDINFO - i2c_register_board_info(0, bfin_i2c_board_info, - ARRAY_SIZE(bfin_i2c_board_info)); -#endif - - platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); - -#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) - irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; -#endif - return 0; -} - -arch_initcall(stamp_init); - -void native_machine_restart(char *cmd) -{ - /* workaround reboot hang when booting from SPI */ - if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_gpio_reset_spi0_ssel1(); -} - -void bfin_get_ether_addr(char *addr) -{ - random_ether_addr(addr); - printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__); -} -EXPORT_SYMBOL(bfin_get_ether_addr); diff --git a/trunk/arch/blackfin/mach-bf527/head.S b/trunk/arch/blackfin/mach-bf527/head.S index fe05cc1ef174..57bdb3ba2fed 100644 --- a/trunk/arch/blackfin/mach-bf527/head.S +++ b/trunk/arch/blackfin/mach-bf527/head.S @@ -32,7 +32,7 @@ #include #include -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK #include #include #endif @@ -185,7 +185,7 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif @@ -318,7 +318,7 @@ ENDPROC(_real_start) __FINIT .section .l1.text -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK ENTRY(_start_dma_code) /* Enable PHY CLK buffer output */ @@ -398,6 +398,12 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; + p0.l = LO(EBIU_SDBCTL); + p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + P2.H = hi(EBIU_SDGCTL); P2.L = lo(EBIU_SDGCTL); R0 = [P2]; diff --git a/trunk/arch/blackfin/mach-bf533/head.S b/trunk/arch/blackfin/mach-bf533/head.S index c671e8549b17..1295deac00a4 100644 --- a/trunk/arch/blackfin/mach-bf533/head.S +++ b/trunk/arch/blackfin/mach-bf533/head.S @@ -31,7 +31,7 @@ #include #include #include -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK #include #include #endif @@ -186,7 +186,7 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif @@ -319,7 +319,7 @@ ENDPROC(_real_start) __FINIT .section .l1.text -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK ENTRY(_start_dma_code) p0.h = hi(SIC_IWR); p0.l = lo(SIC_IWR); @@ -390,6 +390,12 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; + p0.l = LO(EBIU_SDBCTL); + p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + P2.H = hi(EBIU_SDGCTL); P2.L = lo(EBIU_SDGCTL); R0 = [P2]; diff --git a/trunk/arch/blackfin/mach-bf537/boards/stamp.c b/trunk/arch/blackfin/mach-bf537/boards/stamp.c index 6dbc76fb080b..671f9d67f23a 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c +++ b/trunk/arch/blackfin/mach-bf537/boards/stamp.c @@ -29,12 +29,9 @@ */ #include -#include #include #include -#include #include -#include #include #include #include @@ -358,84 +355,6 @@ static struct platform_device net2272_bfin_device = { }; #endif -#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) -#ifdef CONFIG_MTD_PARTITIONS -const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; - -static struct mtd_partition bfin_plat_nand_partitions[] = { - { - .name = "linux kernel", - .size = 0x400000, - .offset = 0, - }, { - .name = "file system", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - }, -}; -#endif - -#define BFIN_NAND_PLAT_CLE 2 -#define BFIN_NAND_PLAT_ALE 1 -static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ - struct nand_chip *this = mtd->priv; - - if (cmd == NAND_CMD_NONE) - return; - - if (ctrl & NAND_CLE) - writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_CLE)); - else - writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_ALE)); -} - -#define BFIN_NAND_PLAT_READY GPIO_PF3 -static int bfin_plat_nand_dev_ready(struct mtd_info *mtd) -{ - return gpio_get_value(BFIN_NAND_PLAT_READY); -} - -static struct platform_nand_data bfin_plat_nand_data = { - .chip = { - .chip_delay = 30, -#ifdef CONFIG_MTD_PARTITIONS - .part_probe_types = part_probes, - .partitions = bfin_plat_nand_partitions, - .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions), -#endif - }, - .ctrl = { - .cmd_ctrl = bfin_plat_nand_cmd_ctrl, - .dev_ready = bfin_plat_nand_dev_ready, - }, -}; - -#define MAX(x, y) (x > y ? x : y) -static struct resource bfin_plat_nand_resources = { - .start = 0x20212000, - .end = 0x20212000 + (1 << MAX(BFIN_NAND_PLAT_CLE, BFIN_NAND_PLAT_ALE)), - .flags = IORESOURCE_IO, -}; - -static struct platform_device bfin_async_nand_device = { - .name = "gen_nand", - .id = -1, - .num_resources = 1, - .resource = &bfin_plat_nand_resources, - .dev = { - .platform_data = &bfin_plat_nand_data, - }, -}; - -static void bfin_plat_nand_init(void) -{ - gpio_request(BFIN_NAND_PLAT_READY, "bfin_nand_plat"); -} -#else -static void bfin_plat_nand_init(void) {} -#endif - #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) static struct mtd_partition stamp_partitions[] = { { @@ -861,7 +780,7 @@ static struct platform_device bfin_sport1_uart_device = { #endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) -#define PATA_INT IRQ_PF5 +#define PATA_INT 55 static struct pata_platform_info bfin_pata_platform_data = { .ioport_shift = 1, @@ -1003,10 +922,6 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_gpios_device, -#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) - &bfin_async_nand_device, -#endif - #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) &stamp_flash_device, #endif @@ -1021,7 +936,6 @@ static int __init stamp_init(void) ARRAY_SIZE(bfin_i2c_board_info)); #endif - bfin_plat_nand_init(); platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); diff --git a/trunk/arch/blackfin/mach-bf537/head.S b/trunk/arch/blackfin/mach-bf537/head.S index 6b019eaee0b6..48cd58a410a0 100644 --- a/trunk/arch/blackfin/mach-bf537/head.S +++ b/trunk/arch/blackfin/mach-bf537/head.S @@ -32,7 +32,7 @@ #include #include -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK #include #include #endif @@ -217,7 +217,7 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif @@ -350,7 +350,7 @@ ENDPROC(_real_start) __FINIT .section .l1.text -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK ENTRY(_start_dma_code) /* Enable PHY CLK buffer output */ @@ -430,6 +430,12 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; + p0.l = LO(EBIU_SDBCTL); + p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + P2.H = hi(EBIU_SDGCTL); P2.L = lo(EBIU_SDGCTL); R0 = [P2]; diff --git a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c index 166fa2201ee7..af7c211a580e 100644 --- a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c @@ -61,49 +61,6 @@ const char bfin_board_name[] = "ADSP-BF548-EZKIT"; * Driver needs to know address, irq and flag pin. */ -#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) -static struct resource bfin_isp1761_resources[] = { - [0] = { - .name = "isp1761-regs", - .start = 0x2C0C0000, - .end = 0x2C0C0000 + 0xfffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PG7, - .end = IRQ_PG7, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_isp1761_device = { - .name = "isp1761", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_isp1761_resources), - .resource = bfin_isp1761_resources, -}; - -static struct platform_device *bfin_isp1761_devices[] = { - &bfin_isp1761_device, -}; - -int __init bfin_isp1761_init(void) -{ - unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices); - - printk(KERN_INFO "%s(): registering device resources\n", __func__); - set_irq_type(bfin_isp1761_resources[1].start, IRQF_TRIGGER_FALLING); - - return platform_add_devices(bfin_isp1761_devices, num_devices); -} - -void __exit bfin_isp1761_exit(void) -{ - platform_device_unregister(&bfin_isp1761_device); -} -arch_initcall(bfin_isp1761_init); -#endif - #if defined(CONFIG_FB_BF54X_LQ043) || defined(CONFIG_FB_BF54X_LQ043_MODULE) #include @@ -220,7 +177,6 @@ static struct resource bfin_uart_resources[] = { { .start = 0xFFC03100, .end = 0xFFC031FF, - .flags = IORESOURCE_MEM, }, #endif }; diff --git a/trunk/arch/blackfin/mach-bf548/head.S b/trunk/arch/blackfin/mach-bf548/head.S index 06b9178cfcfe..f7191141a3ce 100644 --- a/trunk/arch/blackfin/mach-bf548/head.S +++ b/trunk/arch/blackfin/mach-bf548/head.S @@ -31,7 +31,7 @@ #include #include #include -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK #include #include #endif @@ -130,7 +130,7 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif /* Code for initializing Async memory banks */ @@ -288,7 +288,7 @@ ENDPROC(_real_start) __FINIT .section .l1.text -#ifdef CONFIG_BFIN_KERNEL_CLOCK +#if CONFIG_BFIN_KERNEL_CLOCK ENTRY(_start_dma_code) /* Enable PHY CLK buffer output */ diff --git a/trunk/arch/blackfin/mach-bf561/head.S b/trunk/arch/blackfin/mach-bf561/head.S index cf1a2dff01e7..5b8bd40851dd 100644 --- a/trunk/arch/blackfin/mach-bf561/head.S +++ b/trunk/arch/blackfin/mach-bf561/head.S @@ -377,6 +377,12 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; + p0.l = LO(EBIU_SDBCTL); + p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + P2.H = hi(EBIU_SDGCTL); P2.L = lo(EBIU_SDGCTL); R0 = [P2]; diff --git a/trunk/arch/blackfin/mach-common/arch_checks.c b/trunk/arch/blackfin/mach-common/arch_checks.c index f9160d83b91f..caaab49e9cfa 100644 --- a/trunk/arch/blackfin/mach-common/arch_checks.c +++ b/trunk/arch/blackfin/mach-common/arch_checks.c @@ -53,3 +53,9 @@ # endif #endif /* CONFIG_BFIN_KERNEL_CLOCK */ + +#ifdef CONFIG_MEM_SIZE +#if (CONFIG_MEM_SIZE % 4) +#error "SDRAM mem size must be multible of 4MB" +#endif +#endif diff --git a/trunk/arch/blackfin/mach-common/dpmc_modes.S b/trunk/arch/blackfin/mach-common/dpmc_modes.S index 5e3f1d8a4fb8..b7981d31c392 100644 --- a/trunk/arch/blackfin/mach-common/dpmc_modes.S +++ b/trunk/arch/blackfin/mach-common/dpmc_modes.S @@ -7,7 +7,7 @@ #include #include #include -#include + .section .l1.text @@ -51,32 +51,31 @@ ENTRY(_sleep_mode) RETS = [SP++]; ( R7:0, P5:0 ) = [SP++]; RTS; -ENDPROC(_sleep_mode) ENTRY(_hibernate_mode) [--SP] = ( R7:0, P5:0 ); [--SP] = RETS; - R3 = R0; - R0 = IWR_DISABLE_ALL; - R1 = IWR_DISABLE_ALL; - R2 = IWR_DISABLE_ALL; call _set_sic_iwr; - call _set_dram_srfs; - SSYNC; R0 = 0xFFFF (Z); call _set_rtc_istat; P0.H = hi(VR_CTL); P0.L = lo(VR_CTL); + R1 = W[P0](z); + BITSET (R1, 8); + BITCLR (R1, 0); + BITCLR (R1, 1); + W[P0] = R1.L; + SSYNC; - W[P0] = R3.L; CLI R2; IDLE; -.Lforever: - jump .Lforever; -ENDPROC(_hibernate_mode) + + /* Actually, adding anything may not be necessary...SDRAM contents + * are lost + */ ENTRY(_deep_sleep) [--SP] = ( R7:0, P5:0 ); @@ -132,7 +131,6 @@ ENTRY(_deep_sleep) RETS = [SP++]; ( R7:0, P5:0 ) = [SP++]; RTS; -ENDPROC(_deep_sleep) ENTRY(_sleep_deeper) [--SP] = ( R7:0, P5:0 ); @@ -234,73 +232,53 @@ ENTRY(_sleep_deeper) RETS = [SP++]; ( R7:0, P5:0 ) = [SP++]; RTS; -ENDPROC(_sleep_deeper) ENTRY(_set_dram_srfs) /* set the dram to self refresh mode */ - SSYNC; -#if defined(EBIU_RSTCTL) /* DDR */ +#if defined(CONFIG_BF54x) P0.H = hi(EBIU_RSTCTL); P0.L = lo(EBIU_RSTCTL); R2 = [P0]; - BITSET(R2, 3); /* SRREQ enter self-refresh mode */ - [P0] = R2; - SSYNC; -1: - R2 = [P0]; - CC = BITTST(R2, 4); - if !CC JUMP 1b; -#else /* SDRAM */ - P0.L = lo(EBIU_SDGCTL); + R3.H = hi(SRREQ); + R3.L = lo(SRREQ); +#else P0.H = hi(EBIU_SDGCTL); - R2 = [P0]; - BITSET(R2, 24); /* SRFS enter self-refresh mode */ - [P0] = R2; - SSYNC; - - P0.L = lo(EBIU_SDSTAT); - P0.H = hi(EBIU_SDSTAT); -1: - R2 = w[P0]; - SSYNC; - cc = BITTST(R2, 1); /* SDSRA poll self-refresh status */ - if !cc jump 1b; - P0.L = lo(EBIU_SDGCTL); - P0.H = hi(EBIU_SDGCTL); R2 = [P0]; - BITCLR(R2, 0); /* SCTLE disable CLKOUT */ + R3.H = hi(SRFS); + R3.L = lo(SRFS); +#endif + R2 = R2|R3; [P0] = R2; + ssync; +#if defined(CONFIG_BF54x) +.LSRR_MODE: + R2 = [P0]; + CC = BITTST(R2, 4); + if !CC JUMP .LSRR_MODE; #endif RTS; -ENDPROC(_set_dram_srfs) ENTRY(_unset_dram_srfs) /* set the dram out of self refresh mode */ -#if defined(EBIU_RSTCTL) /* DDR */ +#if defined(CONFIG_BF54x) P0.H = hi(EBIU_RSTCTL); P0.L = lo(EBIU_RSTCTL); R2 = [P0]; - BITCLR(R2, 3); /* clear SRREQ bit */ - [P0] = R2; -#elif defined(EBIU_SDGCTL) /* SDRAM */ - - P0.L = lo(EBIU_SDGCTL); /* release CLKOUT from self-refresh */ - P0.H = hi(EBIU_SDGCTL); - R2 = [P0]; - BITSET(R2, 0); /* SCTLE enable CLKOUT */ - [P0] = R2 - SSYNC; - - P0.L = lo(EBIU_SDGCTL); /* release SDRAM from self-refresh */ + R3.H = hi(SRREQ); + R3.L = lo(SRREQ); +#else P0.H = hi(EBIU_SDGCTL); + P0.L = lo(EBIU_SDGCTL); R2 = [P0]; - BITCLR(R2, 24); /* clear SRFS bit */ - [P0] = R2 + R3.H = hi(SRFS); + R3.L = lo(SRFS); #endif - SSYNC; + R3 = ~R3; + R2 = R2&R3; + [P0] = R2; + ssync; RTS; -ENDPROC(_unset_dram_srfs) ENTRY(_set_sic_iwr) #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) @@ -322,7 +300,6 @@ ENTRY(_set_sic_iwr) SSYNC; RTS; -ENDPROC(_set_sic_iwr) ENTRY(_set_rtc_istat) #ifndef CONFIG_BF561 @@ -330,14 +307,8 @@ ENTRY(_set_rtc_istat) P0.L = lo(RTC_ISTAT); w[P0] = R0.L; SSYNC; -#elif (ANOMALY_05000371) - nop; - nop; - nop; - nop; #endif RTS; -ENDPROC(_set_rtc_istat) ENTRY(_test_pll_locked) P0.H = hi(PLL_STAT); @@ -347,509 +318,3 @@ ENTRY(_test_pll_locked) CC = BITTST(R0,5); IF !CC JUMP 1b; RTS; -ENDPROC(_test_pll_locked) - -.section .text - -ENTRY(_do_hibernate) - [--SP] = ( R7:0, P5:0 ); - [--SP] = RETS; - /* Save System MMRs */ - R2 = R0; - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - -#ifdef SIC_IMASK0 - PM_SYS_PUSH(SIC_IMASK0) -#endif -#ifdef SIC_IMASK1 - PM_SYS_PUSH(SIC_IMASK1) -#endif -#ifdef SIC_IMASK2 - PM_SYS_PUSH(SIC_IMASK2) -#endif -#ifdef SIC_IMASK - PM_SYS_PUSH(SIC_IMASK) -#endif -#ifdef SICA_IMASK0 - PM_SYS_PUSH(SICA_IMASK0) -#endif -#ifdef SICA_IMASK1 - PM_SYS_PUSH(SICA_IMASK1) -#endif -#ifdef SIC_IAR2 - PM_SYS_PUSH(SIC_IAR0) - PM_SYS_PUSH(SIC_IAR1) - PM_SYS_PUSH(SIC_IAR2) -#endif -#ifdef SIC_IAR3 - PM_SYS_PUSH(SIC_IAR3) -#endif -#ifdef SIC_IAR4 - PM_SYS_PUSH(SIC_IAR4) - PM_SYS_PUSH(SIC_IAR5) - PM_SYS_PUSH(SIC_IAR6) -#endif -#ifdef SIC_IAR7 - PM_SYS_PUSH(SIC_IAR7) -#endif -#ifdef SIC_IAR8 - PM_SYS_PUSH(SIC_IAR8) - PM_SYS_PUSH(SIC_IAR9) - PM_SYS_PUSH(SIC_IAR10) - PM_SYS_PUSH(SIC_IAR11) -#endif - -#ifdef SICA_IAR0 - PM_SYS_PUSH(SICA_IAR0) - PM_SYS_PUSH(SICA_IAR1) - PM_SYS_PUSH(SICA_IAR2) - PM_SYS_PUSH(SICA_IAR3) - PM_SYS_PUSH(SICA_IAR4) - PM_SYS_PUSH(SICA_IAR5) - PM_SYS_PUSH(SICA_IAR6) - PM_SYS_PUSH(SICA_IAR7) -#endif - -#ifdef SIC_IWR - PM_SYS_PUSH(SIC_IWR) -#endif -#ifdef SIC_IWR0 - PM_SYS_PUSH(SIC_IWR0) -#endif -#ifdef SIC_IWR1 - PM_SYS_PUSH(SIC_IWR1) -#endif -#ifdef SIC_IWR2 - PM_SYS_PUSH(SIC_IWR2) -#endif -#ifdef SICA_IWR0 - PM_SYS_PUSH(SICA_IWR0) -#endif -#ifdef SICA_IWR1 - PM_SYS_PUSH(SICA_IWR1) -#endif - -#ifdef PINT0_ASSIGN - PM_SYS_PUSH(PINT0_ASSIGN) - PM_SYS_PUSH(PINT1_ASSIGN) - PM_SYS_PUSH(PINT2_ASSIGN) - PM_SYS_PUSH(PINT3_ASSIGN) -#endif - - PM_SYS_PUSH(EBIU_AMBCTL0) - PM_SYS_PUSH(EBIU_AMBCTL1) - PM_SYS_PUSH16(EBIU_AMGCTL) - -#ifdef EBIU_FCTL - PM_SYS_PUSH(EBIU_MBSCTL) - PM_SYS_PUSH(EBIU_MODE) - PM_SYS_PUSH(EBIU_FCTL) -#endif - - PM_SYS_PUSH16(SYSCR) - - /* Save Core MMRs */ - P0.H = hi(SRAM_BASE_ADDRESS); - P0.L = lo(SRAM_BASE_ADDRESS); - - PM_PUSH(DMEM_CONTROL) - PM_PUSH(DCPLB_ADDR0) - PM_PUSH(DCPLB_ADDR1) - PM_PUSH(DCPLB_ADDR2) - PM_PUSH(DCPLB_ADDR3) - PM_PUSH(DCPLB_ADDR4) - PM_PUSH(DCPLB_ADDR5) - PM_PUSH(DCPLB_ADDR6) - PM_PUSH(DCPLB_ADDR7) - PM_PUSH(DCPLB_ADDR8) - PM_PUSH(DCPLB_ADDR9) - PM_PUSH(DCPLB_ADDR10) - PM_PUSH(DCPLB_ADDR11) - PM_PUSH(DCPLB_ADDR12) - PM_PUSH(DCPLB_ADDR13) - PM_PUSH(DCPLB_ADDR14) - PM_PUSH(DCPLB_ADDR15) - PM_PUSH(DCPLB_DATA0) - PM_PUSH(DCPLB_DATA1) - PM_PUSH(DCPLB_DATA2) - PM_PUSH(DCPLB_DATA3) - PM_PUSH(DCPLB_DATA4) - PM_PUSH(DCPLB_DATA5) - PM_PUSH(DCPLB_DATA6) - PM_PUSH(DCPLB_DATA7) - PM_PUSH(DCPLB_DATA8) - PM_PUSH(DCPLB_DATA9) - PM_PUSH(DCPLB_DATA10) - PM_PUSH(DCPLB_DATA11) - PM_PUSH(DCPLB_DATA12) - PM_PUSH(DCPLB_DATA13) - PM_PUSH(DCPLB_DATA14) - PM_PUSH(DCPLB_DATA15) - PM_PUSH(IMEM_CONTROL) - PM_PUSH(ICPLB_ADDR0) - PM_PUSH(ICPLB_ADDR1) - PM_PUSH(ICPLB_ADDR2) - PM_PUSH(ICPLB_ADDR3) - PM_PUSH(ICPLB_ADDR4) - PM_PUSH(ICPLB_ADDR5) - PM_PUSH(ICPLB_ADDR6) - PM_PUSH(ICPLB_ADDR7) - PM_PUSH(ICPLB_ADDR8) - PM_PUSH(ICPLB_ADDR9) - PM_PUSH(ICPLB_ADDR10) - PM_PUSH(ICPLB_ADDR11) - PM_PUSH(ICPLB_ADDR12) - PM_PUSH(ICPLB_ADDR13) - PM_PUSH(ICPLB_ADDR14) - PM_PUSH(ICPLB_ADDR15) - PM_PUSH(ICPLB_DATA0) - PM_PUSH(ICPLB_DATA1) - PM_PUSH(ICPLB_DATA2) - PM_PUSH(ICPLB_DATA3) - PM_PUSH(ICPLB_DATA4) - PM_PUSH(ICPLB_DATA5) - PM_PUSH(ICPLB_DATA6) - PM_PUSH(ICPLB_DATA7) - PM_PUSH(ICPLB_DATA8) - PM_PUSH(ICPLB_DATA9) - PM_PUSH(ICPLB_DATA10) - PM_PUSH(ICPLB_DATA11) - PM_PUSH(ICPLB_DATA12) - PM_PUSH(ICPLB_DATA13) - PM_PUSH(ICPLB_DATA14) - PM_PUSH(ICPLB_DATA15) - PM_PUSH(EVT0) - PM_PUSH(EVT1) - PM_PUSH(EVT2) - PM_PUSH(EVT3) - PM_PUSH(EVT4) - PM_PUSH(EVT5) - PM_PUSH(EVT6) - PM_PUSH(EVT7) - PM_PUSH(EVT8) - PM_PUSH(EVT9) - PM_PUSH(EVT10) - PM_PUSH(EVT11) - PM_PUSH(EVT12) - PM_PUSH(EVT13) - PM_PUSH(EVT14) - PM_PUSH(EVT15) - PM_PUSH(IMASK) - PM_PUSH(ILAT) - PM_PUSH(IPRIO) - PM_PUSH(TCNTL) - PM_PUSH(TPERIOD) - PM_PUSH(TSCALE) - PM_PUSH(TCOUNT) - PM_PUSH(TBUFCTL) - - /* Save Core Registers */ - [--sp] = SYSCFG; - [--sp] = ( R7:0, P5:0 ); - [--sp] = fp; - [--sp] = usp; - - [--sp] = i0; - [--sp] = i1; - [--sp] = i2; - [--sp] = i3; - - [--sp] = m0; - [--sp] = m1; - [--sp] = m2; - [--sp] = m3; - - [--sp] = l0; - [--sp] = l1; - [--sp] = l2; - [--sp] = l3; - - [--sp] = b0; - [--sp] = b1; - [--sp] = b2; - [--sp] = b3; - [--sp] = a0.x; - [--sp] = a0.w; - [--sp] = a1.x; - [--sp] = a1.w; - - [--sp] = LC0; - [--sp] = LC1; - [--sp] = LT0; - [--sp] = LT1; - [--sp] = LB0; - [--sp] = LB1; - - [--sp] = ASTAT; - [--sp] = CYCLES; - [--sp] = CYCLES2; - - [--sp] = RETS; - r0 = RETI; - [--sp] = r0; - [--sp] = RETX; - [--sp] = RETN; - [--sp] = RETE; - [--sp] = SEQSTAT; - - /* Save Magic, return address and Stack Pointer */ - P0.H = 0; - P0.L = 0; - R0.H = 0xDEAD; /* Hibernate Magic */ - R0.L = 0xBEEF; - [P0++] = R0; /* Store Hibernate Magic */ - R0.H = .Lpm_resume_here; - R0.L = .Lpm_resume_here; - [P0++] = R0; /* Save Return Address */ - [P0++] = SP; /* Save Stack Pointer */ - P0.H = _hibernate_mode; - P0.L = _hibernate_mode; - R0 = R2; - call (P0); /* Goodbye */ - -.Lpm_resume_here: - - /* Restore Core Registers */ - SEQSTAT = [sp++]; - RETE = [sp++]; - RETN = [sp++]; - RETX = [sp++]; - r0 = [sp++]; - RETI = r0; - RETS = [sp++]; - - CYCLES2 = [sp++]; - CYCLES = [sp++]; - ASTAT = [sp++]; - - LB1 = [sp++]; - LB0 = [sp++]; - LT1 = [sp++]; - LT0 = [sp++]; - LC1 = [sp++]; - LC0 = [sp++]; - - a1.w = [sp++]; - a1.x = [sp++]; - a0.w = [sp++]; - a0.x = [sp++]; - b3 = [sp++]; - b2 = [sp++]; - b1 = [sp++]; - b0 = [sp++]; - - l3 = [sp++]; - l2 = [sp++]; - l1 = [sp++]; - l0 = [sp++]; - - m3 = [sp++]; - m2 = [sp++]; - m1 = [sp++]; - m0 = [sp++]; - - i3 = [sp++]; - i2 = [sp++]; - i1 = [sp++]; - i0 = [sp++]; - - usp = [sp++]; - fp = [sp++]; - - ( R7 : 0, P5 : 0) = [ SP ++ ]; - SYSCFG = [sp++]; - - /* Restore Core MMRs */ - - PM_POP(TBUFCTL) - PM_POP(TCOUNT) - PM_POP(TSCALE) - PM_POP(TPERIOD) - PM_POP(TCNTL) - PM_POP(IPRIO) - PM_POP(ILAT) - PM_POP(IMASK) - PM_POP(EVT15) - PM_POP(EVT14) - PM_POP(EVT13) - PM_POP(EVT12) - PM_POP(EVT11) - PM_POP(EVT10) - PM_POP(EVT9) - PM_POP(EVT8) - PM_POP(EVT7) - PM_POP(EVT6) - PM_POP(EVT5) - PM_POP(EVT4) - PM_POP(EVT3) - PM_POP(EVT2) - PM_POP(EVT1) - PM_POP(EVT0) - PM_POP(ICPLB_DATA15) - PM_POP(ICPLB_DATA14) - PM_POP(ICPLB_DATA13) - PM_POP(ICPLB_DATA12) - PM_POP(ICPLB_DATA11) - PM_POP(ICPLB_DATA10) - PM_POP(ICPLB_DATA9) - PM_POP(ICPLB_DATA8) - PM_POP(ICPLB_DATA7) - PM_POP(ICPLB_DATA6) - PM_POP(ICPLB_DATA5) - PM_POP(ICPLB_DATA4) - PM_POP(ICPLB_DATA3) - PM_POP(ICPLB_DATA2) - PM_POP(ICPLB_DATA1) - PM_POP(ICPLB_DATA0) - PM_POP(ICPLB_ADDR15) - PM_POP(ICPLB_ADDR14) - PM_POP(ICPLB_ADDR13) - PM_POP(ICPLB_ADDR12) - PM_POP(ICPLB_ADDR11) - PM_POP(ICPLB_ADDR10) - PM_POP(ICPLB_ADDR9) - PM_POP(ICPLB_ADDR8) - PM_POP(ICPLB_ADDR7) - PM_POP(ICPLB_ADDR6) - PM_POP(ICPLB_ADDR5) - PM_POP(ICPLB_ADDR4) - PM_POP(ICPLB_ADDR3) - PM_POP(ICPLB_ADDR2) - PM_POP(ICPLB_ADDR1) - PM_POP(ICPLB_ADDR0) - PM_POP(IMEM_CONTROL) - PM_POP(DCPLB_DATA15) - PM_POP(DCPLB_DATA14) - PM_POP(DCPLB_DATA13) - PM_POP(DCPLB_DATA12) - PM_POP(DCPLB_DATA11) - PM_POP(DCPLB_DATA10) - PM_POP(DCPLB_DATA9) - PM_POP(DCPLB_DATA8) - PM_POP(DCPLB_DATA7) - PM_POP(DCPLB_DATA6) - PM_POP(DCPLB_DATA5) - PM_POP(DCPLB_DATA4) - PM_POP(DCPLB_DATA3) - PM_POP(DCPLB_DATA2) - PM_POP(DCPLB_DATA1) - PM_POP(DCPLB_DATA0) - PM_POP(DCPLB_ADDR15) - PM_POP(DCPLB_ADDR14) - PM_POP(DCPLB_ADDR13) - PM_POP(DCPLB_ADDR12) - PM_POP(DCPLB_ADDR11) - PM_POP(DCPLB_ADDR10) - PM_POP(DCPLB_ADDR9) - PM_POP(DCPLB_ADDR8) - PM_POP(DCPLB_ADDR7) - PM_POP(DCPLB_ADDR6) - PM_POP(DCPLB_ADDR5) - PM_POP(DCPLB_ADDR4) - PM_POP(DCPLB_ADDR3) - PM_POP(DCPLB_ADDR2) - PM_POP(DCPLB_ADDR1) - PM_POP(DCPLB_ADDR0) - PM_POP(DMEM_CONTROL) - - /* Restore System MMRs */ - - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - PM_SYS_POP16(SYSCR) - -#ifdef EBIU_FCTL - PM_SYS_POP(EBIU_FCTL) - PM_SYS_POP(EBIU_MODE) - PM_SYS_POP(EBIU_MBSCTL) -#endif - PM_SYS_POP16(EBIU_AMGCTL) - PM_SYS_POP(EBIU_AMBCTL1) - PM_SYS_POP(EBIU_AMBCTL0) - -#ifdef PINT0_ASSIGN - PM_SYS_POP(PINT3_ASSIGN) - PM_SYS_POP(PINT2_ASSIGN) - PM_SYS_POP(PINT1_ASSIGN) - PM_SYS_POP(PINT0_ASSIGN) -#endif - -#ifdef SICA_IWR1 - PM_SYS_POP(SICA_IWR1) -#endif -#ifdef SICA_IWR0 - PM_SYS_POP(SICA_IWR0) -#endif -#ifdef SIC_IWR2 - PM_SYS_POP(SIC_IWR2) -#endif -#ifdef SIC_IWR1 - PM_SYS_POP(SIC_IWR1) -#endif -#ifdef SIC_IWR0 - PM_SYS_POP(SIC_IWR0) -#endif -#ifdef SIC_IWR - PM_SYS_POP(SIC_IWR) -#endif - -#ifdef SICA_IAR0 - PM_SYS_POP(SICA_IAR7) - PM_SYS_POP(SICA_IAR6) - PM_SYS_POP(SICA_IAR5) - PM_SYS_POP(SICA_IAR4) - PM_SYS_POP(SICA_IAR3) - PM_SYS_POP(SICA_IAR2) - PM_SYS_POP(SICA_IAR1) - PM_SYS_POP(SICA_IAR0) -#endif - -#ifdef SIC_IAR8 - PM_SYS_POP(SIC_IAR11) - PM_SYS_POP(SIC_IAR10) - PM_SYS_POP(SIC_IAR9) - PM_SYS_POP(SIC_IAR8) -#endif -#ifdef SIC_IAR7 - PM_SYS_POP(SIC_IAR7) -#endif -#ifdef SIC_IAR6 - PM_SYS_POP(SIC_IAR6) - PM_SYS_POP(SIC_IAR5) - PM_SYS_POP(SIC_IAR4) -#endif -#ifdef SIC_IAR3 - PM_SYS_POP(SIC_IAR3) -#endif -#ifdef SIC_IAR2 - PM_SYS_POP(SIC_IAR2) - PM_SYS_POP(SIC_IAR1) - PM_SYS_POP(SIC_IAR0) -#endif -#ifdef SICA_IMASK1 - PM_SYS_POP(SICA_IMASK1) -#endif -#ifdef SICA_IMASK0 - PM_SYS_POP(SICA_IMASK0) -#endif -#ifdef SIC_IMASK - PM_SYS_POP(SIC_IMASK) -#endif -#ifdef SIC_IMASK2 - PM_SYS_POP(SIC_IMASK2) -#endif -#ifdef SIC_IMASK1 - PM_SYS_POP(SIC_IMASK1) -#endif -#ifdef SIC_IMASK0 - PM_SYS_POP(SIC_IMASK0) -#endif - - [--sp] = RETI; /* Clear Global Interrupt Disable */ - SP += 4; - - RETS = [SP++]; - ( R7:0, P5:0 ) = [SP++]; - RTS; -ENDPROC(_do_hibernate) diff --git a/trunk/arch/blackfin/mach-common/entry.S b/trunk/arch/blackfin/mach-common/entry.S index eceb484d90f9..038f70e0be65 100644 --- a/trunk/arch/blackfin/mach-common/entry.S +++ b/trunk/arch/blackfin/mach-common/entry.S @@ -158,45 +158,23 @@ ENTRY(_ex_single_step) cc = r7 == r6; if cc jump _bfin_return_from_exception; - /* Don't do single step in hardware exception handler */ - p5.l = lo(IPEND); - p5.h = hi(IPEND); - r6 = [p5]; - cc = bittst(r6, 5); - if cc jump _bfin_return_from_exception; - -#ifdef CONFIG_KGDB - /* skip single step if current interrupt priority is higher than - * that of the first instruction, from which gdb starts single step */ - r6 >>= 6; - r7 = 10; -.Lfind_priority_start: - cc = bittst(r6, 0); - if cc jump .Lfind_priority_done; - r6 >>= 1; - r7 += -1; - cc = r7 == 0; - if cc jump .Lfind_priority_done; - jump.s .Lfind_priority_start; -.Lfind_priority_done: - p4.l = _debugger_step; - p4.h = _debugger_step; - r6 = [p4]; - cc = r6 == 0; - if cc jump .Ldo_single_step; - r6 += -1; - cc = r6 < r7; - if cc jump _bfin_return_from_exception; -.Ldo_single_step: -#endif - /* If we were in user mode, do the single step normally. */ + p5.l = lo(IPEND); + p5.h = hi(IPEND); r6 = [p5]; r7 = 0xffe0 (z); r7 = r7 & r6; cc = r7 == 0; - if cc jump 1f; + if !cc jump 1f; + + /* Single stepping only a single instruction, so clear the trace + * bit here. */ + r7 = syscfg; + bitclr (r7, 0); + syscfg = R7; + jump _ex_trap_c; +1: /* * We were in an interrupt handler. By convention, all of them save * SYSCFG with their first instruction, so by checking whether our @@ -224,15 +202,11 @@ ENTRY(_ex_single_step) cc = R7 == R6; if !cc jump _bfin_return_from_exception; -1: - /* Single stepping only a single instruction, so clear the trace - * bit here. */ r7 = syscfg; bitclr (r7, 0); syscfg = R7; - jump _ex_trap_c; - + /* Fall through to _bfin_return_from_exception. */ ENDPROC(_ex_single_step) ENTRY(_bfin_return_from_exception) diff --git a/trunk/arch/blackfin/mach-common/ints-priority.c b/trunk/arch/blackfin/mach-common/ints-priority.c index 64d746114e4b..f5fd768022ea 100644 --- a/trunk/arch/blackfin/mach-common/ints-priority.c +++ b/trunk/arch/blackfin/mach-common/ints-priority.c @@ -459,8 +459,6 @@ static struct irq_chip bfin_gpio_irqchip = { .mask = bfin_gpio_mask_irq, .mask_ack = bfin_gpio_mask_ack_irq, .unmask = bfin_gpio_unmask_irq, - .disable = bfin_gpio_mask_irq, - .enable = bfin_gpio_unmask_irq, .set_type = bfin_gpio_irq_type, .startup = bfin_gpio_irq_startup, .shutdown = bfin_gpio_irq_shutdown, @@ -848,8 +846,6 @@ static struct irq_chip bfin_gpio_irqchip = { .mask = bfin_gpio_mask_irq, .mask_ack = bfin_gpio_mask_ack_irq, .unmask = bfin_gpio_unmask_irq, - .disable = bfin_gpio_mask_irq, - .enable = bfin_gpio_unmask_irq, .set_type = bfin_gpio_irq_type, .startup = bfin_gpio_irq_startup, .shutdown = bfin_gpio_irq_shutdown, diff --git a/trunk/arch/blackfin/mach-common/pm.c b/trunk/arch/blackfin/mach-common/pm.c index 4fe6a2366b13..0be805ca423f 100644 --- a/trunk/arch/blackfin/mach-common/pm.c +++ b/trunk/arch/blackfin/mach-common/pm.c @@ -38,9 +38,8 @@ #include #include -#include -#include #include +#include #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H #define WAKEUP_TYPE PM_WAKE_HIGH @@ -62,17 +61,16 @@ #define WAKEUP_TYPE PM_WAKE_BOTH_EDGES #endif - void bfin_pm_suspend_standby_enter(void) { - unsigned long flags; - #ifdef CONFIG_PM_WAKEUP_BY_GPIO gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); #endif + u32 flags; + local_irq_save(flags); - bfin_pm_standby_setup(); + bfin_pm_setup(); #ifdef CONFIG_PM_BFIN_SLEEP_DEEPER sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); @@ -80,7 +78,7 @@ void bfin_pm_suspend_standby_enter(void) sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); #endif - bfin_pm_standby_restore(); + bfin_pm_restore(); #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) bfin_write_SIC_IWR0(IWR_ENABLE_ALL); @@ -95,195 +93,6 @@ void bfin_pm_suspend_standby_enter(void) local_irq_restore(flags); } -int bf53x_suspend_l1_mem(unsigned char *memptr) -{ - dma_memcpy(memptr, (const void *) L1_CODE_START, L1_CODE_LENGTH); - dma_memcpy(memptr + L1_CODE_LENGTH, (const void *) L1_DATA_A_START, - L1_DATA_A_LENGTH); - dma_memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH, - (const void *) L1_DATA_B_START, L1_DATA_B_LENGTH); - memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH + - L1_DATA_B_LENGTH, (const void *) L1_SCRATCH_START, - L1_SCRATCH_LENGTH); - - return 0; -} - -int bf53x_resume_l1_mem(unsigned char *memptr) -{ - dma_memcpy((void *) L1_CODE_START, memptr, L1_CODE_LENGTH); - dma_memcpy((void *) L1_DATA_A_START, memptr + L1_CODE_LENGTH, - L1_DATA_A_LENGTH); - dma_memcpy((void *) L1_DATA_B_START, memptr + L1_CODE_LENGTH + - L1_DATA_A_LENGTH, L1_DATA_B_LENGTH); - memcpy((void *) L1_SCRATCH_START, memptr + L1_CODE_LENGTH + - L1_DATA_A_LENGTH + L1_DATA_B_LENGTH, L1_SCRATCH_LENGTH); - - return 0; -} - -#ifdef CONFIG_BFIN_WB -static void flushinv_all_dcache(void) -{ - u32 way, bank, subbank, set; - u32 status, addr; - u32 dmem_ctl = bfin_read_DMEM_CONTROL(); - - for (bank = 0; bank < 2; ++bank) { - if (!(dmem_ctl & (1 << (DMC1_P - bank)))) - continue; - - for (way = 0; way < 2; ++way) - for (subbank = 0; subbank < 4; ++subbank) - for (set = 0; set < 64; ++set) { - - bfin_write_DTEST_COMMAND( - way << 26 | - bank << 23 | - subbank << 16 | - set << 5 - ); - CSYNC(); - status = bfin_read_DTEST_DATA0(); - - /* only worry about valid/dirty entries */ - if ((status & 0x3) != 0x3) - continue; - - /* construct the address using the tag */ - addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5); - - /* flush it */ - __asm__ __volatile__("FLUSHINV[%0];" : : "a"(addr)); - } - } -} -#endif - -static inline void dcache_disable(void) -{ -#ifdef CONFIG_BFIN_DCACHE - unsigned long ctrl; - -#ifdef CONFIG_BFIN_WB - flushinv_all_dcache(); -#endif - SSYNC(); - ctrl = bfin_read_DMEM_CONTROL(); - ctrl &= ~ENDCPLB; - bfin_write_DMEM_CONTROL(ctrl); - SSYNC(); -#endif -} - -static inline void dcache_enable(void) -{ -#ifdef CONFIG_BFIN_DCACHE - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_DMEM_CONTROL(); - ctrl |= ENDCPLB; - bfin_write_DMEM_CONTROL(ctrl); - SSYNC(); -#endif -} - -static inline void icache_disable(void) -{ -#ifdef CONFIG_BFIN_ICACHE - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_IMEM_CONTROL(); - ctrl &= ~ENICPLB; - bfin_write_IMEM_CONTROL(ctrl); - SSYNC(); -#endif -} - -static inline void icache_enable(void) -{ -#ifdef CONFIG_BFIN_ICACHE - unsigned long ctrl; - SSYNC(); - ctrl = bfin_read_IMEM_CONTROL(); - ctrl |= ENICPLB; - bfin_write_IMEM_CONTROL(ctrl); - SSYNC(); -#endif -} - -int bfin_pm_suspend_mem_enter(void) -{ - unsigned long flags; - int wakeup, ret; - - unsigned char *memptr = kmalloc(L1_CODE_LENGTH + L1_DATA_A_LENGTH - + L1_DATA_B_LENGTH + L1_SCRATCH_LENGTH, - GFP_KERNEL); - - if (memptr == NULL) { - panic("bf53x_suspend_l1_mem malloc failed"); - return -ENOMEM; - } - - wakeup = bfin_read_VR_CTL() & ~FREQ; - wakeup |= SCKELOW; - - /* FIXME: merge this somehow with set_irq_wake */ -#ifdef CONFIG_PM_BFIN_WAKE_RTC - wakeup |= WAKE; -#endif -#ifdef CONFIG_PM_BFIN_WAKE_PH6 - wakeup |= PHYWE; -#endif -#ifdef CONFIG_PM_BFIN_WAKE_CAN - wakeup |= CANWE; -#endif -#ifdef CONFIG_PM_BFIN_WAKE_GP - wakeup |= GPWE; -#endif -#ifdef CONFIG_PM_BFIN_WAKE_USB - wakeup |= USBWE; -#endif -#ifdef CONFIG_PM_BFIN_WAKE_KEYPAD - wakeup |= KPADWE; -#endif -#ifdef CONFIG_PM_BFIN_WAKE_ROTARY - wakeup |= ROTWE; -#endif - - local_irq_save(flags); - - ret = blackfin_dma_suspend(); - - if (ret) { - local_irq_restore(flags); - kfree(memptr); - return ret; - } - - bfin_gpio_pm_hibernate_suspend(); - - dcache_disable(); - icache_disable(); - bf53x_suspend_l1_mem(memptr); - - do_hibernate(wakeup); /* Goodbye */ - - bf53x_resume_l1_mem(memptr); - - icache_enable(); - dcache_enable(); - - bfin_gpio_pm_hibernate_restore(); - blackfin_dma_resume(); - - local_irq_restore(flags); - kfree(memptr); - - return 0; -} - /* * bfin_pm_valid - Tell the PM core that we only support the standby sleep * state @@ -292,24 +101,7 @@ int bfin_pm_suspend_mem_enter(void) */ static int bfin_pm_valid(suspend_state_t state) { - return (state == PM_SUSPEND_STANDBY -#ifndef BF533_FAMILY - /* - * On BF533/2/1: - * If we enter Hibernate the SCKE Pin is driven Low, - * so that the SDRAM enters Self Refresh Mode. - * However when the reset sequence that follows hibernate - * state is executed, SCKE is driven High, taking the - * SDRAM out of Self Refresh. - * - * If you reconfigure and access the SDRAM "very quickly", - * you are likely to avoid errors, otherwise the SDRAM - * start losing its contents. - * An external HW workaround is possible using logic gates. - */ - || state == PM_SUSPEND_MEM -#endif - ); + return (state == PM_SUSPEND_STANDBY); } /* @@ -323,9 +115,10 @@ static int bfin_pm_enter(suspend_state_t state) case PM_SUSPEND_STANDBY: bfin_pm_suspend_standby_enter(); break; + case PM_SUSPEND_MEM: - bfin_pm_suspend_mem_enter(); - break; + return -ENOTSUPP; + default: return -EINVAL; } diff --git a/trunk/arch/blackfin/mm/blackfin_sram.c b/trunk/arch/blackfin/mm/blackfin_sram.c index 5af3c31c9365..3246f91c7baa 100644 --- a/trunk/arch/blackfin/mm/blackfin_sram.c +++ b/trunk/arch/blackfin/mm/blackfin_sram.c @@ -41,309 +41,215 @@ #include #include "blackfin_sram.h" -static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; -static spinlock_t l2_sram_lock; +spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; + +#if CONFIG_L1_MAX_PIECE < 16 +#undef CONFIG_L1_MAX_PIECE +#define CONFIG_L1_MAX_PIECE 16 +#endif + +#if CONFIG_L1_MAX_PIECE > 1024 +#undef CONFIG_L1_MAX_PIECE +#define CONFIG_L1_MAX_PIECE 1024 +#endif + +#define SRAM_SLT_NULL 0 +#define SRAM_SLT_FREE 1 +#define SRAM_SLT_ALLOCATED 2 /* the data structure for L1 scratchpad and DATA SRAM */ -struct sram_piece { +struct l1_sram_piece { void *paddr; int size; + int flag; pid_t pid; - struct sram_piece *next; }; -static struct sram_piece free_l1_ssram_head, used_l1_ssram_head; +static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE]; #if L1_DATA_A_LENGTH != 0 -static struct sram_piece free_l1_data_A_sram_head, used_l1_data_A_sram_head; +static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE]; #endif #if L1_DATA_B_LENGTH != 0 -static struct sram_piece free_l1_data_B_sram_head, used_l1_data_B_sram_head; +static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE]; #endif #if L1_CODE_LENGTH != 0 -static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head; -#endif - -#ifdef L2_LENGTH -static struct sram_piece free_l2_sram_head, used_l2_sram_head; +static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE]; #endif -static struct kmem_cache *sram_piece_cache; - /* L1 Scratchpad SRAM initialization function */ -static void __init l1sram_init(void) +void __init l1sram_init(void) { - free_l1_ssram_head.next = - kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); - if (!free_l1_ssram_head.next) { - printk(KERN_INFO"Fail to initialize Scratchpad data SRAM.\n"); - return; - } - - free_l1_ssram_head.next->paddr = (void *)L1_SCRATCH_START; - free_l1_ssram_head.next->size = L1_SCRATCH_LENGTH; - free_l1_ssram_head.next->pid = 0; - free_l1_ssram_head.next->next = NULL; + printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", + L1_SCRATCH_LENGTH >> 10); - used_l1_ssram_head.next = NULL; + memset(&l1_ssram, 0x00, sizeof(l1_ssram)); + l1_ssram[0].paddr = (void *)L1_SCRATCH_START; + l1_ssram[0].size = L1_SCRATCH_LENGTH; + l1_ssram[0].flag = SRAM_SLT_FREE; /* mutex initialize */ spin_lock_init(&l1sram_lock); - - printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", - L1_SCRATCH_LENGTH >> 10); } -static void __init l1_data_sram_init(void) +void __init l1_data_sram_init(void) { #if L1_DATA_A_LENGTH != 0 - free_l1_data_A_sram_head.next = - kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); - if (!free_l1_data_A_sram_head.next) { - printk(KERN_INFO"Fail to initialize L1 Data A SRAM.\n"); - return; - } - - free_l1_data_A_sram_head.next->paddr = - (void *)L1_DATA_A_START + (_ebss_l1 - _sdata_l1); - free_l1_data_A_sram_head.next->size = - L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); - free_l1_data_A_sram_head.next->pid = 0; - free_l1_data_A_sram_head.next->next = NULL; - - used_l1_data_A_sram_head.next = NULL; - - printk(KERN_INFO "Blackfin L1 Data A SRAM: %d KB (%d KB free)\n", - L1_DATA_A_LENGTH >> 10, - free_l1_data_A_sram_head.next->size >> 10); + memset(&l1_data_A_sram, 0x00, sizeof(l1_data_A_sram)); + l1_data_A_sram[0].paddr = (void *)L1_DATA_A_START + + (_ebss_l1 - _sdata_l1); + l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); + l1_data_A_sram[0].flag = SRAM_SLT_FREE; + + printk(KERN_INFO "Blackfin Data A SRAM: %d KB (%d KB free)\n", + L1_DATA_A_LENGTH >> 10, l1_data_A_sram[0].size >> 10); #endif #if L1_DATA_B_LENGTH != 0 - free_l1_data_B_sram_head.next = - kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); - if (!free_l1_data_B_sram_head.next) { - printk(KERN_INFO"Fail to initialize L1 Data B SRAM.\n"); - return; - } - - free_l1_data_B_sram_head.next->paddr = - (void *)L1_DATA_B_START + (_ebss_b_l1 - _sdata_b_l1); - free_l1_data_B_sram_head.next->size = - L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1); - free_l1_data_B_sram_head.next->pid = 0; - free_l1_data_B_sram_head.next->next = NULL; - - used_l1_data_B_sram_head.next = NULL; - - printk(KERN_INFO "Blackfin L1 Data B SRAM: %d KB (%d KB free)\n", - L1_DATA_B_LENGTH >> 10, - free_l1_data_B_sram_head.next->size >> 10); + memset(&l1_data_B_sram, 0x00, sizeof(l1_data_B_sram)); + l1_data_B_sram[0].paddr = (void *)L1_DATA_B_START + + (_ebss_b_l1 - _sdata_b_l1); + l1_data_B_sram[0].size = L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1); + l1_data_B_sram[0].flag = SRAM_SLT_FREE; + + printk(KERN_INFO "Blackfin Data B SRAM: %d KB (%d KB free)\n", + L1_DATA_B_LENGTH >> 10, l1_data_B_sram[0].size >> 10); #endif /* mutex initialize */ spin_lock_init(&l1_data_sram_lock); } -static void __init l1_inst_sram_init(void) +void __init l1_inst_sram_init(void) { #if L1_CODE_LENGTH != 0 - free_l1_inst_sram_head.next = - kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); - if (!free_l1_inst_sram_head.next) { - printk(KERN_INFO"Fail to initialize L1 Instruction SRAM.\n"); - return; - } + memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram)); + l1_inst_sram[0].paddr = (void *)L1_CODE_START + (_etext_l1 - _stext_l1); + l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1); + l1_inst_sram[0].flag = SRAM_SLT_FREE; - free_l1_inst_sram_head.next->paddr = - (void *)L1_CODE_START + (_etext_l1 - _stext_l1); - free_l1_inst_sram_head.next->size = - L1_CODE_LENGTH - (_etext_l1 - _stext_l1); - free_l1_inst_sram_head.next->pid = 0; - free_l1_inst_sram_head.next->next = NULL; - - used_l1_inst_sram_head.next = NULL; - - printk(KERN_INFO "Blackfin L1 Instruction SRAM: %d KB (%d KB free)\n", - L1_CODE_LENGTH >> 10, - free_l1_inst_sram_head.next->size >> 10); + printk(KERN_INFO "Blackfin Instruction SRAM: %d KB (%d KB free)\n", + L1_CODE_LENGTH >> 10, l1_inst_sram[0].size >> 10); #endif /* mutex initialize */ spin_lock_init(&l1_inst_sram_lock); } -static void __init l2_sram_init(void) +/* L1 memory allocate function */ +static void *_l1_sram_alloc(size_t size, struct l1_sram_piece *pfree, int count) { -#ifdef L2_LENGTH - free_l2_sram_head.next = - kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); - if (!free_l2_sram_head.next) { - printk(KERN_INFO"Fail to initialize L2 SRAM.\n"); - return; - } - - free_l2_sram_head.next->paddr = (void *)L2_START + - (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); - free_l2_sram_head.next->size = L2_LENGTH - - (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); - free_l2_sram_head.next->pid = 0; - free_l2_sram_head.next->next = NULL; - - used_l2_sram_head.next = NULL; - - printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n", - L2_LENGTH >> 10, - free_l2_sram_head.next->size >> 10); -#endif - - /* mutex initialize */ - spin_lock_init(&l2_sram_lock); -} -void __init bfin_sram_init(void) -{ - sram_piece_cache = kmem_cache_create("sram_piece_cache", - sizeof(struct sram_piece), - 0, SLAB_PANIC, NULL); - - l1sram_init(); - l1_data_sram_init(); - l1_inst_sram_init(); - l2_sram_init(); -} - -/* SRAM allocate function */ -static void *_sram_alloc(size_t size, struct sram_piece *pfree_head, - struct sram_piece *pused_head) -{ - struct sram_piece *pslot, *plast, *pavail; + int i, index = 0; + void *addr = NULL; - if (size <= 0 || !pfree_head || !pused_head) + if (size <= 0) return NULL; /* Align the size */ size = (size + 3) & ~3; - pslot = pfree_head->next; - plast = pfree_head; - - /* search an available piece slot */ - while (pslot != NULL && size > pslot->size) { - plast = pslot; - pslot = pslot->next; + /* not use the good method to match the best slot !!! */ + /* search an available memory slot */ + for (i = 0; i < count; i++) { + if ((pfree[i].flag == SRAM_SLT_FREE) + && (pfree[i].size >= size)) { + addr = pfree[i].paddr; + pfree[i].flag = SRAM_SLT_ALLOCATED; + pfree[i].pid = current->pid; + index = i; + break; + } } - - if (!pslot) + if (i >= count) return NULL; - if (pslot->size == size) { - plast->next = pslot->next; - pavail = pslot; - } else { - pavail = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); - - if (!pavail) - return NULL; - - pavail->paddr = pslot->paddr; - pavail->size = size; - pslot->paddr += size; - pslot->size -= size; - } - - pavail->pid = current->pid; - - pslot = pused_head->next; - plast = pused_head; - - /* insert new piece into used piece list !!! */ - while (pslot != NULL && pavail->paddr < pslot->paddr) { - plast = pslot; - pslot = pslot->next; + /* updated the NULL memory slot !!! */ + if (pfree[i].size > size) { + for (i = 0; i < count; i++) { + if (pfree[i].flag == SRAM_SLT_NULL) { + pfree[i].pid = 0; + pfree[i].flag = SRAM_SLT_FREE; + pfree[i].paddr = addr + size; + pfree[i].size = pfree[index].size - size; + pfree[index].size = size; + break; + } + } } - pavail->next = pslot; - plast->next = pavail; - - return pavail->paddr; + return addr; } /* Allocate the largest available block. */ -static void *_sram_alloc_max(struct sram_piece *pfree_head, - struct sram_piece *pused_head, +static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count, unsigned long *psize) { - struct sram_piece *pslot, *pmax; - - if (!pfree_head || !pused_head) - return NULL; - - pmax = pslot = pfree_head->next; + unsigned long best = 0; + int i, index = -1; + void *addr = NULL; - /* search an available piece slot */ - while (pslot != NULL) { - if (pslot->size > pmax->size) - pmax = pslot; - pslot = pslot->next; + /* search an available memory slot */ + for (i = 0; i < count; i++) { + if (pfree[i].flag == SRAM_SLT_FREE && pfree[i].size > best) { + addr = pfree[i].paddr; + index = i; + best = pfree[i].size; + } } - - if (!pmax) + if (index < 0) return NULL; + *psize = best; - *psize = pmax->size; - - return _sram_alloc(*psize, pfree_head, pused_head); + pfree[index].pid = current->pid; + pfree[index].flag = SRAM_SLT_ALLOCATED; + return addr; } -/* SRAM free function */ -static int _sram_free(const void *addr, - struct sram_piece *pfree_head, - struct sram_piece *pused_head) +/* L1 memory free function */ +static int _l1_sram_free(const void *addr, + struct l1_sram_piece *pfree, + int count) { - struct sram_piece *pslot, *plast, *pavail; - - if (!pfree_head || !pused_head) - return -1; + int i, index = 0; /* search the relevant memory slot */ - pslot = pused_head->next; - plast = pused_head; - - /* search an available piece slot */ - while (pslot != NULL && pslot->paddr != addr) { - plast = pslot; - pslot = pslot->next; + for (i = 0; i < count; i++) { + if (pfree[i].paddr == addr) { + if (pfree[i].flag != SRAM_SLT_ALLOCATED) { + /* error log */ + return -1; + } + index = i; + break; + } } - - if (!pslot) + if (i >= count) return -1; - plast->next = pslot->next; - pavail = pslot; - pavail->pid = 0; - - /* insert free pieces back to the free list */ - pslot = pfree_head->next; - plast = pfree_head; - - while (pslot != NULL && addr > pslot->paddr) { - plast = pslot; - pslot = pslot->next; - } - - if (plast != pfree_head && plast->paddr + plast->size == pavail->paddr) { - plast->size += pavail->size; - kmem_cache_free(sram_piece_cache, pavail); - } else { - pavail->next = plast; - plast->next = pavail; - plast = pavail; + pfree[index].pid = 0; + pfree[index].flag = SRAM_SLT_FREE; + + /* link the next address slot */ + for (i = 0; i < count; i++) { + if (((pfree[index].paddr + pfree[index].size) == pfree[i].paddr) + && (pfree[i].flag == SRAM_SLT_FREE)) { + pfree[i].pid = 0; + pfree[i].flag = SRAM_SLT_NULL; + pfree[index].size += pfree[i].size; + pfree[index].flag = SRAM_SLT_FREE; + break; + } } - if (pslot && plast->paddr + plast->size == pslot->paddr) { - plast->size += pslot->size; - plast->next = pslot->next; - kmem_cache_free(sram_piece_cache, pslot); + /* link the last address slot */ + for (i = 0; i < count; i++) { + if (((pfree[i].paddr + pfree[i].size) == pfree[index].paddr) && + (pfree[i].flag == SRAM_SLT_FREE)) { + pfree[index].flag = SRAM_SLT_NULL; + pfree[i].size += pfree[index].size; + break; + } } return 0; @@ -366,11 +272,6 @@ int sram_free(const void *addr) else if (addr >= (void *)L1_DATA_B_START && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH)) return l1_data_B_sram_free(addr); -#endif -#ifdef L2_LENGTH - else if (addr >= (void *)L2_START - && addr < (void *)(L2_START + L2_LENGTH)) - return l2_sram_free(addr); #endif else return -1; @@ -386,8 +287,7 @@ void *l1_data_A_sram_alloc(size_t size) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - addr = _sram_alloc(size, &free_l1_data_A_sram_head, - &used_l1_data_A_sram_head); + addr = _l1_sram_alloc(size, l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); #endif /* add mutex operation */ @@ -409,8 +309,8 @@ int l1_data_A_sram_free(const void *addr) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - ret = _sram_free(addr, &free_l1_data_A_sram_head, - &used_l1_data_A_sram_head); + ret = _l1_sram_free(addr, + l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); #else ret = -1; #endif @@ -431,8 +331,7 @@ void *l1_data_B_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - addr = _sram_alloc(size, &free_l1_data_B_sram_head, - &used_l1_data_B_sram_head); + addr = _l1_sram_alloc(size, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); /* add mutex operation */ spin_unlock_irqrestore(&l1_data_sram_lock, flags); @@ -456,8 +355,7 @@ int l1_data_B_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - ret = _sram_free(addr, &free_l1_data_B_sram_head, - &used_l1_data_B_sram_head); + ret = _l1_sram_free(addr, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); /* add mutex operation */ spin_unlock_irqrestore(&l1_data_sram_lock, flags); @@ -510,8 +408,7 @@ void *l1_inst_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - addr = _sram_alloc(size, &free_l1_inst_sram_head, - &used_l1_inst_sram_head); + addr = _l1_sram_alloc(size, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); /* add mutex operation */ spin_unlock_irqrestore(&l1_inst_sram_lock, flags); @@ -535,8 +432,7 @@ int l1_inst_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - ret = _sram_free(addr, &free_l1_inst_sram_head, - &used_l1_inst_sram_head); + ret = _l1_sram_free(addr, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); /* add mutex operation */ spin_unlock_irqrestore(&l1_inst_sram_lock, flags); @@ -557,8 +453,7 @@ void *l1sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _sram_alloc(size, &free_l1_ssram_head, - &used_l1_ssram_head); + addr = _l1_sram_alloc(size, l1_ssram, ARRAY_SIZE(l1_ssram)); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -575,8 +470,7 @@ void *l1sram_alloc_max(size_t *psize) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _sram_alloc_max(&free_l1_ssram_head, - &used_l1_ssram_head, psize); + addr = _l1_sram_alloc_max(l1_ssram, ARRAY_SIZE(l1_ssram), psize); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -593,8 +487,7 @@ int l1sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - ret = _sram_free(addr, &free_l1_ssram_head, - &used_l1_ssram_head); + ret = _l1_sram_free(addr, l1_ssram, ARRAY_SIZE(l1_ssram)); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -602,64 +495,6 @@ int l1sram_free(const void *addr) return ret; } -void *l2_sram_alloc(size_t size) -{ -#ifdef L2_LENGTH - unsigned flags; - void *addr; - - /* add mutex operation */ - spin_lock_irqsave(&l2_sram_lock, flags); - - addr = _sram_alloc(size, &free_l2_sram_head, - &used_l2_sram_head); - - /* add mutex operation */ - spin_unlock_irqrestore(&l2_sram_lock, flags); - - pr_debug("Allocated address in l2_sram_alloc is 0x%lx+0x%lx\n", - (long unsigned int)addr, size); - - return addr; -#else - return NULL; -#endif -} -EXPORT_SYMBOL(l2_sram_alloc); - -void *l2_sram_zalloc(size_t size) -{ - void *addr = l2_sram_alloc(size); - - if (addr) - memset(addr, 0x00, size); - - return addr; -} -EXPORT_SYMBOL(l2_sram_zalloc); - -int l2_sram_free(const void *addr) -{ -#ifdef L2_LENGTH - unsigned flags; - int ret; - - /* add mutex operation */ - spin_lock_irqsave(&l2_sram_lock, flags); - - ret = _sram_free(addr, &free_l2_sram_head, - &used_l2_sram_head); - - /* add mutex operation */ - spin_unlock_irqrestore(&l2_sram_lock, flags); - - return ret; -#else - return -1; -#endif -} -EXPORT_SYMBOL(l2_sram_free); - int sram_free_with_lsl(const void *addr) { struct sram_list_struct *lsl, **tmp; @@ -698,9 +533,6 @@ void *sram_alloc_with_lsl(size_t size, unsigned long flags) if (addr == NULL && (flags & L1_DATA_B_SRAM)) addr = l1_data_B_sram_alloc(size); - if (addr == NULL && (flags & L2_SRAM)) - addr = l2_sram_alloc(size); - if (addr == NULL) { kfree(lsl); return NULL; @@ -717,80 +549,49 @@ EXPORT_SYMBOL(sram_alloc_with_lsl); /* Once we get a real allocator, we'll throw all of this away. * Until then, we need some sort of visibility into the L1 alloc. */ -/* Need to keep line of output the same. Currently, that is 44 bytes - * (including newline). - */ -static int _sram_proc_read(char *buf, int *len, int count, const char *desc, - struct sram_piece *pfree_head, - struct sram_piece *pused_head) +static void _l1sram_proc_read(char *buf, int *len, const char *desc, + struct l1_sram_piece *pfree, const int array_size) { - struct sram_piece *pslot; - - if (!pfree_head || !pused_head) - return -1; - - *len += sprintf(&buf[*len], "--- SRAM %-14s Size PID State \n", desc); - - /* search the relevant memory slot */ - pslot = pused_head->next; - - while (pslot != NULL) { - *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n", - pslot->paddr, pslot->paddr + pslot->size, - pslot->size, pslot->pid, "ALLOCATED"); - - pslot = pslot->next; + int i; + + *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State\n", desc); + for (i = 0; i < array_size; ++i) { + const char *alloc_type; + switch (pfree[i].flag) { + case SRAM_SLT_NULL: alloc_type = "NULL"; break; + case SRAM_SLT_FREE: alloc_type = "FREE"; break; + case SRAM_SLT_ALLOCATED: alloc_type = "ALLOCATED"; break; + default: alloc_type = "????"; break; + } + *len += sprintf(&buf[*len], "%p-%p %8i %4i %s\n", + pfree[i].paddr, pfree[i].paddr + pfree[i].size, + pfree[i].size, pfree[i].pid, alloc_type); } - - pslot = pfree_head->next; - - while (pslot != NULL) { - *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n", - pslot->paddr, pslot->paddr + pslot->size, - pslot->size, pslot->pid, "FREE"); - - pslot = pslot->next; - } - - return 0; } -static int sram_proc_read(char *buf, char **start, off_t offset, int count, +static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len = 0; - if (_sram_proc_read(buf, &len, count, "Scratchpad", - &free_l1_ssram_head, &used_l1_ssram_head)) - goto not_done; + _l1sram_proc_read(buf, &len, "Scratchpad", + l1_ssram, ARRAY_SIZE(l1_ssram)); #if L1_DATA_A_LENGTH != 0 - if (_sram_proc_read(buf, &len, count, "L1 Data A", - &free_l1_data_A_sram_head, - &used_l1_data_A_sram_head)) - goto not_done; + _l1sram_proc_read(buf, &len, "Data A", + l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); #endif #if L1_DATA_B_LENGTH != 0 - if (_sram_proc_read(buf, &len, count, "L1 Data B", - &free_l1_data_B_sram_head, - &used_l1_data_B_sram_head)) - goto not_done; + _l1sram_proc_read(buf, &len, "Data B", + l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); #endif #if L1_CODE_LENGTH != 0 - if (_sram_proc_read(buf, &len, count, "L1 Instruction", - &free_l1_inst_sram_head, &used_l1_inst_sram_head)) - goto not_done; -#endif -#ifdef L2_LENGTH - if (_sram_proc_read(buf, &len, count, "L2", - &free_l2_sram_head, &used_l2_sram_head)) - goto not_done; + _l1sram_proc_read(buf, &len, "Instruction", + l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); #endif - *eof = 1; - not_done: return len; } -static int __init sram_proc_init(void) +static int __init l1sram_proc_init(void) { struct proc_dir_entry *ptr; ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL); @@ -799,8 +600,8 @@ static int __init sram_proc_init(void) return -1; } ptr->owner = THIS_MODULE; - ptr->read_proc = sram_proc_read; + ptr->read_proc = l1sram_proc_read; return 0; } -late_initcall(sram_proc_init); +late_initcall(l1sram_proc_init); #endif diff --git a/trunk/arch/blackfin/mm/blackfin_sram.h b/trunk/arch/blackfin/mm/blackfin_sram.h index 8cb0945563f9..0fb73b78dd60 100644 --- a/trunk/arch/blackfin/mm/blackfin_sram.h +++ b/trunk/arch/blackfin/mm/blackfin_sram.h @@ -30,7 +30,9 @@ #ifndef __BLACKFIN_SRAM_H__ #define __BLACKFIN_SRAM_H__ -extern void bfin_sram_init(void); +extern void l1sram_init(void); +extern void l1_inst_sram_init(void); +extern void l1_data_sram_init(void); extern void *l1sram_alloc(size_t); #endif diff --git a/trunk/arch/blackfin/mm/init.c b/trunk/arch/blackfin/mm/init.c index bc240abb8745..ec3141fefd20 100644 --- a/trunk/arch/blackfin/mm/init.c +++ b/trunk/arch/blackfin/mm/init.c @@ -53,6 +53,33 @@ static unsigned long empty_bad_page; unsigned long empty_zero_page; +void show_mem(void) +{ + unsigned long i; + int free = 0, total = 0, reserved = 0, shared = 0; + + int cached = 0; + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map + i)) + reserved++; + else if (PageSwapCache(mem_map + i)) + cached++; + else if (!page_count(mem_map + i)) + free++; + else + shared += page_count(mem_map + i) - 1; + } + printk(KERN_INFO "%d pages of RAM\n", total); + printk(KERN_INFO "%d free pages\n", free); + printk(KERN_INFO "%d reserved pages\n", reserved); + printk(KERN_INFO "%d pages shared\n", shared); + printk(KERN_INFO "%d pages swap cached\n", cached); +} + /* * paging_init() continues the virtual memory environment setup which * was begun by the code in arch/head.S. @@ -137,14 +164,11 @@ void __init mem_init(void) "(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n", (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); -} - -static int __init sram_init(void) -{ - unsigned long tmp; /* Initialize the blackfin L1 Memory. */ - bfin_sram_init(); + l1sram_init(); + l1_data_sram_init(); + l1_inst_sram_init(); /* Allocate this once; never free it. We assume this gives us a pointer to the start of L1 scratchpad memory; panic if it @@ -155,10 +179,7 @@ static int __init sram_init(void) tmp, (unsigned long)L1_SCRATCH_TASK_INFO); panic("No L1, time to give up\n"); } - - return 0; } -pure_initcall(sram_init); static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) { diff --git a/trunk/arch/cris/arch-v10/kernel/kgdb.c b/trunk/arch/cris/arch-v10/kernel/kgdb.c index 6fea45f2e40c..a3ca55150745 100644 --- a/trunk/arch/cris/arch-v10/kernel/kgdb.c +++ b/trunk/arch/cris/arch-v10/kernel/kgdb.c @@ -278,6 +278,14 @@ void putDebugChar (int val); void enableDebugIRQ (void); +/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte, + represented by int x. */ +static char highhex (int x); + +/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte, + represented by int x. */ +static char lowhex (int x); + /* Returns the integer equivalent of a hexadecimal character. */ static int hex (char ch); @@ -348,6 +356,9 @@ extern unsigned char executing_task; /* Run-length encoding maximum length. Send 64 at most. */ #define RUNLENMAX 64 +/* Definition of all valid hexadecimal characters */ +static const char hexchars[] = "0123456789abcdef"; + /* The inbound/outbound buffers used in packet I/O */ static char remcomInBuffer[BUFMAX]; static char remcomOutBuffer[BUFMAX]; @@ -488,8 +499,8 @@ gdb_cris_strtol (const char *s, char **endptr, int base) char *sd; int x = 0; - for (s1 = (char*)s; (sd = gdb_cris_memchr(hex_asc, *s1, base)) != NULL; ++s1) - x = x * base + (sd - hex_asc); + for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1) + x = x * base + (sd - hexchars); if (endptr) { @@ -659,6 +670,22 @@ read_register (char regno, unsigned int *valptr) } /********************************** Packet I/O ******************************/ +/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte, + represented by int x. */ +static inline char +highhex(int x) +{ + return hexchars[(x >> 4) & 0xf]; +} + +/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte, + represented by int x. */ +static inline char +lowhex(int x) +{ + return hexchars[x & 0xf]; +} + /* Returns the integer equivalent of a hexadecimal character. */ static int hex (char ch) @@ -694,7 +721,8 @@ mem2hex(char *buf, unsigned char *mem, int count) /* Valid mem address. */ for (i = 0; i < count; i++) { ch = *mem++; - buf = pack_hex_byte(buf, ch); + *buf++ = highhex (ch); + *buf++ = lowhex (ch); } } @@ -829,9 +857,9 @@ putpacket(char *buffer) src++; } } - putDebugChar('#'); - putDebugChar(hex_asc_hi(checksum)); - putDebugChar(hex_asc_lo(checksum)); + putDebugChar ('#'); + putDebugChar (highhex (checksum)); + putDebugChar (lowhex (checksum)); } while(kgdb_started && (getDebugChar() != '+')); } @@ -867,8 +895,9 @@ stub_is_stopped(int sigval) /* Send trap type (converted to signal) */ - *ptr++ = 'T'; - ptr = pack_hex_byte(ptr, sigval); + *ptr++ = 'T'; + *ptr++ = highhex (sigval); + *ptr++ = lowhex (sigval); /* Send register contents. We probably only need to send the * PC, frame pointer and stack pointer here. Other registers will be @@ -881,7 +910,9 @@ stub_is_stopped(int sigval) status = read_register (regno, ®_cont); if (status == SUCCESS) { - ptr = pack_hex_byte(ptr, regno); + + *ptr++ = highhex (regno); + *ptr++ = lowhex (regno); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, @@ -906,8 +937,8 @@ stub_is_stopped(int sigval) /* Store thread:r...; with the executing task TID. */ gdb_cris_strcpy (&remcomOutBuffer[pos], "thread:"); pos += gdb_cris_strlen ("thread:"); - remcomOutBuffer[pos++] = hex_asc_hi(executing_task); - remcomOutBuffer[pos++] = hex_asc_lo(executing_task); + remcomOutBuffer[pos++] = highhex (executing_task); + remcomOutBuffer[pos++] = lowhex (executing_task); gdb_cris_strcpy (&remcomOutBuffer[pos], ";"); #endif @@ -1095,8 +1126,8 @@ handle_exception (int sigval) Success: SAA, where AA is the signal number. Failure: void. */ remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hex_asc_hi(sigval); - remcomOutBuffer[2] = hex_asc_lo(sigval); + remcomOutBuffer[1] = highhex (sigval); + remcomOutBuffer[2] = lowhex (sigval); remcomOutBuffer[3] = 0; break; @@ -1193,23 +1224,23 @@ handle_exception (int sigval) case 'C': /* Identify the remote current thread. */ gdb_cris_strcpy (&remcomOutBuffer[0], "QC"); - remcomOutBuffer[2] = hex_asc_hi(current_thread_c); - remcomOutBuffer[3] = hex_asc_lo(current_thread_c); + remcomOutBuffer[2] = highhex (current_thread_c); + remcomOutBuffer[3] = lowhex (current_thread_c); remcomOutBuffer[4] = '\0'; break; case 'L': gdb_cris_strcpy (&remcomOutBuffer[0], "QM"); /* Reply with number of threads. */ if (os_is_started()) { - remcomOutBuffer[2] = hex_asc_hi(number_of_tasks); - remcomOutBuffer[3] = hex_asc_lo(number_of_tasks); + remcomOutBuffer[2] = highhex (number_of_tasks); + remcomOutBuffer[3] = lowhex (number_of_tasks); } else { - remcomOutBuffer[2] = hex_asc_hi(0); - remcomOutBuffer[3] = hex_asc_lo(1); + remcomOutBuffer[2] = highhex (0); + remcomOutBuffer[3] = lowhex (1); } /* Done with the reply. */ - remcomOutBuffer[4] = hex_asc_lo(1); + remcomOutBuffer[4] = lowhex (1); pos = 5; /* Expects the argument thread id. */ for (; pos < (5 + HEXCHARS_IN_THREAD_ID); pos++) @@ -1220,16 +1251,16 @@ handle_exception (int sigval) for (thread_id = 0; thread_id < number_of_tasks; thread_id++) { nextpos = pos + HEXCHARS_IN_THREAD_ID - 1; for (; pos < nextpos; pos ++) - remcomOutBuffer[pos] = hex_asc_lo(0); - remcomOutBuffer[pos++] = hex_asc_lo(thread_id); + remcomOutBuffer[pos] = lowhex (0); + remcomOutBuffer[pos++] = lowhex (thread_id); } } else { /* Store the thread identifier of the boot task. */ nextpos = pos + HEXCHARS_IN_THREAD_ID - 1; for (; pos < nextpos; pos ++) - remcomOutBuffer[pos] = hex_asc_lo(0); - remcomOutBuffer[pos++] = hex_asc_lo(current_thread_c); + remcomOutBuffer[pos] = lowhex (0); + remcomOutBuffer[pos++] = lowhex (current_thread_c); } remcomOutBuffer[pos] = '\0'; break; diff --git a/trunk/arch/cris/arch-v32/kernel/kgdb.c b/trunk/arch/cris/arch-v32/kernel/kgdb.c index 8bd5a5bc0dc7..4e2e2e271efb 100644 --- a/trunk/arch/cris/arch-v32/kernel/kgdb.c +++ b/trunk/arch/cris/arch-v32/kernel/kgdb.c @@ -398,6 +398,14 @@ void putDebugChar(int val) } #endif +/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte, + represented by int x. */ +static char highhex(int x); + +/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte, + represented by int x. */ +static char lowhex(int x); + /* Returns the integer equivalent of a hexadecimal character. */ static int hex(char ch); @@ -456,6 +464,9 @@ void breakpoint(void); /* Run-length encoding maximum length. Send 64 at most. */ #define RUNLENMAX 64 +/* Definition of all valid hexadecimal characters */ +static const char hexchars[] = "0123456789abcdef"; + /* The inbound/outbound buffers used in packet I/O */ static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; @@ -539,8 +550,8 @@ gdb_cris_strtol(const char *s, char **endptr, int base) char *sd; int x = 0; - for (s1 = (char*)s; (sd = gdb_cris_memchr(hex_asc, *s1, base)) != NULL; ++s1) - x = x * base + (sd - hex_asc); + for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1) + x = x * base + (sd - hexchars); if (endptr) { /* Unconverted suffix is stored in endptr unless endptr is NULL. */ @@ -644,6 +655,22 @@ read_register(char regno, unsigned int *valptr) } /********************************** Packet I/O ******************************/ +/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte, + represented by int x. */ +static inline char +highhex(int x) +{ + return hexchars[(x >> 4) & 0xf]; +} + +/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte, + represented by int x. */ +static inline char +lowhex(int x) +{ + return hexchars[x & 0xf]; +} + /* Returns the integer equivalent of a hexadecimal character. */ static int hex(char ch) @@ -677,7 +704,8 @@ mem2hex(char *buf, unsigned char *mem, int count) /* Valid mem address. */ for (i = 0; i < count; i++) { ch = *mem++; - buf = pack_hex_byte(buf, ch); + *buf++ = highhex (ch); + *buf++ = lowhex (ch); } } /* Terminate properly. */ @@ -695,7 +723,8 @@ mem2hex_nbo(char *buf, unsigned char *mem, int count) mem += count - 1; for (i = 0; i < count; i++) { ch = *mem--; - buf = pack_hex_byte(buf, ch); + *buf++ = highhex (ch); + *buf++ = lowhex (ch); } /* Terminate properly. */ @@ -833,8 +862,8 @@ putpacket(char *buffer) } } putDebugChar('#'); - putDebugChar(hex_asc_hi(checksum)); - putDebugChar(hex_asc_lo(checksum)); + putDebugChar(highhex (checksum)); + putDebugChar(lowhex (checksum)); } while(kgdb_started && (getDebugChar() != '+')); } @@ -880,7 +909,8 @@ stub_is_stopped(int sigval) /* Send trap type (converted to signal) */ *ptr++ = 'T'; - ptr = pack_hex_byte(ptr, sigval); + *ptr++ = highhex(sigval); + *ptr++ = lowhex(sigval); if (((reg.exs & 0xff00) >> 8) == 0xc) { @@ -988,26 +1018,30 @@ stub_is_stopped(int sigval) } /* Only send PC, frame and stack pointer. */ read_register(PC, ®_cont); - ptr = pack_hex_byte(PC); + *ptr++ = highhex(PC); + *ptr++ = lowhex(PC); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[PC]); *ptr++ = ';'; read_register(R8, ®_cont); - ptr = pack_hex_byte(R8); + *ptr++ = highhex(R8); + *ptr++ = lowhex(R8); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[R8]); *ptr++ = ';'; read_register(SP, ®_cont); - ptr = pack_hex_byte(SP); + *ptr++ = highhex(SP); + *ptr++ = lowhex(SP); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[SP]); *ptr++ = ';'; /* Send ERP as well; this will save us an entire register fetch in some cases. */ read_register(ERP, ®_cont); - ptr = pack_hex_byte(ERP); + *ptr++ = highhex(ERP); + *ptr++ = lowhex(ERP); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[ERP]); *ptr++ = ';'; @@ -1499,8 +1533,8 @@ handle_exception(int sigval) Success: SAA, where AA is the signal number. Failure: void. */ output_buffer[0] = 'S'; - output_buffer[1] = hex_asc_hi(sigval); - output_buffer[2] = hex_asc_lo(sigval); + output_buffer[1] = highhex(sigval); + output_buffer[2] = lowhex(sigval); output_buffer[3] = 0; break; diff --git a/trunk/arch/cris/mm/init.c b/trunk/arch/cris/mm/init.c index 2fdd212eb250..5b06ffa15e34 100644 --- a/trunk/arch/cris/mm/init.c +++ b/trunk/arch/cris/mm/init.c @@ -19,6 +19,36 @@ unsigned long empty_zero_page; extern char _stext, _edata, _etext; /* From linkerscript */ extern char __init_begin, __init_end; +void +show_mem(void) +{ + int i,free = 0,total = 0,cached = 0, reserved = 0, nonshared = 0; + int shared = 0; + + printk("\nMem-info:\n"); + show_free_areas(); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (!page_count(mem_map+i)) + free++; + else if (page_count(mem_map+i) == 1) + nonshared++; + else + shared += page_count(mem_map+i) - 1; + } + printk("%d pages of RAM\n",total); + printk("%d free pages\n",free); + printk("%d reserved pages\n",reserved); + printk("%d pages nonshared\n",nonshared); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); +} + void __init mem_init(void) { diff --git a/trunk/arch/frv/kernel/gdb-stub.c b/trunk/arch/frv/kernel/gdb-stub.c index 7ca8a6b19ac9..48a0393e7cee 100644 --- a/trunk/arch/frv/kernel/gdb-stub.c +++ b/trunk/arch/frv/kernel/gdb-stub.c @@ -182,6 +182,8 @@ extern volatile u32 __attribute__((section(".bss"))) gdbstub_trace_through_excep static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; +static const char hexchars[] = "0123456789abcdef"; + static const char *regnames[] = { "PSR ", "ISR ", "CCR ", "CCCR", "LR ", "LCR ", "PC ", "_stt", @@ -381,8 +383,8 @@ static int gdbstub_send_packet(char *buffer) } gdbstub_tx_char('#'); - gdbstub_tx_char(hex_asc_hi(checksum)); - gdbstub_tx_char(hex_asc_lo(checksum)); + gdbstub_tx_char(hexchars[checksum >> 4]); + gdbstub_tx_char(hexchars[checksum & 0xf]); } while (gdbstub_rx_char(&ch,0), #ifdef GDBSTUB_DEBUG_PROTOCOL @@ -672,7 +674,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa if ((uint32_t)mem&1 && count>=1) { if (!gdbstub_read_byte(mem,ch)) return NULL; - buf = pack_hex_byte(buf, ch[0]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; mem++; count--; } @@ -680,8 +683,10 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa if ((uint32_t)mem&3 && count>=2) { if (!gdbstub_read_word(mem,(uint16_t *)ch)) return NULL; - buf = pack_hex_byte(buf, ch[0]); - buf = pack_hex_byte(buf, ch[1]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; + *buf++ = hexchars[ch[1] >> 4]; + *buf++ = hexchars[ch[1] & 0xf]; mem += 2; count -= 2; } @@ -689,10 +694,14 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa while (count>=4) { if (!gdbstub_read_dword(mem,(uint32_t *)ch)) return NULL; - buf = pack_hex_byte(buf, ch[0]); - buf = pack_hex_byte(buf, ch[1]); - buf = pack_hex_byte(buf, ch[2]); - buf = pack_hex_byte(buf, ch[3]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; + *buf++ = hexchars[ch[1] >> 4]; + *buf++ = hexchars[ch[1] & 0xf]; + *buf++ = hexchars[ch[2] >> 4]; + *buf++ = hexchars[ch[2] & 0xf]; + *buf++ = hexchars[ch[3] >> 4]; + *buf++ = hexchars[ch[3] & 0xf]; mem += 4; count -= 4; } @@ -700,8 +709,10 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa if (count>=2) { if (!gdbstub_read_word(mem,(uint16_t *)ch)) return NULL; - buf = pack_hex_byte(buf, ch[0]); - buf = pack_hex_byte(buf, ch[1]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; + *buf++ = hexchars[ch[1] >> 4]; + *buf++ = hexchars[ch[1] & 0xf]; mem += 2; count -= 2; } @@ -709,7 +720,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa if (count>=1) { if (!gdbstub_read_byte(mem,ch)) return NULL; - buf = pack_hex_byte(buf, ch[0]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; } *buf = 0; @@ -1459,22 +1471,22 @@ void gdbstub(int sigval) *ptr++ = 'O'; ptr = mem2hex(title, ptr, sizeof(title) - 1,0); - hx = hex_asc_hi(brr >> 24); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(brr >> 24); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_hi(brr >> 16); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(brr >> 16); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_hi(brr >> 8); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(brr >> 8); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_hi(brr); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(brr); - ptr = pack_hex_byte(ptr, hx); + hx = hexchars[(brr & 0xf0000000) >> 28]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(brr & 0x0f000000) >> 24]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(brr & 0x00f00000) >> 20]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(brr & 0x000f0000) >> 16]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(brr & 0x0000f000) >> 12]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(brr & 0x00000f00) >> 8]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(brr & 0x000000f0) >> 4]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(brr & 0x0000000f)]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0); *ptr = 0; @@ -1488,10 +1500,12 @@ void gdbstub(int sigval) /* Send trap type (converted to signal) */ *ptr++ = 'T'; - ptr = pack_hex_byte(ptr, sigval); + *ptr++ = hexchars[sigval >> 4]; + *ptr++ = hexchars[sigval & 0xf]; /* Send Error PC */ - ptr = pack_hex_byte(ptr, GDB_REG_PC); + *ptr++ = hexchars[GDB_REG_PC >> 4]; + *ptr++ = hexchars[GDB_REG_PC & 0xf]; *ptr++ = ':'; ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0); *ptr++ = ';'; @@ -1499,7 +1513,8 @@ void gdbstub(int sigval) /* * Send frame pointer */ - ptr = pack_hex_byte(ptr, GDB_REG_FP); + *ptr++ = hexchars[GDB_REG_FP >> 4]; + *ptr++ = hexchars[GDB_REG_FP & 0xf]; *ptr++ = ':'; ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0); *ptr++ = ';'; @@ -1507,7 +1522,8 @@ void gdbstub(int sigval) /* * Send stack pointer */ - ptr = pack_hex_byte(ptr, GDB_REG_SP); + *ptr++ = hexchars[GDB_REG_SP >> 4]; + *ptr++ = hexchars[GDB_REG_SP & 0xf]; *ptr++ = ':'; ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0); *ptr++ = ';'; @@ -1532,8 +1548,8 @@ void gdbstub(int sigval) /* request repeat of last signal number */ case '?': output_buffer[0] = 'S'; - output_buffer[1] = hex_asc_hi(sigval); - output_buffer[2] = hex_asc_lo(sigval); + output_buffer[1] = hexchars[sigval >> 4]; + output_buffer[2] = hexchars[sigval & 0xf]; output_buffer[3] = 0; break; @@ -2043,8 +2059,8 @@ void gdbstub_exit(int status) } gdbstub_tx_char('#'); - gdbstub_tx_char(hex_asc_hi(checksum)); - gdbstub_tx_char(hex_asc_lo(checksum)); + gdbstub_tx_char(hexchars[checksum >> 4]); + gdbstub_tx_char(hexchars[checksum & 0xf]); /* make sure the output is flushed, or else RedBoot might clobber it */ gdbstub_tx_char('-'); diff --git a/trunk/arch/frv/mm/init.c b/trunk/arch/frv/mm/init.c index 1b851db34186..9af7740f32fb 100644 --- a/trunk/arch/frv/mm/init.c +++ b/trunk/arch/frv/mm/init.c @@ -61,6 +61,37 @@ static unsigned long empty_bad_page; unsigned long empty_zero_page; EXPORT_SYMBOL(empty_zero_page); +/*****************************************************************************/ +/* + * + */ +void show_mem(void) +{ + unsigned long i; + int free = 0, total = 0, reserved = 0, shared = 0; + + printk("\nMem-info:\n"); + show_free_areas(); + i = max_mapnr; + while (i-- > 0) { + struct page *page = &mem_map[i]; + + total++; + if (PageReserved(page)) + reserved++; + else if (!page_count(page)) + free++; + else + shared += page_count(page) - 1; + } + + printk("%d pages of RAM\n",total); + printk("%d free pages\n",free); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + +} /* end show_mem() */ + /*****************************************************************************/ /* * paging_init() continues the virtual memory environment setup which diff --git a/trunk/arch/h8300/mm/init.c b/trunk/arch/h8300/mm/init.c index a1d228f5e4e6..e4f4199f97ab 100644 --- a/trunk/arch/h8300/mm/init.c +++ b/trunk/arch/h8300/mm/init.c @@ -64,6 +64,33 @@ unsigned long empty_zero_page; extern unsigned long rom_length; +void show_mem(void) +{ + unsigned long i; + int free = 0, total = 0, reserved = 0, shared = 0; + int cached = 0; + + printk("\nMem-info:\n"); + show_free_areas(); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (!page_count(mem_map+i)) + free++; + else + shared += page_count(mem_map+i) - 1; + } + printk("%d pages of RAM\n",total); + printk("%d free pages\n",free); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); +} + extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/trunk/arch/ia64/hp/common/hwsw_iommu.c b/trunk/arch/ia64/hp/common/hwsw_iommu.c index 88b6e6f3fd88..1c44ec2a1d58 100644 --- a/trunk/arch/ia64/hp/common/hwsw_iommu.c +++ b/trunk/arch/ia64/hp/common/hwsw_iommu.c @@ -186,10 +186,9 @@ hwsw_dma_supported (struct device *dev, u64 mask) } int -hwsw_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +hwsw_dma_mapping_error (dma_addr_t dma_addr) { - return hwiommu_dma_mapping_error(dev, dma_addr) || - swiotlb_dma_mapping_error(dev, dma_addr); + return hwiommu_dma_mapping_error (dma_addr) || swiotlb_dma_mapping_error(dma_addr); } EXPORT_SYMBOL(hwsw_dma_mapping_error); diff --git a/trunk/arch/ia64/hp/common/sba_iommu.c b/trunk/arch/ia64/hp/common/sba_iommu.c index 4956be40d7b5..34421aed1e2a 100644 --- a/trunk/arch/ia64/hp/common/sba_iommu.c +++ b/trunk/arch/ia64/hp/common/sba_iommu.c @@ -2147,7 +2147,7 @@ sba_dma_supported (struct device *dev, u64 mask) } int -sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +sba_dma_mapping_error (dma_addr_t dma_addr) { return 0; } diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index fc8f3509df27..19d4493c6193 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -2626,7 +2626,7 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task) /* * make sure the task is off any CPU */ - wait_task_inactive(task, 0); + wait_task_inactive(task); /* more to come... */ @@ -4774,7 +4774,7 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags) UNPROTECT_CTX(ctx, flags); - wait_task_inactive(task, 0); + wait_task_inactive(task); PROTECT_CTX(ctx, flags); diff --git a/trunk/arch/ia64/kvm/kvm-ia64.c b/trunk/arch/ia64/kvm/kvm-ia64.c index 7a37d06376be..2672f4d278ac 100644 --- a/trunk/arch/ia64/kvm/kvm-ia64.c +++ b/trunk/arch/ia64/kvm/kvm-ia64.c @@ -125,9 +125,9 @@ void kvm_arch_hardware_enable(void *garbage) PAGE_KERNEL)); local_irq_save(saved_psr); slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); - local_irq_restore(saved_psr); if (slot < 0) return; + local_irq_restore(saved_psr); spin_lock(&vp_lock); status = ia64_pal_vp_init_env(kvm_vsa_base ? @@ -160,9 +160,9 @@ void kvm_arch_hardware_disable(void *garbage) local_irq_save(saved_psr); slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); - local_irq_restore(saved_psr); if (slot < 0) return; + local_irq_restore(saved_psr); status = ia64_pal_vp_exit_env(host_iva); if (status) @@ -1253,7 +1253,6 @@ static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id) uninit: kvm_vcpu_uninit(vcpu); fail: - local_irq_restore(psr); return r; } diff --git a/trunk/arch/ia64/sn/pci/pci_dma.c b/trunk/arch/ia64/sn/pci/pci_dma.c index 53ebb6484495..52175af299a0 100644 --- a/trunk/arch/ia64/sn/pci/pci_dma.c +++ b/trunk/arch/ia64/sn/pci/pci_dma.c @@ -350,7 +350,7 @@ void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } EXPORT_SYMBOL(sn_dma_sync_sg_for_device); -int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +int sn_dma_mapping_error(dma_addr_t dma_addr) { return 0; } diff --git a/trunk/arch/m32r/mm/init.c b/trunk/arch/m32r/mm/init.c index 24d429f9358a..2554eb59cfef 100644 --- a/trunk/arch/m32r/mm/init.c +++ b/trunk/arch/m32r/mm/init.c @@ -36,6 +36,42 @@ pgd_t swapper_pg_dir[1024]; DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); +void show_mem(void) +{ + int total = 0, reserved = 0; + int shared = 0, cached = 0; + int highmem = 0; + struct page *page; + pg_data_t *pgdat; + unsigned long i; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + for_each_online_pgdat(pgdat) { + unsigned long flags; + pgdat_resize_lock(pgdat, &flags); + for (i = 0; i < pgdat->node_spanned_pages; ++i) { + page = pgdat_page_nr(pgdat, i); + total++; + if (PageHighMem(page)) + highmem++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + pgdat_resize_unlock(pgdat, &flags); + } + printk("%d pages of RAM\n", total); + printk("%d pages of HIGHMEM\n",highmem); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); +} + /* * Cache of MMU context last used. */ diff --git a/trunk/arch/m68k/mm/init.c b/trunk/arch/m68k/mm/init.c index 81bb08ceec18..79f5f94d4800 100644 --- a/trunk/arch/m68k/mm/init.c +++ b/trunk/arch/m68k/mm/init.c @@ -69,6 +69,36 @@ void __init m68k_setup_node(int node) void *empty_zero_page; EXPORT_SYMBOL(empty_zero_page); +void show_mem(void) +{ + pg_data_t *pgdat; + int free = 0, total = 0, reserved = 0, shared = 0; + int cached = 0; + int i; + + printk("\nMem-info:\n"); + show_free_areas(); + for_each_online_pgdat(pgdat) { + for (i = 0; i < pgdat->node_spanned_pages; i++) { + struct page *page = pgdat->node_mem_map + i; + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (!page_count(page)) + free++; + else + shared += page_count(page) - 1; + } + } + printk("%d pages of RAM\n",total); + printk("%d free pages\n",free); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); +} + extern void init_pointer_table(unsigned long ptable); /* References to section boundaries */ diff --git a/trunk/arch/m68knommu/mm/init.c b/trunk/arch/m68knommu/mm/init.c index 3bf249c53e41..22e2a0d02b81 100644 --- a/trunk/arch/m68knommu/mm/init.c +++ b/trunk/arch/m68knommu/mm/init.c @@ -62,6 +62,33 @@ static unsigned long empty_bad_page; unsigned long empty_zero_page; +void show_mem(void) +{ + unsigned long i; + int free = 0, total = 0, reserved = 0, shared = 0; + int cached = 0; + + printk(KERN_INFO "\nMem-info:\n"); + show_free_areas(); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (!page_count(mem_map+i)) + free++; + else + shared += page_count(mem_map+i) - 1; + } + printk(KERN_INFO "%d pages of RAM\n",total); + printk(KERN_INFO "%d free pages\n",free); + printk(KERN_INFO "%d reserved pages\n",reserved); + printk(KERN_INFO "%d pages shared\n",shared); + printk(KERN_INFO "%d pages swap cached\n",cached); +} + extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/trunk/arch/mips/mm/Makefile b/trunk/arch/mips/mm/Makefile index 44e8dd8106bf..48731020ca0e 100644 --- a/trunk/arch/mips/mm/Makefile +++ b/trunk/arch/mips/mm/Makefile @@ -3,7 +3,8 @@ # obj-y += cache.o dma-default.o extable.o fault.o \ - init.o tlbex.o tlbex-fault.o uasm.o page.o + init.o pgtable.o tlbex.o tlbex-fault.o \ + uasm.o page.o obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_64BIT) += pgtable-64.o diff --git a/trunk/arch/mips/mm/dma-default.c b/trunk/arch/mips/mm/dma-default.c index 891312f8e5a6..ae39dd88b9aa 100644 --- a/trunk/arch/mips/mm/dma-default.c +++ b/trunk/arch/mips/mm/dma-default.c @@ -348,7 +348,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele EXPORT_SYMBOL(dma_sync_sg_for_device); -int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +int dma_mapping_error(dma_addr_t dma_addr) { return 0; } diff --git a/trunk/arch/mips/mm/pgtable.c b/trunk/arch/mips/mm/pgtable.c new file mode 100644 index 000000000000..7dfa579ab24c --- /dev/null +++ b/trunk/arch/mips/mm/pgtable.c @@ -0,0 +1,36 @@ +#include +#include +#include + +void show_mem(void) +{ +#ifndef CONFIG_NEED_MULTIPLE_NODES /* XXX(hch): later.. */ + int pfn, total = 0, reserved = 0; + int shared = 0, cached = 0; + int highmem = 0; + struct page *page; + + printk("Mem-info:\n"); + show_free_areas(); + pfn = max_mapnr; + while (pfn-- > 0) { + if (!pfn_valid(pfn)) + continue; + page = pfn_to_page(pfn); + total++; + if (PageHighMem(page)) + highmem++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + printk("%d pages of RAM\n", total); + printk("%d pages of HIGHMEM\n", highmem); + printk("%d reserved pages\n", reserved); + printk("%d pages shared\n", shared); + printk("%d pages swap cached\n", cached); +#endif +} diff --git a/trunk/arch/mn10300/kernel/gdb-stub.c b/trunk/arch/mn10300/kernel/gdb-stub.c index 54be6afb5555..21891c71d549 100644 --- a/trunk/arch/mn10300/kernel/gdb-stub.c +++ b/trunk/arch/mn10300/kernel/gdb-stub.c @@ -163,6 +163,8 @@ static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; static char trans_buffer[BUFMAX]; +static const char hexchars[] = "0123456789abcdef"; + struct gdbstub_bkpt { u8 *addr; /* address of breakpoint */ u8 len; /* size of breakpoint */ @@ -361,8 +363,8 @@ static int putpacket(char *buffer) } gdbstub_io_tx_char('#'); - gdbstub_io_tx_char(hex_asc_hi(checksum)); - gdbstub_io_tx_char(hex_asc_lo(checksum)); + gdbstub_io_tx_char(hexchars[checksum >> 4]); + gdbstub_io_tx_char(hexchars[checksum & 0xf]); } while (gdbstub_io_rx_char(&ch, 0), ch == '-' && (gdbstub_io("### GDB Rx NAK\n"), 0), @@ -820,7 +822,8 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) if ((u32) mem & 1 && count >= 1) { if (gdbstub_read_byte(mem, ch) != 0) return 0; - buf = pack_hex_byte(buf, ch[0]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; mem++; count--; } @@ -828,8 +831,10 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) if ((u32) mem & 3 && count >= 2) { if (gdbstub_read_word(mem, ch) != 0) return 0; - buf = pack_hex_byte(buf, ch[0]); - buf = pack_hex_byte(buf, ch[1]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; + *buf++ = hexchars[ch[1] >> 4]; + *buf++ = hexchars[ch[1] & 0xf]; mem += 2; count -= 2; } @@ -837,10 +842,14 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) while (count >= 4) { if (gdbstub_read_dword(mem, ch) != 0) return 0; - buf = pack_hex_byte(buf, ch[0]); - buf = pack_hex_byte(buf, ch[1]); - buf = pack_hex_byte(buf, ch[2]); - buf = pack_hex_byte(buf, ch[3]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; + *buf++ = hexchars[ch[1] >> 4]; + *buf++ = hexchars[ch[1] & 0xf]; + *buf++ = hexchars[ch[2] >> 4]; + *buf++ = hexchars[ch[2] & 0xf]; + *buf++ = hexchars[ch[3] >> 4]; + *buf++ = hexchars[ch[3] & 0xf]; mem += 4; count -= 4; } @@ -848,8 +857,10 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) if (count >= 2) { if (gdbstub_read_word(mem, ch) != 0) return 0; - buf = pack_hex_byte(buf, ch[0]); - buf = pack_hex_byte(buf, ch[1]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; + *buf++ = hexchars[ch[1] >> 4]; + *buf++ = hexchars[ch[1] & 0xf]; mem += 2; count -= 2; } @@ -857,7 +868,8 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) if (count >= 1) { if (gdbstub_read_byte(mem, ch) != 0) return 0; - buf = pack_hex_byte(buf, ch[0]); + *buf++ = hexchars[ch[0] >> 4]; + *buf++ = hexchars[ch[0] & 0xf]; } *buf = 0; @@ -1292,14 +1304,14 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) *ptr++ = 'O'; ptr = mem2hex(title, ptr, sizeof(title) - 1, 0); - hx = hex_asc_hi(excep >> 8); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(excep >> 8); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_hi(excep); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(excep); - ptr = pack_hex_byte(ptr, hx); + hx = hexchars[(excep & 0xf000) >> 12]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(excep & 0x0f00) >> 8]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(excep & 0x00f0) >> 4]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(excep & 0x000f)]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0); *ptr = 0; @@ -1310,22 +1322,22 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) *ptr++ = 'O'; ptr = mem2hex(tbcberr, ptr, sizeof(tbcberr) - 1, 0); - hx = hex_asc_hi(bcberr >> 24); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(bcberr >> 24); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_hi(bcberr >> 16); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(bcberr >> 16); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_hi(bcberr >> 8); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(bcberr >> 8); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_hi(bcberr); - ptr = pack_hex_byte(ptr, hx); - hx = hex_asc_lo(bcberr); - ptr = pack_hex_byte(ptr, hx); + hx = hexchars[(bcberr & 0xf0000000) >> 28]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(bcberr & 0x0f000000) >> 24]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(bcberr & 0x00f00000) >> 20]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(bcberr & 0x000f0000) >> 16]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(bcberr & 0x0000f000) >> 12]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(bcberr & 0x00000f00) >> 8]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(bcberr & 0x000000f0) >> 4]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hexchars[(bcberr & 0x0000000f)]; + *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0); *ptr = 0; @@ -1341,12 +1353,14 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) * Send trap type (converted to signal) */ *ptr++ = 'T'; - ptr = pack_hex_byte(ptr, sigval); + *ptr++ = hexchars[sigval >> 4]; + *ptr++ = hexchars[sigval & 0xf]; /* * Send Error PC */ - ptr = pack_hex_byte(ptr, GDB_REGID_PC); + *ptr++ = hexchars[GDB_REGID_PC >> 4]; + *ptr++ = hexchars[GDB_REGID_PC & 0xf]; *ptr++ = ':'; ptr = mem2hex(®s->pc, ptr, 4, 0); *ptr++ = ';'; @@ -1354,7 +1368,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) /* * Send frame pointer */ - ptr = pack_hex_byte(ptr, GDB_REGID_FP); + *ptr++ = hexchars[GDB_REGID_FP >> 4]; + *ptr++ = hexchars[GDB_REGID_FP & 0xf]; *ptr++ = ':'; ptr = mem2hex(®s->a3, ptr, 4, 0); *ptr++ = ';'; @@ -1363,7 +1378,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) * Send stack pointer */ ssp = (unsigned long) (regs + 1); - ptr = pack_hex_byte(ptr, GDB_REGID_SP); + *ptr++ = hexchars[GDB_REGID_SP >> 4]; + *ptr++ = hexchars[GDB_REGID_SP & 0xf]; *ptr++ = ':'; ptr = mem2hex(&ssp, ptr, 4, 0); *ptr++ = ';'; @@ -1383,8 +1399,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) /* request repeat of last signal number */ case '?': output_buffer[0] = 'S'; - output_buffer[1] = hex_asc_hi(sigval); - output_buffer[2] = hex_asc_lo(sigval); + output_buffer[1] = hexchars[sigval >> 4]; + output_buffer[2] = hexchars[sigval & 0xf]; output_buffer[3] = 0; break; @@ -1822,8 +1838,8 @@ void gdbstub_exit(int status) gdbstub_busy = 1; output_buffer[0] = 'W'; - output_buffer[1] = hex_asc_hi(status); - output_buffer[2] = hex_asc_lo(status); + output_buffer[1] = hexchars[(status >> 4) & 0x0F]; + output_buffer[2] = hexchars[status & 0x0F]; output_buffer[3] = 0; gdbstub_io_tx_char('$'); @@ -1837,8 +1853,8 @@ void gdbstub_exit(int status) } gdbstub_io_tx_char('#'); - gdbstub_io_tx_char(hex_asc_hi(checksum)); - gdbstub_io_tx_char(hex_asc_lo(checksum)); + gdbstub_io_tx_char(hexchars[checksum >> 4]); + gdbstub_io_tx_char(hexchars[checksum & 0xf]); /* make sure the output is flushed, or else RedBoot might clobber it */ gdbstub_io_tx_flush(); diff --git a/trunk/arch/mn10300/mm/pgtable.c b/trunk/arch/mn10300/mm/pgtable.c index baffc581e031..a477038752ba 100644 --- a/trunk/arch/mn10300/mm/pgtable.c +++ b/trunk/arch/mn10300/mm/pgtable.c @@ -27,6 +27,33 @@ #include #include +void show_mem(void) +{ + unsigned long i; + int free = 0, total = 0, reserved = 0, shared = 0; + + int cached = 0; + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map + i)) + reserved++; + else if (PageSwapCache(mem_map + i)) + cached++; + else if (!page_count(mem_map + i)) + free++; + else + shared += page_count(mem_map + i) - 1; + } + printk(KERN_INFO "%d pages of RAM\n", total); + printk(KERN_INFO "%d free pages\n", free); + printk(KERN_INFO "%d reserved pages\n", reserved); + printk(KERN_INFO "%d pages shared\n", shared); + printk(KERN_INFO "%d pages swap cached\n", cached); +} + /* * Associate a large virtual page frame with a given physical page frame * and protection flags for that frame. pfn is for the base of the page, diff --git a/trunk/arch/parisc/hpux/sys_hpux.c b/trunk/arch/parisc/hpux/sys_hpux.c index 18072e03a019..be255ebb609c 100644 --- a/trunk/arch/parisc/hpux/sys_hpux.c +++ b/trunk/arch/parisc/hpux/sys_hpux.c @@ -210,19 +210,19 @@ static int vfs_statfs_hpux(struct dentry *dentry, struct hpux_statfs *buf) } /* hpux statfs */ -asmlinkage long hpux_statfs(const char __user *pathname, +asmlinkage long hpux_statfs(const char __user *path, struct hpux_statfs __user *buf) { - struct path path; + struct nameidata nd; int error; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (!error) { struct hpux_statfs tmp; - error = vfs_statfs_hpux(path.dentry, &tmp); + error = vfs_statfs_hpux(nd.path.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&path); + path_put(&nd.path); } return error; } diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c index aab76887a842..29a0e039d436 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ b/trunk/arch/powerpc/kernel/machine_kexec.c @@ -48,7 +48,7 @@ void machine_kexec_cleanup(struct kimage *image) * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */ -void machine_kexec(struct kimage *image) +NORET_TYPE void machine_kexec(struct kimage *image) { if (ppc_md.machine_kexec) ppc_md.machine_kexec(image); diff --git a/trunk/arch/powerpc/kernel/rtas_flash.c b/trunk/arch/powerpc/kernel/rtas_flash.c index 149cb112cd1a..09ded5c424a9 100644 --- a/trunk/arch/powerpc/kernel/rtas_flash.c +++ b/trunk/arch/powerpc/kernel/rtas_flash.c @@ -286,7 +286,7 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf, } /* constructor for flash_block_cache */ -void rtas_block_ctor(void *ptr) +void rtas_block_ctor(struct kmem_cache *cache, void *ptr) { memset(ptr, 0, RTAS_BLK_SIZE); } diff --git a/trunk/arch/powerpc/kvm/44x_tlb.c b/trunk/arch/powerpc/kvm/44x_tlb.c index 5a5602da5091..75dff7cfa814 100644 --- a/trunk/arch/powerpc/kvm/44x_tlb.c +++ b/trunk/arch/powerpc/kvm/44x_tlb.c @@ -177,8 +177,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, vcpu->arch.msr & MSR_PR); } -void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, - gva_t eend, u32 asid) +void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid) { unsigned int pid = asid & 0xff; int i; @@ -192,7 +191,7 @@ void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, if (!get_tlb_v(stlbe)) continue; - if (eend < get_tlb_eaddr(stlbe)) + if (eaddr < get_tlb_eaddr(stlbe)) continue; if (eaddr > get_tlb_end(stlbe)) diff --git a/trunk/arch/powerpc/kvm/emulate.c b/trunk/arch/powerpc/kvm/emulate.c index 8c605d0a5488..000097461283 100644 --- a/trunk/arch/powerpc/kvm/emulate.c +++ b/trunk/arch/powerpc/kvm/emulate.c @@ -137,7 +137,7 @@ static int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u32 inst) if (tlbe->word0 & PPC44x_TLB_VALID) { eaddr = get_tlb_eaddr(tlbe); asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid; - kvmppc_mmu_invalidate(vcpu, eaddr, get_tlb_end(tlbe), asid); + kvmppc_mmu_invalidate(vcpu, eaddr, asid); } switch (ws) { diff --git a/trunk/arch/powerpc/mm/hugetlbpage.c b/trunk/arch/powerpc/mm/hugetlbpage.c index ed0aab0208a6..fb42c4dd3217 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage.c +++ b/trunk/arch/powerpc/mm/hugetlbpage.c @@ -113,7 +113,7 @@ static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, unsigned long address, unsigned int psize) { - pte_t *new = kmem_cache_zalloc(huge_pgtable_cache(psize), + pte_t *new = kmem_cache_alloc(huge_pgtable_cache(psize), GFP_KERNEL|__GFP_REPEAT); if (! new) @@ -730,6 +730,11 @@ static int __init hugepage_setup_sz(char *str) } __setup("hugepagesz=", hugepage_setup_sz); +static void zero_ctor(struct kmem_cache *cache, void *addr) +{ + memset(addr, 0, kmem_cache_size(cache)); +} + static int __init hugetlbpage_init(void) { unsigned int psize; @@ -751,7 +756,7 @@ static int __init hugetlbpage_init(void) HUGEPTE_TABLE_SIZE(psize), HUGEPTE_TABLE_SIZE(psize), 0, - NULL); + zero_ctor); if (!huge_pgtable_cache(psize)) panic("hugetlbpage_init(): could not create %s"\ "\n", HUGEPTE_CACHE_NAME(psize)); diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index 4f7df85129d8..a41bc5aa2043 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -136,14 +136,9 @@ static int __init setup_kcore(void) module_init(setup_kcore); #endif -static void pgd_ctor(void *addr) +static void zero_ctor(struct kmem_cache *cache, void *addr) { - memset(addr, 0, PGD_TABLE_SIZE); -} - -static void pmd_ctor(void *addr) -{ - memset(addr, 0, PMD_TABLE_SIZE); + memset(addr, 0, kmem_cache_size(cache)); } static const unsigned int pgtable_cache_size[2] = { @@ -168,8 +163,19 @@ struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; void pgtable_cache_init(void) { - pgtable_cache[0] = kmem_cache_create(pgtable_cache_name[0], PGD_TABLE_SIZE, PGD_TABLE_SIZE, SLAB_PANIC, pgd_ctor); - pgtable_cache[1] = kmem_cache_create(pgtable_cache_name[1], PMD_TABLE_SIZE, PMD_TABLE_SIZE, SLAB_PANIC, pmd_ctor); + int i; + + for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) { + int size = pgtable_cache_size[i]; + const char *name = pgtable_cache_name[i]; + + pr_debug("Allocating page table cache %s (#%d) " + "for size: %08x...\n", name, i, size); + pgtable_cache[i] = kmem_cache_create(name, + size, size, + SLAB_PANIC, + zero_ctor); + } } #ifdef CONFIG_SPARSEMEM_VMEMMAP diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 702691cb9e82..1ca2235f0965 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -186,6 +186,45 @@ walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg, } EXPORT_SYMBOL_GPL(walk_memory_resource); +void show_mem(void) +{ + unsigned long total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; + unsigned long highmem = 0; + struct page *page; + pg_data_t *pgdat; + unsigned long i; + + printk("Mem-info:\n"); + show_free_areas(); + for_each_online_pgdat(pgdat) { + unsigned long flags; + pgdat_resize_lock(pgdat, &flags); + for (i = 0; i < pgdat->node_spanned_pages; i++) { + if (!pfn_valid(pgdat->node_start_pfn + i)) + continue; + page = pgdat_page_nr(pgdat, i); + total++; + if (PageHighMem(page)) + highmem++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + pgdat_resize_unlock(pgdat, &flags); + } + printk("%ld pages of RAM\n", total); +#ifdef CONFIG_HIGHMEM + printk("%ld pages of HIGHMEM\n", highmem); +#endif + printk("%ld reserved pages\n", reserved); + printk("%ld pages shared\n", shared); + printk("%ld pages swap cached\n", cached); +} + /* * Initialize the bootmem system and give it all the memory we * have available. If we are using highmem, we only put the diff --git a/trunk/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/trunk/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 3e7e0f1568ef..0e04f8fb152a 100644 --- a/trunk/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/trunk/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -281,7 +281,7 @@ static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data) dummy_page_da = dma_map_single(bus->phb->parent, dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(bus->phb->parent, dummy_page_da)) { + if (dma_mapping_error(dummy_page_da)) { pr_err("PCIEX:Map dummy page failed.\n"); kfree(dummy_page_va); return -1; diff --git a/trunk/arch/powerpc/platforms/cell/spider-pci.c b/trunk/arch/powerpc/platforms/cell/spider-pci.c index 5122ec145271..418b605ac35a 100644 --- a/trunk/arch/powerpc/platforms/cell/spider-pci.c +++ b/trunk/arch/powerpc/platforms/cell/spider-pci.c @@ -111,7 +111,7 @@ static int __init spiderpci_pci_setup_chip(struct pci_controller *phb, dummy_page_da = dma_map_single(phb->parent, dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(phb->parent, dummy_page_da)) { + if (dma_mapping_error(dummy_page_da)) { pr_err("SPIDER-IOWA:Map dummy page filed.\n"); kfree(dummy_page_va); return -1; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 690ca7b0dcf6..7123472801d9 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -78,7 +78,7 @@ spufs_destroy_inode(struct inode *inode) } static void -spufs_init_once(void *p) +spufs_init_once(struct kmem_cache *cachep, void *p) { struct spufs_inode_info *ei = p; diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index 731d7b157749..1dc7295746da 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -871,7 +871,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off, count = 256 - off; dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); - if (dma_mapping_error(NULL, dma_addr)) + if (dma_mapping_error(dma_addr)) return -ENOMEM; memset(page, 0, off + count); memset(&vsp_cmd, 0, sizeof(vsp_cmd)); diff --git a/trunk/arch/s390/kvm/gaccess.h b/trunk/arch/s390/kvm/gaccess.h index ed60f3a74a85..4e0633c413f3 100644 --- a/trunk/arch/s390/kvm/gaccess.h +++ b/trunk/arch/s390/kvm/gaccess.h @@ -18,11 +18,11 @@ #include static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu, - unsigned long guestaddr) + u64 guestaddr) { - unsigned long prefix = vcpu->arch.sie_block->prefix; - unsigned long origin = vcpu->kvm->arch.guest_origin; - unsigned long memsize = vcpu->kvm->arch.guest_memsize; + u64 prefix = vcpu->arch.sie_block->prefix; + u64 origin = vcpu->kvm->arch.guest_origin; + u64 memsize = vcpu->kvm->arch.guest_memsize; if (guestaddr < 2 * PAGE_SIZE) guestaddr += prefix; @@ -37,7 +37,7 @@ static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu, return (void __user *) guestaddr; } -static inline int get_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr, +static inline int get_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr, u64 *result) { void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); @@ -47,10 +47,10 @@ static inline int get_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr, if (IS_ERR((void __force *) uptr)) return PTR_ERR((void __force *) uptr); - return get_user(*result, (unsigned long __user *) uptr); + return get_user(*result, (u64 __user *) uptr); } -static inline int get_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr, +static inline int get_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr, u32 *result) { void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); @@ -63,7 +63,7 @@ static inline int get_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr, return get_user(*result, (u32 __user *) uptr); } -static inline int get_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr, +static inline int get_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr, u16 *result) { void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); @@ -76,7 +76,7 @@ static inline int get_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr, return get_user(*result, (u16 __user *) uptr); } -static inline int get_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr, +static inline int get_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr, u8 *result) { void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); @@ -87,7 +87,7 @@ static inline int get_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr, return get_user(*result, (u8 __user *) uptr); } -static inline int put_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr, +static inline int put_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr, u64 value) { void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); @@ -100,7 +100,7 @@ static inline int put_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr, return put_user(value, (u64 __user *) uptr); } -static inline int put_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr, +static inline int put_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr, u32 value) { void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); @@ -113,7 +113,7 @@ static inline int put_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr, return put_user(value, (u32 __user *) uptr); } -static inline int put_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr, +static inline int put_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr, u16 value) { void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); @@ -126,7 +126,7 @@ static inline int put_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr, return put_user(value, (u16 __user *) uptr); } -static inline int put_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr, +static inline int put_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr, u8 value) { void __user *uptr = __guestaddr_to_user(vcpu, guestaddr); @@ -138,8 +138,7 @@ static inline int put_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr, } -static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, - unsigned long guestdest, +static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, u64 guestdest, const void *from, unsigned long n) { int rc; @@ -154,12 +153,12 @@ static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, return 0; } -static inline int copy_to_guest(struct kvm_vcpu *vcpu, unsigned long guestdest, +static inline int copy_to_guest(struct kvm_vcpu *vcpu, u64 guestdest, const void *from, unsigned long n) { - unsigned long prefix = vcpu->arch.sie_block->prefix; - unsigned long origin = vcpu->kvm->arch.guest_origin; - unsigned long memsize = vcpu->kvm->arch.guest_memsize; + u64 prefix = vcpu->arch.sie_block->prefix; + u64 origin = vcpu->kvm->arch.guest_origin; + u64 memsize = vcpu->kvm->arch.guest_memsize; if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE)) goto slowpath; @@ -190,8 +189,7 @@ static inline int copy_to_guest(struct kvm_vcpu *vcpu, unsigned long guestdest, } static inline int __copy_from_guest_slow(struct kvm_vcpu *vcpu, void *to, - unsigned long guestsrc, - unsigned long n) + u64 guestsrc, unsigned long n) { int rc; unsigned long i; @@ -206,11 +204,11 @@ static inline int __copy_from_guest_slow(struct kvm_vcpu *vcpu, void *to, } static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to, - unsigned long guestsrc, unsigned long n) + u64 guestsrc, unsigned long n) { - unsigned long prefix = vcpu->arch.sie_block->prefix; - unsigned long origin = vcpu->kvm->arch.guest_origin; - unsigned long memsize = vcpu->kvm->arch.guest_memsize; + u64 prefix = vcpu->arch.sie_block->prefix; + u64 origin = vcpu->kvm->arch.guest_origin; + u64 memsize = vcpu->kvm->arch.guest_memsize; if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE)) goto slowpath; @@ -240,12 +238,11 @@ static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to, return __copy_from_guest_slow(vcpu, to, guestsrc, n); } -static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, - unsigned long guestdest, +static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, u64 guestdest, const void *from, unsigned long n) { - unsigned long origin = vcpu->kvm->arch.guest_origin; - unsigned long memsize = vcpu->kvm->arch.guest_memsize; + u64 origin = vcpu->kvm->arch.guest_origin; + u64 memsize = vcpu->kvm->arch.guest_memsize; if (guestdest + n > memsize) return -EFAULT; @@ -259,11 +256,10 @@ static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, } static inline int copy_from_guest_absolute(struct kvm_vcpu *vcpu, void *to, - unsigned long guestsrc, - unsigned long n) + u64 guestsrc, unsigned long n) { - unsigned long origin = vcpu->kvm->arch.guest_origin; - unsigned long memsize = vcpu->kvm->arch.guest_memsize; + u64 origin = vcpu->kvm->arch.guest_origin; + u64 memsize = vcpu->kvm->arch.guest_memsize; if (guestsrc + n > memsize) return -EFAULT; diff --git a/trunk/arch/s390/kvm/intercept.c b/trunk/arch/s390/kvm/intercept.c index 61236102203e..47a0b642174c 100644 --- a/trunk/arch/s390/kvm/intercept.c +++ b/trunk/arch/s390/kvm/intercept.c @@ -20,7 +20,7 @@ #include "kvm-s390.h" #include "gaccess.h" -static int handle_lctlg(struct kvm_vcpu *vcpu) +static int handle_lctg(struct kvm_vcpu *vcpu) { int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; int reg3 = vcpu->arch.sie_block->ipa & 0x000f; @@ -30,7 +30,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) u64 useraddr; int reg, rc; - vcpu->stat.instruction_lctlg++; + vcpu->stat.instruction_lctg++; if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f) return -ENOTSUPP; @@ -38,12 +38,9 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) if (base2) useraddr += vcpu->arch.guest_gprs[base2]; - if (useraddr & 7) - return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - reg = reg1; - VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2, + VCPU_EVENT(vcpu, 5, "lctg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2, disp2); do { @@ -77,9 +74,6 @@ static int handle_lctl(struct kvm_vcpu *vcpu) if (base2) useraddr += vcpu->arch.guest_gprs[base2]; - if (useraddr & 3) - return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2, disp2); @@ -105,7 +99,7 @@ static intercept_handler_t instruction_handlers[256] = { [0xae] = kvm_s390_handle_sigp, [0xb2] = kvm_s390_handle_priv, [0xb7] = handle_lctl, - [0xeb] = handle_lctlg, + [0xeb] = handle_lctg, }; static int handle_noop(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/s390/kvm/interrupt.c b/trunk/arch/s390/kvm/interrupt.c index 2960702b4824..11230b0db957 100644 --- a/trunk/arch/s390/kvm/interrupt.c +++ b/trunk/arch/s390/kvm/interrupt.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "kvm-s390.h" #include "gaccess.h" @@ -247,10 +246,15 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu, default: BUG(); } + if (exception) { - printk("kvm: The guest lowcore is not mapped during interrupt " - "delivery, killing userspace\n"); - do_exit(SIGKILL); + VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering" + " interrupt"); + kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); + if (inti->type == KVM_S390_PROGRAM_INT) { + printk(KERN_WARNING "kvm: recursive program check\n"); + BUG(); + } } } @@ -273,11 +277,14 @@ static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu) __LC_EXT_NEW_PSW, sizeof(psw_t)); if (rc == -EFAULT) exception = 1; + if (exception) { - printk("kvm: The guest lowcore is not mapped during interrupt " - "delivery, killing userspace\n"); - do_exit(SIGKILL); + VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering" \ + " ckc interrupt"); + kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); + return 0; } + return 1; } diff --git a/trunk/arch/s390/kvm/kvm-s390.c b/trunk/arch/s390/kvm/kvm-s390.c index 8b00eb2ddf57..1782cbcd2829 100644 --- a/trunk/arch/s390/kvm/kvm-s390.c +++ b/trunk/arch/s390/kvm/kvm-s390.c @@ -39,7 +39,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "exit_instruction", VCPU_STAT(exit_instruction) }, { "exit_program_interruption", VCPU_STAT(exit_program_interruption) }, { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) }, - { "instruction_lctlg", VCPU_STAT(instruction_lctlg) }, + { "instruction_lctg", VCPU_STAT(instruction_lctg) }, { "instruction_lctl", VCPU_STAT(instruction_lctl) }, { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) }, { "deliver_service_signal", VCPU_STAT(deliver_service_signal) }, @@ -112,12 +112,7 @@ long kvm_arch_dev_ioctl(struct file *filp, int kvm_dev_ioctl_check_extension(long ext) { - switch (ext) { - case KVM_CAP_USER_MEMORY: - return 1; - default: - return 0; - } + return 0; } /* Section: vm related */ diff --git a/trunk/arch/s390/kvm/sigp.c b/trunk/arch/s390/kvm/sigp.c index 170392687ce0..5a556114eaa5 100644 --- a/trunk/arch/s390/kvm/sigp.c +++ b/trunk/arch/s390/kvm/sigp.c @@ -43,8 +43,7 @@ #define SIGP_STAT_RECEIVER_CHECK 0x00000001UL -static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, - unsigned long *reg) +static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, u64 *reg) { struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; int rc; @@ -168,7 +167,7 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) } static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, - unsigned long *reg) + u64 *reg) { struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; struct kvm_s390_local_interrupt *li; diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index 4993b0f594eb..388cc7420055 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -42,6 +42,38 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); +void show_mem(void) +{ + unsigned long i, total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; + unsigned long flags; + struct page *page; + pg_data_t *pgdat; + + printk("Mem-info:\n"); + show_free_areas(); + for_each_online_pgdat(pgdat) { + pgdat_resize_lock(pgdat, &flags); + for (i = 0; i < pgdat->node_spanned_pages; i++) { + if (!pfn_valid(pgdat->node_start_pfn + i)) + continue; + page = pfn_to_page(pgdat->node_start_pfn + i); + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + pgdat_resize_unlock(pgdat, &flags); + } + printk("%ld pages of RAM\n", total); + printk("%ld reserved pages\n", reserved); + printk("%ld pages shared\n", shared); + printk("%ld pages swap cached\n", cached); +} + /* * paging_init() sets up the page tables */ diff --git a/trunk/arch/sh/kernel/machine_kexec.c b/trunk/arch/sh/kernel/machine_kexec.c index ec1eadce4aaa..5c17de51987e 100644 --- a/trunk/arch/sh/kernel/machine_kexec.c +++ b/trunk/arch/sh/kernel/machine_kexec.c @@ -70,7 +70,7 @@ static void kexec_info(struct kimage *image) * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */ -void machine_kexec(struct kimage *image) +NORET_TYPE void machine_kexec(struct kimage *image) { unsigned long page_list; diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index b75a7acd62fb..d652d375eb1e 100644 --- a/trunk/arch/sh/mm/init.c +++ b/trunk/arch/sh/mm/init.c @@ -25,6 +25,47 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD]; unsigned long cached_to_uncached = 0; +void show_mem(void) +{ + int total = 0, reserved = 0, free = 0; + int shared = 0, cached = 0, slab = 0; + pg_data_t *pgdat; + + printk("Mem-info:\n"); + show_free_areas(); + + for_each_online_pgdat(pgdat) { + unsigned long flags, i; + + pgdat_resize_lock(pgdat, &flags); + for (i = 0; i < pgdat->node_spanned_pages; i++) { + struct page *page = pgdat_page_nr(pgdat, i); + 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; + } + pgdat_resize_unlock(pgdat, &flags); + } + + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk("%d pages of RAM\n", total); + printk("%d free pages\n", free); + printk("%d reserved pages\n", reserved); + printk("%d slab pages\n", slab); + printk("%d pages shared\n", shared); + printk("%d pages swap cached\n", cached); + printk(KERN_INFO "Total of %ld pages in page table cache\n", + quicklist_total_size()); +} + #ifdef CONFIG_MMU static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) { diff --git a/trunk/arch/sh/mm/pmb.c b/trunk/arch/sh/mm/pmb.c index 46911bcbf17b..0b0ec6e04753 100644 --- a/trunk/arch/sh/mm/pmb.c +++ b/trunk/arch/sh/mm/pmb.c @@ -293,7 +293,7 @@ void pmb_unmap(unsigned long addr) } while (pmbe); } -static void pmb_cache_ctor(void *pmb) +static void pmb_cache_ctor(struct kmem_cache *cachep, void *pmb) { struct pmb_entry *pmbe = pmb; diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index 4e821b3ecb03..713297473951 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -392,6 +392,51 @@ void __kprobes flush_icache_range(unsigned long start, unsigned long end) } } +void show_mem(void) +{ + unsigned long total = 0, reserved = 0; + unsigned long shared = 0, cached = 0; + pg_data_t *pgdat; + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(); + printk(KERN_INFO "Free swap: %6ldkB\n", + nr_swap_pages << (PAGE_SHIFT-10)); + for_each_online_pgdat(pgdat) { + unsigned long i, flags; + + pgdat_resize_lock(pgdat, &flags); + for (i = 0; i < pgdat->node_spanned_pages; i++) { + struct page *page = pgdat_page_nr(pgdat, i); + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + pgdat_resize_unlock(pgdat, &flags); + } + + printk(KERN_INFO "%lu pages of RAM\n", total); + printk(KERN_INFO "%lu reserved pages\n", reserved); + printk(KERN_INFO "%lu pages shared\n", shared); + printk(KERN_INFO "%lu pages swap cached\n", cached); + + printk(KERN_INFO "%lu pages dirty\n", + global_page_state(NR_FILE_DIRTY)); + printk(KERN_INFO "%lu pages writeback\n", + global_page_state(NR_WRITEBACK)); + printk(KERN_INFO "%lu pages mapped\n", + global_page_state(NR_FILE_MAPPED)); + printk(KERN_INFO "%lu pages slab\n", + global_page_state(NR_SLAB_RECLAIMABLE) + + global_page_state(NR_SLAB_UNRECLAIMABLE)); + printk(KERN_INFO "%lu pages pagetables\n", + global_page_state(NR_PAGETABLE)); +} + void mmu_info(struct seq_file *m) { if (tlb_type == cheetah) diff --git a/trunk/arch/um/kernel/mem.c b/trunk/arch/um/kernel/mem.c index 61d7e6138ff5..e2274ef3155d 100644 --- a/trunk/arch/um/kernel/mem.c +++ b/trunk/arch/um/kernel/mem.c @@ -264,6 +264,37 @@ void free_initrd_mem(unsigned long start, unsigned long end) } #endif +void show_mem(void) +{ + int pfn, total = 0, reserved = 0; + int shared = 0, cached = 0; + int high_mem = 0; + struct page *page; + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(); + printk(KERN_INFO "Free swap: %6ldkB\n", + nr_swap_pages<<(PAGE_SHIFT-10)); + pfn = max_mapnr; + while (pfn-- > 0) { + page = pfn_to_page(pfn); + total++; + if (PageHighMem(page)) + high_mem++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + printk(KERN_INFO "%d pages of RAM\n", total); + printk(KERN_INFO "%d pages of HIGHMEM\n", high_mem); + printk(KERN_INFO "%d reserved pages\n", reserved); + printk(KERN_INFO "%d pages shared\n", shared); + printk(KERN_INFO "%d pages swap cached\n", cached); +} + /* Allocate and free page tables. */ pgd_t *pgd_alloc(struct mm_struct *mm) diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index b6fa2877b173..e3cba0b45600 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -22,9 +22,8 @@ config X86 select HAVE_IDE select HAVE_OPROFILE select HAVE_IOREMAP_PROT - select HAVE_GET_USER_PAGES_FAST select HAVE_KPROBES - select ARCH_WANT_OPTIONAL_GPIOLIB + select ARCH_WANT_OPTIONAL_GPIOLIB if !X86_RDC321X select HAVE_KRETPROBES select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE @@ -333,6 +332,20 @@ config X86_BIGSMP endif +config X86_RDC321X + bool "RDC R-321x SoC" + depends on X86_32 + select M486 + select X86_REBOOTFIXUPS + select GENERIC_GPIO + select LEDS_CLASS + select LEDS_GPIO + select NEW_LEDS + help + This option is needed for RDC R-321x system-on-chip, also known + as R-8610-(G). + If you don't have one of these chips, you should say N here. + config X86_VSMP bool "Support for ScaleMP vSMP" select PARAVIRT @@ -356,16 +369,6 @@ config X86_VISWS A kernel compiled for the Visual Workstation will run on general PCs as well. See for details. -config X86_RDC321X - bool "RDC R-321x SoC" - depends on X86_32 - select M486 - select X86_REBOOTFIXUPS - help - This option is needed for RDC R-321x system-on-chip, also known - as R-8610-(G). - If you don't have one of these chips, you should say N here. - config SCHED_NO_NO_OMIT_FRAME_POINTER def_bool y prompt "Single-depth WCHAN output" @@ -1276,14 +1279,6 @@ config CRASH_DUMP (CONFIG_RELOCATABLE=y). For more details see Documentation/kdump/kdump.txt -config KEXEC_JUMP - bool "kexec jump (EXPERIMENTAL)" - depends on EXPERIMENTAL - depends on KEXEC && HIBERNATION && X86_32 - help - Jump between original kernel and kexeced kernel and invoke - code in physical address mode via KEXEC - config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) default "0x1000000" if X86_NUMAQ diff --git a/trunk/arch/x86/Makefile b/trunk/arch/x86/Makefile index f5631da585b6..919ce21ea654 100644 --- a/trunk/arch/x86/Makefile +++ b/trunk/arch/x86/Makefile @@ -118,6 +118,11 @@ mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic fcore-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/ mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default/ +# RDC R-321x subarch support +mflags-$(CONFIG_X86_RDC321X) := -Iinclude/asm-x86/mach-rdc321x +mcore-$(CONFIG_X86_RDC321X) := arch/x86/mach-default/ +core-$(CONFIG_X86_RDC321X) += arch/x86/mach-rdc321x/ + # default subarch .h files mflags-y += -Iinclude/asm-x86/mach-default diff --git a/trunk/arch/x86/ia32/ia32_aout.c b/trunk/arch/x86/ia32/ia32_aout.c index a0e1dbe67dc1..58cccb6483b0 100644 --- a/trunk/arch/x86/ia32/ia32_aout.c +++ b/trunk/arch/x86/ia32/ia32_aout.c @@ -441,6 +441,12 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0; set_fs(USER_DS); + if (unlikely(current->ptrace & PT_PTRACED)) { + if (current->ptrace & PT_TRACE_EXEC) + ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP); + else + send_sig(SIGTRAP, current, 0); + } return 0; } diff --git a/trunk/arch/x86/kernel/amd_iommu.c b/trunk/arch/x86/kernel/amd_iommu.c index 74697408576f..c25210e6ac88 100644 --- a/trunk/arch/x86/kernel/amd_iommu.c +++ b/trunk/arch/x86/kernel/amd_iommu.c @@ -667,7 +667,7 @@ static int get_device_resources(struct device *dev, _bdf = calc_devid(pcidev->bus->number, pcidev->devfn); /* device not translated by any IOMMU in the system? */ - if (_bdf > amd_iommu_last_bdf) { + if (_bdf >= amd_iommu_last_bdf) { *iommu = NULL; *domain = NULL; *bdf = 0xffff; @@ -1085,7 +1085,7 @@ void prealloc_protection_domains(void) while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { devid = (dev->bus->number << 8) | dev->devfn; - if (devid > amd_iommu_last_bdf) + if (devid >= amd_iommu_last_bdf) continue; devid = amd_iommu_alias_table[devid]; if (domain_for_device(devid)) diff --git a/trunk/arch/x86/kernel/amd_iommu_init.c b/trunk/arch/x86/kernel/amd_iommu_init.c index d9a9da597e79..c9d8ff2eb130 100644 --- a/trunk/arch/x86/kernel/amd_iommu_init.c +++ b/trunk/arch/x86/kernel/amd_iommu_init.c @@ -732,7 +732,7 @@ static int __init init_exclusion_range(struct ivmd_header *m) set_device_exclusion_range(m->devid, m); break; case ACPI_IVMD_TYPE_ALL: - for (i = 0; i <= amd_iommu_last_bdf; ++i) + for (i = 0; i < amd_iommu_last_bdf; ++i) set_device_exclusion_range(i, m); break; case ACPI_IVMD_TYPE_RANGE: @@ -934,7 +934,7 @@ int __init amd_iommu_init(void) /* * let all alias entries point to itself */ - for (i = 0; i <= amd_iommu_last_bdf; ++i) + for (i = 0; i < amd_iommu_last_bdf; ++i) amd_iommu_alias_table[i] = i; /* diff --git a/trunk/arch/x86/kernel/machine_kexec_32.c b/trunk/arch/x86/kernel/machine_kexec_32.c index 9fe478d98406..8864230d55af 100644 --- a/trunk/arch/x86/kernel/machine_kexec_32.c +++ b/trunk/arch/x86/kernel/machine_kexec_32.c @@ -22,7 +22,6 @@ #include #include #include -#include #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) static u32 kexec_pgd[1024] PAGE_ALIGNED; @@ -86,12 +85,10 @@ static void load_segments(void) * reboot code buffer to allow us to avoid allocations * later. * - * Make control page executable. + * Currently nothing. */ int machine_kexec_prepare(struct kimage *image) { - if (nx_enabled) - set_pages_x(image->control_code_page, 1); return 0; } @@ -101,48 +98,27 @@ int machine_kexec_prepare(struct kimage *image) */ void machine_kexec_cleanup(struct kimage *image) { - if (nx_enabled) - set_pages_nx(image->control_code_page, 1); } /* * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */ -void machine_kexec(struct kimage *image) +NORET_TYPE void machine_kexec(struct kimage *image) { unsigned long page_list[PAGES_NR]; void *control_page; - asmlinkage unsigned long - (*relocate_kernel_ptr)(unsigned long indirection_page, - unsigned long control_page, - unsigned long start_address, - unsigned int has_pae, - unsigned int preserve_context); tracer_disable(); /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); - if (image->preserve_context) { -#ifdef CONFIG_X86_IO_APIC - /* We need to put APICs in legacy mode so that we can - * get timer interrupts in second kernel. kexec/kdump - * paths already have calls to disable_IO_APIC() in - * one form or other. kexec jump path also need - * one. - */ - disable_IO_APIC(); -#endif - } - control_page = page_address(image->control_code_page); - memcpy(control_page, relocate_kernel, PAGE_SIZE/2); + memcpy(control_page, relocate_kernel, PAGE_SIZE); - relocate_kernel_ptr = control_page; page_list[PA_CONTROL_PAGE] = __pa(control_page); - page_list[VA_CONTROL_PAGE] = (unsigned long)control_page; + page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; page_list[PA_PGD] = __pa(kexec_pgd); page_list[VA_PGD] = (unsigned long)kexec_pgd; #ifdef CONFIG_X86_PAE @@ -155,7 +131,6 @@ void machine_kexec(struct kimage *image) page_list[VA_PTE_0] = (unsigned long)kexec_pte0; page_list[PA_PTE_1] = __pa(kexec_pte1); page_list[VA_PTE_1] = (unsigned long)kexec_pte1; - page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page) << PAGE_SHIFT); /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is @@ -174,10 +149,8 @@ void machine_kexec(struct kimage *image) set_idt(phys_to_virt(0),0); /* now call it */ - image->start = relocate_kernel_ptr((unsigned long)image->head, - (unsigned long)page_list, - image->start, cpu_has_pae, - image->preserve_context); + relocate_kernel((unsigned long)image->head, (unsigned long)page_list, + image->start, cpu_has_pae); } void arch_crash_save_vmcoreinfo(void) diff --git a/trunk/arch/x86/kernel/machine_kexec_64.c b/trunk/arch/x86/kernel/machine_kexec_64.c index c43caa3a91f3..9dd9262693a3 100644 --- a/trunk/arch/x86/kernel/machine_kexec_64.c +++ b/trunk/arch/x86/kernel/machine_kexec_64.c @@ -181,7 +181,7 @@ void machine_kexec_cleanup(struct kimage *image) * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */ -void machine_kexec(struct kimage *image) +NORET_TYPE void machine_kexec(struct kimage *image) { unsigned long page_list[PAGES_NR]; void *control_page; diff --git a/trunk/arch/x86/kernel/pci-calgary_64.c b/trunk/arch/x86/kernel/pci-calgary_64.c index b67a4b1d4eae..19e7fc7c2c4f 100644 --- a/trunk/arch/x86/kernel/pci-calgary_64.c +++ b/trunk/arch/x86/kernel/pci-calgary_64.c @@ -37,7 +37,6 @@ #include #include #include - #include #include #include @@ -414,6 +413,22 @@ static void calgary_unmap_sg(struct device *dev, } } +static int calgary_nontranslate_map_sg(struct device* dev, + struct scatterlist *sg, int nelems, int direction) +{ + struct scatterlist *s; + int i; + + for_each_sg(sg, s, nelems, i) { + struct page *p = sg_page(s); + + BUG_ON(!p); + s->dma_address = virt_to_bus(sg_virt(s)); + s->dma_length = s->length; + } + return nelems; +} + static int calgary_map_sg(struct device *dev, struct scatterlist *sg, int nelems, int direction) { @@ -424,6 +439,9 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, unsigned long entry; int i; + if (!translation_enabled(tbl)) + return calgary_nontranslate_map_sg(dev, sg, nelems, direction); + for_each_sg(sg, s, nelems, i) { BUG_ON(!sg_page(s)); @@ -459,6 +477,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, size_t size, int direction) { + dma_addr_t dma_handle = bad_dma_address; void *vaddr = phys_to_virt(paddr); unsigned long uaddr; unsigned int npages; @@ -467,7 +486,12 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, uaddr = (unsigned long)vaddr; npages = num_dma_pages(uaddr, size); - return iommu_alloc(dev, tbl, vaddr, npages, direction); + if (translation_enabled(tbl)) + dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction); + else + dma_handle = virt_to_bus(vaddr); + + return dma_handle; } static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, @@ -476,6 +500,9 @@ static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, struct iommu_table *tbl = find_iommu_table(dev); unsigned int npages; + if (!translation_enabled(tbl)) + return; + npages = num_dma_pages(dma_handle, size); iommu_free(tbl, dma_handle, npages); } @@ -498,12 +525,18 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size, goto error; memset(ret, 0, size); - /* set up tces to cover the allocated range */ - mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL); - if (mapping == bad_dma_address) - goto free; - *dma_handle = mapping; + if (translation_enabled(tbl)) { + /* set up tces to cover the allocated range */ + mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL); + if (mapping == bad_dma_address) + goto free; + + *dma_handle = mapping; + } else /* non translated slot */ + *dma_handle = virt_to_bus(ret); + return ret; + free: free_pages((unsigned long)ret, get_order(size)); ret = NULL; @@ -511,7 +544,7 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size, return ret; } -static struct dma_mapping_ops calgary_dma_ops = { +static const struct dma_mapping_ops calgary_dma_ops = { .alloc_coherent = calgary_alloc_coherent, .map_single = calgary_map_single, .unmap_single = calgary_unmap_single, @@ -1208,16 +1241,6 @@ static int __init calgary_init(void) goto error; } while (1); - dev = NULL; - for_each_pci_dev(dev) { - struct iommu_table *tbl; - - tbl = find_iommu_table(&dev->dev); - - if (translation_enabled(tbl)) - dev->dev.archdata.dma_ops = &calgary_dma_ops; - } - return ret; error: @@ -1239,7 +1262,6 @@ 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() */ - dev->dev.archdata.dma_ops = NULL; } while (1); return ret; @@ -1481,10 +1503,6 @@ void __init detect_calgary(void) printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, " "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size, debugging ? "enabled" : "disabled"); - - /* swiotlb for devices that aren't behind the Calgary. */ - if (max_pfn > MAX_DMA32_PFN) - swiotlb = 1; } return; @@ -1501,7 +1519,7 @@ int __init calgary_iommu_init(void) { int ret; - if (no_iommu || (swiotlb && !calgary_detected)) + if (no_iommu || swiotlb) return -ENODEV; if (!calgary_detected) @@ -1514,14 +1532,15 @@ int __init calgary_iommu_init(void) if (ret) { printk(KERN_ERR "PCI-DMA: Calgary init failed %d, " "falling back to no_iommu\n", ret); + if (max_pfn > MAX_DMA32_PFN) + printk(KERN_ERR "WARNING more than 4GB of memory, " + "32bit PCI may malfunction.\n"); return ret; } force_iommu = 1; bad_dma_address = 0x0; - /* dma_ops is set to swiotlb or nommu */ - if (!dma_ops) - dma_ops = &nommu_dma_ops; + dma_ops = &calgary_dma_ops; return 0; } diff --git a/trunk/arch/x86/kernel/pci-dma.c b/trunk/arch/x86/kernel/pci-dma.c index 37544123896d..cbecb05551bb 100644 --- a/trunk/arch/x86/kernel/pci-dma.c +++ b/trunk/arch/x86/kernel/pci-dma.c @@ -11,7 +11,7 @@ static int forbid_dac __read_mostly; -struct dma_mapping_ops *dma_ops; +const struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); static int iommu_sac_force __read_mostly; @@ -312,8 +312,6 @@ static int dma_release_coherent(struct device *dev, int order, void *vaddr) int dma_supported(struct device *dev, u64 mask) { - struct dma_mapping_ops *ops = get_dma_ops(dev); - #ifdef CONFIG_PCI if (mask > 0xffffffff && forbid_dac > 0) { dev_info(dev, "PCI: Disallowing DAC for device\n"); @@ -321,8 +319,8 @@ int dma_supported(struct device *dev, u64 mask) } #endif - if (ops->dma_supported) - return ops->dma_supported(dev, mask); + if (dma_ops->dma_supported) + return dma_ops->dma_supported(dev, mask); /* Copied from i386. Doesn't make much sense, because it will only work for pci_alloc_coherent. @@ -369,7 +367,6 @@ void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) { - struct dma_mapping_ops *ops = get_dma_ops(dev); void *memory = NULL; struct page *page; unsigned long dma_mask = 0; @@ -438,8 +435,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, /* Let low level make its own zone decisions */ gfp &= ~(GFP_DMA32|GFP_DMA); - if (ops->alloc_coherent) - return ops->alloc_coherent(dev, size, + if (dma_ops->alloc_coherent) + return dma_ops->alloc_coherent(dev, size, dma_handle, gfp); return NULL; } @@ -451,14 +448,14 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, } } - if (ops->alloc_coherent) { + if (dma_ops->alloc_coherent) { free_pages((unsigned long)memory, get_order(size)); gfp &= ~(GFP_DMA|GFP_DMA32); - return ops->alloc_coherent(dev, size, dma_handle, gfp); + return dma_ops->alloc_coherent(dev, size, dma_handle, gfp); } - if (ops->map_simple) { - *dma_handle = ops->map_simple(dev, virt_to_phys(memory), + if (dma_ops->map_simple) { + *dma_handle = dma_ops->map_simple(dev, virt_to_phys(memory), size, PCI_DMA_BIDIRECTIONAL); if (*dma_handle != bad_dma_address) @@ -480,14 +477,12 @@ EXPORT_SYMBOL(dma_alloc_coherent); void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t bus) { - struct dma_mapping_ops *ops = get_dma_ops(dev); - int order = get_order(size); WARN_ON(irqs_disabled()); /* for portability */ if (dma_release_coherent(dev, order, vaddr)) return; - if (ops->unmap_single) - ops->unmap_single(dev, bus, size, 0); + if (dma_ops->unmap_single) + dma_ops->unmap_single(dev, bus, size, 0); free_pages((unsigned long)vaddr, order); } EXPORT_SYMBOL(dma_free_coherent); diff --git a/trunk/arch/x86/kernel/pci-gart_64.c b/trunk/arch/x86/kernel/pci-gart_64.c index 744126e64950..df5f142657d2 100644 --- a/trunk/arch/x86/kernel/pci-gart_64.c +++ b/trunk/arch/x86/kernel/pci-gart_64.c @@ -692,7 +692,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info) extern int agp_amd64_init(void); -static struct dma_mapping_ops gart_dma_ops = { +static const struct dma_mapping_ops gart_dma_ops = { + .mapping_error = NULL, .map_single = gart_map_single, .map_simple = gart_map_simple, .unmap_single = gart_unmap_single, diff --git a/trunk/arch/x86/kernel/pci-nommu.c b/trunk/arch/x86/kernel/pci-nommu.c index 3f91f71cdc3e..792b9179eff3 100644 --- a/trunk/arch/x86/kernel/pci-nommu.c +++ b/trunk/arch/x86/kernel/pci-nommu.c @@ -72,9 +72,21 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, return nents; } -struct dma_mapping_ops nommu_dma_ops = { +/* Make sure we keep the same behaviour */ +static int nommu_mapping_error(dma_addr_t dma_addr) +{ +#ifdef CONFIG_X86_32 + return 0; +#else + return (dma_addr == bad_dma_address); +#endif +} + + +const struct dma_mapping_ops nommu_dma_ops = { .map_single = nommu_map_single, .map_sg = nommu_map_sg, + .mapping_error = nommu_mapping_error, .is_phys = 1, }; diff --git a/trunk/arch/x86/kernel/pci-swiotlb_64.c b/trunk/arch/x86/kernel/pci-swiotlb_64.c index c4ce0332759e..20df839b9c20 100644 --- a/trunk/arch/x86/kernel/pci-swiotlb_64.c +++ b/trunk/arch/x86/kernel/pci-swiotlb_64.c @@ -18,7 +18,7 @@ swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); } -struct dma_mapping_ops swiotlb_dma_ops = { +const struct dma_mapping_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, .alloc_coherent = swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, diff --git a/trunk/arch/x86/kernel/relocate_kernel_32.S b/trunk/arch/x86/kernel/relocate_kernel_32.S index 703310a99023..c30fe25d470d 100644 --- a/trunk/arch/x86/kernel/relocate_kernel_32.S +++ b/trunk/arch/x86/kernel/relocate_kernel_32.S @@ -20,44 +20,11 @@ #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) #define PAE_PGD_ATTR (_PAGE_PRESENT) -/* control_page + PAGE_SIZE/2 ~ control_page + PAGE_SIZE * 3/4 are - * used to save some data for jumping back - */ -#define DATA(offset) (PAGE_SIZE/2+(offset)) - -/* Minimal CPU state */ -#define ESP DATA(0x0) -#define CR0 DATA(0x4) -#define CR3 DATA(0x8) -#define CR4 DATA(0xc) - -/* other data */ -#define CP_VA_CONTROL_PAGE DATA(0x10) -#define CP_PA_PGD DATA(0x14) -#define CP_PA_SWAP_PAGE DATA(0x18) -#define CP_PA_BACKUP_PAGES_MAP DATA(0x1c) - .text .align PAGE_SIZE .globl relocate_kernel relocate_kernel: - /* Save the CPU context, used for jumping back */ - - pushl %ebx - pushl %esi - pushl %edi - pushl %ebp - pushf - - movl 20+8(%esp), %ebp /* list of pages */ - movl PTR(VA_CONTROL_PAGE)(%ebp), %edi - movl %esp, ESP(%edi) - movl %cr0, %eax - movl %eax, CR0(%edi) - movl %cr3, %eax - movl %eax, CR3(%edi) - movl %cr4, %eax - movl %eax, CR4(%edi) + movl 8(%esp), %ebp /* list of pages */ #ifdef CONFIG_X86_PAE /* map the control page at its virtual address */ @@ -171,25 +138,15 @@ relocate_kernel: relocate_new_kernel: /* read the arguments and say goodbye to the stack */ - movl 20+4(%esp), %ebx /* page_list */ - movl 20+8(%esp), %ebp /* list of pages */ - movl 20+12(%esp), %edx /* start address */ - movl 20+16(%esp), %ecx /* cpu_has_pae */ - movl 20+20(%esp), %esi /* preserve_context */ + movl 4(%esp), %ebx /* page_list */ + movl 8(%esp), %ebp /* list of pages */ + movl 12(%esp), %edx /* start address */ + movl 16(%esp), %ecx /* cpu_has_pae */ /* zero out flags, and disable interrupts */ pushl $0 popfl - /* save some information for jumping back */ - movl PTR(VA_CONTROL_PAGE)(%ebp), %edi - movl %edi, CP_VA_CONTROL_PAGE(%edi) - movl PTR(PA_PGD)(%ebp), %eax - movl %eax, CP_PA_PGD(%edi) - movl PTR(PA_SWAP_PAGE)(%ebp), %eax - movl %eax, CP_PA_SWAP_PAGE(%edi) - movl %ebx, CP_PA_BACKUP_PAGES_MAP(%edi) - /* get physical address of control page now */ /* this is impossible after page table switch */ movl PTR(PA_CONTROL_PAGE)(%ebp), %edi @@ -240,90 +197,8 @@ identity_mapped: xorl %eax, %eax movl %eax, %cr3 - movl CP_PA_SWAP_PAGE(%edi), %eax - pushl %eax - pushl %ebx - call swap_pages - addl $8, %esp - - /* To be certain of avoiding problems with self-modifying code - * I need to execute a serializing instruction here. - * So I flush the TLB, it's handy, and not processor dependent. - */ - xorl %eax, %eax - movl %eax, %cr3 - - /* set all of the registers to known values */ - /* leave %esp alone */ - - testl %esi, %esi - jnz 1f - xorl %edi, %edi - xorl %eax, %eax - xorl %ebx, %ebx - xorl %ecx, %ecx - xorl %edx, %edx - xorl %esi, %esi - xorl %ebp, %ebp - ret -1: - popl %edx - movl CP_PA_SWAP_PAGE(%edi), %esp - addl $PAGE_SIZE, %esp -2: - call *%edx - - /* get the re-entry point of the peer system */ - movl 0(%esp), %ebp - call 1f -1: - popl %ebx - subl $(1b - relocate_kernel), %ebx - movl CP_VA_CONTROL_PAGE(%ebx), %edi - lea PAGE_SIZE(%ebx), %esp - movl CP_PA_SWAP_PAGE(%ebx), %eax - movl CP_PA_BACKUP_PAGES_MAP(%ebx), %edx - pushl %eax - pushl %edx - call swap_pages - addl $8, %esp - movl CP_PA_PGD(%ebx), %eax - movl %eax, %cr3 - movl %cr0, %eax - orl $(1<<31), %eax - movl %eax, %cr0 - lea PAGE_SIZE(%edi), %esp - movl %edi, %eax - addl $(virtual_mapped - relocate_kernel), %eax - pushl %eax - ret - -virtual_mapped: - movl CR4(%edi), %eax - movl %eax, %cr4 - movl CR3(%edi), %eax - movl %eax, %cr3 - movl CR0(%edi), %eax - movl %eax, %cr0 - movl ESP(%edi), %esp - movl %ebp, %eax - - popf - popl %ebp - popl %edi - popl %esi - popl %ebx - ret - /* Do the copies */ -swap_pages: - movl 8(%esp), %edx - movl 4(%esp), %ecx - pushl %ebp - pushl %ebx - pushl %edi - pushl %esi - movl %ecx, %ebx + movl %ebx, %ecx jmp 1f 0: /* top, read another word from the indirection page */ @@ -351,28 +226,27 @@ swap_pages: movl %ecx, %esi /* For every source page do a copy */ andl $0xfffff000, %esi - movl %edi, %eax - movl %esi, %ebp - - movl %edx, %edi movl $1024, %ecx rep ; movsl + jmp 0b - movl %ebp, %edi - movl %eax, %esi - movl $1024, %ecx - rep ; movsl +3: - movl %eax, %edi - movl %edx, %esi - movl $1024, %ecx - rep ; movsl + /* To be certain of avoiding problems with self-modifying code + * I need to execute a serializing instruction here. + * So I flush the TLB, it's handy, and not processor dependent. + */ + xorl %eax, %eax + movl %eax, %cr3 - lea PAGE_SIZE(%ebp), %esi - jmp 0b -3: - popl %esi - popl %edi - popl %ebx - popl %ebp + /* set all of the registers to known values */ + /* leave %esp alone */ + + xorl %eax, %eax + xorl %ebx, %ebx + xorl %ecx, %ecx + xorl %edx, %edx + xorl %esi, %esi + xorl %edi, %edi + xorl %ebp, %ebp ret diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 2fa231923cf7..b0e4ddca6c18 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -1814,7 +1814,6 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva) spin_unlock(&vcpu->kvm->mmu_lock); return r; } -EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt); void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) { @@ -1871,12 +1870,6 @@ void kvm_enable_tdp(void) } EXPORT_SYMBOL_GPL(kvm_enable_tdp); -void kvm_disable_tdp(void) -{ - tdp_enabled = false; -} -EXPORT_SYMBOL_GPL(kvm_disable_tdp); - static void free_mmu_pages(struct kvm_vcpu *vcpu) { struct kvm_mmu_page *sp; diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index e2ee264740c7..b756e876dce3 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -453,8 +453,7 @@ static __init int svm_hardware_setup(void) if (npt_enabled) { printk(KERN_INFO "kvm: Nested Paging enabled\n"); kvm_enable_tdp(); - } else - kvm_disable_tdp(); + } return 0; @@ -1008,13 +1007,10 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) struct kvm *kvm = svm->vcpu.kvm; u64 fault_address; u32 error_code; - bool event_injection = false; if (!irqchip_in_kernel(kvm) && - is_external_interrupt(exit_int_info)) { - event_injection = true; + is_external_interrupt(exit_int_info)) push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK); - } fault_address = svm->vmcb->control.exit_info_2; error_code = svm->vmcb->control.exit_info_1; @@ -1028,8 +1024,6 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) (u32)fault_address, (u32)(fault_address >> 32), handler); - if (event_injection) - kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address); return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); } diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 2a69773e3b26..0cac63701719 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -2298,8 +2298,6 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) cr2 = vmcs_readl(EXIT_QUALIFICATION); KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2, (u32)((u64)cr2 >> 32), handler); - if (vect_info & VECTORING_INFO_VALID_MASK) - kvm_mmu_unprotect_page_virt(vcpu, cr2); return kvm_mmu_page_fault(vcpu, cr2, error_code); } @@ -3118,6 +3116,15 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) return ERR_PTR(-ENOMEM); allocate_vpid(vmx); + if (id == 0 && vm_need_ept()) { + kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | + VMX_EPT_WRITABLE_MASK | + VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); + kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK, + VMX_EPT_FAKE_DIRTY_MASK, 0ull, + VMX_EPT_EXECUTABLE_MASK); + kvm_enable_tdp(); + } err = kvm_vcpu_init(&vmx->vcpu, kvm, id); if (err) @@ -3296,17 +3303,8 @@ static int __init vmx_init(void) vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_ESP); vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_EIP); - if (vm_need_ept()) { + if (cpu_has_vmx_ept()) bypass_guest_pf = 0; - kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | - VMX_EPT_WRITABLE_MASK | - VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); - kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK, - VMX_EPT_FAKE_DIRTY_MASK, 0ull, - VMX_EPT_EXECUTABLE_MASK); - kvm_enable_tdp(); - } else - kvm_disable_tdp(); if (bypass_guest_pf) kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 5916191420c7..9f1cdb011cff 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -3184,10 +3184,6 @@ static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, kvm_desct->base |= seg_desc->base2 << 24; kvm_desct->limit = seg_desc->limit0; kvm_desct->limit |= seg_desc->limit << 16; - if (seg_desc->g) { - kvm_desct->limit <<= 12; - kvm_desct->limit |= 0xfff; - } kvm_desct->selector = selector; kvm_desct->type = seg_desc->type; kvm_desct->present = seg_desc->p; @@ -3227,7 +3223,6 @@ static void get_segment_descritptor_dtable(struct kvm_vcpu *vcpu, static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, struct desc_struct *seg_desc) { - gpa_t gpa; struct descriptor_table dtable; u16 index = selector >> 3; @@ -3237,16 +3232,13 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); return 1; } - gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); - gpa += index * 8; - return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8); + return kvm_read_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8); } /* allowed just for 8 bytes segments */ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, struct desc_struct *seg_desc) { - gpa_t gpa; struct descriptor_table dtable; u16 index = selector >> 3; @@ -3254,9 +3246,7 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, if (dtable.limit < index * 8 + 7) return 1; - gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); - gpa += index * 8; - return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8); + return kvm_write_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8); } static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, @@ -3268,7 +3258,55 @@ static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, base_addr |= (seg_desc->base1 << 16); base_addr |= (seg_desc->base2 << 24); - return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr); + return base_addr; +} + +static int load_tss_segment32(struct kvm_vcpu *vcpu, + struct desc_struct *seg_desc, + struct tss_segment_32 *tss) +{ + u32 base_addr; + + base_addr = get_tss_base_addr(vcpu, seg_desc); + + return kvm_read_guest(vcpu->kvm, base_addr, tss, + sizeof(struct tss_segment_32)); +} + +static int save_tss_segment32(struct kvm_vcpu *vcpu, + struct desc_struct *seg_desc, + struct tss_segment_32 *tss) +{ + u32 base_addr; + + base_addr = get_tss_base_addr(vcpu, seg_desc); + + return kvm_write_guest(vcpu->kvm, base_addr, tss, + sizeof(struct tss_segment_32)); +} + +static int load_tss_segment16(struct kvm_vcpu *vcpu, + struct desc_struct *seg_desc, + struct tss_segment_16 *tss) +{ + u32 base_addr; + + base_addr = get_tss_base_addr(vcpu, seg_desc); + + return kvm_read_guest(vcpu->kvm, base_addr, tss, + sizeof(struct tss_segment_16)); +} + +static int save_tss_segment16(struct kvm_vcpu *vcpu, + struct desc_struct *seg_desc, + struct tss_segment_16 *tss) +{ + u32 base_addr; + + base_addr = get_tss_base_addr(vcpu, seg_desc); + + return kvm_write_guest(vcpu->kvm, base_addr, tss, + sizeof(struct tss_segment_16)); } static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) @@ -3428,26 +3466,20 @@ static int load_state_from_tss16(struct kvm_vcpu *vcpu, } static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, - u32 old_tss_base, + struct desc_struct *cseg_desc, struct desc_struct *nseg_desc) { struct tss_segment_16 tss_segment_16; int ret = 0; - if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_16, - sizeof tss_segment_16)) + if (load_tss_segment16(vcpu, cseg_desc, &tss_segment_16)) goto out; save_state_to_tss16(vcpu, &tss_segment_16); + save_tss_segment16(vcpu, cseg_desc, &tss_segment_16); - if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_16, - sizeof tss_segment_16)) + if (load_tss_segment16(vcpu, nseg_desc, &tss_segment_16)) goto out; - - if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc), - &tss_segment_16, sizeof tss_segment_16)) - goto out; - if (load_state_from_tss16(vcpu, &tss_segment_16)) goto out; @@ -3457,26 +3489,20 @@ static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, } static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, - u32 old_tss_base, + struct desc_struct *cseg_desc, struct desc_struct *nseg_desc) { struct tss_segment_32 tss_segment_32; int ret = 0; - if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_32, - sizeof tss_segment_32)) + if (load_tss_segment32(vcpu, cseg_desc, &tss_segment_32)) goto out; save_state_to_tss32(vcpu, &tss_segment_32); + save_tss_segment32(vcpu, cseg_desc, &tss_segment_32); - if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_32, - sizeof tss_segment_32)) - goto out; - - if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc), - &tss_segment_32, sizeof tss_segment_32)) + if (load_tss_segment32(vcpu, nseg_desc, &tss_segment_32)) goto out; - if (load_state_from_tss32(vcpu, &tss_segment_32)) goto out; @@ -3491,20 +3517,16 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) struct desc_struct cseg_desc; struct desc_struct nseg_desc; int ret = 0; - u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR); - u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR); - old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base); + kvm_get_segment(vcpu, &tr_seg, VCPU_SREG_TR); - /* FIXME: Handle errors. Failure to read either TSS or their - * descriptors should generate a pagefault. - */ if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc)) goto out; - if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc)) + if (load_guest_segment_descriptor(vcpu, tr_seg.selector, &cseg_desc)) goto out; + if (reason != TASK_SWITCH_IRET) { int cpl; @@ -3522,7 +3544,8 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { cseg_desc.type &= ~(1 << 1); //clear the B flag - save_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc); + save_guest_segment_descriptor(vcpu, tr_seg.selector, + &cseg_desc); } if (reason == TASK_SWITCH_IRET) { @@ -3534,10 +3557,10 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) kvm_x86_ops->cache_regs(vcpu); if (nseg_desc.type & 8) - ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_base, + ret = kvm_task_switch_32(vcpu, tss_selector, &cseg_desc, &nseg_desc); else - ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_base, + ret = kvm_task_switch_16(vcpu, tss_selector, &cseg_desc, &nseg_desc); if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) { diff --git a/trunk/arch/x86/mm/Makefile b/trunk/arch/x86/mm/Makefile index 2977ea37791f..1fbb844c3d7a 100644 --- a/trunk/arch/x86/mm/Makefile +++ b/trunk/arch/x86/mm/Makefile @@ -1,7 +1,6 @@ obj-y := init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ pat.o pgtable.o -obj-$(CONFIG_HAVE_GET_USER_PAGES_FAST) += gup.o obj-$(CONFIG_X86_32) += pgtable_32.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/trunk/arch/x86/mm/gup.c b/trunk/arch/x86/mm/gup.c deleted file mode 100644 index 3085f25b4355..000000000000 --- a/trunk/arch/x86/mm/gup.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Lockless get_user_pages_fast for x86 - * - * Copyright (C) 2008 Nick Piggin - * Copyright (C) 2008 Novell Inc. - */ -#include -#include -#include -#include - -#include - -static inline pte_t gup_get_pte(pte_t *ptep) -{ -#ifndef CONFIG_X86_PAE - return *ptep; -#else - /* - * With get_user_pages_fast, we walk down the pagetables without taking - * any locks. For this we would like to load the pointers atoimcally, - * but that is not possible (without expensive cmpxchg8b) on PAE. What - * we do have is the guarantee that a pte will only either go from not - * present to present, or present to not present or both -- it will not - * switch to a completely different present page without a TLB flush in - * between; something that we are blocking by holding interrupts off. - * - * Setting ptes from not present to present goes: - * ptep->pte_high = h; - * smp_wmb(); - * ptep->pte_low = l; - * - * And present to not present goes: - * ptep->pte_low = 0; - * smp_wmb(); - * ptep->pte_high = 0; - * - * We must ensure here that the load of pte_low sees l iff pte_high - * sees h. We load pte_high *after* loading pte_low, which ensures we - * don't see an older value of pte_high. *Then* we recheck pte_low, - * which ensures that we haven't picked up a changed pte high. We might - * have got rubbish values from pte_low and pte_high, but we are - * guaranteed that pte_low will not have the present bit set *unless* - * it is 'l'. And get_user_pages_fast only operates on present ptes, so - * we're safe. - * - * gup_get_pte should not be used or copied outside gup.c without being - * very careful -- it does not atomically load the pte or anything that - * is likely to be useful for you. - */ - pte_t pte; - -retry: - pte.pte_low = ptep->pte_low; - smp_rmb(); - pte.pte_high = ptep->pte_high; - smp_rmb(); - if (unlikely(pte.pte_low != ptep->pte_low)) - goto retry; - - return pte; -#endif -} - -/* - * The performance critical leaf functions are made noinline otherwise gcc - * inlines everything into a single function which results in too much - * register pressure. - */ -static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, - unsigned long end, int write, struct page **pages, int *nr) -{ - unsigned long mask; - pte_t *ptep; - - mask = _PAGE_PRESENT|_PAGE_USER; - if (write) - mask |= _PAGE_RW; - - ptep = pte_offset_map(&pmd, addr); - do { - pte_t pte = gup_get_pte(ptep); - struct page *page; - - if ((pte_val(pte) & (mask | _PAGE_SPECIAL)) != mask) { - pte_unmap(ptep); - return 0; - } - VM_BUG_ON(!pfn_valid(pte_pfn(pte))); - page = pte_page(pte); - get_page(page); - pages[*nr] = page; - (*nr)++; - - } while (ptep++, addr += PAGE_SIZE, addr != end); - pte_unmap(ptep - 1); - - return 1; -} - -static inline void get_head_page_multiple(struct page *page, int nr) -{ - VM_BUG_ON(page != compound_head(page)); - VM_BUG_ON(page_count(page) == 0); - atomic_add(nr, &page->_count); -} - -static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, - unsigned long end, int write, struct page **pages, int *nr) -{ - unsigned long mask; - pte_t pte = *(pte_t *)&pmd; - struct page *head, *page; - int refs; - - mask = _PAGE_PRESENT|_PAGE_USER; - if (write) - mask |= _PAGE_RW; - if ((pte_val(pte) & mask) != mask) - return 0; - /* hugepages are never "special" */ - VM_BUG_ON(pte_val(pte) & _PAGE_SPECIAL); - VM_BUG_ON(!pfn_valid(pte_pfn(pte))); - - refs = 0; - head = pte_page(pte); - page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT); - do { - VM_BUG_ON(compound_head(page) != head); - pages[*nr] = page; - (*nr)++; - page++; - refs++; - } while (addr += PAGE_SIZE, addr != end); - get_head_page_multiple(head, refs); - - return 1; -} - -static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, - int write, struct page **pages, int *nr) -{ - unsigned long next; - pmd_t *pmdp; - - pmdp = pmd_offset(&pud, addr); - do { - pmd_t pmd = *pmdp; - - next = pmd_addr_end(addr, end); - if (pmd_none(pmd)) - return 0; - if (unlikely(pmd_large(pmd))) { - if (!gup_huge_pmd(pmd, addr, next, write, pages, nr)) - return 0; - } else { - if (!gup_pte_range(pmd, addr, next, write, pages, nr)) - return 0; - } - } while (pmdp++, addr = next, addr != end); - - return 1; -} - -static noinline int gup_huge_pud(pud_t pud, unsigned long addr, - unsigned long end, int write, struct page **pages, int *nr) -{ - unsigned long mask; - pte_t pte = *(pte_t *)&pud; - struct page *head, *page; - int refs; - - mask = _PAGE_PRESENT|_PAGE_USER; - if (write) - mask |= _PAGE_RW; - if ((pte_val(pte) & mask) != mask) - return 0; - /* hugepages are never "special" */ - VM_BUG_ON(pte_val(pte) & _PAGE_SPECIAL); - VM_BUG_ON(!pfn_valid(pte_pfn(pte))); - - refs = 0; - head = pte_page(pte); - page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT); - do { - VM_BUG_ON(compound_head(page) != head); - pages[*nr] = page; - (*nr)++; - page++; - refs++; - } while (addr += PAGE_SIZE, addr != end); - get_head_page_multiple(head, refs); - - return 1; -} - -static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, - int write, struct page **pages, int *nr) -{ - unsigned long next; - pud_t *pudp; - - pudp = pud_offset(&pgd, addr); - do { - pud_t pud = *pudp; - - next = pud_addr_end(addr, end); - if (pud_none(pud)) - return 0; - if (unlikely(pud_large(pud))) { - if (!gup_huge_pud(pud, addr, next, write, pages, nr)) - return 0; - } else { - if (!gup_pmd_range(pud, addr, next, write, pages, nr)) - return 0; - } - } while (pudp++, addr = next, addr != end); - - return 1; -} - -int get_user_pages_fast(unsigned long start, int nr_pages, int write, - struct page **pages) -{ - struct mm_struct *mm = current->mm; - unsigned long end = start + (nr_pages << PAGE_SHIFT); - unsigned long addr = start; - unsigned long next; - pgd_t *pgdp; - int nr = 0; - - if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, - start, nr_pages*PAGE_SIZE))) - goto slow_irqon; - - /* - * XXX: batch / limit 'nr', to avoid large irq off latency - * needs some instrumenting to determine the common sizes used by - * important workloads (eg. DB2), and whether limiting the batch size - * will decrease performance. - * - * It seems like we're in the clear for the moment. Direct-IO is - * the main guy that batches up lots of get_user_pages, and even - * they are limited to 64-at-a-time which is not so many. - */ - /* - * This doesn't prevent pagetable teardown, but does prevent - * the pagetables and pages from being freed on x86. - * - * So long as we atomically load page table pointers versus teardown - * (which we do on x86, with the above PAE exception), we can follow the - * address down to the the page and take a ref on it. - */ - local_irq_disable(); - pgdp = pgd_offset(mm, addr); - do { - pgd_t pgd = *pgdp; - - next = pgd_addr_end(addr, end); - if (pgd_none(pgd)) - goto slow; - if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) - goto slow; - } while (pgdp++, addr = next, addr != end); - local_irq_enable(); - - VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT); - return nr; - - { - int ret; - -slow: - local_irq_enable(); -slow_irqon: - /* Try to get the remaining pages with get_user_pages */ - start += nr << PAGE_SHIFT; - pages += nr; - - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - (end - start) >> PAGE_SHIFT, write, 0, pages, NULL); - up_read(&mm->mmap_sem); - - /* Have to be a bit careful with return values */ - if (nr > 0) { - if (ret < 0) - ret = nr; - else - ret += nr; - } - - return ret; - } -} diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index 129618ca0ea2..ec37121f6709 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -86,6 +86,43 @@ early_param("gbpages", parse_direct_gbpages_on); * around without checking the pgd every time. */ +void show_mem(void) +{ + long i, total = 0, reserved = 0; + long shared = 0, cached = 0; + struct page *page; + pg_data_t *pgdat; + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(); + for_each_online_pgdat(pgdat) { + for (i = 0; i < pgdat->node_spanned_pages; ++i) { + /* + * This loop can take a while with 256 GB and + * 4k pages so defer the NMI watchdog: + */ + if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) + touch_nmi_watchdog(); + + if (!pfn_valid(pgdat->node_start_pfn + i)) + continue; + + page = pfn_to_page(pgdat->node_start_pfn + i); + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + } + printk(KERN_INFO "%lu pages of RAM\n", total); + printk(KERN_INFO "%lu reserved pages\n", reserved); + printk(KERN_INFO "%lu pages shared\n", shared); + printk(KERN_INFO "%lu pages swap cached\n", cached); +} + int after_bootmem; static __init void *spp_getpage(void) diff --git a/trunk/arch/x86/mm/pgtable_32.c b/trunk/arch/x86/mm/pgtable_32.c index cab0abbd1ebe..b4becbf8c570 100644 --- a/trunk/arch/x86/mm/pgtable_32.c +++ b/trunk/arch/x86/mm/pgtable_32.c @@ -20,6 +20,53 @@ #include #include +void show_mem(void) +{ + int total = 0, reserved = 0; + int shared = 0, cached = 0; + int highmem = 0; + struct page *page; + pg_data_t *pgdat; + unsigned long i; + unsigned long flags; + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(); + for_each_online_pgdat(pgdat) { + pgdat_resize_lock(pgdat, &flags); + for (i = 0; i < pgdat->node_spanned_pages; ++i) { + if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) + touch_nmi_watchdog(); + page = pgdat_page_nr(pgdat, i); + total++; + if (PageHighMem(page)) + highmem++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + pgdat_resize_unlock(pgdat, &flags); + } + printk(KERN_INFO "%d pages of RAM\n", total); + printk(KERN_INFO "%d pages of HIGHMEM\n", highmem); + printk(KERN_INFO "%d reserved pages\n", reserved); + printk(KERN_INFO "%d pages shared\n", shared); + printk(KERN_INFO "%d pages swap cached\n", cached); + + printk(KERN_INFO "%lu pages dirty\n", global_page_state(NR_FILE_DIRTY)); + printk(KERN_INFO "%lu pages writeback\n", + global_page_state(NR_WRITEBACK)); + printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); + printk(KERN_INFO "%lu pages slab\n", + global_page_state(NR_SLAB_RECLAIMABLE) + + global_page_state(NR_SLAB_UNRECLAIMABLE)); + printk(KERN_INFO "%lu pages pagetables\n", + global_page_state(NR_PAGETABLE)); +} + /* * Associate a virtual page frame with a given physical page frame * and protection flags for that frame. diff --git a/trunk/arch/xtensa/mm/init.c b/trunk/arch/xtensa/mm/init.c index 34163cfaaffc..81d0560eaea2 100644 --- a/trunk/arch/xtensa/mm/init.c +++ b/trunk/arch/xtensa/mm/init.c @@ -280,9 +280,36 @@ void free_initmem(void) (&__init_end - &__init_begin) >> 10); } +void show_mem(void) +{ + int i, free = 0, total = 0, reserved = 0; + int shared = 0, cached = 0; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (!page_count(mem_map + i)) + free++; + else + shared += page_count(mem_map + i) - 1; + } + printk("%d pages of RAM\n", total); + printk("%d reserved pages\n", reserved); + printk("%d pages shared\n", shared); + printk("%d pages swap cached\n",cached); + printk("%d free pages\n", free); +} + struct kmem_cache *pgtable_cache __read_mostly; -static void pgd_ctor(void* addr) +static void pgd_ctor(struct kmem_cache *cache, void* addr) { pte_t* ptep = (pte_t*)addr; int i; diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index cf4eb0eefbbf..9735acb5b4f5 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -837,7 +837,8 @@ static void as_completed_request(struct request_queue *q, struct request *rq) WARN_ON(!list_empty(&rq->queuelist)); if (RQ_STATE(rq) != AS_RQ_REMOVED) { - WARN(1, "rq->state %d\n", RQ_STATE(rq)); + printk("rq->state %d\n", RQ_STATE(rq)); + WARN_ON(1); goto out; } diff --git a/trunk/block/blk-map.c b/trunk/block/blk-map.c index af37e4ae62f5..ddd96fb11a7d 100644 --- a/trunk/block/blk-map.c +++ b/trunk/block/blk-map.c @@ -269,6 +269,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, int reading = rq_data_dir(rq) == READ; int do_copy = 0; struct bio *bio; + unsigned long stack_mask = ~(THREAD_SIZE - 1); if (len > (q->max_hw_sectors << 9)) return -EINVAL; @@ -277,8 +278,11 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, kaddr = (unsigned long)kbuf; alignment = queue_dma_alignment(q) | q->dma_pad_mask; - do_copy = ((kaddr & alignment) || (len & alignment) || - object_is_on_stack(kbuf)); + do_copy = ((kaddr & alignment) || (len & alignment)); + + if (!((kaddr & stack_mask) ^ + ((unsigned long)current->stack & stack_mask))) + do_copy = 1; if (do_copy) bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index b7f2963693a7..d592dbb1d12a 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -272,8 +272,6 @@ static atomic_t c3_cpu_count; /* Common C-state entry for C2, C3, .. */ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) { - /* Don't trace irqs off for idle */ - stop_critical_timings(); if (cstate->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cstate); @@ -286,7 +284,6 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) gets asserted in time to freeze execution properly. */ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } - start_critical_timings(); } #endif /* !CONFIG_CPU_IDLE */ @@ -1421,8 +1418,6 @@ static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, */ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) { - /* Don't trace irqs off for idle */ - stop_critical_timings(); if (cx->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cx); @@ -1437,7 +1432,6 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) gets asserted in time to freeze execution properly. */ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } - start_critical_timings(); } /** diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 068aa1c9538c..7d5c63c81a59 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -116,10 +116,12 @@ static void device_release(struct kobject *kobj) dev->type->release(dev); else if (dev->class && dev->class->dev_release) dev->class->dev_release(dev); - else - WARN(1, KERN_ERR "Device '%s' does not have a release() " + else { + printk(KERN_ERR "Device '%s' does not have a release() " "function, it is broken and must be fixed.\n", dev->bus_id); + WARN_ON(1); + } } static struct kobj_type device_ktype = { diff --git a/trunk/drivers/base/isa.c b/trunk/drivers/base/isa.c index efd577574948..d2222397a401 100644 --- a/trunk/drivers/base/isa.c +++ b/trunk/drivers/base/isa.c @@ -7,7 +7,6 @@ #include #include #include -#include #include static struct device isa_bus = { @@ -142,9 +141,6 @@ int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev) isa_dev->dev.release = isa_dev_release; isa_dev->id = id; - isa_dev->dev.coherent_dma_mask = DMA_24BIT_MASK; - isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; - error = device_register(&isa_dev->dev); if (error) { put_device(&isa_dev->dev); diff --git a/trunk/drivers/base/memory.c b/trunk/drivers/base/memory.c index 3ad49a00029f..855ed1a9f97b 100644 --- a/trunk/drivers/base/memory.c +++ b/trunk/drivers/base/memory.c @@ -204,8 +204,9 @@ memory_block_action(struct memory_block *mem, unsigned long action) } break; default: - WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", + printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", __func__, mem, action, action); + WARN_ON(1); ret = -EINVAL; } diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c index 75dd6e22faff..40fc14f03540 100644 --- a/trunk/drivers/base/sys.c +++ b/trunk/drivers/base/sys.c @@ -168,16 +168,19 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) int err = 0; if (!cls) { - WARN(1, KERN_WARNING "sysdev: invalid class passed to " + printk(KERN_WARNING "sysdev: invalid class passed to " "sysdev_driver_register!\n"); + WARN_ON(1); return -EINVAL; } /* Check whether this driver has already been added to a class. */ - if (drv->entry.next && !list_empty(&drv->entry)) - WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already" + if (drv->entry.next && !list_empty(&drv->entry)) { + printk(KERN_WARNING "sysdev: class %s: driver (%p) has already" " been registered to a class, something is wrong, but " "will forge on!\n", cls->name, drv); + WARN_ON(1); + } mutex_lock(&sysdev_drivers_lock); if (cls && kset_get(&cls->kset)) { @@ -191,7 +194,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) } } else { err = -EINVAL; - WARN(1, KERN_ERR "%s: invalid device class\n", __func__); + printk(KERN_ERR "%s: invalid device class\n", __func__); + WARN_ON(1); } mutex_unlock(&sysdev_drivers_lock); return err; diff --git a/trunk/drivers/char/dsp56k.c b/trunk/drivers/char/dsp56k.c index ca7c72a486b2..19b88504e960 100644 --- a/trunk/drivers/char/dsp56k.c +++ b/trunk/drivers/char/dsp56k.c @@ -304,9 +304,9 @@ static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t co } static long dsp56k_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - int dev = iminor(file->f_path.dentry->d_inode) & 0x0f; + int dev = iminor(inode) & 0x0f; void __user *argp = (void __user *)arg; switch(dev) diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index d9799e2bcfbf..dbefbb30ed44 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/drivers/char/rtc.c @@ -144,7 +144,6 @@ static ssize_t rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static void rtc_get_rtc_time(struct rtc_time *rtc_tm); #ifdef RTC_IRQ static unsigned int rtc_poll(struct file *file, poll_table *wait); @@ -236,7 +235,7 @@ static inline unsigned char rtc_is_updating(void) * (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.) */ -static irqreturn_t rtc_interrupt(int irq, void *dev_id) +irqreturn_t rtc_interrupt(int irq, void *dev_id) { /* * Can be an alarm interrupt, update complete interrupt, @@ -1304,7 +1303,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file) } #endif -static void rtc_get_rtc_time(struct rtc_time *rtc_tm) +void rtc_get_rtc_time(struct rtc_time *rtc_tm) { unsigned long uip_watchdog = jiffies, flags; unsigned char ctrl; diff --git a/trunk/drivers/char/ser_a2232.c b/trunk/drivers/char/ser_a2232.c index 7b0c35207d9b..4ba3aec9e1cd 100644 --- a/trunk/drivers/char/ser_a2232.c +++ b/trunk/drivers/char/ser_a2232.c @@ -192,7 +192,7 @@ static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) Maybe one could implement a more efficient version by not only transferring one character at a time. */ - struct tty_struct *tty = port->gs.port.tty; + struct tty_struct *tty = port->gs.tty; #if 0 switch(err) { @@ -226,7 +226,7 @@ static void a2232_disable_tx_interrupts(void *ptr) /* Does this here really have to be? */ local_irq_save(flags); - port->gs.port.flags &= ~GS_TX_INTEN; + port->gs.flags &= ~GS_TX_INTEN; local_irq_restore(flags); } @@ -242,7 +242,7 @@ static void a2232_enable_tx_interrupts(void *ptr) /* Does this here really have to be? */ local_irq_save(flags); - port->gs.port.flags |= GS_TX_INTEN; + port->gs.flags |= GS_TX_INTEN; local_irq_restore(flags); } @@ -276,9 +276,9 @@ static void a2232_shutdown_port(void *ptr) local_irq_save(flags); - port->gs.port.flags &= ~GS_ACTIVE; + port->gs.flags &= ~GS_ACTIVE; - if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL) { + if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) { /* Set DTR and RTS to Low, flush output. The NetBSD driver "msc.c" does it this way. */ stat->Command = ( (stat->Command & ~A2232CMD_CMask) | @@ -309,7 +309,7 @@ static int a2232_set_real_termios(void *ptr) volatile struct a2232status *status; volatile struct a2232memory *mem; - if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; + if (!port->gs.tty || !port->gs.tty->termios) return 0; status = a2232stat(port->which_a2232, port->which_port_on_a2232); mem = a2232mem(port->which_a2232); @@ -345,7 +345,7 @@ static int a2232_set_real_termios(void *ptr) } a2232_param |= rate; - cflag = port->gs.port.tty->termios->c_cflag; + cflag = port->gs.tty->termios->c_cflag; // get character size chsize = cflag & CSIZE; @@ -382,7 +382,7 @@ static int a2232_set_real_termios(void *ptr) the conventional way of inserting START/STOP characters by hand in throttle()/unthrottle(). */ - softflow = !!( port->gs.port.tty->termios->c_iflag & IXOFF ); + softflow = !!( port->gs.tty->termios->c_iflag & IXOFF ); // get Parity (Enabled/Disabled? If Enabled, Odd or Even?) parity = cflag & (PARENB | PARODD); @@ -400,9 +400,9 @@ static int a2232_set_real_termios(void *ptr) /* Hmm. Maybe an own a2232_port structure member would be cleaner? */ if (cflag & CLOCAL) - port->gs.port.flags &= ~ASYNC_CHECK_CD; + port->gs.flags &= ~ASYNC_CHECK_CD; else - port->gs.port.flags |= ASYNC_CHECK_CD; + port->gs.flags |= ASYNC_CHECK_CD; /* Now we have all parameters and can go to set them: */ @@ -482,18 +482,18 @@ static int a2232_open(struct tty_struct * tty, struct file * filp) port = &a2232_ports[line]; tty->driver_data = port; - port->gs.port.tty = tty; - port->gs.port.count++; + port->gs.tty = tty; + port->gs.count++; retval = gs_init_port(&port->gs); if (retval) { - port->gs.port.count--; + port->gs.count--; return retval; } - port->gs.port.flags |= GS_ACTIVE; + port->gs.flags |= GS_ACTIVE; retval = gs_block_til_ready(port, filp); if (retval) { - port->gs.port.count--; + port->gs.count--; return retval; } @@ -522,7 +522,7 @@ int ch, err, n, p; for (p = 0; p < NUMLINES; p++){ /* for every port on this board */ err = 0; port = &a2232_ports[n*NUMLINES+p]; - if ( port->gs.port.flags & GS_ACTIVE ){ /* if the port is used */ + if ( port->gs.flags & GS_ACTIVE ){ /* if the port is used */ status = a2232stat(n,p); @@ -577,8 +577,8 @@ int ch, err, n, p; obuf = mem->OutBuf[p]; bufpos = status->OutHead; while ( (port->gs.xmit_cnt > 0) && - (!port->gs.port.tty->stopped) && - (!port->gs.port.tty->hw_stopped) ){ /* While there are chars to transmit */ + (!port->gs.tty->stopped) && + (!port->gs.tty->hw_stopped) ){ /* While there are chars to transmit */ if (((bufpos+1) & A2232_IOBUFLENMASK) != status->OutTail) { /* If the A2232 buffer is not full */ ch = port->gs.xmit_buf[port->gs.xmit_tail]; /* get the next char to transmit */ port->gs.xmit_tail = (port->gs.xmit_tail+1) & (SERIAL_XMIT_SIZE-1); /* modulo-addition for the gs.xmit_buf ring-buffer */ @@ -592,8 +592,8 @@ int ch, err, n, p; status->OutHead = bufpos; /* WakeUp if output buffer runs low */ - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { - tty_wakeup(port->gs.port.tty); + if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { + tty_wakeup(port->gs.tty); } } // if the port is used } // for every port on the board @@ -613,16 +613,16 @@ int ch, err, n, p; struct a2232_port *port = &a2232_ports[n*7+p]; port->cd_status = !(ncd & 1); /* ncd&1 <=> CD is now off */ - if (!(port->gs.port.flags & ASYNC_CHECK_CD)) + if (!(port->gs.flags & ASYNC_CHECK_CD)) ; /* Don't report DCD changes */ else if (port->cd_status) { // if DCD on: DCD went UP! /* Are we blocking in open?*/ - wake_up_interruptible(&port->gs.port.open_wait); + wake_up_interruptible(&port->gs.open_wait); } else { // if DCD off: DCD went DOWN! - if (port->gs.port.tty) - tty_hangup (port->gs.port.tty); + if (port->gs.tty) + tty_hangup (port->gs.tty); } } // if CD changed for this port @@ -655,8 +655,8 @@ static void a2232_init_portstructs(void) #ifdef NEW_WRITE_LOCKING mutex_init(&(port->gs.port_write_mutex)); #endif - init_waitqueue_head(&port->gs.port.open_wait); - init_waitqueue_head(&port->gs.port.close_wait); + init_waitqueue_head(&port->gs.open_wait); + init_waitqueue_head(&port->gs.close_wait); } } diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index ae766d868454..e1fc193d9396 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -580,133 +580,91 @@ void tpm_continue_selftest(struct tpm_chip *chip) } EXPORT_SYMBOL_GPL(tpm_continue_selftest); -#define TPM_INTERNAL_RESULT_SIZE 200 - ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, char *buf) { - u8 *data; + u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)]; ssize_t rc; struct tpm_chip *chip = dev_get_drvdata(dev); if (chip == NULL) return -ENODEV; - data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); - if (!data) - return -ENOMEM; - memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM; - rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, - "attemtping to determine the permanent enabled state"); - if (rc) { - kfree(data); + rc = transmit_cmd(chip, data, sizeof(data), + "attemtping to determine the permanent state"); + if (rc) return 0; - } - - rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]); - - kfree(data); - return rc; + return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]); } EXPORT_SYMBOL_GPL(tpm_show_enabled); ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr, char *buf) { - u8 *data; + u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)]; ssize_t rc; struct tpm_chip *chip = dev_get_drvdata(dev); if (chip == NULL) return -ENODEV; - data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); - if (!data) - return -ENOMEM; - memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM; - rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, - "attemtping to determine the permanent active state"); - if (rc) { - kfree(data); + rc = transmit_cmd(chip, data, sizeof(data), + "attemtping to determine the permanent state"); + if (rc) return 0; - } - - rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]); - - kfree(data); - return rc; + return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]); } EXPORT_SYMBOL_GPL(tpm_show_active); ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr, char *buf) { - u8 *data; + u8 data[sizeof(tpm_cap)]; ssize_t rc; struct tpm_chip *chip = dev_get_drvdata(dev); if (chip == NULL) return -ENODEV; - data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); - if (!data) - return -ENOMEM; - memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER; - rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, + rc = transmit_cmd(chip, data, sizeof(data), "attempting to determine the owner state"); - if (rc) { - kfree(data); + if (rc) return 0; - } - - rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]); - - kfree(data); - return rc; + return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]); } EXPORT_SYMBOL_GPL(tpm_show_owned); ssize_t tpm_show_temp_deactivated(struct device * dev, struct device_attribute * attr, char *buf) { - u8 *data; + u8 data[sizeof(tpm_cap)]; ssize_t rc; struct tpm_chip *chip = dev_get_drvdata(dev); if (chip == NULL) return -ENODEV; - data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); - if (!data) - return -ENOMEM; - memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL; - rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, + rc = transmit_cmd(chip, data, sizeof(data), "attempting to determine the temporary state"); - if (rc) { - kfree(data); + if (rc) return 0; - } - - rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]); - - kfree(data); - return rc; + return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]); } EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated); @@ -720,7 +678,7 @@ static const u8 pcrread[] = { ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, char *buf) { - u8 *data; + u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)]; ssize_t rc; int i, j, num_pcrs; __be32 index; @@ -730,27 +688,21 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, if (chip == NULL) return -ENODEV; - data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); - if (!data) - return -ENOMEM; - memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR; - rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, + rc = transmit_cmd(chip, data, sizeof(data), "attempting to determine the number of PCRS"); - if (rc) { - kfree(data); + if (rc) return 0; - } num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); for (i = 0; i < num_pcrs; i++) { memcpy(data, pcrread, sizeof(pcrread)); index = cpu_to_be32(i); memcpy(data + 10, &index, 4); - rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, + rc = transmit_cmd(chip, data, sizeof(data), "attempting to read a PCR"); if (rc) goto out; @@ -760,7 +712,6 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, str += sprintf(str, "\n"); } out: - kfree(data); return str - buf; } EXPORT_SYMBOL_GPL(tpm_show_pcrs); @@ -844,7 +795,7 @@ static const u8 cap_version[] = { ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, char *buf) { - u8 *data; + u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)]; ssize_t rc; char *str = buf; @@ -852,27 +803,21 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, if (chip == NULL) return -ENODEV; - data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); - if (!data) - return -ENOMEM; - memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; - rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, + rc = transmit_cmd(chip, data, sizeof(data), "attempting to determine the manufacturer"); - if (rc) { - kfree(data); + if (rc) return 0; - } str += sprintf(str, "Manufacturer: 0x%x\n", be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); memcpy(data, cap_version, sizeof(cap_version)); data[CAP_VERSION_IDX] = CAP_VERSION_1_1; - rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, + rc = transmit_cmd(chip, data, sizeof(data), "attempting to determine the 1.1 version"); if (rc) goto out; @@ -883,7 +828,6 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, (int) data[17]); out: - kfree(data); return str - buf; } EXPORT_SYMBOL_GPL(tpm_show_caps); @@ -891,7 +835,7 @@ EXPORT_SYMBOL_GPL(tpm_show_caps); ssize_t tpm_show_caps_1_2(struct device * dev, struct device_attribute * attr, char *buf) { - u8 *data; + u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)]; ssize_t len; char *str = buf; @@ -899,20 +843,15 @@ ssize_t tpm_show_caps_1_2(struct device * dev, if (chip == NULL) return -ENODEV; - data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); - if (!data) - return -ENOMEM; - memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; - len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE); - if (len <= TPM_ERROR_SIZE) { + if ((len = tpm_transmit(chip, data, sizeof(data))) <= + TPM_ERROR_SIZE) { dev_dbg(chip->dev, "A TPM error (%d) occurred " "attempting to determine the manufacturer\n", be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)))); - kfree(data); return 0; } @@ -922,8 +861,8 @@ ssize_t tpm_show_caps_1_2(struct device * dev, memcpy(data, cap_version, sizeof(cap_version)); data[CAP_VERSION_IDX] = CAP_VERSION_1_2; - len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE); - if (len <= TPM_ERROR_SIZE) { + if ((len = tpm_transmit(chip, data, sizeof(data))) <= + TPM_ERROR_SIZE) { dev_err(chip->dev, "A TPM error (%d) occurred " "attempting to determine the 1.2 version\n", be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)))); @@ -935,7 +874,6 @@ ssize_t tpm_show_caps_1_2(struct device * dev, (int) data[19]); out: - kfree(data); return str - buf; } EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); @@ -1028,7 +966,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf, size_t size, loff_t *off) { struct tpm_chip *chip = file->private_data; - size_t in_size = size, out_size; + int in_size = size, out_size; /* cannot perform a write until the read has cleared either via tpm_read or a user_read_timer timeout */ @@ -1063,7 +1001,7 @@ ssize_t tpm_read(struct file *file, char __user *buf, size_t size, loff_t *off) { struct tpm_chip *chip = file->private_data; - ssize_t ret_size; + int ret_size; del_singleshot_timer_sync(&chip->user_read_timer); flush_scheduled_work(); diff --git a/trunk/drivers/char/tpm/tpm_bios.c b/trunk/drivers/char/tpm/tpm_bios.c index 68f052b42ed7..60a2d2630e36 100644 --- a/trunk/drivers/char/tpm/tpm_bios.c +++ b/trunk/drivers/char/tpm/tpm_bios.c @@ -448,7 +448,7 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, goto out; } -static const struct file_operations tpm_ascii_bios_measurements_ops = { +const struct file_operations tpm_ascii_bios_measurements_ops = { .open = tpm_ascii_bios_measurements_open, .read = seq_read, .llseek = seq_lseek, @@ -486,7 +486,7 @@ static int tpm_binary_bios_measurements_open(struct inode *inode, goto out; } -static const struct file_operations tpm_binary_bios_measurements_ops = { +const struct file_operations tpm_binary_bios_measurements_ops = { .open = tpm_binary_bios_measurements_open, .read = seq_read, .llseek = seq_lseek, diff --git a/trunk/drivers/char/tpm/tpm_tis.c b/trunk/drivers/char/tpm/tpm_tis.c index ed1879c0dd8d..c7a977bc03e8 100644 --- a/trunk/drivers/char/tpm/tpm_tis.c +++ b/trunk/drivers/char/tpm/tpm_tis.c @@ -622,7 +622,6 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { {"ATM1200", 0}, /* Atmel */ {"IFX0102", 0}, /* Infineon */ {"BCM0101", 0}, /* Broadcom */ - {"BCM0102", 0}, /* Broadcom */ {"NSC1200", 0}, /* National */ {"ICO0102", 0}, /* Intel */ /* Add new here */ diff --git a/trunk/drivers/char/vme_scc.c b/trunk/drivers/char/vme_scc.c index 1718b3c481db..69c5afe97f19 100644 --- a/trunk/drivers/char/vme_scc.c +++ b/trunk/drivers/char/vme_scc.c @@ -183,8 +183,8 @@ static void scc_init_portstructs(void) #ifdef NEW_WRITE_LOCKING port->gs.port_write_mutex = MUTEX; #endif - init_waitqueue_head(&port->gs.port.open_wait); - init_waitqueue_head(&port->gs.port.close_wait); + init_waitqueue_head(&port->gs.open_wait); + init_waitqueue_head(&port->gs.close_wait); } } @@ -422,7 +422,7 @@ static irqreturn_t scc_rx_int(int irq, void *data) { unsigned char ch; struct scc_port *port = data; - struct tty_struct *tty = port->gs.port.tty; + struct tty_struct *tty = port->gs.tty; SCC_ACCESS_INIT(port); ch = SCCread_NB(RX_DATA_REG); @@ -453,7 +453,7 @@ static irqreturn_t scc_rx_int(int irq, void *data) static irqreturn_t scc_spcond_int(int irq, void *data) { struct scc_port *port = data; - struct tty_struct *tty = port->gs.port.tty; + struct tty_struct *tty = port->gs.tty; unsigned char stat, ch, err; int int_pending_mask = port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX; @@ -500,7 +500,7 @@ static irqreturn_t scc_tx_int(int irq, void *data) struct scc_port *port = data; SCC_ACCESS_INIT(port); - if (!port->gs.port.tty) { + if (!port->gs.tty) { printk(KERN_WARNING "scc_tx_int with NULL tty!\n"); SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); @@ -512,9 +512,8 @@ static irqreturn_t scc_tx_int(int irq, void *data) SCCwrite(TX_DATA_REG, port->x_char); port->x_char = 0; } - else if ((port->gs.xmit_cnt <= 0) || - port->gs.port.tty->stopped || - port->gs.port.tty->hw_stopped) + else if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped || + port->gs.tty->hw_stopped) break; else { SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]); @@ -523,15 +522,15 @@ static irqreturn_t scc_tx_int(int irq, void *data) break; } } - if ((port->gs.xmit_cnt <= 0) || port->gs.port.tty->stopped || - port->gs.port.tty->hw_stopped) { + if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped || + port->gs.tty->hw_stopped) { /* disable tx interrupts */ SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); /* disable tx_int on next tx underrun? */ - port->gs.port.flags &= ~GS_TX_INTEN; + port->gs.flags &= ~GS_TX_INTEN; } - if (port->gs.port.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) - tty_wakeup(port->gs.port.tty); + if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) + tty_wakeup(port->gs.tty); SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); return IRQ_HANDLED; @@ -551,14 +550,14 @@ static irqreturn_t scc_stat_int(int irq, void *data) if (changed & SR_DCD) { port->c_dcd = !!(sr & SR_DCD); - if (!(port->gs.port.flags & ASYNC_CHECK_CD)) + if (!(port->gs.flags & ASYNC_CHECK_CD)) ; /* Don't report DCD changes */ else if (port->c_dcd) { - wake_up_interruptible(&port->gs.port.open_wait); + wake_up_interruptible(&port->gs.open_wait); } else { - if (port->gs.port.tty) - tty_hangup (port->gs.port.tty); + if (port->gs.tty) + tty_hangup (port->gs.tty); } } SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET); @@ -579,7 +578,7 @@ static void scc_disable_tx_interrupts(void *ptr) local_irq_save(flags); SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); - port->gs.port.flags &= ~GS_TX_INTEN; + port->gs.flags &= ~GS_TX_INTEN; local_irq_restore(flags); } @@ -637,8 +636,8 @@ static void scc_shutdown_port(void *ptr) { struct scc_port *port = ptr; - port->gs.port.flags &= ~ GS_ACTIVE; - if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL) { + port->gs.flags &= ~ GS_ACTIVE; + if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) { scc_setsignals (port, 0, 0); } } @@ -653,14 +652,14 @@ static int scc_set_real_termios (void *ptr) struct scc_port *port = ptr; SCC_ACCESS_INIT(port); - if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; + if (!port->gs.tty || !port->gs.tty->termios) return 0; channel = port->channel; if (channel == CHANNEL_A) return 0; /* Settings controlled by boot PROM */ - cflag = port->gs.port.tty->termios->c_cflag; + cflag = port->gs.tty->termios->c_cflag; baud = port->gs.baud; chsize = (cflag & CSIZE) >> 4; @@ -679,9 +678,9 @@ static int scc_set_real_termios (void *ptr) } if (cflag & CLOCAL) - port->gs.port.flags &= ~ASYNC_CHECK_CD; + port->gs.flags &= ~ASYNC_CHECK_CD; else - port->gs.port.flags |= ASYNC_CHECK_CD; + port->gs.flags |= ASYNC_CHECK_CD; #ifdef CONFIG_MVME147_SCC if (MACH_IS_MVME147) @@ -857,7 +856,7 @@ static int scc_open (struct tty_struct * tty, struct file * filp) { COMMAND_REG, CR_EXTSTAT_RESET }, }; #endif - if (!(port->gs.port.flags & ASYNC_INITIALIZED)) { + if (!(port->gs.flags & ASYNC_INITIALIZED)) { local_irq_save(flags); #if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC) if (MACH_IS_MVME147 || MACH_IS_MVME16x) { @@ -881,18 +880,18 @@ static int scc_open (struct tty_struct * tty, struct file * filp) } tty->driver_data = port; - port->gs.port.tty = tty; - port->gs.port.count++; + port->gs.tty = tty; + port->gs.count++; retval = gs_init_port(&port->gs); if (retval) { - port->gs.port.count--; + port->gs.count--; return retval; } - port->gs.port.flags |= GS_ACTIVE; + port->gs.flags |= GS_ACTIVE; retval = gs_block_til_ready(port, filp); if (retval) { - port->gs.port.count--; + port->gs.count--; return retval; } diff --git a/trunk/drivers/crypto/talitos.c b/trunk/drivers/crypto/talitos.c index 681c15f42083..b11943dadefd 100644 --- a/trunk/drivers/crypto/talitos.c +++ b/trunk/drivers/crypto/talitos.c @@ -99,9 +99,6 @@ struct talitos_private { /* next channel to be assigned next incoming descriptor */ atomic_t last_chan; - /* per-channel number of requests pending in channel h/w fifo */ - atomic_t *submit_count; - /* per-channel request fifo */ struct talitos_request **fifo; @@ -266,15 +263,15 @@ static int talitos_submit(struct device *dev, struct talitos_desc *desc, spin_lock_irqsave(&priv->head_lock[ch], flags); - if (!atomic_inc_not_zero(&priv->submit_count[ch])) { - /* h/w fifo is full */ + head = priv->head[ch]; + request = &priv->fifo[ch][head]; + + if (request->desc) { + /* request queue is full */ spin_unlock_irqrestore(&priv->head_lock[ch], flags); return -EAGAIN; } - head = priv->head[ch]; - request = &priv->fifo[ch][head]; - /* map descriptor and save caller data */ request->dma_desc = dma_map_single(dev, desc, sizeof(*desc), DMA_BIDIRECTIONAL); @@ -338,9 +335,6 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch) priv->tail[ch] = (tail + 1) & (priv->fifo_len - 1); spin_unlock_irqrestore(&priv->tail_lock[ch], flags); - - atomic_dec(&priv->submit_count[ch]); - saved_req.callback(dev, saved_req.desc, saved_req.context, status); /* channel may resume processing in single desc error case */ @@ -848,7 +842,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count, /* adjust (decrease) last one (or two) entry's len to cryptlen */ link_tbl_ptr--; - while (be16_to_cpu(link_tbl_ptr->len) <= (-cryptlen)) { + while (link_tbl_ptr->len <= (-cryptlen)) { /* Empty this entry, and move to previous one */ cryptlen += be16_to_cpu(link_tbl_ptr->len); link_tbl_ptr->len = 0; @@ -880,7 +874,7 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, unsigned int cryptlen = areq->cryptlen; unsigned int authsize = ctx->authsize; unsigned int ivsize; - int sg_count, ret; + int sg_count; /* hmac key */ map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key, @@ -984,12 +978,7 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, 0, DMA_FROM_DEVICE); - ret = talitos_submit(dev, desc, callback, areq); - if (ret != -EINPROGRESS) { - ipsec_esp_unmap(dev, edesc, areq); - kfree(edesc); - } - return ret; + return talitos_submit(dev, desc, callback, areq); } @@ -1020,8 +1009,6 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, struct talitos_ctx *ctx = crypto_aead_ctx(authenc); struct ipsec_esp_edesc *edesc; int src_nents, dst_nents, alloc_len, dma_len; - gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : - GFP_ATOMIC; if (areq->cryptlen + ctx->authsize > TALITOS_MAX_DATA_LEN) { dev_err(ctx->dev, "cryptlen exceeds h/w max limit\n"); @@ -1035,7 +1022,7 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, dst_nents = src_nents; } else { dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize); - dst_nents = (dst_nents == 1) ? 0 : dst_nents; + dst_nents = (dst_nents == 1) ? 0 : src_nents; } /* @@ -1053,7 +1040,7 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, alloc_len += icv_stashing ? ctx->authsize : 0; } - edesc = kmalloc(alloc_len, GFP_DMA | flags); + edesc = kmalloc(alloc_len, GFP_DMA); if (!edesc) { dev_err(ctx->dev, "could not allocate edescriptor\n"); return ERR_PTR(-ENOMEM); @@ -1350,7 +1337,6 @@ static int __devexit talitos_remove(struct of_device *ofdev) if (hw_supports(dev, DESC_HDR_SEL0_RNG)) talitos_unregister_rng(dev); - kfree(priv->submit_count); kfree(priv->tail); kfree(priv->head); @@ -1480,6 +1466,9 @@ static int talitos_probe(struct of_device *ofdev, goto err_out; } + of_node_put(np); + np = NULL; + priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, GFP_KERNEL); priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, @@ -1515,16 +1504,6 @@ static int talitos_probe(struct of_device *ofdev, } } - priv->submit_count = kmalloc(sizeof(atomic_t) * priv->num_channels, - GFP_KERNEL); - if (!priv->submit_count) { - dev_err(dev, "failed to allocate fifo submit count space\n"); - err = -ENOMEM; - goto err_out; - } - for (i = 0; i < priv->num_channels; i++) - atomic_set(&priv->submit_count[i], -priv->chfifo_len); - priv->head = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); priv->tail = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); if (!priv->head || !priv->tail) { @@ -1580,6 +1559,8 @@ static int talitos_probe(struct of_device *ofdev, err_out: talitos_remove(ofdev); + if (np) + of_node_put(np); return err; } diff --git a/trunk/drivers/firewire/Kconfig b/trunk/drivers/firewire/Kconfig index fa6d6abefd4d..76f26710fc16 100644 --- a/trunk/drivers/firewire/Kconfig +++ b/trunk/drivers/firewire/Kconfig @@ -16,13 +16,8 @@ config FIREWIRE enable the new stack. To compile this driver as a module, say M here: the module will be - called firewire-core. - - This module functionally replaces ieee1394, raw1394, and video1394. - To access it from application programs, you generally need at least - libraw1394 version 2. IIDC/DCAM applications also need libdc1394 - version 2. No libraries are required to access storage devices - through the firewire-sbp2 driver. + called firewire-core. It functionally replaces ieee1394, raw1394, + and video1394. config FIREWIRE_OHCI tristate "OHCI-1394 controllers" diff --git a/trunk/drivers/firewire/fw-card.c b/trunk/drivers/firewire/fw-card.c index bbd73a406e53..da873d795aad 100644 --- a/trunk/drivers/firewire/fw-card.c +++ b/trunk/drivers/firewire/fw-card.c @@ -539,7 +539,7 @@ fw_core_remove_card(struct fw_card *card) wait_for_completion(&card->done); cancel_delayed_work_sync(&card->work); - WARN_ON(!list_empty(&card->transaction_list)); + fw_flush_transactions(card); del_timer_sync(&card->flush_timer); } EXPORT_SYMBOL(fw_core_remove_card); diff --git a/trunk/drivers/firewire/fw-cdev.c b/trunk/drivers/firewire/fw-cdev.c index bc81d6fcd2fd..c639915fc3cb 100644 --- a/trunk/drivers/firewire/fw-cdev.c +++ b/trunk/drivers/firewire/fw-cdev.c @@ -382,9 +382,9 @@ complete_transaction(struct fw_card *card, int rcode, response->response.type = FW_CDEV_EVENT_RESPONSE; response->response.rcode = rcode; - queue_event(client, &response->event, &response->response, - sizeof(response->response) + response->response.length, - NULL, 0); + queue_event(client, &response->event, + &response->response, sizeof(response->response), + response->response.data, response->response.length); } static int ioctl_send_request(struct client *client, void *buffer) diff --git a/trunk/drivers/firewire/fw-iso.c b/trunk/drivers/firewire/fw-iso.c index e14c03dc0065..bcbe794a3ea5 100644 --- a/trunk/drivers/firewire/fw-iso.c +++ b/trunk/drivers/firewire/fw-iso.c @@ -50,7 +50,7 @@ fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card, address = dma_map_page(card->device, buffer->pages[i], 0, PAGE_SIZE, direction); - if (dma_mapping_error(card->device, address)) { + if (dma_mapping_error(address)) { __free_page(buffer->pages[i]); goto out_pages; } diff --git a/trunk/drivers/firewire/fw-ohci.c b/trunk/drivers/firewire/fw-ohci.c index 251416f2148f..333b12544dd1 100644 --- a/trunk/drivers/firewire/fw-ohci.c +++ b/trunk/drivers/firewire/fw-ohci.c @@ -171,6 +171,7 @@ struct iso_context { struct fw_ohci { struct fw_card card; + u32 version; __iomem char *registers; dma_addr_t self_id_bus; __le32 *self_id_cpu; @@ -179,8 +180,6 @@ struct fw_ohci { int generation; int request_generation; /* for timestamping incoming requests */ u32 bus_seconds; - - bool use_dualbuffer; bool old_uninorth; bool bus_reset_packet_quirk; @@ -954,7 +953,7 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet) payload_bus = dma_map_single(ohci->card.device, packet->payload, packet->payload_length, DMA_TO_DEVICE); - if (dma_mapping_error(ohci->card.device, payload_bus)) { + if (dma_mapping_error(payload_bus)) { packet->ack = RCODE_SEND_ERROR; return -1; } @@ -1886,7 +1885,7 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size) } else { mask = &ohci->ir_context_mask; list = ohci->ir_context_list; - if (ohci->use_dualbuffer) + if (ohci->version >= OHCI_VERSION_1_1) callback = handle_ir_dualbuffer_packet; else callback = handle_ir_packet_per_buffer; @@ -1950,7 +1949,7 @@ static int ohci_start_iso(struct fw_iso_context *base, } else { index = ctx - ohci->ir_context_list; control = IR_CONTEXT_ISOCH_HEADER; - if (ohci->use_dualbuffer) + if (ohci->version >= OHCI_VERSION_1_1) control |= IR_CONTEXT_DUAL_BUFFER_MODE; match = (tags << 28) | (sync << 8) | ctx->base.channel; if (cycle >= 0) { @@ -2280,7 +2279,7 @@ ohci_queue_iso(struct fw_iso_context *base, spin_lock_irqsave(&ctx->context.ohci->lock, flags); if (base->type == FW_ISO_CONTEXT_TRANSMIT) retval = ohci_queue_iso_transmit(base, packet, buffer, payload); - else if (ctx->context.ohci->use_dualbuffer) + else if (ctx->context.ohci->version >= OHCI_VERSION_1_1) retval = ohci_queue_iso_receive_dualbuffer(base, packet, buffer, payload); else @@ -2342,7 +2341,7 @@ static int __devinit pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { struct fw_ohci *ohci; - u32 bus_options, max_receive, link_speed, version; + u32 bus_options, max_receive, link_speed; u64 guid; int err; size_t size; @@ -2367,6 +2366,12 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); pci_set_drvdata(dev, ohci); +#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) + ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && + dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; +#endif + ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; + spin_lock_init(&ohci->lock); tasklet_init(&ohci->bus_reset_tasklet, @@ -2385,23 +2390,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) goto fail_iomem; } - version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; - ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; - -/* x86-32 currently doesn't use highmem for dma_alloc_coherent */ -#if !defined(CONFIG_X86_32) - /* dual-buffer mode is broken with descriptor addresses above 2G */ - if (dev->vendor == PCI_VENDOR_ID_TI && - dev->device == PCI_DEVICE_ID_TI_TSB43AB22) - ohci->use_dualbuffer = false; -#endif - -#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) - ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && - dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; -#endif - ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; - ar_context_init(&ohci->ar_request_ctx, ohci, OHCI1394_AsReqRcvContextControlSet); @@ -2453,8 +2441,9 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (err < 0) goto fail_self_id; + ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", - dev->dev.bus_id, version >> 16, version & 0xff); + dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff); return 0; fail_self_id: diff --git a/trunk/drivers/firewire/fw-sbp2.c b/trunk/drivers/firewire/fw-sbp2.c index aaff50ebba1d..53fc5a641e6d 100644 --- a/trunk/drivers/firewire/fw-sbp2.c +++ b/trunk/drivers/firewire/fw-sbp2.c @@ -543,7 +543,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, orb->response_bus = dma_map_single(device->card->device, &orb->response, sizeof(orb->response), DMA_FROM_DEVICE); - if (dma_mapping_error(device->card->device, orb->response_bus)) + if (dma_mapping_error(orb->response_bus)) goto fail_mapping_response; orb->request.response.high = 0; @@ -577,7 +577,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(device->card->device, orb->base.request_bus)) + if (dma_mapping_error(orb->base.request_bus)) goto fail_mapping_request; sbp2_send_orb(&orb->base, lu, node_id, generation, @@ -1424,7 +1424,7 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, orb->page_table_bus = dma_map_single(device->card->device, orb->page_table, sizeof(orb->page_table), DMA_TO_DEVICE); - if (dma_mapping_error(device->card->device, orb->page_table_bus)) + if (dma_mapping_error(orb->page_table_bus)) goto fail_page_table; /* @@ -1509,7 +1509,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(device->card->device, orb->base.request_bus)) + if (dma_mapping_error(orb->base.request_bus)) goto out; sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation, diff --git a/trunk/drivers/firewire/fw-topology.c b/trunk/drivers/firewire/fw-topology.c index c1b81077c4a8..213b0ff8f3d6 100644 --- a/trunk/drivers/firewire/fw-topology.c +++ b/trunk/drivers/firewire/fw-topology.c @@ -510,6 +510,8 @@ fw_core_handle_bus_reset(struct fw_card *card, struct fw_node *local_node; unsigned long flags; + fw_flush_transactions(card); + spin_lock_irqsave(&card->lock, flags); /* diff --git a/trunk/drivers/firewire/fw-transaction.c b/trunk/drivers/firewire/fw-transaction.c index e5d1a0b64fcf..40db80752272 100644 --- a/trunk/drivers/firewire/fw-transaction.c +++ b/trunk/drivers/firewire/fw-transaction.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -152,7 +151,7 @@ transmit_complete_callback(struct fw_packet *packet, static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, - int destination_id, int source_id, int generation, int speed, + int node_id, int source_id, int generation, int speed, unsigned long long offset, void *payload, size_t length) { int ext_tcode; @@ -167,7 +166,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, HEADER_RETRY(RETRY_X) | HEADER_TLABEL(tlabel) | HEADER_TCODE(tcode) | - HEADER_DESTINATION(destination_id); + HEADER_DESTINATION(node_id); packet->header[1] = HEADER_OFFSET_HIGH(offset >> 32) | HEADER_SOURCE(source_id); packet->header[2] = @@ -253,7 +252,7 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, fw_transaction_callback_t callback, void *callback_data) { unsigned long flags; - int tlabel; + int tlabel, source; /* * Bump the flush timer up 100ms first of all so we @@ -269,6 +268,7 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, spin_lock_irqsave(&card->lock, flags); + source = card->node_id; tlabel = card->current_tlabel; if (card->tlabel_mask & (1 << tlabel)) { spin_unlock_irqrestore(&card->lock, flags); @@ -279,58 +279,77 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, card->current_tlabel = (card->current_tlabel + 1) & 0x1f; card->tlabel_mask |= (1 << tlabel); + list_add_tail(&t->link, &card->transaction_list); + + spin_unlock_irqrestore(&card->lock, flags); + + /* Initialize rest of transaction, fill out packet and send it. */ t->node_id = node_id; t->tlabel = tlabel; t->callback = callback; t->callback_data = callback_data; - fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id, - generation, speed, offset, payload, length); + fw_fill_request(&t->packet, tcode, t->tlabel, + node_id, source, generation, + speed, offset, payload, length); t->packet.callback = transmit_complete_callback; - list_add_tail(&t->link, &card->transaction_list); - - spin_unlock_irqrestore(&card->lock, flags); - card->driver->send_request(card, &t->packet); } EXPORT_SYMBOL(fw_send_request); -static DEFINE_MUTEX(phy_config_mutex); -static DECLARE_COMPLETION(phy_config_done); +struct fw_phy_packet { + struct fw_packet packet; + struct completion done; + struct kref kref; +}; + +static void phy_packet_release(struct kref *kref) +{ + struct fw_phy_packet *p = + container_of(kref, struct fw_phy_packet, kref); + kfree(p); +} static void transmit_phy_packet_callback(struct fw_packet *packet, struct fw_card *card, int status) { - complete(&phy_config_done); -} + struct fw_phy_packet *p = + container_of(packet, struct fw_phy_packet, packet); -static struct fw_packet phy_config_packet = { - .header_length = 8, - .payload_length = 0, - .speed = SCODE_100, - .callback = transmit_phy_packet_callback, -}; + complete(&p->done); + kref_put(&p->kref, phy_packet_release); +} void fw_send_phy_config(struct fw_card *card, int node_id, int generation, int gap_count) { + struct fw_phy_packet *p; long timeout = DIV_ROUND_UP(HZ, 10); u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | PHY_CONFIG_ROOT_ID(node_id) | PHY_CONFIG_GAP_COUNT(gap_count); - mutex_lock(&phy_config_mutex); - - phy_config_packet.header[0] = data; - phy_config_packet.header[1] = ~data; - phy_config_packet.generation = generation; - INIT_COMPLETION(phy_config_done); - - card->driver->send_request(card, &phy_config_packet); - wait_for_completion_timeout(&phy_config_done, timeout); + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) + return; - mutex_unlock(&phy_config_mutex); + p->packet.header[0] = data; + p->packet.header[1] = ~data; + p->packet.header_length = 8; + p->packet.payload_length = 0; + p->packet.speed = SCODE_100; + p->packet.generation = generation; + p->packet.callback = transmit_phy_packet_callback; + init_completion(&p->done); + kref_set(&p->kref, 2); + + card->driver->send_request(card, &p->packet); + timeout = wait_for_completion_timeout(&p->done, timeout); + kref_put(&p->kref, phy_packet_release); + + /* will leak p if the callback is never executed */ + WARN_ON(timeout == 0); } void fw_flush_transactions(struct fw_card *card) diff --git a/trunk/drivers/firmware/memmap.c b/trunk/drivers/firmware/memmap.c index 001622eb86f9..e23399c7f773 100644 --- a/trunk/drivers/firmware/memmap.c +++ b/trunk/drivers/firmware/memmap.c @@ -153,14 +153,12 @@ int __init firmware_map_add_early(resource_size_t start, resource_size_t end, static ssize_t start_show(struct firmware_map_entry *entry, char *buf) { - return snprintf(buf, PAGE_SIZE, "0x%llx\n", - (unsigned long long)entry->start); + return snprintf(buf, PAGE_SIZE, "0x%llx\n", entry->start); } static ssize_t end_show(struct firmware_map_entry *entry, char *buf) { - return snprintf(buf, PAGE_SIZE, "0x%llx\n", - (unsigned long long)entry->end); + return snprintf(buf, PAGE_SIZE, "0x%llx\n", entry->end); } static ssize_t type_show(struct firmware_map_entry *entry, char *buf) diff --git a/trunk/drivers/gpu/drm/drm_drv.c b/trunk/drivers/gpu/drm/drm_drv.c index 452c2d866ec5..564138714bb5 100644 --- a/trunk/drivers/gpu/drm/drm_drv.c +++ b/trunk/drivers/gpu/drm/drm_drv.c @@ -318,7 +318,7 @@ static void drm_cleanup(struct drm_device * dev) DRM_ERROR("Cannot unload module\n"); } -static int drm_minors_cleanup(int id, void *ptr, void *data) +int drm_minors_cleanup(int id, void *ptr, void *data) { struct drm_minor *minor = ptr; struct drm_device *dev; diff --git a/trunk/drivers/infiniband/core/ucm.c b/trunk/drivers/infiniband/core/ucm.c index e603736682bf..9494005d1c9a 100644 --- a/trunk/drivers/infiniband/core/ucm.c +++ b/trunk/drivers/infiniband/core/ucm.c @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -1153,18 +1154,11 @@ static unsigned int ib_ucm_poll(struct file *filp, return mask; } -/* - * ib_ucm_open() does not need the BKL: - * - * - no global state is referred to; - * - there is no ioctl method to race against; - * - no further module initialization is required for open to work - * after the device is registered. - */ static int ib_ucm_open(struct inode *inode, struct file *filp) { struct ib_ucm_file *file; + cycle_kernel_lock(); file = kmalloc(sizeof(*file), GFP_KERNEL); if (!file) return -ENOMEM; diff --git a/trunk/drivers/infiniband/core/ucma.c b/trunk/drivers/infiniband/core/ucma.c index b41dd26bbfa1..195f97302fe5 100644 --- a/trunk/drivers/infiniband/core/ucma.c +++ b/trunk/drivers/infiniband/core/ucma.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -1148,14 +1149,6 @@ static unsigned int ucma_poll(struct file *filp, struct poll_table_struct *wait) return mask; } -/* - * ucma_open() does not need the BKL: - * - * - no global state is referred to; - * - there is no ioctl method to race against; - * - no further module initialization is required for open to work - * after the device is registered. - */ static int ucma_open(struct inode *inode, struct file *filp) { struct ucma_file *file; @@ -1164,6 +1157,7 @@ static int ucma_open(struct inode *inode, struct file *filp) if (!file) return -ENOMEM; + lock_kernel(); INIT_LIST_HEAD(&file->event_list); INIT_LIST_HEAD(&file->ctx_list); init_waitqueue_head(&file->poll_wait); @@ -1171,6 +1165,7 @@ static int ucma_open(struct inode *inode, struct file *filp) filp->private_data = file; file->filp = filp; + unlock_kernel(); return 0; } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c b/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c index 284c9bca517e..eaba03273e4f 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -698,7 +698,7 @@ int ipath_sdma_verbs_send(struct ipath_devdata *dd, addr = dma_map_single(&dd->pcidev->dev, tx->txreq.map_addr, tx->map_len, DMA_TO_DEVICE); - if (dma_mapping_error(&dd->pcidev->dev, addr)) { + if (dma_mapping_error(addr)) { ret = -EIO; goto unlock; } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/trunk/drivers/infiniband/hw/ipath/ipath_user_sdma.c index 82d9a0b5ca2f..86e016916cd1 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_user_sdma.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_user_sdma.c @@ -206,7 +206,7 @@ static int ipath_user_sdma_coalesce(const struct ipath_devdata *dd, dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, DMA_TO_DEVICE); - if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { + if (dma_mapping_error(dma_addr)) { ret = -ENOMEM; goto free_unmap; } @@ -301,7 +301,7 @@ static int ipath_user_sdma_pin_pages(const struct ipath_devdata *dd, pages[j], 0, flen, DMA_TO_DEVICE); unsigned long fofs = addr & ~PAGE_MASK; - if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { + if (dma_mapping_error(dma_addr)) { ret = -ENOMEM; goto done; } @@ -508,7 +508,7 @@ static int ipath_user_sdma_queue_pkts(const struct ipath_devdata *dd, if (page) { dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, DMA_TO_DEVICE); - if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { + if (dma_mapping_error(dma_addr)) { ret = -ENOMEM; goto free_pbc; } diff --git a/trunk/drivers/infiniband/hw/mlx4/cq.c b/trunk/drivers/infiniband/hw/mlx4/cq.c index a1464574bfdd..0b191a4842ce 100644 --- a/trunk/drivers/infiniband/hw/mlx4/cq.c +++ b/trunk/drivers/infiniband/hw/mlx4/cq.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/mlx4/main.c b/trunk/drivers/infiniband/hw/mlx4/main.c index a3c2851c0545..38d6907ab521 100644 --- a/trunk/drivers/infiniband/hw/mlx4/main.c +++ b/trunk/drivers/infiniband/hw/mlx4/main.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h b/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h index 6e2b0dc21b61..d26a91317d4d 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2006, 2007 Cisco Systems. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/mlx4/mr.c b/trunk/drivers/infiniband/hw/mlx4/mr.c index a4cdb465cd1d..db2086faa4ed 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mr.c +++ b/trunk/drivers/infiniband/hw/mlx4/mr.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/mlx4/qp.c b/trunk/drivers/infiniband/hw/mlx4/qp.c index f7bc7dd8578a..02a99bc4442e 100644 --- a/trunk/drivers/infiniband/hw/mlx4/qp.c +++ b/trunk/drivers/infiniband/hw/mlx4/qp.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/mlx4/srq.c b/trunk/drivers/infiniband/hw/mlx4/srq.c index d42565258fb7..12d6bc6f8007 100644 --- a/trunk/drivers/infiniband/hw/mlx4/srq.c +++ b/trunk/drivers/infiniband/hw/mlx4/srq.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/mlx4/user.h b/trunk/drivers/infiniband/hw/mlx4/user.h index 13beedeeef9f..e2d11be4525c 100644 --- a/trunk/drivers/infiniband/hw/mlx4/user.h +++ b/trunk/drivers/infiniband/hw/mlx4/user.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c index cc6858f0b65b..4e36aa7cb3d2 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c @@ -780,7 +780,7 @@ int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt) return -ENOMEM; dev->eq_table.icm_dma = pci_map_page(dev->pdev, dev->eq_table.icm_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, dev->eq_table.icm_dma)) { + if (pci_dma_mapping_error(dev->eq_table.icm_dma)) { __free_page(dev->eq_table.icm_page); return -ENOMEM; } diff --git a/trunk/drivers/infiniband/hw/nes/nes.c b/trunk/drivers/infiniband/hw/nes/nes.c index b0cab64e5e3d..d2884e778098 100644 --- a/trunk/drivers/infiniband/hw/nes/nes.c +++ b/trunk/drivers/infiniband/hw/nes/nes.c @@ -276,7 +276,6 @@ static void nes_cqp_rem_ref_callback(struct nes_device *nesdev, struct nes_cqp_r } nes_free_resource(nesadapter, nesadapter->allocated_qps, nesqp->hwqp.qp_id); - nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = NULL; kfree(nesqp->allocated_buffer); } @@ -290,6 +289,7 @@ void nes_rem_ref(struct ib_qp *ibqp) struct nes_qp *nesqp; struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); struct nes_device *nesdev = nesvnic->nesdev; + struct nes_adapter *nesadapter = nesdev->nesadapter; struct nes_hw_cqp_wqe *cqp_wqe; struct nes_cqp_request *cqp_request; u32 opcode; @@ -303,6 +303,8 @@ void nes_rem_ref(struct ib_qp *ibqp) } if (atomic_dec_and_test(&nesqp->refcount)) { + nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = NULL; + /* Destroy the QP */ cqp_request = nes_get_cqp_request(nesdev); if (cqp_request == NULL) { diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.c b/trunk/drivers/infiniband/hw/nes/nes_cm.c index 9f0b964b2c99..6aa531d5276d 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.c +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.c @@ -74,59 +74,36 @@ atomic_t cm_nodes_destroyed; atomic_t cm_accel_dropped_pkts; atomic_t cm_resets_recvd; -static inline int mini_cm_accelerated(struct nes_cm_core *, - struct nes_cm_node *); +static inline int mini_cm_accelerated(struct nes_cm_core *, struct nes_cm_node *); static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *, - struct nes_vnic *, struct nes_cm_info *); + struct nes_vnic *, struct nes_cm_info *); +static int add_ref_cm_node(struct nes_cm_node *); +static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *); static int mini_cm_del_listen(struct nes_cm_core *, struct nes_cm_listener *); +static struct sk_buff *form_cm_frame(struct sk_buff *, struct nes_cm_node *, + void *, u32, void *, u32, u8); +static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node); + static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *, - struct nes_vnic *, u16, void *, struct nes_cm_info *); -static int mini_cm_close(struct nes_cm_core *, struct nes_cm_node *); + struct nes_vnic *, + struct ietf_mpa_frame *, + struct nes_cm_info *); static int mini_cm_accept(struct nes_cm_core *, struct ietf_mpa_frame *, - struct nes_cm_node *); + struct nes_cm_node *); static int mini_cm_reject(struct nes_cm_core *, struct ietf_mpa_frame *, - struct nes_cm_node *); -static void mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *, - struct sk_buff *); + struct nes_cm_node *); +static int mini_cm_close(struct nes_cm_core *, struct nes_cm_node *); +static int mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *, + struct sk_buff *); static int mini_cm_dealloc_core(struct nes_cm_core *); static int mini_cm_get(struct nes_cm_core *); static int mini_cm_set(struct nes_cm_core *, u32, u32); - -static struct sk_buff *form_cm_frame(struct sk_buff *, struct nes_cm_node *, - void *, u32, void *, u32, u8); -static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node); -static int add_ref_cm_node(struct nes_cm_node *); -static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *); - static int nes_cm_disconn_true(struct nes_qp *); static int nes_cm_post_event(struct nes_cm_event *event); static int nes_disconnect(struct nes_qp *nesqp, int abrupt); static void nes_disconnect_worker(struct work_struct *work); - -static int send_mpa_request(struct nes_cm_node *, struct sk_buff *); -static int send_syn(struct nes_cm_node *, u32, struct sk_buff *); -static int send_reset(struct nes_cm_node *, struct sk_buff *); -static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb); +static int send_ack(struct nes_cm_node *cm_node); static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb); -static void process_packet(struct nes_cm_node *, struct sk_buff *, - struct nes_cm_core *); - -static void active_open_err(struct nes_cm_node *, struct sk_buff *, int); -static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int); -static void cleanup_retrans_entry(struct nes_cm_node *); -static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *, - enum nes_cm_event_type); -static void free_retrans_entry(struct nes_cm_node *cm_node); -static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph, - struct sk_buff *skb, int optionsize, int passive); - -/* CM event handler functions */ -static void cm_event_connected(struct nes_cm_event *); -static void cm_event_connect_error(struct nes_cm_event *); -static void cm_event_reset(struct nes_cm_event *); -static void cm_event_mpa_req(struct nes_cm_event *); - -static void print_core(struct nes_cm_core *core); /* External CM API Interface */ /* instance of function pointers for client API */ @@ -181,11 +158,11 @@ static struct nes_cm_event *create_event(struct nes_cm_node *cm_node, event->cm_info.loc_port = cm_node->loc_port; event->cm_info.cm_id = cm_node->cm_id; - nes_debug(NES_DBG_CM, "cm_node=%p Created event=%p, type=%u, " - "dst_addr=%08x[%x], src_addr=%08x[%x]\n", - cm_node, event, type, event->cm_info.loc_addr, - event->cm_info.loc_port, event->cm_info.rem_addr, - event->cm_info.rem_port); + nes_debug(NES_DBG_CM, "Created event=%p, type=%u, dst_addr=%08x[%x]," + " src_addr=%08x[%x]\n", + event, type, + event->cm_info.loc_addr, event->cm_info.loc_port, + event->cm_info.rem_addr, event->cm_info.rem_port); nes_cm_post_event(event); return event; @@ -195,11 +172,14 @@ static struct nes_cm_event *create_event(struct nes_cm_node *cm_node, /** * send_mpa_request */ -static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb) +static int send_mpa_request(struct nes_cm_node *cm_node) { + struct sk_buff *skb; int ret; + + skb = get_free_pkt(cm_node); if (!skb) { - nes_debug(NES_DBG_CM, "skb set to NULL\n"); + nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); return -1; } @@ -208,8 +188,9 @@ static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb) cm_node->mpa_frame_size, SET_ACK); ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0); - if (ret < 0) + if (ret < 0) { return ret; + } return 0; } @@ -247,13 +228,47 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len) } +/** + * handle_exception_pkt - process an exception packet. + * We have been in a TSA state, and we have now received SW + * TCP/IP traffic should be a FIN request or IP pkt with options + */ +static int handle_exception_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb) +{ + int ret = 0; + struct tcphdr *tcph = tcp_hdr(skb); + + /* first check to see if this a FIN pkt */ + if (tcph->fin) { + /* we need to ACK the FIN request */ + send_ack(cm_node); + + /* check which side we are (client/server) and set next state accordingly */ + if (cm_node->tcp_cntxt.client) + cm_node->state = NES_CM_STATE_CLOSING; + else { + /* we are the server side */ + cm_node->state = NES_CM_STATE_CLOSE_WAIT; + /* since this is a self contained CM we don't wait for */ + /* an APP to close us, just send final FIN immediately */ + ret = send_fin(cm_node, NULL); + cm_node->state = NES_CM_STATE_LAST_ACK; + } + } else { + ret = -EINVAL; + } + + return ret; +} + + /** * form_cm_frame - get a free packet and build empty frame Use * node info to build. */ -static struct sk_buff *form_cm_frame(struct sk_buff *skb, - struct nes_cm_node *cm_node, void *options, u32 optionsize, - void *data, u32 datasize, u8 flags) +static struct sk_buff *form_cm_frame(struct sk_buff *skb, struct nes_cm_node *cm_node, + void *options, u32 optionsize, void *data, + u32 datasize, u8 flags) { struct tcphdr *tcph; struct iphdr *iph; @@ -317,12 +332,10 @@ static struct sk_buff *form_cm_frame(struct sk_buff *skb, cm_node->tcp_cntxt.loc_seq_num++; tcph->syn = 1; } else - cm_node->tcp_cntxt.loc_seq_num += datasize; + cm_node->tcp_cntxt.loc_seq_num += datasize; /* data (no headers) */ - if (flags & SET_FIN) { - cm_node->tcp_cntxt.loc_seq_num++; + if (flags & SET_FIN) tcph->fin = 1; - } if (flags & SET_RST) tcph->rst = 1; @@ -376,7 +389,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, int close_when_complete) { unsigned long flags; - struct nes_cm_core *cm_core = cm_node->cm_core; + struct nes_cm_core *cm_core; struct nes_timer_entry *new_send; int ret = 0; u32 was_timer_set; @@ -398,7 +411,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, new_send->close_when_complete = close_when_complete; if (type == NES_TIMER_TYPE_CLOSE) { - new_send->timetosend += (HZ/10); + new_send->timetosend += (HZ/2); /* TODO: decide on the correct value here */ spin_lock_irqsave(&cm_node->recv_list_lock, flags); list_add_tail(&new_send->list, &cm_node->recv_list); spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); @@ -407,28 +420,36 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, if (type == NES_TIMER_TYPE_SEND) { new_send->seq_num = ntohl(tcp_hdr(skb)->seq); atomic_inc(&new_send->skb->users); - spin_lock_irqsave(&cm_node->retrans_list_lock, flags); - cm_node->send_entry = new_send; - add_ref_cm_node(cm_node); - spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); - new_send->timetosend = jiffies + NES_RETRY_TIMEOUT; ret = nes_nic_cm_xmit(new_send->skb, cm_node->netdev); if (ret != NETDEV_TX_OK) { - nes_debug(NES_DBG_CM, "Error sending packet %p " - "(jiffies = %lu)\n", new_send, jiffies); + nes_debug(NES_DBG_CM, "Error sending packet %p (jiffies = %lu)\n", + new_send, jiffies); atomic_dec(&new_send->skb->users); new_send->timetosend = jiffies; } else { cm_packets_sent++; if (!send_retrans) { - cleanup_retrans_entry(cm_node); if (close_when_complete) - rem_ref_cm_node(cm_core, cm_node); + rem_ref_cm_node(cm_node->cm_core, cm_node); + dev_kfree_skb_any(new_send->skb); + kfree(new_send); return ret; } + new_send->timetosend = jiffies + NES_RETRY_TIMEOUT; } + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); + list_add_tail(&new_send->list, &cm_node->retrans_list); + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); + } + if (type == NES_TIMER_TYPE_RECV) { + new_send->seq_num = ntohl(tcp_hdr(skb)->seq); + new_send->timetosend = jiffies; + spin_lock_irqsave(&cm_node->recv_list_lock, flags); + list_add_tail(&new_send->list, &cm_node->recv_list); + spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); } + cm_core = cm_node->cm_core; was_timer_set = timer_pending(&cm_core->tcp_timer); @@ -455,27 +476,23 @@ static void nes_cm_timer_tick(unsigned long pass) struct list_head *list_node, *list_node_temp; struct nes_cm_core *cm_core = g_cm_core; struct nes_qp *nesqp; + struct sk_buff *skb; u32 settimer = 0; int ret = NETDEV_TX_OK; - enum nes_cm_node_state last_state; + int node_done; spin_lock_irqsave(&cm_core->ht_lock, flags); - list_for_each_safe(list_node, list_core_temp, - &cm_core->connected_nodes) { + list_for_each_safe(list_node, list_core_temp, &cm_core->connected_nodes) { cm_node = container_of(list_node, struct nes_cm_node, list); add_ref_cm_node(cm_node); spin_unlock_irqrestore(&cm_core->ht_lock, flags); spin_lock_irqsave(&cm_node->recv_list_lock, flags); - list_for_each_safe(list_core, list_node_temp, - &cm_node->recv_list) { - recv_entry = container_of(list_core, - struct nes_timer_entry, list); - if (!recv_entry) - break; - if (time_after(recv_entry->timetosend, jiffies)) { - if (nexttimeout > recv_entry->timetosend || - !settimer) { + list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) { + recv_entry = container_of(list_core, struct nes_timer_entry, list); + if ((time_after(recv_entry->timetosend, jiffies)) && + (recv_entry->type == NES_TIMER_TYPE_CLOSE)) { + if (nexttimeout > recv_entry->timetosend || !settimer) { nexttimeout = recv_entry->timetosend; settimer = 1; } @@ -484,143 +501,157 @@ static void nes_cm_timer_tick(unsigned long pass) list_del(&recv_entry->list); cm_id = cm_node->cm_id; spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); - nesqp = (struct nes_qp *)recv_entry->skb; - spin_lock_irqsave(&nesqp->lock, qplockflags); - if (nesqp->cm_id) { - nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, " - "refcount = %d: HIT A " - "NES_TIMER_TYPE_CLOSE with something " - "to do!!!\n", nesqp->hwqp.qp_id, cm_id, - atomic_read(&nesqp->refcount)); - nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; - nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; - nesqp->ibqp_state = IB_QPS_ERR; - spin_unlock_irqrestore(&nesqp->lock, - qplockflags); - nes_cm_disconn(nesqp); - } else { - spin_unlock_irqrestore(&nesqp->lock, - qplockflags); - nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, " - "refcount = %d: HIT A " - "NES_TIMER_TYPE_CLOSE with nothing " - "to do!!!\n", nesqp->hwqp.qp_id, cm_id, - atomic_read(&nesqp->refcount)); + if (recv_entry->type == NES_TIMER_TYPE_CLOSE) { + nesqp = (struct nes_qp *)recv_entry->skb; + spin_lock_irqsave(&nesqp->lock, qplockflags); + if (nesqp->cm_id) { + nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, refcount = %d: " + "****** HIT A NES_TIMER_TYPE_CLOSE" + " with something to do!!! ******\n", + nesqp->hwqp.qp_id, cm_id, + atomic_read(&nesqp->refcount)); + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; + nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; + nesqp->ibqp_state = IB_QPS_ERR; + spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_cm_disconn(nesqp); + } else { + spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, refcount = %d:" + " ****** HIT A NES_TIMER_TYPE_CLOSE" + " with nothing to do!!! ******\n", + nesqp->hwqp.qp_id, cm_id, + atomic_read(&nesqp->refcount)); + nes_rem_ref(&nesqp->ibqp); + } + if (cm_id) + cm_id->rem_ref(cm_id); } - if (cm_id) - cm_id->rem_ref(cm_id); - kfree(recv_entry); spin_lock_irqsave(&cm_node->recv_list_lock, flags); } spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); spin_lock_irqsave(&cm_node->retrans_list_lock, flags); - do { - send_entry = cm_node->send_entry; - if (!send_entry) - continue; + node_done = 0; + list_for_each_safe(list_core, list_node_temp, &cm_node->retrans_list) { + if (node_done) { + break; + } + send_entry = container_of(list_core, struct nes_timer_entry, list); if (time_after(send_entry->timetosend, jiffies)) { if (cm_node->state != NES_CM_STATE_TSA) { - if ((nexttimeout > - send_entry->timetosend) || - !settimer) { - nexttimeout = - send_entry->timetosend; + if ((nexttimeout > send_entry->timetosend) || !settimer) { + nexttimeout = send_entry->timetosend; settimer = 1; - continue; } + node_done = 1; + continue; } else { - free_retrans_entry(cm_node); + list_del(&send_entry->list); + skb = send_entry->skb; + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); + dev_kfree_skb_any(skb); + kfree(send_entry); + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); continue; } } - - if ((cm_node->state == NES_CM_STATE_TSA) || - (cm_node->state == NES_CM_STATE_CLOSED)) { - free_retrans_entry(cm_node); + if (send_entry->type == NES_TIMER_NODE_CLEANUP) { + list_del(&send_entry->list); + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); + kfree(send_entry); + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); + continue; + } + if ((send_entry->seq_num < cm_node->tcp_cntxt.rem_ack_num) || + (cm_node->state == NES_CM_STATE_TSA) || + (cm_node->state == NES_CM_STATE_CLOSED)) { + skb = send_entry->skb; + list_del(&send_entry->list); + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); + kfree(send_entry); + dev_kfree_skb_any(skb); + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); continue; } - if (!send_entry->retranscount || - !send_entry->retrycount) { + if (!send_entry->retranscount || !send_entry->retrycount) { cm_packets_dropped++; - last_state = cm_node->state; - cm_node->state = NES_CM_STATE_CLOSED; - free_retrans_entry(cm_node); - spin_unlock_irqrestore( - &cm_node->retrans_list_lock, flags); - if (last_state == NES_CM_STATE_SYN_RCVD) + skb = send_entry->skb; + list_del(&send_entry->list); + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); + dev_kfree_skb_any(skb); + kfree(send_entry); + if (cm_node->state == NES_CM_STATE_SYN_RCVD) { + /* this node never even generated an indication up to the cm */ rem_ref_cm_node(cm_core, cm_node); - else - create_event(cm_node, - NES_CM_EVENT_ABORTED); - spin_lock_irqsave(&cm_node->retrans_list_lock, - flags); + } else { + cm_node->state = NES_CM_STATE_CLOSED; + create_event(cm_node, NES_CM_EVENT_ABORTED); + } + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); continue; } + /* this seems like the correct place, but leave send entry unprotected */ + /* spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); */ atomic_inc(&send_entry->skb->users); cm_packets_retrans++; - nes_debug(NES_DBG_CM, "Retransmitting send_entry %p " - "for node %p, jiffies = %lu, time to send = " - "%lu, retranscount = %u, send_entry->seq_num = " - "0x%08X, cm_node->tcp_cntxt.rem_ack_num = " - "0x%08X\n", send_entry, cm_node, jiffies, - send_entry->timetosend, - send_entry->retranscount, - send_entry->seq_num, - cm_node->tcp_cntxt.rem_ack_num); - - spin_unlock_irqrestore(&cm_node->retrans_list_lock, - flags); + nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p," + " jiffies = %lu, time to send = %lu, retranscount = %u, " + "send_entry->seq_num = 0x%08X, cm_node->tcp_cntxt.rem_ack_num = 0x%08X\n", + send_entry, cm_node, jiffies, send_entry->timetosend, send_entry->retranscount, + send_entry->seq_num, cm_node->tcp_cntxt.rem_ack_num); + + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); ret = nes_nic_cm_xmit(send_entry->skb, cm_node->netdev); - spin_lock_irqsave(&cm_node->retrans_list_lock, flags); if (ret != NETDEV_TX_OK) { - nes_debug(NES_DBG_CM, "rexmit failed for " - "node=%p\n", cm_node); cm_packets_bounced++; atomic_dec(&send_entry->skb->users); send_entry->retrycount--; nexttimeout = jiffies + NES_SHORT_TIME; settimer = 1; + node_done = 1; + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); continue; } else { cm_packets_sent++; } - nes_debug(NES_DBG_CM, "Packet Sent: retrans count = " - "%u, retry count = %u.\n", - send_entry->retranscount, - send_entry->retrycount); + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); + list_del(&send_entry->list); + nes_debug(NES_DBG_CM, "Packet Sent: retrans count = %u, retry count = %u.\n", + send_entry->retranscount, send_entry->retrycount); if (send_entry->send_retrans) { send_entry->retranscount--; - send_entry->timetosend = jiffies + - NES_RETRY_TIMEOUT; - if (nexttimeout > send_entry->timetosend || - !settimer) { + send_entry->timetosend = jiffies + NES_RETRY_TIMEOUT; + if (nexttimeout > send_entry->timetosend || !settimer) { nexttimeout = send_entry->timetosend; settimer = 1; } + list_add(&send_entry->list, &cm_node->retrans_list); + continue; } else { int close_when_complete; - close_when_complete = - send_entry->close_when_complete; - nes_debug(NES_DBG_CM, "cm_node=%p state=%d\n", - cm_node, cm_node->state); - free_retrans_entry(cm_node); - if (close_when_complete) - rem_ref_cm_node(cm_node->cm_core, - cm_node); + skb = send_entry->skb; + close_when_complete = send_entry->close_when_complete; + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); + if (close_when_complete) { + BUG_ON(atomic_read(&cm_node->ref_count) == 1); + rem_ref_cm_node(cm_core, cm_node); + } + dev_kfree_skb_any(skb); + kfree(send_entry); + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); + continue; } - } while (0); - + } spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); - rem_ref_cm_node(cm_node->cm_core, cm_node); + + rem_ref_cm_node(cm_core, cm_node); + spin_lock_irqsave(&cm_core->ht_lock, flags); - if (ret != NETDEV_TX_OK) { - nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n", - cm_node); + if (ret != NETDEV_TX_OK) break; - } } spin_unlock_irqrestore(&cm_core->ht_lock, flags); @@ -636,14 +667,14 @@ static void nes_cm_timer_tick(unsigned long pass) /** * send_syn */ -static int send_syn(struct nes_cm_node *cm_node, u32 sendack, - struct sk_buff *skb) +static int send_syn(struct nes_cm_node *cm_node, u32 sendack) { int ret; int flags = SET_SYN; + struct sk_buff *skb; char optionsbuffer[sizeof(struct option_mss) + - sizeof(struct option_windowscale) + sizeof(struct option_base) + - TCP_OPTIONS_PADDING]; + sizeof(struct option_windowscale) + + sizeof(struct option_base) + 1]; int optionssize = 0; /* Sending MSS option */ @@ -664,7 +695,8 @@ static int send_syn(struct nes_cm_node *cm_node, u32 sendack, options->as_windowscale.shiftcount = cm_node->tcp_cntxt.rcv_wscale; optionssize += sizeof(struct option_windowscale); - if (sendack && !(NES_DRV_OPT_SUPRESS_OPTION_BC & nes_drv_opt)) { + if (sendack && !(NES_DRV_OPT_SUPRESS_OPTION_BC & nes_drv_opt) + ) { options = (union all_known_options *)&optionsbuffer[optionssize]; options->as_base.optionnum = OPTION_NUMBER_WRITE0; options->as_base.length = sizeof(struct option_base); @@ -682,8 +714,7 @@ static int send_syn(struct nes_cm_node *cm_node, u32 sendack, options->as_end = OPTION_NUMBER_END; optionssize += 1; - if (!skb) - skb = get_free_pkt(cm_node); + skb = get_free_pkt(cm_node); if (!skb) { nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); return -1; @@ -702,18 +733,18 @@ static int send_syn(struct nes_cm_node *cm_node, u32 sendack, /** * send_reset */ -static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb) +static int send_reset(struct nes_cm_node *cm_node) { int ret; + struct sk_buff *skb = get_free_pkt(cm_node); int flags = SET_RST | SET_ACK; - if (!skb) - skb = get_free_pkt(cm_node); if (!skb) { nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); return -1; } + add_ref_cm_node(cm_node); form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags); ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 1); @@ -724,12 +755,10 @@ static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb) /** * send_ack */ -static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb) +static int send_ack(struct nes_cm_node *cm_node) { int ret; - - if (!skb) - skb = get_free_pkt(cm_node); + struct sk_buff *skb = get_free_pkt(cm_node); if (!skb) { nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); @@ -893,8 +922,7 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node if (!cm_node || !cm_core) return -EINVAL; - nes_debug(NES_DBG_CM, "Adding Node %p to Active Connection HT\n", - cm_node); + nes_debug(NES_DBG_CM, "Adding Node to Active Connection HT\n"); /* first, make an index into our hash table */ hashkey = make_hashkey(cm_node->loc_port, cm_node->loc_addr, @@ -918,35 +946,10 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node * mini_cm_dec_refcnt_listen */ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, - struct nes_cm_listener *listener, int free_hanging_nodes) + struct nes_cm_listener *listener, int free_hanging_nodes) { int ret = 1; unsigned long flags; - struct list_head *list_pos = NULL; - struct list_head *list_temp = NULL; - struct nes_cm_node *cm_node = NULL; - - nes_debug(NES_DBG_CM, "attempting listener= %p free_nodes= %d, " - "refcnt=%d\n", listener, free_hanging_nodes, - atomic_read(&listener->ref_count)); - /* free non-accelerated child nodes for this listener */ - if (free_hanging_nodes) { - spin_lock_irqsave(&cm_core->ht_lock, flags); - list_for_each_safe(list_pos, list_temp, - &g_cm_core->connected_nodes) { - cm_node = container_of(list_pos, struct nes_cm_node, - list); - if ((cm_node->listener == listener) && - (!cm_node->accelerated)) { - cleanup_retrans_entry(cm_node); - spin_unlock_irqrestore(&cm_core->ht_lock, - flags); - send_reset(cm_node, NULL); - spin_lock_irqsave(&cm_core->ht_lock, flags); - } - } - spin_unlock_irqrestore(&cm_core->ht_lock, flags); - } spin_lock_irqsave(&cm_core->listen_list_lock, flags); if (!atomic_dec_return(&listener->ref_count)) { list_del(&listener->list); @@ -1064,18 +1067,18 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, cm_node->loc_port = cm_info->loc_port; cm_node->rem_port = cm_info->rem_port; cm_node->send_write0 = send_first; - nes_debug(NES_DBG_CM, "Make node addresses : loc = " NIPQUAD_FMT - ":%x, rem = " NIPQUAD_FMT ":%x\n", - HIPQUAD(cm_node->loc_addr), cm_node->loc_port, - HIPQUAD(cm_node->rem_addr), cm_node->rem_port); + nes_debug(NES_DBG_CM, "Make node addresses : loc = " NIPQUAD_FMT ":%x, rem = " NIPQUAD_FMT ":%x\n", + HIPQUAD(cm_node->loc_addr), cm_node->loc_port, + HIPQUAD(cm_node->rem_addr), cm_node->rem_port); cm_node->listener = listener; cm_node->netdev = nesvnic->netdev; cm_node->cm_id = cm_info->cm_id; memcpy(cm_node->loc_mac, nesvnic->netdev->dev_addr, ETH_ALEN); - nes_debug(NES_DBG_CM, "listener=%p, cm_id=%p\n", cm_node->listener, - cm_node->cm_id); + nes_debug(NES_DBG_CM, "listener=%p, cm_id=%p\n", + cm_node->listener, cm_node->cm_id); + INIT_LIST_HEAD(&cm_node->retrans_list); spin_lock_init(&cm_node->retrans_list_lock); INIT_LIST_HEAD(&cm_node->recv_list); spin_lock_init(&cm_node->recv_list_lock); @@ -1139,9 +1142,10 @@ static int add_ref_cm_node(struct nes_cm_node *cm_node) * rem_ref_cm_node - destroy an instance of a cm node */ static int rem_ref_cm_node(struct nes_cm_core *cm_core, - struct nes_cm_node *cm_node) + struct nes_cm_node *cm_node) { unsigned long flags, qplockflags; + struct nes_timer_entry *send_entry; struct nes_timer_entry *recv_entry; struct iw_cm_id *cm_id; struct list_head *list_core, *list_node_temp; @@ -1165,33 +1169,48 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core, atomic_dec(&cm_node->listener->pend_accepts_cnt); BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); } - BUG_ON(cm_node->send_entry); + + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); + list_for_each_safe(list_core, list_node_temp, &cm_node->retrans_list) { + send_entry = container_of(list_core, struct nes_timer_entry, list); + list_del(&send_entry->list); + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); + dev_kfree_skb_any(send_entry->skb); + kfree(send_entry); + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); + continue; + } + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); + spin_lock_irqsave(&cm_node->recv_list_lock, flags); list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) { - recv_entry = container_of(list_core, struct nes_timer_entry, - list); + recv_entry = container_of(list_core, struct nes_timer_entry, list); list_del(&recv_entry->list); cm_id = cm_node->cm_id; spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); - nesqp = (struct nes_qp *)recv_entry->skb; - spin_lock_irqsave(&nesqp->lock, qplockflags); - if (nesqp->cm_id) { - nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A " - "NES_TIMER_TYPE_CLOSE with something to do!\n", - nesqp->hwqp.qp_id, cm_id); - nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; - nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; - nesqp->ibqp_state = IB_QPS_ERR; - spin_unlock_irqrestore(&nesqp->lock, qplockflags); - nes_cm_disconn(nesqp); - } else { - spin_unlock_irqrestore(&nesqp->lock, qplockflags); - nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A " - "NES_TIMER_TYPE_CLOSE with nothing to do!\n", - nesqp->hwqp.qp_id, cm_id); + if (recv_entry->type == NES_TIMER_TYPE_CLOSE) { + nesqp = (struct nes_qp *)recv_entry->skb; + spin_lock_irqsave(&nesqp->lock, qplockflags); + if (nesqp->cm_id) { + nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: ****** HIT A NES_TIMER_TYPE_CLOSE" + " with something to do!!! ******\n", + nesqp->hwqp.qp_id, cm_id); + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; + nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; + nesqp->ibqp_state = IB_QPS_ERR; + spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_cm_disconn(nesqp); + } else { + spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: ****** HIT A NES_TIMER_TYPE_CLOSE" + " with nothing to do!!! ******\n", + nesqp->hwqp.qp_id, cm_id); + nes_rem_ref(&nesqp->ibqp); + } + cm_id->rem_ref(cm_id); + } else if (recv_entry->type == NES_TIMER_TYPE_RECV) { + dev_kfree_skb_any(recv_entry->skb); } - cm_id->rem_ref(cm_id); - kfree(recv_entry); spin_lock_irqsave(&cm_node->recv_list_lock, flags); } @@ -1202,31 +1221,23 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core, } else { if (cm_node->apbvt_set && cm_node->nesvnic) { nes_manage_apbvt(cm_node->nesvnic, cm_node->loc_port, - PCI_FUNC( - cm_node->nesvnic->nesdev->pcidev->devfn), - NES_MANAGE_APBVT_DEL); + PCI_FUNC(cm_node->nesvnic->nesdev->pcidev->devfn), + NES_MANAGE_APBVT_DEL); } } + kfree(cm_node); atomic_dec(&cm_core->node_cnt); atomic_inc(&cm_nodes_destroyed); - nesqp = cm_node->nesqp; - if (nesqp) { - nesqp->cm_node = NULL; - nes_rem_ref(&nesqp->ibqp); - cm_node->nesqp = NULL; - } - cm_node->freed = 1; - kfree(cm_node); return 0; } + /** * process_options */ -static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc, - u32 optionsize, u32 syn_packet) +static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc, u32 optionsize, u32 syn_packet) { u32 tmp; u32 offset = 0; @@ -1236,37 +1247,35 @@ static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc, while (offset < optionsize) { all_options = (union all_known_options *)(optionsloc + offset); switch (all_options->as_base.optionnum) { - case OPTION_NUMBER_END: - offset = optionsize; - break; - case OPTION_NUMBER_NONE: - offset += 1; - continue; - case OPTION_NUMBER_MSS: - nes_debug(NES_DBG_CM, "%s: MSS Length: %d Offset: %d " - "Size: %d\n", __func__, - all_options->as_mss.length, offset, optionsize); - got_mss_option = 1; - if (all_options->as_mss.length != 4) { - return 1; - } else { - tmp = ntohs(all_options->as_mss.mss); - if (tmp > 0 && tmp < - cm_node->tcp_cntxt.mss) - cm_node->tcp_cntxt.mss = tmp; - } - break; - case OPTION_NUMBER_WINDOW_SCALE: - cm_node->tcp_cntxt.snd_wscale = - all_options->as_windowscale.shiftcount; - break; - case OPTION_NUMBER_WRITE0: - cm_node->send_write0 = 1; - break; - default: - nes_debug(NES_DBG_CM, "TCP Option not understood: %x\n", - all_options->as_base.optionnum); - break; + case OPTION_NUMBER_END: + offset = optionsize; + break; + case OPTION_NUMBER_NONE: + offset += 1; + continue; + case OPTION_NUMBER_MSS: + nes_debug(NES_DBG_CM, "%s: MSS Length: %d Offset: %d Size: %d\n", + __func__, + all_options->as_mss.length, offset, optionsize); + got_mss_option = 1; + if (all_options->as_mss.length != 4) { + return 1; + } else { + tmp = ntohs(all_options->as_mss.mss); + if (tmp > 0 && tmp < cm_node->tcp_cntxt.mss) + cm_node->tcp_cntxt.mss = tmp; + } + break; + case OPTION_NUMBER_WINDOW_SCALE: + cm_node->tcp_cntxt.snd_wscale = all_options->as_windowscale.shiftcount; + break; + case OPTION_NUMBER_WRITE0: + cm_node->send_write0 = 1; + break; + default: + nes_debug(NES_DBG_CM, "TCP Option not understood: %x\n", + all_options->as_base.optionnum); + break; } offset += all_options->as_base.length; } @@ -1275,491 +1284,300 @@ static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc, return 0; } -static void drop_packet(struct sk_buff *skb) -{ - atomic_inc(&cm_accel_dropped_pkts); - dev_kfree_skb_any(skb); -} - -static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, - struct tcphdr *tcph) -{ - atomic_inc(&cm_resets_recvd); - nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. " - "refcnt=%d\n", cm_node, cm_node->state, - atomic_read(&cm_node->ref_count)); - cm_node->tcp_cntxt.rcv_nxt++; - cleanup_retrans_entry(cm_node); - switch (cm_node->state) { - case NES_CM_STATE_SYN_RCVD: - case NES_CM_STATE_SYN_SENT: - case NES_CM_STATE_ESTABLISHED: - case NES_CM_STATE_MPAREQ_SENT: - cm_node->state = NES_CM_STATE_LAST_ACK; - send_fin(cm_node, skb); - break; - case NES_CM_STATE_FIN_WAIT1: - cm_node->state = NES_CM_STATE_CLOSING; - send_ack(cm_node, skb); - break; - case NES_CM_STATE_FIN_WAIT2: - cm_node->state = NES_CM_STATE_TIME_WAIT; - send_ack(cm_node, skb); - cm_node->state = NES_CM_STATE_CLOSED; - break; - case NES_CM_STATE_TSA: - default: - nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n", - cm_node, cm_node->state); - drop_packet(skb); - break; - } -} - - -static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, - struct tcphdr *tcph) -{ - - int reset = 0; /* whether to send reset in case of err.. */ - atomic_inc(&cm_resets_recvd); - nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u." - " refcnt=%d\n", cm_node, cm_node->state, - atomic_read(&cm_node->ref_count)); - cleanup_retrans_entry(cm_node); - switch (cm_node->state) { - case NES_CM_STATE_SYN_SENT: - case NES_CM_STATE_MPAREQ_SENT: - nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p " - "listener=%p state=%d\n", __func__, __LINE__, cm_node, - cm_node->listener, cm_node->state); - active_open_err(cm_node, skb, reset); - break; - /* For PASSIVE open states, remove the cm_node event */ - case NES_CM_STATE_ESTABLISHED: - case NES_CM_STATE_SYN_RCVD: - case NES_CM_STATE_LISTENING: - nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__); - passive_open_err(cm_node, skb, reset); - break; - case NES_CM_STATE_TSA: - default: - break; - } -} - -static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb, - enum nes_cm_event_type type) -{ - - int ret; - int datasize = skb->len; - u8 *dataloc = skb->data; - ret = parse_mpa(cm_node, dataloc, datasize); - if (ret < 0) { - nes_debug(NES_DBG_CM, "didn't like MPA Request\n"); - if (type == NES_CM_EVENT_CONNECTED) { - nes_debug(NES_DBG_CM, "%s[%u] create abort for " - "cm_node=%p listener=%p state=%d\n", __func__, - __LINE__, cm_node, cm_node->listener, - cm_node->state); - active_open_err(cm_node, skb, 1); - } else { - passive_open_err(cm_node, skb, 1); - } - } else { - cleanup_retrans_entry(cm_node); - dev_kfree_skb_any(skb); - if (type == NES_CM_EVENT_CONNECTED) - cm_node->state = NES_CM_STATE_TSA; - create_event(cm_node, type); - - } - return ; -} - -static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb) -{ - switch (cm_node->state) { - case NES_CM_STATE_SYN_SENT: - case NES_CM_STATE_MPAREQ_SENT: - nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p " - "listener=%p state=%d\n", __func__, __LINE__, cm_node, - cm_node->listener, cm_node->state); - active_open_err(cm_node, skb, 1); - break; - case NES_CM_STATE_ESTABLISHED: - case NES_CM_STATE_SYN_RCVD: - passive_open_err(cm_node, skb, 1); - break; - case NES_CM_STATE_TSA: - default: - drop_packet(skb); - } -} -static int check_syn(struct nes_cm_node *cm_node, struct tcphdr *tcph, - struct sk_buff *skb) -{ - int err; - - err = ((ntohl(tcph->ack_seq) == cm_node->tcp_cntxt.loc_seq_num))? 0 : 1; - if (err) - active_open_err(cm_node, skb, 1); - - return err; -} - -static int check_seq(struct nes_cm_node *cm_node, struct tcphdr *tcph, - struct sk_buff *skb) -{ - int err = 0; - u32 seq; - u32 ack_seq; - u32 loc_seq_num = cm_node->tcp_cntxt.loc_seq_num; - u32 rcv_nxt = cm_node->tcp_cntxt.rcv_nxt; - u32 rcv_wnd; - seq = ntohl(tcph->seq); - ack_seq = ntohl(tcph->ack_seq); - rcv_wnd = cm_node->tcp_cntxt.rcv_wnd; - if (ack_seq != loc_seq_num) - err = 1; - else if ((seq + rcv_wnd) < rcv_nxt) - err = 1; - if (err) { - nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p " - "listener=%p state=%d\n", __func__, __LINE__, cm_node, - cm_node->listener, cm_node->state); - indicate_pkt_err(cm_node, skb); - nes_debug(NES_DBG_CM, "seq ERROR cm_node =%p seq=0x%08X " - "rcv_nxt=0x%08X rcv_wnd=0x%x\n", cm_node, seq, rcv_nxt, - rcv_wnd); - } - return err; -} - -/* - * handle_syn_pkt() is for Passive node. The syn packet is received when a node - * is created with a listener or it may comein as rexmitted packet which in - * that case will be just dropped. +/** + * process_packet */ - -static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, - struct tcphdr *tcph) +static int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, + struct nes_cm_core *cm_core) { - int ret; - u32 inc_sequence; int optionsize; + int datasize; + int ret = 0; + struct tcphdr *tcph = tcp_hdr(skb); + u32 inc_sequence; + if (cm_node->state == NES_CM_STATE_SYN_SENT && tcph->syn) { + inc_sequence = ntohl(tcph->seq); + cm_node->tcp_cntxt.rcv_nxt = inc_sequence; + } - optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); - skb_pull(skb, tcph->doff << 2); - inc_sequence = ntohl(tcph->seq); - - switch (cm_node->state) { - case NES_CM_STATE_SYN_SENT: - case NES_CM_STATE_MPAREQ_SENT: - /* Rcvd syn on active open connection*/ - active_open_err(cm_node, skb, 1); - break; - case NES_CM_STATE_LISTENING: - /* Passive OPEN */ - cm_node->accept_pend = 1; - atomic_inc(&cm_node->listener->pend_accepts_cnt); - if (atomic_read(&cm_node->listener->pend_accepts_cnt) > - cm_node->listener->backlog) { - nes_debug(NES_DBG_CM, "drop syn due to backlog " - "pressure \n"); - cm_backlog_drops++; - passive_open_err(cm_node, skb, 0); - break; - } - ret = handle_tcp_options(cm_node, tcph, skb, optionsize, - 1); - if (ret) { - passive_open_err(cm_node, skb, 0); - /* drop pkt */ - break; - } - cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1; - BUG_ON(cm_node->send_entry); - cm_node->state = NES_CM_STATE_SYN_RCVD; - send_syn(cm_node, 1, skb); - break; - case NES_CM_STATE_TSA: - case NES_CM_STATE_ESTABLISHED: - case NES_CM_STATE_FIN_WAIT1: - case NES_CM_STATE_FIN_WAIT2: - case NES_CM_STATE_MPAREQ_RCVD: - case NES_CM_STATE_LAST_ACK: - case NES_CM_STATE_CLOSING: - case NES_CM_STATE_UNKNOWN: - case NES_CM_STATE_CLOSED: - default: - drop_packet(skb); - break; + if ((!tcph) || (cm_node->state == NES_CM_STATE_TSA)) { + BUG_ON(!tcph); + atomic_inc(&cm_accel_dropped_pkts); + return -1; } -} -static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, - struct tcphdr *tcph) -{ + if (tcph->rst) { + atomic_inc(&cm_resets_recvd); + nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u. refcnt=%d\n", + cm_node, cm_node->state, atomic_read(&cm_node->ref_count)); + switch (cm_node->state) { + case NES_CM_STATE_LISTENING: + rem_ref_cm_node(cm_core, cm_node); + break; + case NES_CM_STATE_TSA: + case NES_CM_STATE_CLOSED: + break; + case NES_CM_STATE_SYN_RCVD: + nes_debug(NES_DBG_CM, "Received a reset for local 0x%08X:%04X," + " remote 0x%08X:%04X, node state = %u\n", + cm_node->loc_addr, cm_node->loc_port, + cm_node->rem_addr, cm_node->rem_port, + cm_node->state); + rem_ref_cm_node(cm_core, cm_node); + break; + case NES_CM_STATE_ONE_SIDE_ESTABLISHED: + case NES_CM_STATE_ESTABLISHED: + case NES_CM_STATE_MPAREQ_SENT: + default: + nes_debug(NES_DBG_CM, "Received a reset for local 0x%08X:%04X," + " remote 0x%08X:%04X, node state = %u refcnt=%d\n", + cm_node->loc_addr, cm_node->loc_port, + cm_node->rem_addr, cm_node->rem_port, + cm_node->state, atomic_read(&cm_node->ref_count)); + /* create event */ + cm_node->state = NES_CM_STATE_CLOSED; - int ret; - u32 inc_sequence; - int optionsize; + create_event(cm_node, NES_CM_EVENT_ABORTED); + break; - optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); - skb_pull(skb, tcph->doff << 2); - inc_sequence = ntohl(tcph->seq); - switch (cm_node->state) { - case NES_CM_STATE_SYN_SENT: - /* active open */ - if (check_syn(cm_node, tcph, skb)) - return; - cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); - /* setup options */ - ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 0); - if (ret) { - nes_debug(NES_DBG_CM, "cm_node=%p tcp_options failed\n", - cm_node); - break; } - cleanup_retrans_entry(cm_node); - cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1; - send_mpa_request(cm_node, skb); - cm_node->state = NES_CM_STATE_MPAREQ_SENT; - break; - case NES_CM_STATE_MPAREQ_RCVD: - /* passive open, so should not be here */ - passive_open_err(cm_node, skb, 1); - break; - case NES_CM_STATE_ESTABLISHED: - case NES_CM_STATE_FIN_WAIT1: - case NES_CM_STATE_FIN_WAIT2: - case NES_CM_STATE_LAST_ACK: - case NES_CM_STATE_TSA: - case NES_CM_STATE_CLOSING: - case NES_CM_STATE_UNKNOWN: - case NES_CM_STATE_CLOSED: - case NES_CM_STATE_MPAREQ_SENT: - default: - drop_packet(skb); - break; + return -1; } -} -static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, - struct tcphdr *tcph) -{ - int datasize = 0; - u32 inc_sequence; - u32 rem_seq_ack; - u32 rem_seq; - if (check_seq(cm_node, tcph, skb)) - return; + optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); + skb_pull(skb, ip_hdr(skb)->ihl << 2); skb_pull(skb, tcph->doff << 2); - inc_sequence = ntohl(tcph->seq); - rem_seq = ntohl(tcph->seq); - rem_seq_ack = ntohl(tcph->ack_seq); - datasize = skb->len; - switch (cm_node->state) { - case NES_CM_STATE_SYN_RCVD: - /* Passive OPEN */ - cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); - cm_node->state = NES_CM_STATE_ESTABLISHED; - if (datasize) { - cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; - cm_node->state = NES_CM_STATE_MPAREQ_RCVD; - handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_MPA_REQ); - } else { /* rcvd ACK only */ - dev_kfree_skb_any(skb); - cleanup_retrans_entry(cm_node); - } - break; - case NES_CM_STATE_ESTABLISHED: - /* Passive OPEN */ - /* We expect mpa frame to be received only */ - if (datasize) { - cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; - cm_node->state = NES_CM_STATE_MPAREQ_RCVD; - handle_rcv_mpa(cm_node, skb, - NES_CM_EVENT_MPA_REQ); - } else - drop_packet(skb); - break; - case NES_CM_STATE_MPAREQ_SENT: - cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); - if (datasize) { - cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; - handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_CONNECTED); - } else { /* Could be just an ack pkt.. */ - cleanup_retrans_entry(cm_node); - dev_kfree_skb_any(skb); + datasize = skb->len; + inc_sequence = ntohl(tcph->seq); + nes_debug(NES_DBG_CM, "datasize = %u, sequence = 0x%08X, ack_seq = 0x%08X," + " rcv_nxt = 0x%08X Flags: %s %s.\n", + datasize, inc_sequence, ntohl(tcph->ack_seq), + cm_node->tcp_cntxt.rcv_nxt, (tcph->syn ? "SYN":""), + (tcph->ack ? "ACK":"")); + + if (!tcph->syn && (inc_sequence != cm_node->tcp_cntxt.rcv_nxt) + ) { + nes_debug(NES_DBG_CM, "dropping packet, datasize = %u, sequence = 0x%08X," + " ack_seq = 0x%08X, rcv_nxt = 0x%08X Flags: %s.\n", + datasize, inc_sequence, ntohl(tcph->ack_seq), + cm_node->tcp_cntxt.rcv_nxt, (tcph->ack ? "ACK":"")); + if (cm_node->state == NES_CM_STATE_LISTENING) { + rem_ref_cm_node(cm_core, cm_node); } - break; - case NES_CM_STATE_FIN_WAIT1: - case NES_CM_STATE_SYN_SENT: - case NES_CM_STATE_FIN_WAIT2: - case NES_CM_STATE_TSA: - case NES_CM_STATE_CLOSED: - case NES_CM_STATE_MPAREQ_RCVD: - case NES_CM_STATE_LAST_ACK: - case NES_CM_STATE_CLOSING: - case NES_CM_STATE_UNKNOWN: - default: - drop_packet(skb); - break; + return -1; } -} + cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; -static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph, - struct sk_buff *skb, int optionsize, int passive) -{ - u8 *optionsloc = (u8 *)&tcph[1]; if (optionsize) { - if (process_options(cm_node, optionsloc, optionsize, - (u32)tcph->syn)) { - nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n", - __func__, cm_node); - if (passive) - passive_open_err(cm_node, skb, 0); - else - active_open_err(cm_node, skb, 0); - return 1; + u8 *optionsloc = (u8 *)&tcph[1]; + if (process_options(cm_node, optionsloc, optionsize, (u32)tcph->syn)) { + nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n", __func__, cm_node); + send_reset(cm_node); + if (cm_node->state != NES_CM_STATE_SYN_SENT) + rem_ref_cm_node(cm_core, cm_node); + return 0; } - } + } else if (tcph->syn) + cm_node->tcp_cntxt.mss = NES_CM_DEFAULT_MSS; cm_node->tcp_cntxt.snd_wnd = ntohs(tcph->window) << cm_node->tcp_cntxt.snd_wscale; - if (cm_node->tcp_cntxt.snd_wnd > cm_node->tcp_cntxt.max_snd_wnd) + if (cm_node->tcp_cntxt.snd_wnd > cm_node->tcp_cntxt.max_snd_wnd) { cm_node->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.snd_wnd; - return 0; -} + } -/* - * active_open_err() will send reset() if flag set.. - * It will also send ABORT event. - */ + if (tcph->ack) { + cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); + switch (cm_node->state) { + case NES_CM_STATE_SYN_RCVD: + case NES_CM_STATE_SYN_SENT: + /* read and stash current sequence number */ + if (cm_node->tcp_cntxt.rem_ack_num != cm_node->tcp_cntxt.loc_seq_num) { + nes_debug(NES_DBG_CM, "ERROR - cm_node->tcp_cntxt.rem_ack_num !=" + " cm_node->tcp_cntxt.loc_seq_num\n"); + send_reset(cm_node); + return 0; + } + if (cm_node->state == NES_CM_STATE_SYN_SENT) + cm_node->state = NES_CM_STATE_ONE_SIDE_ESTABLISHED; + else { + cm_node->state = NES_CM_STATE_ESTABLISHED; + } + break; + case NES_CM_STATE_LAST_ACK: + cm_node->state = NES_CM_STATE_CLOSED; + break; + case NES_CM_STATE_FIN_WAIT1: + cm_node->state = NES_CM_STATE_FIN_WAIT2; + break; + case NES_CM_STATE_CLOSING: + cm_node->state = NES_CM_STATE_TIME_WAIT; + /* need to schedule this to happen in 2MSL timeouts */ + cm_node->state = NES_CM_STATE_CLOSED; + break; + case NES_CM_STATE_ONE_SIDE_ESTABLISHED: + case NES_CM_STATE_ESTABLISHED: + case NES_CM_STATE_MPAREQ_SENT: + case NES_CM_STATE_CLOSE_WAIT: + case NES_CM_STATE_TIME_WAIT: + case NES_CM_STATE_CLOSED: + break; + case NES_CM_STATE_LISTENING: + nes_debug(NES_DBG_CM, "Received an ACK on a listening port (SYN %d)\n", tcph->syn); + cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); + send_reset(cm_node); + /* send_reset bumps refcount, this should have been a new node */ + rem_ref_cm_node(cm_core, cm_node); + return -1; + break; + case NES_CM_STATE_TSA: + nes_debug(NES_DBG_CM, "Received a packet with the ack bit set while in TSA state\n"); + break; + case NES_CM_STATE_UNKNOWN: + case NES_CM_STATE_INITED: + case NES_CM_STATE_ACCEPTING: + case NES_CM_STATE_FIN_WAIT2: + default: + nes_debug(NES_DBG_CM, "Received ack from unknown state: %x\n", + cm_node->state); + send_reset(cm_node); + break; + } + } -static void active_open_err(struct nes_cm_node *cm_node, struct sk_buff *skb, - int reset) -{ - cleanup_retrans_entry(cm_node); - if (reset) { - nes_debug(NES_DBG_CM, "ERROR active err called for cm_node=%p, " - "state=%d\n", cm_node, cm_node->state); - add_ref_cm_node(cm_node); - send_reset(cm_node, skb); - } else - dev_kfree_skb_any(skb); + if (tcph->syn) { + if (cm_node->state == NES_CM_STATE_LISTENING) { + /* do not exceed backlog */ + atomic_inc(&cm_node->listener->pend_accepts_cnt); + if (atomic_read(&cm_node->listener->pend_accepts_cnt) > + cm_node->listener->backlog) { + nes_debug(NES_DBG_CM, "drop syn due to backlog pressure \n"); + cm_backlog_drops++; + atomic_dec(&cm_node->listener->pend_accepts_cnt); + rem_ref_cm_node(cm_core, cm_node); + return 0; + } + cm_node->accept_pend = 1; - cm_node->state = NES_CM_STATE_CLOSED; - create_event(cm_node, NES_CM_EVENT_ABORTED); -} + } + if (datasize == 0) + cm_node->tcp_cntxt.rcv_nxt ++; -/* - * passive_open_err() will either do a reset() or will free up the skb and - * remove the cm_node. - */ + if (cm_node->state == NES_CM_STATE_LISTENING) { + cm_node->state = NES_CM_STATE_SYN_RCVD; + send_syn(cm_node, 1); + } + if (cm_node->state == NES_CM_STATE_ONE_SIDE_ESTABLISHED) { + cm_node->state = NES_CM_STATE_ESTABLISHED; + /* send final handshake ACK */ + ret = send_ack(cm_node); + if (ret < 0) + return ret; -static void passive_open_err(struct nes_cm_node *cm_node, struct sk_buff *skb, - int reset) -{ - cleanup_retrans_entry(cm_node); - cm_node->state = NES_CM_STATE_CLOSED; - if (reset) { - nes_debug(NES_DBG_CM, "passive_open_err sending RST for " - "cm_node=%p state =%d\n", cm_node, cm_node->state); - send_reset(cm_node, skb); - } else { - dev_kfree_skb_any(skb); - rem_ref_cm_node(cm_node->cm_core, cm_node); + cm_node->state = NES_CM_STATE_MPAREQ_SENT; + ret = send_mpa_request(cm_node); + if (ret < 0) + return ret; + } } -} -/* - * free_retrans_entry() routines assumes that the retrans_list_lock has - * been acquired before calling. - */ -static void free_retrans_entry(struct nes_cm_node *cm_node) -{ - struct nes_timer_entry *send_entry; - send_entry = cm_node->send_entry; - if (send_entry) { - cm_node->send_entry = NULL; - dev_kfree_skb_any(send_entry->skb); - kfree(send_entry); - rem_ref_cm_node(cm_node->cm_core, cm_node); + if (tcph->fin) { + cm_node->tcp_cntxt.rcv_nxt++; + switch (cm_node->state) { + case NES_CM_STATE_SYN_RCVD: + case NES_CM_STATE_SYN_SENT: + case NES_CM_STATE_ONE_SIDE_ESTABLISHED: + case NES_CM_STATE_ESTABLISHED: + case NES_CM_STATE_ACCEPTING: + case NES_CM_STATE_MPAREQ_SENT: + cm_node->state = NES_CM_STATE_CLOSE_WAIT; + cm_node->state = NES_CM_STATE_LAST_ACK; + ret = send_fin(cm_node, NULL); + break; + case NES_CM_STATE_FIN_WAIT1: + cm_node->state = NES_CM_STATE_CLOSING; + ret = send_ack(cm_node); + break; + case NES_CM_STATE_FIN_WAIT2: + cm_node->state = NES_CM_STATE_TIME_WAIT; + cm_node->tcp_cntxt.loc_seq_num ++; + ret = send_ack(cm_node); + /* need to schedule this to happen in 2MSL timeouts */ + cm_node->state = NES_CM_STATE_CLOSED; + break; + case NES_CM_STATE_CLOSE_WAIT: + case NES_CM_STATE_LAST_ACK: + case NES_CM_STATE_CLOSING: + case NES_CM_STATE_TSA: + default: + nes_debug(NES_DBG_CM, "Received a fin while in %x state\n", + cm_node->state); + ret = -EINVAL; + break; + } } -} - -static void cleanup_retrans_entry(struct nes_cm_node *cm_node) -{ - unsigned long flags; - spin_lock_irqsave(&cm_node->retrans_list_lock, flags); - free_retrans_entry(cm_node); - spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); -} - -/** - * process_packet - * Returns skb if to be freed, else it will return NULL if already used.. - */ -static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, - struct nes_cm_core *cm_core) -{ - enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN; - struct tcphdr *tcph = tcp_hdr(skb); - skb_pull(skb, ip_hdr(skb)->ihl << 2); + if (datasize) { + u8 *dataloc = skb->data; + /* figure out what state we are in and handle transition to next state */ + switch (cm_node->state) { + case NES_CM_STATE_LISTENING: + case NES_CM_STATE_SYN_RCVD: + case NES_CM_STATE_SYN_SENT: + case NES_CM_STATE_FIN_WAIT1: + case NES_CM_STATE_FIN_WAIT2: + case NES_CM_STATE_CLOSE_WAIT: + case NES_CM_STATE_LAST_ACK: + case NES_CM_STATE_CLOSING: + break; + case NES_CM_STATE_MPAREQ_SENT: + /* recv the mpa res frame, ret=frame len (incl priv data) */ + ret = parse_mpa(cm_node, dataloc, datasize); + if (ret < 0) + break; + /* set the req frame payload len in skb */ + /* we are done handling this state, set node to a TSA state */ + cm_node->state = NES_CM_STATE_TSA; + send_ack(cm_node); + create_event(cm_node, NES_CM_EVENT_CONNECTED); + break; - nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d " - "ack=%d rst=%d fin=%d\n", cm_node, cm_node->state, tcph->syn, - tcph->ack, tcph->rst, tcph->fin); - - if (tcph->rst) - pkt_type = NES_PKT_TYPE_RST; - else if (tcph->syn) { - pkt_type = NES_PKT_TYPE_SYN; - if (tcph->ack) - pkt_type = NES_PKT_TYPE_SYNACK; - } else if (tcph->fin) - pkt_type = NES_PKT_TYPE_FIN; - else if (tcph->ack) - pkt_type = NES_PKT_TYPE_ACK; - - switch (pkt_type) { - case NES_PKT_TYPE_SYN: - handle_syn_pkt(cm_node, skb, tcph); - break; - case NES_PKT_TYPE_SYNACK: - handle_synack_pkt(cm_node, skb, tcph); - break; - case NES_PKT_TYPE_ACK: - handle_ack_pkt(cm_node, skb, tcph); - break; - case NES_PKT_TYPE_RST: - handle_rst_pkt(cm_node, skb, tcph); - break; - case NES_PKT_TYPE_FIN: - handle_fin_pkt(cm_node, skb, tcph); - break; - default: - drop_packet(skb); - break; + case NES_CM_STATE_ESTABLISHED: + /* we are expecting an MPA req frame */ + ret = parse_mpa(cm_node, dataloc, datasize); + if (ret < 0) { + break; + } + cm_node->state = NES_CM_STATE_TSA; + send_ack(cm_node); + /* we got a valid MPA request, create an event */ + create_event(cm_node, NES_CM_EVENT_MPA_REQ); + break; + case NES_CM_STATE_TSA: + handle_exception_pkt(cm_node, skb); + break; + case NES_CM_STATE_UNKNOWN: + case NES_CM_STATE_INITED: + default: + ret = -1; + } } + + return ret; } + /** * mini_cm_listen - create a listen node with params */ static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core, - struct nes_vnic *nesvnic, struct nes_cm_info *cm_info) + struct nes_vnic *nesvnic, struct nes_cm_info *cm_info) { struct nes_cm_listener *listener; unsigned long flags; @@ -1826,36 +1644,37 @@ static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core, /** * mini_cm_connect - make a connection node with params */ -struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, - struct nes_vnic *nesvnic, u16 private_data_len, - void *private_data, struct nes_cm_info *cm_info) +static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, + struct nes_vnic *nesvnic, + struct ietf_mpa_frame *mpa_frame, + struct nes_cm_info *cm_info) { int ret = 0; struct nes_cm_node *cm_node; struct nes_cm_listener *loopbackremotelistener; struct nes_cm_node *loopbackremotenode; struct nes_cm_info loopback_cm_info; - u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + private_data_len; - struct ietf_mpa_frame *mpa_frame = NULL; + + u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + + ntohs(mpa_frame->priv_data_len); + + cm_info->loc_addr = htonl(cm_info->loc_addr); + cm_info->rem_addr = htonl(cm_info->rem_addr); + cm_info->loc_port = htons(cm_info->loc_port); + cm_info->rem_port = htons(cm_info->rem_port); /* create a CM connection node */ cm_node = make_cm_node(cm_core, nesvnic, cm_info, NULL); if (!cm_node) return NULL; - mpa_frame = &cm_node->mpa_frame; - strcpy(mpa_frame->key, IEFT_MPA_KEY_REQ); - mpa_frame->flags = IETF_MPA_FLAGS_CRC; - mpa_frame->rev = IETF_MPA_VERSION; - mpa_frame->priv_data_len = htons(private_data_len); /* set our node side to client (active) side */ cm_node->tcp_cntxt.client = 1; cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; if (cm_info->loc_addr == cm_info->rem_addr) { - loopbackremotelistener = find_listener(cm_core, - ntohl(nesvnic->local_ipaddr), cm_node->rem_port, - NES_CM_LISTENER_ACTIVE_STATE); + loopbackremotelistener = find_listener(cm_core, cm_node->rem_addr, + cm_node->rem_port, NES_CM_LISTENER_ACTIVE_STATE); if (loopbackremotelistener == NULL) { create_event(cm_node, NES_CM_EVENT_ABORTED); } else { @@ -1864,35 +1683,26 @@ struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, loopback_cm_info.loc_port = cm_info->rem_port; loopback_cm_info.rem_port = cm_info->loc_port; loopback_cm_info.cm_id = loopbackremotelistener->cm_id; - loopbackremotenode = make_cm_node(cm_core, nesvnic, - &loopback_cm_info, loopbackremotelistener); + loopbackremotenode = make_cm_node(cm_core, nesvnic, &loopback_cm_info, + loopbackremotelistener); loopbackremotenode->loopbackpartner = cm_node; - loopbackremotenode->tcp_cntxt.rcv_wscale = - NES_CM_DEFAULT_RCV_WND_SCALE; + loopbackremotenode->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; cm_node->loopbackpartner = loopbackremotenode; - memcpy(loopbackremotenode->mpa_frame_buf, private_data, - private_data_len); - loopbackremotenode->mpa_frame_size = private_data_len; + memcpy(loopbackremotenode->mpa_frame_buf, &mpa_frame->priv_data, + mpa_frame_size); + loopbackremotenode->mpa_frame_size = mpa_frame_size - + sizeof(struct ietf_mpa_frame); - /* we are done handling this state. */ - /* set node to a TSA state */ + /* we are done handling this state, set node to a TSA state */ cm_node->state = NES_CM_STATE_TSA; - cm_node->tcp_cntxt.rcv_nxt = - loopbackremotenode->tcp_cntxt.loc_seq_num; - loopbackremotenode->tcp_cntxt.rcv_nxt = - cm_node->tcp_cntxt.loc_seq_num; - cm_node->tcp_cntxt.max_snd_wnd = - loopbackremotenode->tcp_cntxt.rcv_wnd; - loopbackremotenode->tcp_cntxt.max_snd_wnd = - cm_node->tcp_cntxt.rcv_wnd; - cm_node->tcp_cntxt.snd_wnd = - loopbackremotenode->tcp_cntxt.rcv_wnd; - loopbackremotenode->tcp_cntxt.snd_wnd = - cm_node->tcp_cntxt.rcv_wnd; - cm_node->tcp_cntxt.snd_wscale = - loopbackremotenode->tcp_cntxt.rcv_wscale; - loopbackremotenode->tcp_cntxt.snd_wscale = - cm_node->tcp_cntxt.rcv_wscale; + cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num; + loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num; + cm_node->tcp_cntxt.max_snd_wnd = loopbackremotenode->tcp_cntxt.rcv_wnd; + loopbackremotenode->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.rcv_wnd; + cm_node->tcp_cntxt.snd_wnd = loopbackremotenode->tcp_cntxt.rcv_wnd; + loopbackremotenode->tcp_cntxt.snd_wnd = cm_node->tcp_cntxt.rcv_wnd; + cm_node->tcp_cntxt.snd_wscale = loopbackremotenode->tcp_cntxt.rcv_wscale; + loopbackremotenode->tcp_cntxt.snd_wscale = cm_node->tcp_cntxt.rcv_wscale; create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ); } @@ -1902,29 +1712,16 @@ struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, /* set our node side to client (active) side */ cm_node->tcp_cntxt.client = 1; /* init our MPA frame ptr */ - memcpy(mpa_frame->priv_data, private_data, private_data_len); - + memcpy(&cm_node->mpa_frame, mpa_frame, mpa_frame_size); cm_node->mpa_frame_size = mpa_frame_size; /* send a syn and goto syn sent state */ cm_node->state = NES_CM_STATE_SYN_SENT; - ret = send_syn(cm_node, 0, NULL); - - if (ret) { - /* error in sending the syn free up the cm_node struct */ - nes_debug(NES_DBG_CM, "Api - connect() FAILED: dest " - "addr=0x%08X, port=0x%04x, cm_node=%p, cm_id = %p.\n", - cm_node->rem_addr, cm_node->rem_port, cm_node, - cm_node->cm_id); - rem_ref_cm_node(cm_node->cm_core, cm_node); - cm_node = NULL; - } + ret = send_syn(cm_node, 0); - if (cm_node) - nes_debug(NES_DBG_CM, "Api - connect(): dest addr=0x%08X," - "port=0x%04x, cm_node=%p, cm_id = %p.\n", - cm_node->rem_addr, cm_node->rem_port, cm_node, - cm_node->cm_id); + nes_debug(NES_DBG_CM, "Api - connect(): dest addr=0x%08X, port=0x%04x," + " cm_node=%p, cm_id = %p.\n", + cm_node->rem_addr, cm_node->rem_port, cm_node, cm_node->cm_id); return cm_node; } @@ -1934,8 +1731,8 @@ struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, * mini_cm_accept - accept a connection * This function is never called */ -static int mini_cm_accept(struct nes_cm_core *cm_core, - struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node) +static int mini_cm_accept(struct nes_cm_core *cm_core, struct ietf_mpa_frame *mpa_frame, + struct nes_cm_node *cm_node) { return 0; } @@ -1945,26 +1742,32 @@ static int mini_cm_accept(struct nes_cm_core *cm_core, * mini_cm_reject - reject and teardown a connection */ static int mini_cm_reject(struct nes_cm_core *cm_core, - struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node) + struct ietf_mpa_frame *mpa_frame, + struct nes_cm_node *cm_node) { int ret = 0; + struct sk_buff *skb; + u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + + ntohs(mpa_frame->priv_data_len); - nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n", - __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state); + skb = get_free_pkt(cm_node); + if (!skb) { + nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); + return -1; + } + + /* send an MPA Request frame */ + form_cm_frame(skb, cm_node, NULL, 0, mpa_frame, mpa_frame_size, SET_ACK | SET_FIN); + ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0); - if (cm_node->tcp_cntxt.client) - return ret; - cleanup_retrans_entry(cm_node); cm_node->state = NES_CM_STATE_CLOSED; ret = send_fin(cm_node, NULL); - if (cm_node->accept_pend) { - BUG_ON(!cm_node->listener); - atomic_dec(&cm_node->listener->pend_accepts_cnt); - BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); + if (ret < 0) { + printk(KERN_INFO PFX "failed to send MPA Reply (reject)\n"); + return ret; } - ret = send_reset(cm_node, NULL); return ret; } @@ -1980,39 +1783,35 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod return -EINVAL; switch (cm_node->state) { - case NES_CM_STATE_SYN_RCVD: - case NES_CM_STATE_SYN_SENT: - case NES_CM_STATE_ONE_SIDE_ESTABLISHED: - case NES_CM_STATE_ESTABLISHED: - case NES_CM_STATE_ACCEPTING: - case NES_CM_STATE_MPAREQ_SENT: - case NES_CM_STATE_MPAREQ_RCVD: - cleanup_retrans_entry(cm_node); - send_reset(cm_node, NULL); - break; - case NES_CM_STATE_CLOSE_WAIT: - cm_node->state = NES_CM_STATE_LAST_ACK; - send_fin(cm_node, NULL); - break; - case NES_CM_STATE_FIN_WAIT1: - case NES_CM_STATE_FIN_WAIT2: - case NES_CM_STATE_LAST_ACK: - case NES_CM_STATE_TIME_WAIT: - case NES_CM_STATE_CLOSING: - ret = -1; - break; - case NES_CM_STATE_LISTENING: - case NES_CM_STATE_UNKNOWN: - case NES_CM_STATE_INITED: - case NES_CM_STATE_CLOSED: - ret = rem_ref_cm_node(cm_core, cm_node); - break; - case NES_CM_STATE_TSA: - if (cm_node->send_entry) - printk(KERN_ERR "ERROR Close got called from STATE_TSA " - "send_entry=%p\n", cm_node->send_entry); - ret = rem_ref_cm_node(cm_core, cm_node); - break; + /* if passed in node is null, create a reference key node for node search */ + /* check if we found an owner node for this pkt */ + case NES_CM_STATE_SYN_RCVD: + case NES_CM_STATE_SYN_SENT: + case NES_CM_STATE_ONE_SIDE_ESTABLISHED: + case NES_CM_STATE_ESTABLISHED: + case NES_CM_STATE_ACCEPTING: + case NES_CM_STATE_MPAREQ_SENT: + cm_node->state = NES_CM_STATE_FIN_WAIT1; + send_fin(cm_node, NULL); + break; + case NES_CM_STATE_CLOSE_WAIT: + cm_node->state = NES_CM_STATE_LAST_ACK; + send_fin(cm_node, NULL); + break; + case NES_CM_STATE_FIN_WAIT1: + case NES_CM_STATE_FIN_WAIT2: + case NES_CM_STATE_LAST_ACK: + case NES_CM_STATE_TIME_WAIT: + case NES_CM_STATE_CLOSING: + ret = -1; + break; + case NES_CM_STATE_LISTENING: + case NES_CM_STATE_UNKNOWN: + case NES_CM_STATE_INITED: + case NES_CM_STATE_CLOSED: + case NES_CM_STATE_TSA: + ret = rem_ref_cm_node(cm_core, cm_node); + break; } cm_node->cm_id = NULL; return ret; @@ -2023,30 +1822,25 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod * recv_pkt - recv an ETHERNET packet, and process it through CM * node state machine */ -static void mini_cm_recv_pkt(struct nes_cm_core *cm_core, - struct nes_vnic *nesvnic, struct sk_buff *skb) +static int mini_cm_recv_pkt(struct nes_cm_core *cm_core, struct nes_vnic *nesvnic, + struct sk_buff *skb) { struct nes_cm_node *cm_node = NULL; struct nes_cm_listener *listener = NULL; struct iphdr *iph; struct tcphdr *tcph; struct nes_cm_info nfo; + int ret = 0; - if (!skb) - return; - if (skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) { - dev_kfree_skb_any(skb); - return; + if (!skb || skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) { + ret = -EINVAL; + goto out; } iph = (struct iphdr *)skb->data; tcph = (struct tcphdr *)(skb->data + sizeof(struct iphdr)); skb_reset_network_header(skb); skb_set_transport_header(skb, sizeof(*tcph)); - if (!tcph) { - dev_kfree_skb_any(skb); - return; - } skb->len = ntohs(iph->tot_len); nfo.loc_addr = ntohl(iph->daddr); @@ -2059,60 +1853,61 @@ static void mini_cm_recv_pkt(struct nes_cm_core *cm_core, NIPQUAD(iph->daddr), tcph->dest, NIPQUAD(iph->saddr), tcph->source); - do { - cm_node = find_node(cm_core, + /* note: this call is going to increment cm_node ref count */ + cm_node = find_node(cm_core, nfo.rem_port, nfo.rem_addr, nfo.loc_port, nfo.loc_addr); - if (!cm_node) { - /* Only type of packet accepted are for */ - /* the PASSIVE open (syn only) */ - if ((!tcph->syn) || (tcph->ack)) { - cm_packets_dropped++; - break; - } - listener = find_listener(cm_core, nfo.loc_addr, - nfo.loc_port, + if (!cm_node) { + listener = find_listener(cm_core, nfo.loc_addr, nfo.loc_port, NES_CM_LISTENER_ACTIVE_STATE); - if (listener) { - nfo.cm_id = listener->cm_id; - nfo.conn_type = listener->conn_type; - } else { - nes_debug(NES_DBG_CM, "Unable to find listener " - "for the pkt\n"); - cm_packets_dropped++; - dev_kfree_skb_any(skb); - break; - } + if (listener) { + nfo.cm_id = listener->cm_id; + nfo.conn_type = listener->conn_type; + } else { + nfo.cm_id = NULL; + nfo.conn_type = 0; + } - cm_node = make_cm_node(cm_core, nesvnic, &nfo, - listener); - if (!cm_node) { - nes_debug(NES_DBG_CM, "Unable to allocate " - "node\n"); - cm_packets_dropped++; + cm_node = make_cm_node(cm_core, nesvnic, &nfo, listener); + if (!cm_node) { + nes_debug(NES_DBG_CM, "Unable to allocate node\n"); + if (listener) { + nes_debug(NES_DBG_CM, "unable to allocate node and decrementing listener refcount\n"); atomic_dec(&listener->ref_count); - dev_kfree_skb_any(skb); - break; } - if (!tcph->rst && !tcph->fin) { - cm_node->state = NES_CM_STATE_LISTENING; - } else { - cm_packets_dropped++; - rem_ref_cm_node(cm_core, cm_node); - dev_kfree_skb_any(skb); - break; + ret = -1; + goto out; + } + if (!listener) { + nes_debug(NES_DBG_CM, "Packet found for unknown port %x refcnt=%d\n", + nfo.loc_port, atomic_read(&cm_node->ref_count)); + if (!tcph->rst) { + nes_debug(NES_DBG_CM, "Packet found for unknown port=%d" + " rem_port=%d refcnt=%d\n", + nfo.loc_port, nfo.rem_port, atomic_read(&cm_node->ref_count)); + + cm_node->tcp_cntxt.rcv_nxt = ntohl(tcph->seq); + cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); + send_reset(cm_node); } - add_ref_cm_node(cm_node); - } else if (cm_node->state == NES_CM_STATE_TSA) { rem_ref_cm_node(cm_core, cm_node); - atomic_inc(&cm_accel_dropped_pkts); - dev_kfree_skb_any(skb); - break; + ret = -1; + goto out; } - process_packet(cm_node, skb, cm_core); - rem_ref_cm_node(cm_core, cm_node); - } while (0); + add_ref_cm_node(cm_node); + cm_node->state = NES_CM_STATE_LISTENING; + } + + nes_debug(NES_DBG_CM, "Processing Packet for node %p, data = (%p):\n", + cm_node, skb->data); + process_packet(cm_node, skb, cm_core); + + rem_ref_cm_node(cm_core, cm_node); + out: + if (skb) + dev_kfree_skb_any(skb); + return ret; } @@ -2312,12 +2107,15 @@ int nes_cm_disconn(struct nes_qp *nesqp) if (nesqp->disconn_pending == 0) { nesqp->disconn_pending++; spin_unlock_irqrestore(&nesqp->lock, flags); + /* nes_add_ref(&nesqp->ibqp); */ /* init our disconnect work element, to */ INIT_WORK(&nesqp->disconn_work, nes_disconnect_worker); queue_work(g_cm_core->disconn_wq, &nesqp->disconn_work); - } else + } else { spin_unlock_irqrestore(&nesqp->lock, flags); + nes_rem_ref(&nesqp->ibqp); + } return 0; } @@ -2363,6 +2161,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) nes_debug(NES_DBG_CM, "QP%u disconnect_worker cmid is NULL\n", nesqp->hwqp.qp_id); spin_unlock_irqrestore(&nesqp->lock, flags); + nes_rem_ref(&nesqp->ibqp); return -1; } @@ -2383,31 +2182,30 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) atomic_inc(&cm_disconnects); cm_event.event = IW_CM_EVENT_DISCONNECT; if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) { + issued_disconnect_reset = 1; cm_event.status = IW_CM_EVENT_STATUS_RESET; - nes_debug(NES_DBG_CM, "Generating a CM " - "Disconnect Event (status reset) for " - "QP%u, cm_id = %p. \n", - nesqp->hwqp.qp_id, cm_id); - } else + nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event (status reset) for " + " QP%u, cm_id = %p. \n", + nesqp->hwqp.qp_id, cm_id); + } else { cm_event.status = IW_CM_EVENT_STATUS_OK; + } cm_event.local_addr = cm_id->local_addr; cm_event.remote_addr = cm_id->remote_addr; cm_event.private_data = NULL; cm_event.private_data_len = 0; - nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event" - " for QP%u, SQ Head = %u, SQ Tail = %u. " - "cm_id = %p, refcount = %u.\n", - nesqp->hwqp.qp_id, nesqp->hwqp.sq_head, - nesqp->hwqp.sq_tail, cm_id, - atomic_read(&nesqp->refcount)); + nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event for " + " QP%u, SQ Head = %u, SQ Tail = %u. cm_id = %p, refcount = %u.\n", + nesqp->hwqp.qp_id, + nesqp->hwqp.sq_head, nesqp->hwqp.sq_tail, cm_id, + atomic_read(&nesqp->refcount)); spin_unlock_irqrestore(&nesqp->lock, flags); ret = cm_id->event_handler(cm_id, &cm_event); if (ret) - nes_debug(NES_DBG_CM, "OFA CM event_handler " - "returned, ret=%d\n", ret); + nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); spin_lock_irqsave(&nesqp->lock, flags); } @@ -2449,24 +2247,31 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) if (nesqp->flush_issued == 0) { nesqp->flush_issued = 1; spin_unlock_irqrestore(&nesqp->lock, flags); - flush_wqes(nesvnic->nesdev, nesqp, - NES_CQP_FLUSH_RQ, 1); - } else + flush_wqes(nesvnic->nesdev, nesqp, NES_CQP_FLUSH_RQ, 1); + } else { spin_unlock_irqrestore(&nesqp->lock, flags); + } + + /* This reference is from either ModifyQP or the AE processing, + there is still a race here with modifyqp */ + nes_rem_ref(&nesqp->ibqp); + } else { cm_id = nesqp->cm_id; spin_unlock_irqrestore(&nesqp->lock, flags); /* check to see if the inbound reset beat the outbound reset */ if ((!cm_id) && (last_ae==NES_AEQE_AEID_RESET_SENT)) { - nes_debug(NES_DBG_CM, "QP%u: Decing refcount " - "due to inbound reset beating the " - "outbound reset.\n", nesqp->hwqp.qp_id); + nes_debug(NES_DBG_CM, "QP%u: Decing refcount due to inbound reset" + " beating the outbound reset.\n", + nesqp->hwqp.qp_id); + nes_rem_ref(&nesqp->ibqp); } } } else { nesqp->disconn_pending = 0; spin_unlock_irqrestore(&nesqp->lock, flags); } + nes_rem_ref(&nesqp->ibqp); return 0; } @@ -2544,82 +2349,71 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) nesdev = nesvnic->nesdev; adapter = nesdev->nesadapter; + nes_debug(NES_DBG_CM, "nesvnic=%p, netdev=%p, %s\n", + nesvnic, nesvnic->netdev, nesvnic->netdev->name); + + /* since this is from a listen, we were able to put node handle into cm_id */ cm_node = (struct nes_cm_node *)cm_id->provider_data; - nes_debug(NES_DBG_CM, "nes_accept: cm_node= %p nesvnic=%p, netdev=%p," - "%s\n", cm_node, nesvnic, nesvnic->netdev, - nesvnic->netdev->name); /* associate the node with the QP */ nesqp->cm_node = (void *)cm_node; - cm_node->nesqp = nesqp; - nes_add_ref(&nesqp->ibqp); - nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n", - nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener); + nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu\n", + nesqp->hwqp.qp_id, cm_node, jiffies); atomic_inc(&cm_accepts); nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", atomic_read(&nesvnic->netdev->refcnt)); - /* allocate the ietf frame and space for private data */ - nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, - sizeof(struct ietf_mpa_frame) + conn_param->private_data_len, - &nesqp->ietf_frame_pbase); + /* allocate the ietf frame and space for private data */ + nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, + sizeof(struct ietf_mpa_frame) + conn_param->private_data_len, + &nesqp->ietf_frame_pbase); - if (!nesqp->ietf_frame) { - nes_debug(NES_DBG_CM, "Unable to allocate memory for private " - "data\n"); - return -ENOMEM; - } + if (!nesqp->ietf_frame) { + nes_debug(NES_DBG_CM, "Unable to allocate memory for private data\n"); + return -ENOMEM; + } - /* setup the MPA frame */ - nesqp->private_data_len = conn_param->private_data_len; - memcpy(nesqp->ietf_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE); + /* setup the MPA frame */ + nesqp->private_data_len = conn_param->private_data_len; + memcpy(nesqp->ietf_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE); - memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data, - conn_param->private_data_len); + memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data, + conn_param->private_data_len); - nesqp->ietf_frame->priv_data_len = - cpu_to_be16(conn_param->private_data_len); - nesqp->ietf_frame->rev = mpa_version; - nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC; + nesqp->ietf_frame->priv_data_len = cpu_to_be16(conn_param->private_data_len); + nesqp->ietf_frame->rev = mpa_version; + nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC; - /* setup our first outgoing iWarp send WQE (the IETF frame response) */ - wqe = &nesqp->hwqp.sq_vbase[0]; - - if (cm_id->remote_addr.sin_addr.s_addr != - cm_id->local_addr.sin_addr.s_addr) { - u64temp = (unsigned long)nesqp; - u64temp |= NES_SW_CONTEXT_ALIGN>>1; - set_wqe_64bit_value(wqe->wqe_words, - NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, - u64temp); - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = - cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING | - NES_IWARP_SQ_WQE_WRPDU); - wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = - cpu_to_le32(conn_param->private_data_len + - sizeof(struct ietf_mpa_frame)); - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = - cpu_to_le32((u32)nesqp->ietf_frame_pbase); - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = - cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32)); - wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = - cpu_to_le32(conn_param->private_data_len + - sizeof(struct ietf_mpa_frame)); - wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; - - nesqp->nesqp_context->ird_ord_sizes |= - cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | - NES_QPCONTEXT_ORDIRD_WRPDU); - } else { - nesqp->nesqp_context->ird_ord_sizes |= - cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | - NES_QPCONTEXT_ORDIRD_WRPDU | - NES_QPCONTEXT_ORDIRD_ALSMM)); - } - nesqp->skip_lsmm = 1; + /* setup our first outgoing iWarp send WQE (the IETF frame response) */ + wqe = &nesqp->hwqp.sq_vbase[0]; + + if (cm_id->remote_addr.sin_addr.s_addr != cm_id->local_addr.sin_addr.s_addr) { + u64temp = (unsigned long)nesqp; + u64temp |= NES_SW_CONTEXT_ALIGN>>1; + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, + u64temp); + wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = + cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING | NES_IWARP_SQ_WQE_WRPDU); + wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = + cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); + wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = + cpu_to_le32((u32)nesqp->ietf_frame_pbase); + wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = + cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32)); + wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = + cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); + wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; + + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32( + NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | NES_QPCONTEXT_ORDIRD_WRPDU); + } else { + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | + NES_QPCONTEXT_ORDIRD_WRPDU | NES_QPCONTEXT_ORDIRD_ALSMM)); + } + nesqp->skip_lsmm = 1; /* Cache the cm_id in the qp */ @@ -2630,75 +2424,55 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) cm_id->provider_data = nesqp; nesqp->active_conn = 0; - if (cm_node->state == NES_CM_STATE_TSA) - nes_debug(NES_DBG_CM, "Already state = TSA for cm_node=%p\n", - cm_node); - nes_cm_init_tsa_conn(nesqp, cm_node); - nesqp->nesqp_context->tcpPorts[0] = - cpu_to_le16(ntohs(cm_id->local_addr.sin_port)); - nesqp->nesqp_context->tcpPorts[1] = - cpu_to_le16(ntohs(cm_id->remote_addr.sin_port)); - - if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr)) - nesqp->nesqp_context->ip0 = - cpu_to_le32(ntohl(nesvnic->local_ipaddr)); - else - nesqp->nesqp_context->ip0 = - cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr)); + nesqp->nesqp_context->tcpPorts[0] = cpu_to_le16(ntohs(cm_id->local_addr.sin_port)); + nesqp->nesqp_context->tcpPorts[1] = cpu_to_le16(ntohs(cm_id->remote_addr.sin_port)); + nesqp->nesqp_context->ip0 = cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr)); nesqp->nesqp_context->misc2 |= cpu_to_le32( - (u32)PCI_FUNC(nesdev->pcidev->devfn) << - NES_QPCONTEXT_MISC2_SRC_IP_SHIFT); + (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_QPCONTEXT_MISC2_SRC_IP_SHIFT); - nesqp->nesqp_context->arp_index_vlan |= - cpu_to_le32(nes_arp_table(nesdev, - le32_to_cpu(nesqp->nesqp_context->ip0), NULL, + nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32( + nes_arp_table(nesdev, le32_to_cpu(nesqp->nesqp_context->ip0), NULL, NES_ARP_RESOLVE) << 16); nesqp->nesqp_context->ts_val_delta = cpu_to_le32( - jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW)); + jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW)); nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id); nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32( - ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT)); - nesqp->nesqp_context->ird_ord_sizes |= - cpu_to_le32((u32)conn_param->ord); + ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT)); + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord); memset(&nes_quad, 0, sizeof(nes_quad)); - nes_quad.DstIpAdrIndex = - cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); - if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr)) - nes_quad.SrcIpadr = nesvnic->local_ipaddr; - else - nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr; - nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port; - nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; + nes_quad.DstIpAdrIndex = cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); + nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr; + nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port; + nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; /* Produce hash key */ crc_value = get_crc_value(&nes_quad); nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff); nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n", - nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask); + nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask); nesqp->hte_index &= adapter->hte_index_mask; nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index); cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node); - nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = " - "0x%08X:0x%04X, rcv_nxt=0x%08X, snd_nxt=0x%08X, mpa + " - "private data length=%zu.\n", nesqp->hwqp.qp_id, + nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = 0x%08X:0x%04X," + " rcv_nxt=0x%08X, snd_nxt=0x%08X, mpa + private data length=%zu.\n", + nesqp->hwqp.qp_id, ntohl(cm_id->remote_addr.sin_addr.s_addr), ntohs(cm_id->remote_addr.sin_port), ntohl(cm_id->local_addr.sin_addr.s_addr), ntohs(cm_id->local_addr.sin_port), le32_to_cpu(nesqp->nesqp_context->rcv_nxt), le32_to_cpu(nesqp->nesqp_context->snd_nxt), - conn_param->private_data_len + - sizeof(struct ietf_mpa_frame)); + conn_param->private_data_len+sizeof(struct ietf_mpa_frame)); attr.qp_state = IB_QPS_RTS; nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); @@ -2715,16 +2489,15 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) cm_event.private_data_len = 0; ret = cm_id->event_handler(cm_id, &cm_event); if (cm_node->loopbackpartner) { - cm_node->loopbackpartner->mpa_frame_size = - nesqp->private_data_len; + cm_node->loopbackpartner->mpa_frame_size = nesqp->private_data_len; /* copy entire MPA frame to our cm_node's frame */ - memcpy(cm_node->loopbackpartner->mpa_frame_buf, - nesqp->ietf_frame->priv_data, nesqp->private_data_len); + memcpy(cm_node->loopbackpartner->mpa_frame_buf, nesqp->ietf_frame->priv_data, + nesqp->private_data_len); create_event(cm_node->loopbackpartner, NES_CM_EVENT_CONNECTED); } if (ret) - printk(KERN_ERR "%s[%u] OFA CM event_handler returned, " - "ret=%d\n", __func__, __LINE__, ret); + printk("%s[%u] OFA CM event_handler returned, ret=%d\n", + __func__, __LINE__, ret); return 0; } @@ -2782,61 +2555,74 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) if (!nesdev) return -EINVAL; - nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = " - "0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id, - ntohl(nesvnic->local_ipaddr), - ntohl(cm_id->remote_addr.sin_addr.s_addr), - ntohs(cm_id->remote_addr.sin_port), - ntohl(cm_id->local_addr.sin_addr.s_addr), - ntohs(cm_id->local_addr.sin_port)); - atomic_inc(&cm_connects); + + nesqp->ietf_frame = kzalloc(sizeof(struct ietf_mpa_frame) + + conn_param->private_data_len, GFP_KERNEL); + if (!nesqp->ietf_frame) + return -ENOMEM; + + /* set qp as having an active connection */ nesqp->active_conn = 1; + nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", + nesqp->hwqp.qp_id, + ntohl(cm_id->remote_addr.sin_addr.s_addr), + ntohs(cm_id->remote_addr.sin_port), + ntohl(cm_id->local_addr.sin_addr.s_addr), + ntohs(cm_id->local_addr.sin_port)); + /* cache the cm_id in the qp */ nesqp->cm_id = cm_id; cm_id->provider_data = nesqp; + /* copy the private data */ + if (conn_param->private_data_len) { + memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data, + conn_param->private_data_len); + } + nesqp->private_data_len = conn_param->private_data_len; nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord); nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord); - nes_debug(NES_DBG_CM, "mpa private data len =%u\n", - conn_param->private_data_len); + nes_debug(NES_DBG_CM, "mpa private data len =%u\n", conn_param->private_data_len); + + strcpy(&nesqp->ietf_frame->key[0], IEFT_MPA_KEY_REQ); + nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC; + nesqp->ietf_frame->rev = IETF_MPA_VERSION; + nesqp->ietf_frame->priv_data_len = htons(conn_param->private_data_len); - if (cm_id->local_addr.sin_addr.s_addr != - cm_id->remote_addr.sin_addr.s_addr) + if (cm_id->local_addr.sin_addr.s_addr != cm_id->remote_addr.sin_addr.s_addr) nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), - PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); + PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); /* set up the connection params for the node */ - cm_info.loc_addr = htonl(cm_id->local_addr.sin_addr.s_addr); - cm_info.loc_port = htons(cm_id->local_addr.sin_port); - cm_info.rem_addr = htonl(cm_id->remote_addr.sin_addr.s_addr); - cm_info.rem_port = htons(cm_id->remote_addr.sin_port); + cm_info.loc_addr = (cm_id->local_addr.sin_addr.s_addr); + cm_info.loc_port = (cm_id->local_addr.sin_port); + cm_info.rem_addr = (cm_id->remote_addr.sin_addr.s_addr); + cm_info.rem_port = (cm_id->remote_addr.sin_port); cm_info.cm_id = cm_id; cm_info.conn_type = NES_CM_IWARP_CONN_TYPE; cm_id->add_ref(cm_id); + nes_add_ref(&nesqp->ibqp); /* create a connect CM node connection */ - cm_node = g_cm_core->api->connect(g_cm_core, nesvnic, - conn_param->private_data_len, (void *)conn_param->private_data, - &cm_info); + cm_node = g_cm_core->api->connect(g_cm_core, nesvnic, nesqp->ietf_frame, &cm_info); if (!cm_node) { - if (cm_id->local_addr.sin_addr.s_addr != - cm_id->remote_addr.sin_addr.s_addr) + if (cm_id->local_addr.sin_addr.s_addr != cm_id->remote_addr.sin_addr.s_addr) nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), - PCI_FUNC(nesdev->pcidev->devfn), - NES_MANAGE_APBVT_DEL); - + PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL); + nes_rem_ref(&nesqp->ibqp); + kfree(nesqp->ietf_frame); + nesqp->ietf_frame = NULL; cm_id->rem_ref(cm_id); return -ENOMEM; } cm_node->apbvt_set = 1; nesqp->cm_node = cm_node; - cm_node->nesqp = nesqp; return 0; } @@ -2878,7 +2664,7 @@ int nes_create_listen(struct iw_cm_id *cm_id, int backlog) cm_node = g_cm_core->api->listen(g_cm_core, nesvnic, &cm_info); if (!cm_node) { - printk(KERN_ERR "%s[%u] Error returned from listen API call\n", + printk("%s[%u] Error returned from listen API call\n", __func__, __LINE__); return -ENOMEM; } @@ -2886,13 +2672,10 @@ int nes_create_listen(struct iw_cm_id *cm_id, int backlog) cm_id->provider_data = cm_node; if (!cm_node->reused_node) { - err = nes_manage_apbvt(nesvnic, - ntohs(cm_id->local_addr.sin_port), - PCI_FUNC(nesvnic->nesdev->pcidev->devfn), - NES_MANAGE_APBVT_ADD); + err = nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), + PCI_FUNC(nesvnic->nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); if (err) { - printk(KERN_ERR "nes_manage_apbvt call returned %d.\n", - err); + printk("nes_manage_apbvt call returned %d.\n", err); g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node); return err; } @@ -3012,70 +2795,53 @@ static void cm_event_connected(struct nes_cm_event *event) nes_cm_init_tsa_conn(nesqp, cm_node); /* set the QP tsa context */ - nesqp->nesqp_context->tcpPorts[0] = - cpu_to_le16(ntohs(cm_id->local_addr.sin_port)); - nesqp->nesqp_context->tcpPorts[1] = - cpu_to_le16(ntohs(cm_id->remote_addr.sin_port)); - if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr)) - nesqp->nesqp_context->ip0 = - cpu_to_le32(ntohl(nesvnic->local_ipaddr)); - else - nesqp->nesqp_context->ip0 = - cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr)); + nesqp->nesqp_context->tcpPorts[0] = cpu_to_le16(ntohs(cm_id->local_addr.sin_port)); + nesqp->nesqp_context->tcpPorts[1] = cpu_to_le16(ntohs(cm_id->remote_addr.sin_port)); + nesqp->nesqp_context->ip0 = cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr)); nesqp->nesqp_context->misc2 |= cpu_to_le32( - (u32)PCI_FUNC(nesdev->pcidev->devfn) << - NES_QPCONTEXT_MISC2_SRC_IP_SHIFT); + (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_QPCONTEXT_MISC2_SRC_IP_SHIFT); nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32( - nes_arp_table(nesdev, - le32_to_cpu(nesqp->nesqp_context->ip0), + nes_arp_table(nesdev, le32_to_cpu(nesqp->nesqp_context->ip0), NULL, NES_ARP_RESOLVE) << 16); nesqp->nesqp_context->ts_val_delta = cpu_to_le32( jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW)); nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id); nesqp->nesqp_context->ird_ord_sizes |= - cpu_to_le32((u32)1 << - NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT); + cpu_to_le32((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT); /* Adjust tail for not having a LSMM */ nesqp->hwqp.sq_tail = 1; #if defined(NES_SEND_FIRST_WRITE) - if (cm_node->send_write0) { - nes_debug(NES_DBG_CM, "Sending first write.\n"); - wqe = &nesqp->hwqp.sq_vbase[0]; - u64temp = (unsigned long)nesqp; - u64temp |= NES_SW_CONTEXT_ALIGN>>1; - set_wqe_64bit_value(wqe->wqe_words, - NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, u64temp); - wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = - cpu_to_le32(NES_IWARP_SQ_OP_RDMAW); - wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 0; - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 0; - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 0; - wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0; - wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; - - /* use the reserved spot on the WQ for the extra first WQE */ - nesqp->nesqp_context->ird_ord_sizes &= - cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | - NES_QPCONTEXT_ORDIRD_WRPDU | - NES_QPCONTEXT_ORDIRD_ALSMM)); - nesqp->skip_lsmm = 1; - nesqp->hwqp.sq_tail = 0; - nes_write32(nesdev->regs + NES_WQE_ALLOC, - (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); - } + if (cm_node->send_write0) { + nes_debug(NES_DBG_CM, "Sending first write.\n"); + wqe = &nesqp->hwqp.sq_vbase[0]; + u64temp = (unsigned long)nesqp; + u64temp |= NES_SW_CONTEXT_ALIGN>>1; + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, + u64temp); + wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = cpu_to_le32(NES_IWARP_SQ_OP_RDMAW); + wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 0; + wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 0; + wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 0; + wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0; + wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; + + /* use the reserved spot on the WQ for the extra first WQE */ + nesqp->nesqp_context->ird_ord_sizes &= cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | + NES_QPCONTEXT_ORDIRD_WRPDU | NES_QPCONTEXT_ORDIRD_ALSMM)); + nesqp->skip_lsmm = 1; + nesqp->hwqp.sq_tail = 0; + nes_write32(nesdev->regs + NES_WQE_ALLOC, + (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); + } #endif memset(&nes_quad, 0, sizeof(nes_quad)); - nes_quad.DstIpAdrIndex = - cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); - if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr)) - nes_quad.SrcIpadr = nesvnic->local_ipaddr; - else - nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr; + nes_quad.DstIpAdrIndex = cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); + nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr; nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port; nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; @@ -3092,6 +2858,10 @@ static void cm_event_connected(struct nes_cm_event *event) nesqp->private_data_len = (u8) cm_node->mpa_frame_size; cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node); + /* modify QP state to rts */ + attr.qp_state = IB_QPS_RTS; + nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); + /* notify OF layer we successfully created the requested connection */ cm_event.event = IW_CM_EVENT_CONNECT_REPLY; cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; @@ -3100,21 +2870,20 @@ static void cm_event_connected(struct nes_cm_event *event) cm_event.local_addr.sin_port = cm_id->local_addr.sin_port; cm_event.remote_addr = cm_id->remote_addr; - cm_event.private_data = (void *)event->cm_node->mpa_frame_buf; - cm_event.private_data_len = (u8) event->cm_node->mpa_frame_size; + cm_event.private_data = (void *)event->cm_node->mpa_frame_buf; + cm_event.private_data_len = (u8) event->cm_node->mpa_frame_size; cm_event.local_addr.sin_addr.s_addr = event->cm_info.rem_addr; ret = cm_id->event_handler(cm_id, &cm_event); nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); if (ret) - printk(KERN_ERR "%s[%u] OFA CM event_handler returned, " - "ret=%d\n", __func__, __LINE__, ret); - attr.qp_state = IB_QPS_RTS; - nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); + printk("%s[%u] OFA CM event_handler returned, ret=%d\n", + __func__, __LINE__, ret); + nes_debug(NES_DBG_CM, "Exiting connect thread for QP%u. jiffies = %lu\n", + nesqp->hwqp.qp_id, jiffies ); - nes_debug(NES_DBG_CM, "Exiting connect thread for QP%u. jiffies = " - "%lu\n", nesqp->hwqp.qp_id, jiffies); + nes_rem_ref(&nesqp->ibqp); return; } @@ -3158,19 +2927,17 @@ static void cm_event_connect_error(struct nes_cm_event *event) cm_event.private_data = NULL; cm_event.private_data_len = 0; - nes_debug(NES_DBG_CM, "call CM_EVENT REJECTED, local_addr=%08x, " - "remove_addr=%08x\n", cm_event.local_addr.sin_addr.s_addr, - cm_event.remote_addr.sin_addr.s_addr); + nes_debug(NES_DBG_CM, "call CM_EVENT REJECTED, local_addr=%08x, remove_addr=%08x\n", + cm_event.local_addr.sin_addr.s_addr, cm_event.remote_addr.sin_addr.s_addr); ret = cm_id->event_handler(cm_id, &cm_event); nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); if (ret) - printk(KERN_ERR "%s[%u] OFA CM event_handler returned, " - "ret=%d\n", __func__, __LINE__, ret); + printk("%s[%u] OFA CM event_handler returned, ret=%d\n", + __func__, __LINE__, ret); nes_rem_ref(&nesqp->ibqp); - cm_id->rem_ref(cm_id); + cm_id->rem_ref(cm_id); - rem_ref_cm_node(event->cm_node->cm_core, event->cm_node); return; } @@ -3273,8 +3040,7 @@ static int nes_cm_post_event(struct nes_cm_event *event) add_ref_cm_node(event->cm_node); event->cm_info.cm_id->add_ref(event->cm_info.cm_id); INIT_WORK(&event->event_work, nes_cm_event_handler); - nes_debug(NES_DBG_CM, "cm_node=%p queue_work, event=%p\n", - event->cm_node, event); + nes_debug(NES_DBG_CM, "queue_work, event=%p\n", event); queue_work(event->cm_node->cm_core->event_wq, &event->event_work); @@ -3290,48 +3056,46 @@ static int nes_cm_post_event(struct nes_cm_event *event) */ static void nes_cm_event_handler(struct work_struct *work) { - struct nes_cm_event *event = container_of(work, struct nes_cm_event, - event_work); + struct nes_cm_event *event = container_of(work, struct nes_cm_event, event_work); struct nes_cm_core *cm_core; - if ((!event) || (!event->cm_node) || (!event->cm_node->cm_core)) + if ((!event) || (!event->cm_node) || (!event->cm_node->cm_core)) { return; - + } cm_core = event->cm_node->cm_core; nes_debug(NES_DBG_CM, "event=%p, event->type=%u, events posted=%u\n", - event, event->type, atomic_read(&cm_core->events_posted)); + event, event->type, atomic_read(&cm_core->events_posted)); switch (event->type) { - case NES_CM_EVENT_MPA_REQ: - cm_event_mpa_req(event); - nes_debug(NES_DBG_CM, "cm_node=%p CM Event: MPA REQUEST\n", - event->cm_node); - break; - case NES_CM_EVENT_RESET: - nes_debug(NES_DBG_CM, "cm_node = %p CM Event: RESET\n", - event->cm_node); - cm_event_reset(event); - break; - case NES_CM_EVENT_CONNECTED: - if ((!event->cm_node->cm_id) || - (event->cm_node->state != NES_CM_STATE_TSA)) + case NES_CM_EVENT_MPA_REQ: + cm_event_mpa_req(event); + nes_debug(NES_DBG_CM, "CM Event: MPA REQUEST\n"); + break; + case NES_CM_EVENT_RESET: + nes_debug(NES_DBG_CM, "CM Event: RESET\n"); + cm_event_reset(event); + break; + case NES_CM_EVENT_CONNECTED: + if ((!event->cm_node->cm_id) || + (event->cm_node->state != NES_CM_STATE_TSA)) { + break; + } + cm_event_connected(event); + nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n"); break; - cm_event_connected(event); - nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n"); - break; - case NES_CM_EVENT_ABORTED: - if ((!event->cm_node->cm_id) || - (event->cm_node->state == NES_CM_STATE_TSA)) + case NES_CM_EVENT_ABORTED: + if ((!event->cm_node->cm_id) || (event->cm_node->state == NES_CM_STATE_TSA)) { + break; + } + cm_event_connect_error(event); + nes_debug(NES_DBG_CM, "CM Event: ABORTED\n"); + break; + case NES_CM_EVENT_DROPPED_PKT: + nes_debug(NES_DBG_CM, "CM Event: DROPPED PKT\n"); + break; + default: + nes_debug(NES_DBG_CM, "CM Event: UNKNOWN EVENT TYPE\n"); break; - cm_event_connect_error(event); - nes_debug(NES_DBG_CM, "CM Event: ABORTED\n"); - break; - case NES_CM_EVENT_DROPPED_PKT: - nes_debug(NES_DBG_CM, "CM Event: DROPPED PKT\n"); - break; - default: - nes_debug(NES_DBG_CM, "CM Event: UNKNOWN EVENT TYPE\n"); - break; } atomic_dec(&cm_core->events_posted); diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.h b/trunk/drivers/infiniband/hw/nes/nes_cm.h index 367b3d290140..7717cb2ab500 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.h +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.h @@ -83,8 +83,6 @@ enum nes_timer_type { #define SET_FIN 4 #define SET_RST 8 -#define TCP_OPTIONS_PADDING 3 - struct option_base { u8 optionnum; u8 length; @@ -179,7 +177,6 @@ enum nes_cm_node_state { NES_CM_STATE_ESTABLISHED, NES_CM_STATE_ACCEPTING, NES_CM_STATE_MPAREQ_SENT, - NES_CM_STATE_MPAREQ_RCVD, NES_CM_STATE_TSA, NES_CM_STATE_FIN_WAIT1, NES_CM_STATE_FIN_WAIT2, @@ -190,16 +187,6 @@ enum nes_cm_node_state { NES_CM_STATE_CLOSED }; -enum nes_tcpip_pkt_type { - NES_PKT_TYPE_UNKNOWN, - NES_PKT_TYPE_SYN, - NES_PKT_TYPE_SYNACK, - NES_PKT_TYPE_ACK, - NES_PKT_TYPE_FIN, - NES_PKT_TYPE_RST -}; - - /* type of nes connection */ enum nes_cm_conn_type { NES_CM_IWARP_CONN_TYPE, @@ -270,9 +257,7 @@ struct nes_cm_node { struct net_device *netdev; struct nes_cm_node *loopbackpartner; - - struct nes_timer_entry *send_entry; - + struct list_head retrans_list; spinlock_t retrans_list_lock; struct list_head recv_list; spinlock_t recv_list_lock; @@ -291,8 +276,6 @@ struct nes_cm_node { struct nes_vnic *nesvnic; int apbvt_set; int accept_pend; - int freed; - struct nes_qp *nesqp; }; /* structure for client or CM to fill when making CM api calls. */ @@ -383,14 +366,14 @@ struct nes_cm_ops { struct nes_cm_info *); int (*stop_listener)(struct nes_cm_core *, struct nes_cm_listener *); struct nes_cm_node * (*connect)(struct nes_cm_core *, - struct nes_vnic *, u16, void *, + struct nes_vnic *, struct ietf_mpa_frame *, struct nes_cm_info *); int (*close)(struct nes_cm_core *, struct nes_cm_node *); int (*accept)(struct nes_cm_core *, struct ietf_mpa_frame *, struct nes_cm_node *); int (*reject)(struct nes_cm_core *, struct ietf_mpa_frame *, struct nes_cm_node *); - void (*recv_pkt)(struct nes_cm_core *, struct nes_vnic *, + int (*recv_pkt)(struct nes_cm_core *, struct nes_vnic *, struct sk_buff *); int (*destroy_cm_core)(struct nes_cm_core *); int (*get)(struct nes_cm_core *); diff --git a/trunk/drivers/infiniband/hw/nes/nes_hw.c b/trunk/drivers/infiniband/hw/nes/nes_hw.c index 1513d4066f1b..85f26d19a32b 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_hw.c +++ b/trunk/drivers/infiniband/hw/nes/nes_hw.c @@ -2814,6 +2814,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, nesqp = *((struct nes_qp **)&context); if (atomic_inc_return(&nesqp->close_timer_started) == 1) { nesqp->cm_id->add_ref(nesqp->cm_id); + nes_add_ref(&nesqp->ibqp); schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp, NES_TIMER_TYPE_CLOSE, 1, 0); nes_debug(NES_DBG_AEQ, "QP%u Not decrementing QP refcount (%d)," @@ -2837,6 +2838,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, if (async_event_id == NES_AEQE_AEID_RESET_SENT) { tcp_state = NES_AEQE_TCP_STATE_CLOSED; } + nes_add_ref(&nesqp->ibqp); spin_lock_irqsave(&nesqp->lock, flags); nesqp->hw_iwarp_state = iwarp_state; nesqp->hw_tcp_state = tcp_state; @@ -2874,6 +2876,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, } spin_unlock_irqrestore(&nesqp->lock, flags); if (next_iwarp_state) { + nes_add_ref(&nesqp->ibqp); nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X," " also added another reference\n", nesqp->hwqp.qp_id, next_iwarp_state); @@ -2885,6 +2888,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, /* FIN Received but ib state not RTS, close complete will be on its way */ spin_unlock_irqrestore(&nesqp->lock, flags); + nes_rem_ref(&nesqp->ibqp); return; } spin_unlock_irqrestore(&nesqp->lock, flags); @@ -2918,6 +2922,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) || ((nesqp->ibqp_state == IB_QPS_RTS)&& (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { + nes_add_ref(&nesqp->ibqp); nes_cm_disconn(nesqp); } else { nesqp->in_disconnect = 0; @@ -2926,6 +2931,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, break; case NES_AEQE_AEID_LLP_TOO_MANY_RETRIES: nesqp = *((struct nes_qp **)&context); + nes_add_ref(&nesqp->ibqp); spin_lock_irqsave(&nesqp->lock, flags); nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_ERROR; nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; @@ -3036,6 +3042,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); } /* tell cm to disconnect, cm will queue work to thread */ + nes_add_ref(&nesqp->ibqp); nes_cm_disconn(nesqp); break; case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE: @@ -3055,6 +3062,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); } /* tell cm to disconnect, cm will queue work to thread */ + nes_add_ref(&nesqp->ibqp); nes_cm_disconn(nesqp); break; case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR: @@ -3074,6 +3082,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); } /* tell cm to disconnect, cm will queue work to thread */ + nes_add_ref(&nesqp->ibqp); nes_cm_disconn(nesqp); break; /* TODO: additional AEs need to be here */ diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.c b/trunk/drivers/infiniband/hw/nes/nes_verbs.c index d79942e84979..e3939d13484e 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_verbs.c +++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.c @@ -2867,6 +2867,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, nesqp->hwqp.qp_id, attr->qp_state, nesqp->ibqp_state, nesqp->iwarp_state, atomic_read(&nesqp->refcount)); + nes_add_ref(&nesqp->ibqp); spin_lock_irqsave(&nesqp->lock, qplockflags); nes_debug(NES_DBG_MOD_QP, "QP%u: hw_iwarp_state=0x%X, hw_tcp_state=0x%X," @@ -2881,6 +2882,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, nesqp->hwqp.qp_id); if (nesqp->iwarp_state > (u32)NES_CQP_QP_IWARP_STATE_IDLE) { spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return -EINVAL; } next_iwarp_state = NES_CQP_QP_IWARP_STATE_IDLE; @@ -2891,6 +2893,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, nesqp->hwqp.qp_id); if (nesqp->iwarp_state>(u32)NES_CQP_QP_IWARP_STATE_IDLE) { spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return -EINVAL; } next_iwarp_state = NES_CQP_QP_IWARP_STATE_IDLE; @@ -2901,12 +2904,14 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, nesqp->hwqp.qp_id); if (nesqp->iwarp_state>(u32)NES_CQP_QP_IWARP_STATE_RTS) { spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return -EINVAL; } if (nesqp->cm_id == NULL) { nes_debug(NES_DBG_MOD_QP, "QP%u: Failing attempt to move QP to RTS without a CM_ID. \n", nesqp->hwqp.qp_id ); spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return -EINVAL; } next_iwarp_state = NES_CQP_QP_IWARP_STATE_RTS; @@ -2924,6 +2929,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, nesqp->hwqp.qp_id, nesqp->hwqp.sq_head, nesqp->hwqp.sq_tail); if (nesqp->iwarp_state == (u32)NES_CQP_QP_IWARP_STATE_CLOSING) { spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return 0; } else { if (nesqp->iwarp_state > (u32)NES_CQP_QP_IWARP_STATE_CLOSING) { @@ -2931,6 +2937,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, " ignored due to current iWARP state\n", nesqp->hwqp.qp_id); spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return -EINVAL; } if (nesqp->hw_iwarp_state != NES_AEQE_IWARP_STATE_RTS) { @@ -2962,6 +2969,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, nesqp->hwqp.qp_id); if (nesqp->iwarp_state>=(u32)NES_CQP_QP_IWARP_STATE_TERMINATE) { spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return -EINVAL; } /* next_iwarp_state = (NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000); */ @@ -2974,6 +2982,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, case IB_QPS_RESET: if (nesqp->iwarp_state == (u32)NES_CQP_QP_IWARP_STATE_ERROR) { spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return -EINVAL; } nes_debug(NES_DBG_MOD_QP, "QP%u: new state = error\n", @@ -2999,6 +3008,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, break; default: spin_unlock_irqrestore(&nesqp->lock, qplockflags); + nes_rem_ref(&nesqp->ibqp); return -EINVAL; break; } @@ -3078,6 +3088,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), original_last_aeq, nesqp->last_aeq); /* this one is for the cm_disconnect thread */ + nes_add_ref(&nesqp->ibqp); spin_lock_irqsave(&nesqp->lock, qplockflags); nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; @@ -3086,12 +3097,14 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, } else { nes_debug(NES_DBG_MOD_QP, "QP%u No fake disconnect, QP refcount=%d\n", nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount)); + nes_rem_ref(&nesqp->ibqp); } } else { spin_lock_irqsave(&nesqp->lock, qplockflags); if (nesqp->cm_id) { /* These two are for the timer thread */ if (atomic_inc_return(&nesqp->close_timer_started) == 1) { + nes_add_ref(&nesqp->ibqp); nesqp->cm_id->add_ref(nesqp->cm_id); nes_debug(NES_DBG_MOD_QP, "QP%u Not decrementing QP refcount (%d)," " need ae to finish up, original_last_aeq = 0x%04X." @@ -3115,12 +3128,14 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n", nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), original_last_aeq, nesqp->last_aeq); + nes_rem_ref(&nesqp->ibqp); } } else { nes_debug(NES_DBG_MOD_QP, "QP%u Decrementing QP refcount (%d), No ae to finish up," " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n", nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), original_last_aeq, nesqp->last_aeq); + nes_rem_ref(&nesqp->ibqp); } err = 0; diff --git a/trunk/drivers/infiniband/ulp/ipoib/Kconfig b/trunk/drivers/infiniband/ulp/ipoib/Kconfig index 9d9a9dc51f18..691525cf394a 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/Kconfig +++ b/trunk/drivers/infiniband/ulp/ipoib/Kconfig @@ -11,17 +11,16 @@ config INFINIBAND_IPOIB config INFINIBAND_IPOIB_CM bool "IP-over-InfiniBand Connected Mode support" - depends on INFINIBAND_IPOIB + depends on INFINIBAND_IPOIB && EXPERIMENTAL default n ---help--- - This option enables support for IPoIB connected mode. After - enabling this option, you need to switch to connected mode - through /sys/class/net/ibXXX/mode to actually create - connections, and then increase the interface MTU with - e.g. ifconfig ib0 mtu 65520. + This option enables experimental support for IPoIB connected mode. + After enabling this option, you need to switch to connected mode through + /sys/class/net/ibXXX/mode to actually create connections, and then increase + the interface MTU with e.g. ifconfig ib0 mtu 65520. - WARNING: Enabling connected mode will trigger some packet - drops for multicast and UD mode traffic from this interface, + WARNING: Enabling connected mode will trigger some + packet drops for multicast and UD mode traffic from this interface, unless you limit mtu for these destinations to 2044. config INFINIBAND_IPOIB_DEBUG @@ -34,10 +33,9 @@ config INFINIBAND_IPOIB_DEBUG debug_level and mcast_debug_level module parameters (which can also be set after the driver is loaded through sysfs). - This option also creates a directory tree under ipoib/ in - debugfs, which contains files that expose debugging - information about IB multicast groups used by the IPoIB - driver. + This option also creates an "ipoib_debugfs," which can be + mounted to expose debugging information about IB multicast + groups used by the IPoIB driver. config INFINIBAND_IPOIB_DEBUG_DATA bool "IP-over-InfiniBand data path debugging" diff --git a/trunk/drivers/isdn/Kconfig b/trunk/drivers/isdn/Kconfig index 3d113c6e4a70..66f946aa30b3 100644 --- a/trunk/drivers/isdn/Kconfig +++ b/trunk/drivers/isdn/Kconfig @@ -3,7 +3,7 @@ # menuconfig ISDN - bool "ISDN support" + tristate "ISDN support" depends on NET depends on !S390 ---help--- @@ -21,8 +21,6 @@ menuconfig ISDN if ISDN -source "drivers/isdn/mISDN/Kconfig" - menuconfig ISDN_I4L tristate "Old ISDN4Linux (deprecated)" ---help--- diff --git a/trunk/drivers/isdn/Makefile b/trunk/drivers/isdn/Makefile index 8380a4568d11..988142c30a6d 100644 --- a/trunk/drivers/isdn/Makefile +++ b/trunk/drivers/isdn/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_ISDN_I4L) += i4l/ obj-$(CONFIG_ISDN_CAPI) += capi/ -obj-$(CONFIG_MISDN) += mISDN/ obj-$(CONFIG_ISDN_CAPI) += hardware/ obj-$(CONFIG_ISDN_DIVERSION) += divert/ obj-$(CONFIG_ISDN_DRV_HISAX) += hisax/ diff --git a/trunk/drivers/isdn/hardware/Makefile b/trunk/drivers/isdn/hardware/Makefile index a5d8fce4c4c4..11c8a183948c 100644 --- a/trunk/drivers/isdn/hardware/Makefile +++ b/trunk/drivers/isdn/hardware/Makefile @@ -4,4 +4,3 @@ obj-$(CONFIG_CAPI_AVM) += avm/ obj-$(CONFIG_CAPI_EICON) += eicon/ -obj-$(CONFIG_MISDN) += mISDN/ diff --git a/trunk/drivers/isdn/hardware/mISDN/Kconfig b/trunk/drivers/isdn/hardware/mISDN/Kconfig deleted file mode 100644 index 9cd5f5f62280..000000000000 --- a/trunk/drivers/isdn/hardware/mISDN/Kconfig +++ /dev/null @@ -1,26 +0,0 @@ -# -# Hardware for mISDN -# -comment "mISDN hardware drivers" - -config MISDN_HFCPCI - tristate "Support for HFC PCI cards" - depends on MISDN - depends on PCI - depends on VIRT_TO_BUS - help - Enable support for cards with Cologne Chip AG's - HFC PCI chip. - -config MISDN_HFCMULTI - tristate "Support for HFC multiport cards (HFC-4S/8S/E1)" - depends on PCI - depends on MISDN - help - Enable support for cards with Cologne Chip AG's HFC multiport - chip. There are three types of chips that are quite similar, - but the interface is different: - * HFC-4S (4 S/T interfaces on one chip) - * HFC-8S (8 S/T interfaces on one chip) - * HFC-E1 (E1 interface for 2Mbit ISDN) - diff --git a/trunk/drivers/isdn/hardware/mISDN/Makefile b/trunk/drivers/isdn/hardware/mISDN/Makefile deleted file mode 100644 index 1e7ca5332ad7..000000000000 --- a/trunk/drivers/isdn/hardware/mISDN/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the modular ISDN hardware drivers -# -# - -obj-$(CONFIG_MISDN_HFCPCI) += hfcpci.o -obj-$(CONFIG_MISDN_HFCMULTI) += hfcmulti.o diff --git a/trunk/drivers/isdn/hardware/mISDN/hfc_multi.h b/trunk/drivers/isdn/hardware/mISDN/hfc_multi.h deleted file mode 100644 index a33d87afc843..000000000000 --- a/trunk/drivers/isdn/hardware/mISDN/hfc_multi.h +++ /dev/null @@ -1,1204 +0,0 @@ -/* - * see notice in hfc_multi.c - */ - -extern void ztdummy_extern_interrupt(void); -extern void ztdummy_register_interrupt(void); -extern int ztdummy_unregister_interrupt(void); - -#define DEBUG_HFCMULTI_FIFO 0x00010000 -#define DEBUG_HFCMULTI_CRC 0x00020000 -#define DEBUG_HFCMULTI_INIT 0x00040000 -#define DEBUG_HFCMULTI_PLXSD 0x00080000 -#define DEBUG_HFCMULTI_MODE 0x00100000 -#define DEBUG_HFCMULTI_MSG 0x00200000 -#define DEBUG_HFCMULTI_STATE 0x00400000 -#define DEBUG_HFCMULTI_SYNC 0x01000000 -#define DEBUG_HFCMULTI_DTMF 0x02000000 -#define DEBUG_HFCMULTI_LOCK 0x80000000 - -#define PCI_ENA_REGIO 0x01 -#define PCI_ENA_MEMIO 0x02 - -/* - * NOTE: some registers are assigned multiple times due to different modes - * also registers are assigned differen for HFC-4s/8s and HFC-E1 - */ - -/* -#define MAX_FRAME_SIZE 2048 -*/ - -struct hfc_chan { - struct dchannel *dch; /* link if channel is a D-channel */ - struct bchannel *bch; /* link if channel is a B-channel */ - int port; /* the interface port this */ - /* channel is associated with */ - int nt_timer; /* -1 if off, 0 if elapsed, >0 if running */ - int los, ais, slip_tx, slip_rx, rdi; /* current alarms */ - int jitter; - u_long cfg; /* port configuration */ - int sync; /* sync state (used by E1) */ - u_int protocol; /* current protocol */ - int slot_tx; /* current pcm slot */ - int bank_tx; /* current pcm bank */ - int slot_rx; - int bank_rx; - int conf; /* conference setting of TX slot */ - int txpending; /* if there is currently data in */ - /* the FIFO 0=no, 1=yes, 2=splloop */ - int rx_off; /* set to turn fifo receive off */ - int coeff_count; /* curren coeff block */ - s32 *coeff; /* memory pointer to 8 coeff blocks */ -}; - - -struct hfcm_hw { - u_char r_ctrl; - u_char r_irq_ctrl; - u_char r_cirm; - u_char r_ram_sz; - u_char r_pcm_md0; - u_char r_irqmsk_misc; - u_char r_dtmf; - u_char r_st_sync; - u_char r_sci_msk; - u_char r_tx0, r_tx1; - u_char a_st_ctrl0[8]; - timer_t timer; -}; - - -/* for each stack these flags are used (cfg) */ -#define HFC_CFG_NONCAP_TX 1 /* S/T TX interface has less capacity */ -#define HFC_CFG_DIS_ECHANNEL 2 /* disable E-channel processing */ -#define HFC_CFG_REG_ECHANNEL 3 /* register E-channel */ -#define HFC_CFG_OPTICAL 4 /* the E1 interface is optical */ -#define HFC_CFG_REPORT_LOS 5 /* the card should report loss of signal */ -#define HFC_CFG_REPORT_AIS 6 /* the card should report alarm ind. sign. */ -#define HFC_CFG_REPORT_SLIP 7 /* the card should report bit slips */ -#define HFC_CFG_REPORT_RDI 8 /* the card should report remote alarm */ -#define HFC_CFG_DTMF 9 /* enable DTMF-detection */ -#define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */ - /* use double frame instead. */ - -#define HFC_CHIP_EXRAM_128 0 /* external ram 128k */ -#define HFC_CHIP_EXRAM_512 1 /* external ram 256k */ -#define HFC_CHIP_REVISION0 2 /* old fifo handling */ -#define HFC_CHIP_PCM_SLAVE 3 /* PCM is slave */ -#define HFC_CHIP_PCM_MASTER 4 /* PCM is master */ -#define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */ -#define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */ -#define HFC_CHIP_ULAW 7 /* ULAW mode */ -#define HFC_CHIP_CLOCK2 8 /* double clock mode */ -#define HFC_CHIP_E1CLOCK_GET 9 /* always get clock from E1 interface */ -#define HFC_CHIP_E1CLOCK_PUT 10 /* always put clock from E1 interface */ -#define HFC_CHIP_WATCHDOG 11 /* whether we should send signals */ - /* to the watchdog */ -#define HFC_CHIP_B410P 12 /* whether we have a b410p with echocan in */ - /* hw */ -#define HFC_CHIP_PLXSD 13 /* whether we have a Speech-Design PLX */ - -#define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */ -#define HFC_IO_MODE_REGIO 0x01 /* PCI io access */ -#define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */ - -/* table entry in the PCI devices list */ -struct hm_map { - char *vendor_name; - char *card_name; - int type; - int ports; - int clock2; - int leds; - int opticalsupport; - int dip_type; - int io_mode; -}; - -struct hfc_multi { - struct list_head list; - struct hm_map *mtyp; - int id; - int pcm; /* id of pcm bus */ - int type; - int ports; - - u_int irq; /* irq used by card */ - u_int irqcnt; - struct pci_dev *pci_dev; - int io_mode; /* selects mode */ -#ifdef HFC_REGISTER_DEBUG - void (*HFC_outb)(struct hfc_multi *hc, u_char reg, - u_char val, const char *function, int line); - void (*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg, - u_char val, const char *function, int line); - u_char (*HFC_inb)(struct hfc_multi *hc, u_char reg, - const char *function, int line); - u_char (*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg, - const char *function, int line); - u_short (*HFC_inw)(struct hfc_multi *hc, u_char reg, - const char *function, int line); - u_short (*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg, - const char *function, int line); - void (*HFC_wait)(struct hfc_multi *hc, - const char *function, int line); - void (*HFC_wait_nodebug)(struct hfc_multi *hc, - const char *function, int line); -#else - void (*HFC_outb)(struct hfc_multi *hc, u_char reg, - u_char val); - void (*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg, - u_char val); - u_char (*HFC_inb)(struct hfc_multi *hc, u_char reg); - u_char (*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg); - u_short (*HFC_inw)(struct hfc_multi *hc, u_char reg); - u_short (*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg); - void (*HFC_wait)(struct hfc_multi *hc); - void (*HFC_wait_nodebug)(struct hfc_multi *hc); -#endif - void (*read_fifo)(struct hfc_multi *hc, u_char *data, - int len); - void (*write_fifo)(struct hfc_multi *hc, u_char *data, - int len); - u_long pci_origmembase, plx_origmembase, dsp_origmembase; - u_char *pci_membase; /* PCI memory (MUST BE BYTE POINTER) */ - u_char *plx_membase; /* PLX memory */ - u_char *dsp_membase; /* DSP on PLX */ - u_long pci_iobase; /* PCI IO */ - struct hfcm_hw hw; /* remember data of write-only-registers */ - - u_long chip; /* chip configuration */ - int masterclk; /* port that provides master clock -1=off */ - int dtmf; /* flag that dtmf is currently in process */ - int Flen; /* F-buffer size */ - int Zlen; /* Z-buffer size (must be int for calculation)*/ - int max_trans; /* maximum transparent fifo fill */ - int Zmin; /* Z-buffer offset */ - int DTMFbase; /* base address of DTMF coefficients */ - - u_int slots; /* number of PCM slots */ - u_int leds; /* type of leds */ - u_int ledcount; /* used to animate leds */ - u_long ledstate; /* save last state of leds */ - int opticalsupport; /* has the e1 board */ - /* an optical Interface */ - int dslot; /* channel # of d-channel (E1) default 16 */ - - u_long wdcount; /* every 500 ms we need to */ - /* send the watchdog a signal */ - u_char wdbyte; /* watchdog toggle byte */ - u_int activity[8]; /* if there is any action on this */ - /* port (will be cleared after */ - /* showing led-states) */ - int e1_state; /* keep track of last state */ - int e1_getclock; /* if sync is retrieved from interface */ - int syncronized; /* keep track of existing sync interface */ - int e1_resync; /* resync jobs */ - - spinlock_t lock; /* the lock */ - - /* - * the channel index is counted from 0, regardless where the channel - * is located on the hfc-channel. - * the bch->channel is equvalent to the hfc-channel - */ - struct hfc_chan chan[32]; - u_char created[8]; /* what port is created */ - signed char slot_owner[256]; /* owner channel of slot */ -}; - -/* PLX GPIOs */ -#define PLX_GPIO4_DIR_BIT 13 -#define PLX_GPIO4_BIT 14 -#define PLX_GPIO5_DIR_BIT 16 -#define PLX_GPIO5_BIT 17 -#define PLX_GPIO6_DIR_BIT 19 -#define PLX_GPIO6_BIT 20 -#define PLX_GPIO7_DIR_BIT 22 -#define PLX_GPIO7_BIT 23 -#define PLX_GPIO8_DIR_BIT 25 -#define PLX_GPIO8_BIT 26 - -#define PLX_GPIO4 (1 << PLX_GPIO4_BIT) -#define PLX_GPIO5 (1 << PLX_GPIO5_BIT) -#define PLX_GPIO6 (1 << PLX_GPIO6_BIT) -#define PLX_GPIO7 (1 << PLX_GPIO7_BIT) -#define PLX_GPIO8 (1 << PLX_GPIO8_BIT) - -#define PLX_GPIO4_DIR (1 << PLX_GPIO4_DIR_BIT) -#define PLX_GPIO5_DIR (1 << PLX_GPIO5_DIR_BIT) -#define PLX_GPIO6_DIR (1 << PLX_GPIO6_DIR_BIT) -#define PLX_GPIO7_DIR (1 << PLX_GPIO7_DIR_BIT) -#define PLX_GPIO8_DIR (1 << PLX_GPIO8_DIR_BIT) - -#define PLX_TERM_ON PLX_GPIO7 -#define PLX_SLAVE_EN_N PLX_GPIO5 -#define PLX_MASTER_EN PLX_GPIO6 -#define PLX_SYNC_O_EN PLX_GPIO4 -#define PLX_DSP_RES_N PLX_GPIO8 -/* GPIO4..8 Enable & Set to OUT, SLAVE_EN_N = 1 */ -#define PLX_GPIOC_INIT (PLX_GPIO4_DIR | PLX_GPIO5_DIR | PLX_GPIO6_DIR \ - | PLX_GPIO7_DIR | PLX_GPIO8_DIR | PLX_SLAVE_EN_N) - -/* PLX Interrupt Control/STATUS */ -#define PLX_INTCSR_LINTI1_ENABLE 0x01 -#define PLX_INTCSR_LINTI1_STATUS 0x04 -#define PLX_INTCSR_LINTI2_ENABLE 0x08 -#define PLX_INTCSR_LINTI2_STATUS 0x20 -#define PLX_INTCSR_PCIINT_ENABLE 0x40 - -/* PLX Registers */ -#define PLX_INTCSR 0x4c -#define PLX_CNTRL 0x50 -#define PLX_GPIOC 0x54 - - -/* - * REGISTER SETTING FOR HFC-4S/8S AND HFC-E1 - */ - -/* write only registers */ -#define R_CIRM 0x00 -#define R_CTRL 0x01 -#define R_BRG_PCM_CFG 0x02 -#define R_RAM_ADDR0 0x08 -#define R_RAM_ADDR1 0x09 -#define R_RAM_ADDR2 0x0A -#define R_FIRST_FIFO 0x0B -#define R_RAM_SZ 0x0C -#define R_FIFO_MD 0x0D -#define R_INC_RES_FIFO 0x0E -#define R_FSM_IDX 0x0F -#define R_FIFO 0x0F -#define R_SLOT 0x10 -#define R_IRQMSK_MISC 0x11 -#define R_SCI_MSK 0x12 -#define R_IRQ_CTRL 0x13 -#define R_PCM_MD0 0x14 -#define R_PCM_MD1 0x15 -#define R_PCM_MD2 0x15 -#define R_SH0H 0x15 -#define R_SH1H 0x15 -#define R_SH0L 0x15 -#define R_SH1L 0x15 -#define R_SL_SEL0 0x15 -#define R_SL_SEL1 0x15 -#define R_SL_SEL2 0x15 -#define R_SL_SEL3 0x15 -#define R_SL_SEL4 0x15 -#define R_SL_SEL5 0x15 -#define R_SL_SEL6 0x15 -#define R_SL_SEL7 0x15 -#define R_ST_SEL 0x16 -#define R_ST_SYNC 0x17 -#define R_CONF_EN 0x18 -#define R_TI_WD 0x1A -#define R_BERT_WD_MD 0x1B -#define R_DTMF 0x1C -#define R_DTMF_N 0x1D -#define R_E1_WR_STA 0x20 -#define R_E1_RD_STA 0x20 -#define R_LOS0 0x22 -#define R_LOS1 0x23 -#define R_RX0 0x24 -#define R_RX_FR0 0x25 -#define R_RX_FR1 0x26 -#define R_TX0 0x28 -#define R_TX1 0x29 -#define R_TX_FR0 0x2C - -#define R_TX_FR1 0x2D -#define R_TX_FR2 0x2E -#define R_JATT_ATT 0x2F /* undocumented */ -#define A_ST_RD_STATE 0x30 -#define A_ST_WR_STATE 0x30 -#define R_RX_OFF 0x30 -#define A_ST_CTRL0 0x31 -#define R_SYNC_OUT 0x31 -#define A_ST_CTRL1 0x32 -#define A_ST_CTRL2 0x33 -#define A_ST_SQ_WR 0x34 -#define R_TX_OFF 0x34 -#define R_SYNC_CTRL 0x35 -#define A_ST_CLK_DLY 0x37 -#define R_PWM0 0x38 -#define R_PWM1 0x39 -#define A_ST_B1_TX 0x3C -#define A_ST_B2_TX 0x3D -#define A_ST_D_TX 0x3E -#define R_GPIO_OUT0 0x40 -#define R_GPIO_OUT1 0x41 -#define R_GPIO_EN0 0x42 -#define R_GPIO_EN1 0x43 -#define R_GPIO_SEL 0x44 -#define R_BRG_CTRL 0x45 -#define R_PWM_MD 0x46 -#define R_BRG_MD 0x47 -#define R_BRG_TIM0 0x48 -#define R_BRG_TIM1 0x49 -#define R_BRG_TIM2 0x4A -#define R_BRG_TIM3 0x4B -#define R_BRG_TIM_SEL01 0x4C -#define R_BRG_TIM_SEL23 0x4D -#define R_BRG_TIM_SEL45 0x4E -#define R_BRG_TIM_SEL67 0x4F -#define A_SL_CFG 0xD0 -#define A_CONF 0xD1 -#define A_CH_MSK 0xF4 -#define A_CON_HDLC 0xFA -#define A_SUBCH_CFG 0xFB -#define A_CHANNEL 0xFC -#define A_FIFO_SEQ 0xFD -#define A_IRQ_MSK 0xFF - -/* read only registers */ -#define A_Z12 0x04 -#define A_Z1L 0x04 -#define A_Z1 0x04 -#define A_Z1H 0x05 -#define A_Z2L 0x06 -#define A_Z2 0x06 -#define A_Z2H 0x07 -#define A_F1 0x0C -#define A_F12 0x0C -#define A_F2 0x0D -#define R_IRQ_OVIEW 0x10 -#define R_IRQ_MISC 0x11 -#define R_IRQ_STATECH 0x12 -#define R_CONF_OFLOW 0x14 -#define R_RAM_USE 0x15 -#define R_CHIP_ID 0x16 -#define R_BERT_STA 0x17 -#define R_F0_CNTL 0x18 -#define R_F0_CNTH 0x19 -#define R_BERT_EC 0x1A -#define R_BERT_ECL 0x1A -#define R_BERT_ECH 0x1B -#define R_STATUS 0x1C -#define R_CHIP_RV 0x1F -#define R_STATE 0x20 -#define R_SYNC_STA 0x24 -#define R_RX_SL0_0 0x25 -#define R_RX_SL0_1 0x26 -#define R_RX_SL0_2 0x27 -#define R_JATT_DIR 0x2b /* undocumented */ -#define R_SLIP 0x2c -#define A_ST_RD_STA 0x30 -#define R_FAS_EC 0x30 -#define R_FAS_ECL 0x30 -#define R_FAS_ECH 0x31 -#define R_VIO_EC 0x32 -#define R_VIO_ECL 0x32 -#define R_VIO_ECH 0x33 -#define A_ST_SQ_RD 0x34 -#define R_CRC_EC 0x34 -#define R_CRC_ECL 0x34 -#define R_CRC_ECH 0x35 -#define R_E_EC 0x36 -#define R_E_ECL 0x36 -#define R_E_ECH 0x37 -#define R_SA6_SA13_EC 0x38 -#define R_SA6_SA13_ECL 0x38 -#define R_SA6_SA13_ECH 0x39 -#define R_SA6_SA23_EC 0x3A -#define R_SA6_SA23_ECL 0x3A -#define R_SA6_SA23_ECH 0x3B -#define A_ST_B1_RX 0x3C -#define A_ST_B2_RX 0x3D -#define A_ST_D_RX 0x3E -#define A_ST_E_RX 0x3F -#define R_GPIO_IN0 0x40 -#define R_GPIO_IN1 0x41 -#define R_GPI_IN0 0x44 -#define R_GPI_IN1 0x45 -#define R_GPI_IN2 0x46 -#define R_GPI_IN3 0x47 -#define R_INT_DATA 0x88 -#define R_IRQ_FIFO_BL0 0xC8 -#define R_IRQ_FIFO_BL1 0xC9 -#define R_IRQ_FIFO_BL2 0xCA -#define R_IRQ_FIFO_BL3 0xCB -#define R_IRQ_FIFO_BL4 0xCC -#define R_IRQ_FIFO_BL5 0xCD -#define R_IRQ_FIFO_BL6 0xCE -#define R_IRQ_FIFO_BL7 0xCF - -/* read and write registers */ -#define A_FIFO_DATA0 0x80 -#define A_FIFO_DATA1 0x80 -#define A_FIFO_DATA2 0x80 -#define A_FIFO_DATA0_NOINC 0x84 -#define A_FIFO_DATA1_NOINC 0x84 -#define A_FIFO_DATA2_NOINC 0x84 -#define R_RAM_DATA 0xC0 - - -/* - * BIT SETTING FOR HFC-4S/8S AND HFC-E1 - */ - -/* chapter 2: universal bus interface */ -/* R_CIRM */ -#define V_IRQ_SEL 0x01 -#define V_SRES 0x08 -#define V_HFCRES 0x10 -#define V_PCMRES 0x20 -#define V_STRES 0x40 -#define V_ETRES 0x40 -#define V_RLD_EPR 0x80 -/* R_CTRL */ -#define V_FIFO_LPRIO 0x02 -#define V_SLOW_RD 0x04 -#define V_EXT_RAM 0x08 -#define V_CLK_OFF 0x20 -#define V_ST_CLK 0x40 -/* R_RAM_ADDR0 */ -#define V_RAM_ADDR2 0x01 -#define V_ADDR_RES 0x40 -#define V_ADDR_INC 0x80 -/* R_RAM_SZ */ -#define V_RAM_SZ 0x01 -#define V_PWM0_16KHZ 0x10 -#define V_PWM1_16KHZ 0x20 -#define V_FZ_MD 0x80 -/* R_CHIP_ID */ -#define V_PNP_IRQ 0x01 -#define V_CHIP_ID 0x10 - -/* chapter 3: data flow */ -/* R_FIRST_FIFO */ -#define V_FIRST_FIRO_DIR 0x01 -#define V_FIRST_FIFO_NUM 0x02 -/* R_FIFO_MD */ -#define V_FIFO_MD 0x01 -#define V_CSM_MD 0x04 -#define V_FSM_MD 0x08 -#define V_FIFO_SZ 0x10 -/* R_FIFO */ -#define V_FIFO_DIR 0x01 -#define V_FIFO_NUM 0x02 -#define V_REV 0x80 -/* R_SLOT */ -#define V_SL_DIR 0x01 -#define V_SL_NUM 0x02 -/* A_SL_CFG */ -#define V_CH_DIR 0x01 -#define V_CH_SEL 0x02 -#define V_ROUTING 0x40 -/* A_CON_HDLC */ -#define V_IFF 0x01 -#define V_HDLC_TRP 0x02 -#define V_TRP_IRQ 0x04 -#define V_DATA_FLOW 0x20 -/* A_SUBCH_CFG */ -#define V_BIT_CNT 0x01 -#define V_START_BIT 0x08 -#define V_LOOP_FIFO 0x40 -#define V_INV_DATA 0x80 -/* A_CHANNEL */ -#define V_CH_DIR0 0x01 -#define V_CH_NUM0 0x02 -/* A_FIFO_SEQ */ -#define V_NEXT_FIFO_DIR 0x01 -#define V_NEXT_FIFO_NUM 0x02 -#define V_SEQ_END 0x40 - -/* chapter 4: FIFO handling and HDLC controller */ -/* R_INC_RES_FIFO */ -#define V_INC_F 0x01 -#define V_RES_F 0x02 -#define V_RES_LOST 0x04 - -/* chapter 5: S/T interface */ -/* R_SCI_MSK */ -#define V_SCI_MSK_ST0 0x01 -#define V_SCI_MSK_ST1 0x02 -#define V_SCI_MSK_ST2 0x04 -#define V_SCI_MSK_ST3 0x08 -#define V_SCI_MSK_ST4 0x10 -#define V_SCI_MSK_ST5 0x20 -#define V_SCI_MSK_ST6 0x40 -#define V_SCI_MSK_ST7 0x80 -/* R_ST_SEL */ -#define V_ST_SEL 0x01 -#define V_MULT_ST 0x08 -/* R_ST_SYNC */ -#define V_SYNC_SEL 0x01 -#define V_AUTO_SYNC 0x08 -/* A_ST_WR_STA */ -#define V_ST_SET_STA 0x01 -#define V_ST_LD_STA 0x10 -#define V_ST_ACT 0x20 -#define V_SET_G2_G3 0x80 -/* A_ST_CTRL0 */ -#define V_B1_EN 0x01 -#define V_B2_EN 0x02 -#define V_ST_MD 0x04 -#define V_D_PRIO 0x08 -#define V_SQ_EN 0x10 -#define V_96KHZ 0x20 -#define V_TX_LI 0x40 -#define V_ST_STOP 0x80 -/* A_ST_CTRL1 */ -#define V_G2_G3_EN 0x01 -#define V_D_HI 0x04 -#define V_E_IGNO 0x08 -#define V_E_LO 0x10 -#define V_B12_SWAP 0x80 -/* A_ST_CTRL2 */ -#define V_B1_RX_EN 0x01 -#define V_B2_RX_EN 0x02 -#define V_ST_TRIS 0x40 -/* A_ST_CLK_DLY */ -#define V_ST_CK_DLY 0x01 -#define V_ST_SMPL 0x10 -/* A_ST_D_TX */ -#define V_ST_D_TX 0x40 -/* R_IRQ_STATECH */ -#define V_SCI_ST0 0x01 -#define V_SCI_ST1 0x02 -#define V_SCI_ST2 0x04 -#define V_SCI_ST3 0x08 -#define V_SCI_ST4 0x10 -#define V_SCI_ST5 0x20 -#define V_SCI_ST6 0x40 -#define V_SCI_ST7 0x80 -/* A_ST_RD_STA */ -#define V_ST_STA 0x01 -#define V_FR_SYNC_ST 0x10 -#define V_TI2_EXP 0x20 -#define V_INFO0 0x40 -#define V_G2_G3 0x80 -/* A_ST_SQ_RD */ -#define V_ST_SQ 0x01 -#define V_MF_RX_RDY 0x10 -#define V_MF_TX_RDY 0x80 -/* A_ST_D_RX */ -#define V_ST_D_RX 0x40 -/* A_ST_E_RX */ -#define V_ST_E_RX 0x40 - -/* chapter 5: E1 interface */ -/* R_E1_WR_STA */ -/* R_E1_RD_STA */ -#define V_E1_SET_STA 0x01 -#define V_E1_LD_STA 0x10 -/* R_RX0 */ -#define V_RX_CODE 0x01 -#define V_RX_FBAUD 0x04 -#define V_RX_CMI 0x08 -#define V_RX_INV_CMI 0x10 -#define V_RX_INV_CLK 0x20 -#define V_RX_INV_DATA 0x40 -#define V_AIS_ITU 0x80 -/* R_RX_FR0 */ -#define V_NO_INSYNC 0x01 -#define V_AUTO_RESYNC 0x02 -#define V_AUTO_RECO 0x04 -#define V_SWORD_COND 0x08 -#define V_SYNC_LOSS 0x10 -#define V_XCRC_SYNC 0x20 -#define V_MF_RESYNC 0x40 -#define V_RESYNC 0x80 -/* R_RX_FR1 */ -#define V_RX_MF 0x01 -#define V_RX_MF_SYNC 0x02 -#define V_RX_SL0_RAM 0x04 -#define V_ERR_SIM 0x20 -#define V_RES_NMF 0x40 -/* R_TX0 */ -#define V_TX_CODE 0x01 -#define V_TX_FBAUD 0x04 -#define V_TX_CMI_CODE 0x08 -#define V_TX_INV_CMI_CODE 0x10 -#define V_TX_INV_CLK 0x20 -#define V_TX_INV_DATA 0x40 -#define V_OUT_EN 0x80 -/* R_TX1 */ -#define V_INV_CLK 0x01 -#define V_EXCHG_DATA_LI 0x02 -#define V_AIS_OUT 0x04 -#define V_ATX 0x20 -#define V_NTRI 0x40 -#define V_AUTO_ERR_RES 0x80 -/* R_TX_FR0 */ -#define V_TRP_FAS 0x01 -#define V_TRP_NFAS 0x02 -#define V_TRP_RAL 0x04 -#define V_TRP_SA 0x08 -/* R_TX_FR1 */ -#define V_TX_FAS 0x01 -#define V_TX_NFAS 0x02 -#define V_TX_RAL 0x04 -#define V_TX_SA 0x08 -/* R_TX_FR2 */ -#define V_TX_MF 0x01 -#define V_TRP_SL0 0x02 -#define V_TX_SL0_RAM 0x04 -#define V_TX_E 0x10 -#define V_NEG_E 0x20 -#define V_XS12_ON 0x40 -#define V_XS15_ON 0x80 -/* R_RX_OFF */ -#define V_RX_SZ 0x01 -#define V_RX_INIT 0x04 -/* R_SYNC_OUT */ -#define V_SYNC_E1_RX 0x01 -#define V_IPATS0 0x20 -#define V_IPATS1 0x40 -#define V_IPATS2 0x80 -/* R_TX_OFF */ -#define V_TX_SZ 0x01 -#define V_TX_INIT 0x04 -/* R_SYNC_CTRL */ -#define V_EXT_CLK_SYNC 0x01 -#define V_SYNC_OFFS 0x02 -#define V_PCM_SYNC 0x04 -#define V_NEG_CLK 0x08 -#define V_HCLK 0x10 -/* -#define V_JATT_AUTO_DEL 0x20 -#define V_JATT_AUTO 0x40 -*/ -#define V_JATT_OFF 0x80 -/* R_STATE */ -#define V_E1_STA 0x01 -#define V_ALT_FR_RX 0x40 -#define V_ALT_FR_TX 0x80 -/* R_SYNC_STA */ -#define V_RX_STA 0x01 -#define V_FR_SYNC_E1 0x04 -#define V_SIG_LOS 0x08 -#define V_MFA_STA 0x10 -#define V_AIS 0x40 -#define V_NO_MF_SYNC 0x80 -/* R_RX_SL0_0 */ -#define V_SI_FAS 0x01 -#define V_SI_NFAS 0x02 -#define V_A 0x04 -#define V_CRC_OK 0x08 -#define V_TX_E1 0x10 -#define V_TX_E2 0x20 -#define V_RX_E1 0x40 -#define V_RX_E2 0x80 -/* R_SLIP */ -#define V_SLIP_RX 0x01 -#define V_FOSLIP_RX 0x08 -#define V_SLIP_TX 0x10 -#define V_FOSLIP_TX 0x80 - -/* chapter 6: PCM interface */ -/* R_PCM_MD0 */ -#define V_PCM_MD 0x01 -#define V_C4_POL 0x02 -#define V_F0_NEG 0x04 -#define V_F0_LEN 0x08 -#define V_PCM_ADDR 0x10 -/* R_SL_SEL0 */ -#define V_SL_SEL0 0x01 -#define V_SH_SEL0 0x80 -/* R_SL_SEL1 */ -#define V_SL_SEL1 0x01 -#define V_SH_SEL1 0x80 -/* R_SL_SEL2 */ -#define V_SL_SEL2 0x01 -#define V_SH_SEL2 0x80 -/* R_SL_SEL3 */ -#define V_SL_SEL3 0x01 -#define V_SH_SEL3 0x80 -/* R_SL_SEL4 */ -#define V_SL_SEL4 0x01 -#define V_SH_SEL4 0x80 -/* R_SL_SEL5 */ -#define V_SL_SEL5 0x01 -#define V_SH_SEL5 0x80 -/* R_SL_SEL6 */ -#define V_SL_SEL6 0x01 -#define V_SH_SEL6 0x80 -/* R_SL_SEL7 */ -#define V_SL_SEL7 0x01 -#define V_SH_SEL7 0x80 -/* R_PCM_MD1 */ -#define V_ODEC_CON 0x01 -#define V_PLL_ADJ 0x04 -#define V_PCM_DR 0x10 -#define V_PCM_LOOP 0x40 -/* R_PCM_MD2 */ -#define V_SYNC_PLL 0x02 -#define V_SYNC_SRC 0x04 -#define V_SYNC_OUT 0x08 -#define V_ICR_FR_TIME 0x40 -#define V_EN_PLL 0x80 - -/* chapter 7: pulse width modulation */ -/* R_PWM_MD */ -#define V_EXT_IRQ_EN 0x08 -#define V_PWM0_MD 0x10 -#define V_PWM1_MD 0x40 - -/* chapter 8: multiparty audio conferences */ -/* R_CONF_EN */ -#define V_CONF_EN 0x01 -#define V_ULAW 0x80 -/* A_CONF */ -#define V_CONF_NUM 0x01 -#define V_NOISE_SUPPR 0x08 -#define V_ATT_LEV 0x20 -#define V_CONF_SL 0x80 -/* R_CONF_OFLOW */ -#define V_CONF_OFLOW0 0x01 -#define V_CONF_OFLOW1 0x02 -#define V_CONF_OFLOW2 0x04 -#define V_CONF_OFLOW3 0x08 -#define V_CONF_OFLOW4 0x10 -#define V_CONF_OFLOW5 0x20 -#define V_CONF_OFLOW6 0x40 -#define V_CONF_OFLOW7 0x80 - -/* chapter 9: DTMF contoller */ -/* R_DTMF0 */ -#define V_DTMF_EN 0x01 -#define V_HARM_SEL 0x02 -#define V_DTMF_RX_CH 0x04 -#define V_DTMF_STOP 0x08 -#define V_CHBL_SEL 0x10 -#define V_RST_DTMF 0x40 -#define V_ULAW_SEL 0x80 - -/* chapter 10: BERT */ -/* R_BERT_WD_MD */ -#define V_PAT_SEQ 0x01 -#define V_BERT_ERR 0x08 -#define V_AUTO_WD_RES 0x20 -#define V_WD_RES 0x80 -/* R_BERT_STA */ -#define V_BERT_SYNC_SRC 0x01 -#define V_BERT_SYNC 0x10 -#define V_BERT_INV_DATA 0x20 - -/* chapter 11: auxiliary interface */ -/* R_BRG_PCM_CFG */ -#define V_BRG_EN 0x01 -#define V_BRG_MD 0x02 -#define V_PCM_CLK 0x20 -#define V_ADDR_WRDLY 0x40 -/* R_BRG_CTRL */ -#define V_BRG_CS 0x01 -#define V_BRG_ADDR 0x08 -#define V_BRG_CS_SRC 0x80 -/* R_BRG_MD */ -#define V_BRG_MD0 0x01 -#define V_BRG_MD1 0x02 -#define V_BRG_MD2 0x04 -#define V_BRG_MD3 0x08 -#define V_BRG_MD4 0x10 -#define V_BRG_MD5 0x20 -#define V_BRG_MD6 0x40 -#define V_BRG_MD7 0x80 -/* R_BRG_TIM0 */ -#define V_BRG_TIM0_IDLE 0x01 -#define V_BRG_TIM0_CLK 0x10 -/* R_BRG_TIM1 */ -#define V_BRG_TIM1_IDLE 0x01 -#define V_BRG_TIM1_CLK 0x10 -/* R_BRG_TIM2 */ -#define V_BRG_TIM2_IDLE 0x01 -#define V_BRG_TIM2_CLK 0x10 -/* R_BRG_TIM3 */ -#define V_BRG_TIM3_IDLE 0x01 -#define V_BRG_TIM3_CLK 0x10 -/* R_BRG_TIM_SEL01 */ -#define V_BRG_WR_SEL0 0x01 -#define V_BRG_RD_SEL0 0x04 -#define V_BRG_WR_SEL1 0x10 -#define V_BRG_RD_SEL1 0x40 -/* R_BRG_TIM_SEL23 */ -#define V_BRG_WR_SEL2 0x01 -#define V_BRG_RD_SEL2 0x04 -#define V_BRG_WR_SEL3 0x10 -#define V_BRG_RD_SEL3 0x40 -/* R_BRG_TIM_SEL45 */ -#define V_BRG_WR_SEL4 0x01 -#define V_BRG_RD_SEL4 0x04 -#define V_BRG_WR_SEL5 0x10 -#define V_BRG_RD_SEL5 0x40 -/* R_BRG_TIM_SEL67 */ -#define V_BRG_WR_SEL6 0x01 -#define V_BRG_RD_SEL6 0x04 -#define V_BRG_WR_SEL7 0x10 -#define V_BRG_RD_SEL7 0x40 - -/* chapter 12: clock, reset, interrupt, timer and watchdog */ -/* R_IRQMSK_MISC */ -#define V_STA_IRQMSK 0x01 -#define V_TI_IRQMSK 0x02 -#define V_PROC_IRQMSK 0x04 -#define V_DTMF_IRQMSK 0x08 -#define V_IRQ1S_MSK 0x10 -#define V_SA6_IRQMSK 0x20 -#define V_RX_EOMF_MSK 0x40 -#define V_TX_EOMF_MSK 0x80 -/* R_IRQ_CTRL */ -#define V_FIFO_IRQ 0x01 -#define V_GLOB_IRQ_EN 0x08 -#define V_IRQ_POL 0x10 -/* R_TI_WD */ -#define V_EV_TS 0x01 -#define V_WD_TS 0x10 -/* A_IRQ_MSK */ -#define V_IRQ 0x01 -#define V_BERT_EN 0x02 -#define V_MIX_IRQ 0x04 -/* R_IRQ_OVIEW */ -#define V_IRQ_FIFO_BL0 0x01 -#define V_IRQ_FIFO_BL1 0x02 -#define V_IRQ_FIFO_BL2 0x04 -#define V_IRQ_FIFO_BL3 0x08 -#define V_IRQ_FIFO_BL4 0x10 -#define V_IRQ_FIFO_BL5 0x20 -#define V_IRQ_FIFO_BL6 0x40 -#define V_IRQ_FIFO_BL7 0x80 -/* R_IRQ_MISC */ -#define V_STA_IRQ 0x01 -#define V_TI_IRQ 0x02 -#define V_IRQ_PROC 0x04 -#define V_DTMF_IRQ 0x08 -#define V_IRQ1S 0x10 -#define V_SA6_IRQ 0x20 -#define V_RX_EOMF 0x40 -#define V_TX_EOMF 0x80 -/* R_STATUS */ -#define V_BUSY 0x01 -#define V_PROC 0x02 -#define V_DTMF_STA 0x04 -#define V_LOST_STA 0x08 -#define V_SYNC_IN 0x10 -#define V_EXT_IRQSTA 0x20 -#define V_MISC_IRQSTA 0x40 -#define V_FR_IRQSTA 0x80 -/* R_IRQ_FIFO_BL0 */ -#define V_IRQ_FIFO0_TX 0x01 -#define V_IRQ_FIFO0_RX 0x02 -#define V_IRQ_FIFO1_TX 0x04 -#define V_IRQ_FIFO1_RX 0x08 -#define V_IRQ_FIFO2_TX 0x10 -#define V_IRQ_FIFO2_RX 0x20 -#define V_IRQ_FIFO3_TX 0x40 -#define V_IRQ_FIFO3_RX 0x80 -/* R_IRQ_FIFO_BL1 */ -#define V_IRQ_FIFO4_TX 0x01 -#define V_IRQ_FIFO4_RX 0x02 -#define V_IRQ_FIFO5_TX 0x04 -#define V_IRQ_FIFO5_RX 0x08 -#define V_IRQ_FIFO6_TX 0x10 -#define V_IRQ_FIFO6_RX 0x20 -#define V_IRQ_FIFO7_TX 0x40 -#define V_IRQ_FIFO7_RX 0x80 -/* R_IRQ_FIFO_BL2 */ -#define V_IRQ_FIFO8_TX 0x01 -#define V_IRQ_FIFO8_RX 0x02 -#define V_IRQ_FIFO9_TX 0x04 -#define V_IRQ_FIFO9_RX 0x08 -#define V_IRQ_FIFO10_TX 0x10 -#define V_IRQ_FIFO10_RX 0x20 -#define V_IRQ_FIFO11_TX 0x40 -#define V_IRQ_FIFO11_RX 0x80 -/* R_IRQ_FIFO_BL3 */ -#define V_IRQ_FIFO12_TX 0x01 -#define V_IRQ_FIFO12_RX 0x02 -#define V_IRQ_FIFO13_TX 0x04 -#define V_IRQ_FIFO13_RX 0x08 -#define V_IRQ_FIFO14_TX 0x10 -#define V_IRQ_FIFO14_RX 0x20 -#define V_IRQ_FIFO15_TX 0x40 -#define V_IRQ_FIFO15_RX 0x80 -/* R_IRQ_FIFO_BL4 */ -#define V_IRQ_FIFO16_TX 0x01 -#define V_IRQ_FIFO16_RX 0x02 -#define V_IRQ_FIFO17_TX 0x04 -#define V_IRQ_FIFO17_RX 0x08 -#define V_IRQ_FIFO18_TX 0x10 -#define V_IRQ_FIFO18_RX 0x20 -#define V_IRQ_FIFO19_TX 0x40 -#define V_IRQ_FIFO19_RX 0x80 -/* R_IRQ_FIFO_BL5 */ -#define V_IRQ_FIFO20_TX 0x01 -#define V_IRQ_FIFO20_RX 0x02 -#define V_IRQ_FIFO21_TX 0x04 -#define V_IRQ_FIFO21_RX 0x08 -#define V_IRQ_FIFO22_TX 0x10 -#define V_IRQ_FIFO22_RX 0x20 -#define V_IRQ_FIFO23_TX 0x40 -#define V_IRQ_FIFO23_RX 0x80 -/* R_IRQ_FIFO_BL6 */ -#define V_IRQ_FIFO24_TX 0x01 -#define V_IRQ_FIFO24_RX 0x02 -#define V_IRQ_FIFO25_TX 0x04 -#define V_IRQ_FIFO25_RX 0x08 -#define V_IRQ_FIFO26_TX 0x10 -#define V_IRQ_FIFO26_RX 0x20 -#define V_IRQ_FIFO27_TX 0x40 -#define V_IRQ_FIFO27_RX 0x80 -/* R_IRQ_FIFO_BL7 */ -#define V_IRQ_FIFO28_TX 0x01 -#define V_IRQ_FIFO28_RX 0x02 -#define V_IRQ_FIFO29_TX 0x04 -#define V_IRQ_FIFO29_RX 0x08 -#define V_IRQ_FIFO30_TX 0x10 -#define V_IRQ_FIFO30_RX 0x20 -#define V_IRQ_FIFO31_TX 0x40 -#define V_IRQ_FIFO31_RX 0x80 - -/* chapter 13: general purpose I/O pins (GPIO) and input pins (GPI) */ -/* R_GPIO_OUT0 */ -#define V_GPIO_OUT0 0x01 -#define V_GPIO_OUT1 0x02 -#define V_GPIO_OUT2 0x04 -#define V_GPIO_OUT3 0x08 -#define V_GPIO_OUT4 0x10 -#define V_GPIO_OUT5 0x20 -#define V_GPIO_OUT6 0x40 -#define V_GPIO_OUT7 0x80 -/* R_GPIO_OUT1 */ -#define V_GPIO_OUT8 0x01 -#define V_GPIO_OUT9 0x02 -#define V_GPIO_OUT10 0x04 -#define V_GPIO_OUT11 0x08 -#define V_GPIO_OUT12 0x10 -#define V_GPIO_OUT13 0x20 -#define V_GPIO_OUT14 0x40 -#define V_GPIO_OUT15 0x80 -/* R_GPIO_EN0 */ -#define V_GPIO_EN0 0x01 -#define V_GPIO_EN1 0x02 -#define V_GPIO_EN2 0x04 -#define V_GPIO_EN3 0x08 -#define V_GPIO_EN4 0x10 -#define V_GPIO_EN5 0x20 -#define V_GPIO_EN6 0x40 -#define V_GPIO_EN7 0x80 -/* R_GPIO_EN1 */ -#define V_GPIO_EN8 0x01 -#define V_GPIO_EN9 0x02 -#define V_GPIO_EN10 0x04 -#define V_GPIO_EN11 0x08 -#define V_GPIO_EN12 0x10 -#define V_GPIO_EN13 0x20 -#define V_GPIO_EN14 0x40 -#define V_GPIO_EN15 0x80 -/* R_GPIO_SEL */ -#define V_GPIO_SEL0 0x01 -#define V_GPIO_SEL1 0x02 -#define V_GPIO_SEL2 0x04 -#define V_GPIO_SEL3 0x08 -#define V_GPIO_SEL4 0x10 -#define V_GPIO_SEL5 0x20 -#define V_GPIO_SEL6 0x40 -#define V_GPIO_SEL7 0x80 -/* R_GPIO_IN0 */ -#define V_GPIO_IN0 0x01 -#define V_GPIO_IN1 0x02 -#define V_GPIO_IN2 0x04 -#define V_GPIO_IN3 0x08 -#define V_GPIO_IN4 0x10 -#define V_GPIO_IN5 0x20 -#define V_GPIO_IN6 0x40 -#define V_GPIO_IN7 0x80 -/* R_GPIO_IN1 */ -#define V_GPIO_IN8 0x01 -#define V_GPIO_IN9 0x02 -#define V_GPIO_IN10 0x04 -#define V_GPIO_IN11 0x08 -#define V_GPIO_IN12 0x10 -#define V_GPIO_IN13 0x20 -#define V_GPIO_IN14 0x40 -#define V_GPIO_IN15 0x80 -/* R_GPI_IN0 */ -#define V_GPI_IN0 0x01 -#define V_GPI_IN1 0x02 -#define V_GPI_IN2 0x04 -#define V_GPI_IN3 0x08 -#define V_GPI_IN4 0x10 -#define V_GPI_IN5 0x20 -#define V_GPI_IN6 0x40 -#define V_GPI_IN7 0x80 -/* R_GPI_IN1 */ -#define V_GPI_IN8 0x01 -#define V_GPI_IN9 0x02 -#define V_GPI_IN10 0x04 -#define V_GPI_IN11 0x08 -#define V_GPI_IN12 0x10 -#define V_GPI_IN13 0x20 -#define V_GPI_IN14 0x40 -#define V_GPI_IN15 0x80 -/* R_GPI_IN2 */ -#define V_GPI_IN16 0x01 -#define V_GPI_IN17 0x02 -#define V_GPI_IN18 0x04 -#define V_GPI_IN19 0x08 -#define V_GPI_IN20 0x10 -#define V_GPI_IN21 0x20 -#define V_GPI_IN22 0x40 -#define V_GPI_IN23 0x80 -/* R_GPI_IN3 */ -#define V_GPI_IN24 0x01 -#define V_GPI_IN25 0x02 -#define V_GPI_IN26 0x04 -#define V_GPI_IN27 0x08 -#define V_GPI_IN28 0x10 -#define V_GPI_IN29 0x20 -#define V_GPI_IN30 0x40 -#define V_GPI_IN31 0x80 - -/* map of all registers, used for debugging */ - -#ifdef HFC_REGISTER_DEBUG -struct hfc_register_names { - char *name; - u_char reg; -} hfc_register_names[] = { - /* write registers */ - {"R_CIRM", 0x00}, - {"R_CTRL", 0x01}, - {"R_BRG_PCM_CFG ", 0x02}, - {"R_RAM_ADDR0", 0x08}, - {"R_RAM_ADDR1", 0x09}, - {"R_RAM_ADDR2", 0x0A}, - {"R_FIRST_FIFO", 0x0B}, - {"R_RAM_SZ", 0x0C}, - {"R_FIFO_MD", 0x0D}, - {"R_INC_RES_FIFO", 0x0E}, - {"R_FIFO / R_FSM_IDX", 0x0F}, - {"R_SLOT", 0x10}, - {"R_IRQMSK_MISC", 0x11}, - {"R_SCI_MSK", 0x12}, - {"R_IRQ_CTRL", 0x13}, - {"R_PCM_MD0", 0x14}, - {"R_0x15", 0x15}, - {"R_ST_SEL", 0x16}, - {"R_ST_SYNC", 0x17}, - {"R_CONF_EN", 0x18}, - {"R_TI_WD", 0x1A}, - {"R_BERT_WD_MD", 0x1B}, - {"R_DTMF", 0x1C}, - {"R_DTMF_N", 0x1D}, - {"R_E1_XX_STA", 0x20}, - {"R_LOS0", 0x22}, - {"R_LOS1", 0x23}, - {"R_RX0", 0x24}, - {"R_RX_FR0", 0x25}, - {"R_RX_FR1", 0x26}, - {"R_TX0", 0x28}, - {"R_TX1", 0x29}, - {"R_TX_FR0", 0x2C}, - {"R_TX_FR1", 0x2D}, - {"R_TX_FR2", 0x2E}, - {"R_JATT_ATT", 0x2F}, - {"A_ST_xx_STA/R_RX_OFF", 0x30}, - {"A_ST_CTRL0/R_SYNC_OUT", 0x31}, - {"A_ST_CTRL1", 0x32}, - {"A_ST_CTRL2", 0x33}, - {"A_ST_SQ_WR", 0x34}, - {"R_TX_OFF", 0x34}, - {"R_SYNC_CTRL", 0x35}, - {"A_ST_CLK_DLY", 0x37}, - {"R_PWM0", 0x38}, - {"R_PWM1", 0x39}, - {"A_ST_B1_TX", 0x3C}, - {"A_ST_B2_TX", 0x3D}, - {"A_ST_D_TX", 0x3E}, - {"R_GPIO_OUT0", 0x40}, - {"R_GPIO_OUT1", 0x41}, - {"R_GPIO_EN0", 0x42}, - {"R_GPIO_EN1", 0x43}, - {"R_GPIO_SEL", 0x44}, - {"R_BRG_CTRL", 0x45}, - {"R_PWM_MD", 0x46}, - {"R_BRG_MD", 0x47}, - {"R_BRG_TIM0", 0x48}, - {"R_BRG_TIM1", 0x49}, - {"R_BRG_TIM2", 0x4A}, - {"R_BRG_TIM3", 0x4B}, - {"R_BRG_TIM_SEL01", 0x4C}, - {"R_BRG_TIM_SEL23", 0x4D}, - {"R_BRG_TIM_SEL45", 0x4E}, - {"R_BRG_TIM_SEL67", 0x4F}, - {"A_FIFO_DATA0-2", 0x80}, - {"A_FIFO_DATA0-2_NOINC", 0x84}, - {"R_RAM_DATA", 0xC0}, - {"A_SL_CFG", 0xD0}, - {"A_CONF", 0xD1}, - {"A_CH_MSK", 0xF4}, - {"A_CON_HDLC", 0xFA}, - {"A_SUBCH_CFG", 0xFB}, - {"A_CHANNEL", 0xFC}, - {"A_FIFO_SEQ", 0xFD}, - {"A_IRQ_MSK", 0xFF}, - {NULL, 0}, - - /* read registers */ - {"A_Z1", 0x04}, - {"A_Z1H", 0x05}, - {"A_Z2", 0x06}, - {"A_Z2H", 0x07}, - {"A_F1", 0x0C}, - {"A_F2", 0x0D}, - {"R_IRQ_OVIEW", 0x10}, - {"R_IRQ_MISC", 0x11}, - {"R_IRQ_STATECH", 0x12}, - {"R_CONF_OFLOW", 0x14}, - {"R_RAM_USE", 0x15}, - {"R_CHIP_ID", 0x16}, - {"R_BERT_STA", 0x17}, - {"R_F0_CNTL", 0x18}, - {"R_F0_CNTH", 0x19}, - {"R_BERT_ECL", 0x1A}, - {"R_BERT_ECH", 0x1B}, - {"R_STATUS", 0x1C}, - {"R_CHIP_RV", 0x1F}, - {"R_STATE", 0x20}, - {"R_SYNC_STA", 0x24}, - {"R_RX_SL0_0", 0x25}, - {"R_RX_SL0_1", 0x26}, - {"R_RX_SL0_2", 0x27}, - {"R_JATT_DIR", 0x2b}, - {"R_SLIP", 0x2c}, - {"A_ST_RD_STA", 0x30}, - {"R_FAS_ECL", 0x30}, - {"R_FAS_ECH", 0x31}, - {"R_VIO_ECL", 0x32}, - {"R_VIO_ECH", 0x33}, - {"R_CRC_ECL / A_ST_SQ_RD", 0x34}, - {"R_CRC_ECH", 0x35}, - {"R_E_ECL", 0x36}, - {"R_E_ECH", 0x37}, - {"R_SA6_SA13_ECL", 0x38}, - {"R_SA6_SA13_ECH", 0x39}, - {"R_SA6_SA23_ECL", 0x3A}, - {"R_SA6_SA23_ECH", 0x3B}, - {"A_ST_B1_RX", 0x3C}, - {"A_ST_B2_RX", 0x3D}, - {"A_ST_D_RX", 0x3E}, - {"A_ST_E_RX", 0x3F}, - {"R_GPIO_IN0", 0x40}, - {"R_GPIO_IN1", 0x41}, - {"R_GPI_IN0", 0x44}, - {"R_GPI_IN1", 0x45}, - {"R_GPI_IN2", 0x46}, - {"R_GPI_IN3", 0x47}, - {"A_FIFO_DATA0-2", 0x80}, - {"A_FIFO_DATA0-2_NOINC", 0x84}, - {"R_INT_DATA", 0x88}, - {"R_RAM_DATA", 0xC0}, - {"R_IRQ_FIFO_BL0", 0xC8}, - {"R_IRQ_FIFO_BL1", 0xC9}, - {"R_IRQ_FIFO_BL2", 0xCA}, - {"R_IRQ_FIFO_BL3", 0xCB}, - {"R_IRQ_FIFO_BL4", 0xCC}, - {"R_IRQ_FIFO_BL5", 0xCD}, - {"R_IRQ_FIFO_BL6", 0xCE}, - {"R_IRQ_FIFO_BL7", 0xCF}, -}; -#endif /* HFC_REGISTER_DEBUG */ - diff --git a/trunk/drivers/isdn/hardware/mISDN/hfc_pci.h b/trunk/drivers/isdn/hardware/mISDN/hfc_pci.h deleted file mode 100644 index fd2c9be6d849..000000000000 --- a/trunk/drivers/isdn/hardware/mISDN/hfc_pci.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * specific defines for CCD's HFC 2BDS0 PCI chips - * - * Author Werner Cornelius (werner@isdn4linux.de) - * - * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) - * - * 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. - * - */ - -/* - * thresholds for transparent B-channel mode - * change mask and threshold simultaneously - */ -#define HFCPCI_BTRANS_THRESHOLD 128 -#define HFCPCI_BTRANS_MAX 256 -#define HFCPCI_BTRANS_THRESMASK 0x00 - -/* defines for PCI config */ -#define PCI_ENA_MEMIO 0x02 -#define PCI_ENA_MASTER 0x04 - -/* GCI/IOM bus monitor registers */ -#define HCFPCI_C_I 0x08 -#define HFCPCI_TRxR 0x0C -#define HFCPCI_MON1_D 0x28 -#define HFCPCI_MON2_D 0x2C - -/* GCI/IOM bus timeslot registers */ -#define HFCPCI_B1_SSL 0x80 -#define HFCPCI_B2_SSL 0x84 -#define HFCPCI_AUX1_SSL 0x88 -#define HFCPCI_AUX2_SSL 0x8C -#define HFCPCI_B1_RSL 0x90 -#define HFCPCI_B2_RSL 0x94 -#define HFCPCI_AUX1_RSL 0x98 -#define HFCPCI_AUX2_RSL 0x9C - -/* GCI/IOM bus data registers */ -#define HFCPCI_B1_D 0xA0 -#define HFCPCI_B2_D 0xA4 -#define HFCPCI_AUX1_D 0xA8 -#define HFCPCI_AUX2_D 0xAC - -/* GCI/IOM bus configuration registers */ -#define HFCPCI_MST_EMOD 0xB4 -#define HFCPCI_MST_MODE 0xB8 -#define HFCPCI_CONNECT 0xBC - - -/* Interrupt and status registers */ -#define HFCPCI_FIFO_EN 0x44 -#define HFCPCI_TRM 0x48 -#define HFCPCI_B_MODE 0x4C -#define HFCPCI_CHIP_ID 0x58 -#define HFCPCI_CIRM 0x60 -#define HFCPCI_CTMT 0x64 -#define HFCPCI_INT_M1 0x68 -#define HFCPCI_INT_M2 0x6C -#define HFCPCI_INT_S1 0x78 -#define HFCPCI_INT_S2 0x7C -#define HFCPCI_STATUS 0x70 - -/* S/T section registers */ -#define HFCPCI_STATES 0xC0 -#define HFCPCI_SCTRL 0xC4 -#define HFCPCI_SCTRL_E 0xC8 -#define HFCPCI_SCTRL_R 0xCC -#define HFCPCI_SQ 0xD0 -#define HFCPCI_CLKDEL 0xDC -#define HFCPCI_B1_REC 0xF0 -#define HFCPCI_B1_SEND 0xF0 -#define HFCPCI_B2_REC 0xF4 -#define HFCPCI_B2_SEND 0xF4 -#define HFCPCI_D_REC 0xF8 -#define HFCPCI_D_SEND 0xF8 -#define HFCPCI_E_REC 0xFC - - -/* bits in status register (READ) */ -#define HFCPCI_PCI_PROC 0x02 -#define HFCPCI_NBUSY 0x04 -#define HFCPCI_TIMER_ELAP 0x10 -#define HFCPCI_STATINT 0x20 -#define HFCPCI_FRAMEINT 0x40 -#define HFCPCI_ANYINT 0x80 - -/* bits in CTMT (Write) */ -#define HFCPCI_CLTIMER 0x80 -#define HFCPCI_TIM3_125 0x04 -#define HFCPCI_TIM25 0x10 -#define HFCPCI_TIM50 0x14 -#define HFCPCI_TIM400 0x18 -#define HFCPCI_TIM800 0x1C -#define HFCPCI_AUTO_TIMER 0x20 -#define HFCPCI_TRANSB2 0x02 -#define HFCPCI_TRANSB1 0x01 - -/* bits in CIRM (Write) */ -#define HFCPCI_AUX_MSK 0x07 -#define HFCPCI_RESET 0x08 -#define HFCPCI_B1_REV 0x40 -#define HFCPCI_B2_REV 0x80 - -/* bits in INT_M1 and INT_S1 */ -#define HFCPCI_INTS_B1TRANS 0x01 -#define HFCPCI_INTS_B2TRANS 0x02 -#define HFCPCI_INTS_DTRANS 0x04 -#define HFCPCI_INTS_B1REC 0x08 -#define HFCPCI_INTS_B2REC 0x10 -#define HFCPCI_INTS_DREC 0x20 -#define HFCPCI_INTS_L1STATE 0x40 -#define HFCPCI_INTS_TIMER 0x80 - -/* bits in INT_M2 */ -#define HFCPCI_PROC_TRANS 0x01 -#define HFCPCI_GCI_I_CHG 0x02 -#define HFCPCI_GCI_MON_REC 0x04 -#define HFCPCI_IRQ_ENABLE 0x08 -#define HFCPCI_PMESEL 0x80 - -/* bits in STATES */ -#define HFCPCI_STATE_MSK 0x0F -#define HFCPCI_LOAD_STATE 0x10 -#define HFCPCI_ACTIVATE 0x20 -#define HFCPCI_DO_ACTION 0x40 -#define HFCPCI_NT_G2_G3 0x80 - -/* bits in HFCD_MST_MODE */ -#define HFCPCI_MASTER 0x01 -#define HFCPCI_SLAVE 0x00 -#define HFCPCI_F0IO_POSITIV 0x02 -#define HFCPCI_F0_NEGATIV 0x04 -#define HFCPCI_F0_2C4 0x08 -/* remaining bits are for codecs control */ - -/* bits in HFCD_SCTRL */ -#define SCTRL_B1_ENA 0x01 -#define SCTRL_B2_ENA 0x02 -#define SCTRL_MODE_TE 0x00 -#define SCTRL_MODE_NT 0x04 -#define SCTRL_LOW_PRIO 0x08 -#define SCTRL_SQ_ENA 0x10 -#define SCTRL_TEST 0x20 -#define SCTRL_NONE_CAP 0x40 -#define SCTRL_PWR_DOWN 0x80 - -/* bits in SCTRL_E */ -#define HFCPCI_AUTO_AWAKE 0x01 -#define HFCPCI_DBIT_1 0x04 -#define HFCPCI_IGNORE_COL 0x08 -#define HFCPCI_CHG_B1_B2 0x80 - -/* bits in FIFO_EN register */ -#define HFCPCI_FIFOEN_B1 0x03 -#define HFCPCI_FIFOEN_B2 0x0C -#define HFCPCI_FIFOEN_DTX 0x10 -#define HFCPCI_FIFOEN_B1TX 0x01 -#define HFCPCI_FIFOEN_B1RX 0x02 -#define HFCPCI_FIFOEN_B2TX 0x04 -#define HFCPCI_FIFOEN_B2RX 0x08 - - -/* definitions of fifo memory area */ -#define MAX_D_FRAMES 15 -#define MAX_B_FRAMES 31 -#define B_SUB_VAL 0x200 -#define B_FIFO_SIZE (0x2000 - B_SUB_VAL) -#define D_FIFO_SIZE 512 -#define D_FREG_MASK 0xF - -struct zt { - unsigned short z1; /* Z1 pointer 16 Bit */ - unsigned short z2; /* Z2 pointer 16 Bit */ -}; - -struct dfifo { - u_char data[D_FIFO_SIZE]; /* FIFO data space */ - u_char fill1[0x20A0-D_FIFO_SIZE]; /* reserved, do not use */ - u_char f1, f2; /* f pointers */ - u_char fill2[0x20C0-0x20A2]; /* reserved, do not use */ - /* mask index with D_FREG_MASK for access */ - struct zt za[MAX_D_FRAMES+1]; - u_char fill3[0x4000-0x2100]; /* align 16K */ -}; - -struct bzfifo { - struct zt za[MAX_B_FRAMES+1]; /* only range 0x0..0x1F allowed */ - u_char f1, f2; /* f pointers */ - u_char fill[0x2100-0x2082]; /* alignment */ -}; - - -union fifo_area { - struct { - struct dfifo d_tx; /* D-send channel */ - struct dfifo d_rx; /* D-receive channel */ - } d_chan; - struct { - u_char fill1[0x200]; - u_char txdat_b1[B_FIFO_SIZE]; - struct bzfifo txbz_b1; - struct bzfifo txbz_b2; - u_char txdat_b2[B_FIFO_SIZE]; - u_char fill2[D_FIFO_SIZE]; - u_char rxdat_b1[B_FIFO_SIZE]; - struct bzfifo rxbz_b1; - struct bzfifo rxbz_b2; - u_char rxdat_b2[B_FIFO_SIZE]; - } b_chans; - u_char fill[32768]; -}; - -#define Write_hfc(a, b, c) (writeb(c, (a->hw.pci_io)+b)) -#define Read_hfc(a, b) (readb((a->hw.pci_io)+b)) diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c b/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c deleted file mode 100644 index 2649ea55a9e8..000000000000 --- a/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c +++ /dev/null @@ -1,5320 +0,0 @@ -/* - * hfcmulti.c low level driver for hfc-4s/hfc-8s/hfc-e1 based cards - * - * Author Andreas Eversberg (jolly@eversberg.eu) - * ported to mqueue mechanism: - * Peter Sprenger (sprengermoving-bytes.de) - * - * inspired by existing hfc-pci driver: - * Copyright 1999 by Werner Cornelius (werner@isdn-development.de) - * Copyright 2008 by Karsten Keil (kkeil@suse.de) - * Copyright 2008 by Andreas Eversberg (jolly@eversberg.eu) - * - * 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. - * - * - * Thanks to Cologne Chip AG for this great controller! - */ - -/* - * module parameters: - * type: - * By default (0), the card is automatically detected. - * Or use the following combinations: - * Bit 0-7 = 0x00001 = HFC-E1 (1 port) - * or Bit 0-7 = 0x00004 = HFC-4S (4 ports) - * or Bit 0-7 = 0x00008 = HFC-8S (8 ports) - * Bit 8 = 0x00100 = uLaw (instead of aLaw) - * Bit 9 = 0x00200 = Disable DTMF detect on all B-channels via hardware - * Bit 10 = spare - * Bit 11 = 0x00800 = Force PCM bus into slave mode. (otherwhise auto) - * or Bit 12 = 0x01000 = Force PCM bus into master mode. (otherwhise auto) - * Bit 13 = spare - * Bit 14 = 0x04000 = Use external ram (128K) - * Bit 15 = 0x08000 = Use external ram (512K) - * Bit 16 = 0x10000 = Use 64 timeslots instead of 32 - * or Bit 17 = 0x20000 = Use 128 timeslots instead of anything else - * Bit 18 = spare - * Bit 19 = 0x80000 = Send the Watchdog a Signal (Dual E1 with Watchdog) - * (all other bits are reserved and shall be 0) - * example: 0x20204 one HFC-4S with dtmf detection and 128 timeslots on PCM - * bus (PCM master) - * - * port: (optional or required for all ports on all installed cards) - * HFC-4S/HFC-8S only bits: - * Bit 0 = 0x001 = Use master clock for this S/T interface - * (ony once per chip). - * Bit 1 = 0x002 = transmitter line setup (non capacitive mode) - * Don't use this unless you know what you are doing! - * Bit 2 = 0x004 = Disable E-channel. (No E-channel processing) - * example: 0x0001,0x0000,0x0000,0x0000 one HFC-4S with master clock - * received from port 1 - * - * HFC-E1 only bits: - * Bit 0 = 0x0001 = interface: 0=copper, 1=optical - * Bit 1 = 0x0002 = reserved (later for 32 B-channels transparent mode) - * Bit 2 = 0x0004 = Report LOS - * Bit 3 = 0x0008 = Report AIS - * Bit 4 = 0x0010 = Report SLIP - * Bit 5 = 0x0020 = Report RDI - * Bit 8 = 0x0100 = Turn off CRC-4 Multiframe Mode, use double frame - * mode instead. - * Bit 9 = 0x0200 = Force get clock from interface, even in NT mode. - * or Bit 10 = 0x0400 = Force put clock to interface, even in TE mode. - * Bit 11 = 0x0800 = Use direct RX clock for PCM sync rather than PLL. - * (E1 only) - * Bit 12-13 = 0xX000 = elastic jitter buffer (1-3), Set both bits to 0 - * for default. - * (all other bits are reserved and shall be 0) - * - * debug: - * NOTE: only one debug value must be given for all cards - * enable debugging (see hfc_multi.h for debug options) - * - * poll: - * NOTE: only one poll value must be given for all cards - * Give the number of samples for each fifo process. - * By default 128 is used. Decrease to reduce delay, increase to - * reduce cpu load. If unsure, don't mess with it! - * Valid is 8, 16, 32, 64, 128, 256. - * - * pcm: - * NOTE: only one pcm value must be given for every card. - * The PCM bus id tells the mISDNdsp module about the connected PCM bus. - * By default (0), the PCM bus id is 100 for the card that is PCM master. - * If multiple cards are PCM master (because they are not interconnected), - * each card with PCM master will have increasing PCM id. - * All PCM busses with the same ID are expected to be connected and have - * common time slots slots. - * Only one chip of the PCM bus must be master, the others slave. - * -1 means no support of PCM bus not even. - * Omit this value, if all cards are interconnected or none is connected. - * If unsure, don't give this parameter. - * - * dslot: - * NOTE: only one poll value must be given for every card. - * Also this value must be given for non-E1 cards. If omitted, the E1 - * card has D-channel on time slot 16, which is default. - * If 1..15 or 17..31, an alternate time slot is used for D-channel. - * In this case, the application must be able to handle this. - * If -1 is given, the D-channel is disabled and all 31 slots can be used - * for B-channel. (only for specific applications) - * If you don't know how to use it, you don't need it! - * - * iomode: - * NOTE: only one mode value must be given for every card. - * -> See hfc_multi.h for HFC_IO_MODE_* values - * By default, the IO mode is pci memory IO (MEMIO). - * Some cards requre specific IO mode, so it cannot be changed. - * It may be usefull to set IO mode to register io (REGIO) to solve - * PCI bridge problems. - * If unsure, don't give this parameter. - * - * clockdelay_nt: - * NOTE: only one clockdelay_nt value must be given once for all cards. - * Give the value of the clock control register (A_ST_CLK_DLY) - * of the S/T interfaces in NT mode. - * This register is needed for the TBR3 certification, so don't change it. - * - * clockdelay_te: - * NOTE: only one clockdelay_te value must be given once - * Give the value of the clock control register (A_ST_CLK_DLY) - * of the S/T interfaces in TE mode. - * This register is needed for the TBR3 certification, so don't change it. - */ - -/* - * debug register access (never use this, it will flood your system log) - * #define HFC_REGISTER_DEBUG - */ - -static const char *hfcmulti_revision = "2.00"; - -#include -#include -#include -#include -#include - -/* -#define IRQCOUNT_DEBUG -#define IRQ_DEBUG -*/ - -#include "hfc_multi.h" -#ifdef ECHOPREP -#include "gaintab.h" -#endif - -#define MAX_CARDS 8 -#define MAX_PORTS (8 * MAX_CARDS) - -static LIST_HEAD(HFClist); -static spinlock_t HFClock; /* global hfc list lock */ - -static void ph_state_change(struct dchannel *); -static void (*hfc_interrupt)(void); -static void (*register_interrupt)(void); -static int (*unregister_interrupt)(void); -static int interrupt_registered; - -static struct hfc_multi *syncmaster; -int plxsd_master; /* if we have a master card (yet) */ -static spinlock_t plx_lock; /* may not acquire other lock inside */ -EXPORT_SYMBOL(plx_lock); - -#define TYP_E1 1 -#define TYP_4S 4 -#define TYP_8S 8 - -static int poll_timer = 6; /* default = 128 samples = 16ms */ -/* number of POLL_TIMER interrupts for G2 timeout (ca 1s) */ -static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 }; -#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */ -#define CLKDEL_NT 0x6c /* CLKDEL in NT mode - (0x60 MUST be included!) */ -static u_char silence = 0xff; /* silence by LAW */ - -#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */ -#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */ -#define DIP_E1 0x3 /* DIP Switches for Beronet E1 cards */ - -/* - * module stuff - */ - -static uint type[MAX_CARDS]; -static uint pcm[MAX_CARDS]; -static uint dslot[MAX_CARDS]; -static uint iomode[MAX_CARDS]; -static uint port[MAX_PORTS]; -static uint debug; -static uint poll; -static uint timer; -static uint clockdelay_te = CLKDEL_TE; -static uint clockdelay_nt = CLKDEL_NT; - -static int HFC_cnt, Port_cnt, PCM_cnt = 99; - -MODULE_AUTHOR("Andreas Eversberg"); -MODULE_LICENSE("GPL"); -module_param(debug, uint, S_IRUGO | S_IWUSR); -module_param(poll, uint, S_IRUGO | S_IWUSR); -module_param(timer, uint, S_IRUGO | S_IWUSR); -module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR); -module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR); -module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(pcm, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(dslot, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); - -#ifdef HFC_REGISTER_DEBUG -#define HFC_outb(hc, reg, val) \ - (hc->HFC_outb(hc, reg, val, __func__, __LINE__)) -#define HFC_outb_nodebug(hc, reg, val) \ - (hc->HFC_outb_nodebug(hc, reg, val, __func__, __LINE__)) -#define HFC_inb(hc, reg) \ - (hc->HFC_inb(hc, reg, __func__, __LINE__)) -#define HFC_inb_nodebug(hc, reg) \ - (hc->HFC_inb_nodebug(hc, reg, __func__, __LINE__)) -#define HFC_inw(hc, reg) \ - (hc->HFC_inw(hc, reg, __func__, __LINE__)) -#define HFC_inw_nodebug(hc, reg) \ - (hc->HFC_inw_nodebug(hc, reg, __func__, __LINE__)) -#define HFC_wait(hc) \ - (hc->HFC_wait(hc, __func__, __LINE__)) -#define HFC_wait_nodebug(hc) \ - (hc->HFC_wait_nodebug(hc, __func__, __LINE__)) -#else -#define HFC_outb(hc, reg, val) (hc->HFC_outb(hc, reg, val)) -#define HFC_outb_nodebug(hc, reg, val) (hc->HFC_outb_nodebug(hc, reg, val)) -#define HFC_inb(hc, reg) (hc->HFC_inb(hc, reg)) -#define HFC_inb_nodebug(hc, reg) (hc->HFC_inb_nodebug(hc, reg)) -#define HFC_inw(hc, reg) (hc->HFC_inw(hc, reg)) -#define HFC_inw_nodebug(hc, reg) (hc->HFC_inw_nodebug(hc, reg)) -#define HFC_wait(hc) (hc->HFC_wait(hc)) -#define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc)) -#endif - -/* HFC_IO_MODE_PCIMEM */ -static void -#ifdef HFC_REGISTER_DEBUG -HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val, - const char *function, int line) -#else -HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val) -#endif -{ - writeb(val, (hc->pci_membase)+reg); -} -static u_char -#ifdef HFC_REGISTER_DEBUG -HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line) -#else -HFC_inb_pcimem(struct hfc_multi *hc, u_char reg) -#endif -{ - return readb((hc->pci_membase)+reg); -} -static u_short -#ifdef HFC_REGISTER_DEBUG -HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line) -#else -HFC_inw_pcimem(struct hfc_multi *hc, u_char reg) -#endif -{ - return readw((hc->pci_membase)+reg); -} -static void -#ifdef HFC_REGISTER_DEBUG -HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line) -#else -HFC_wait_pcimem(struct hfc_multi *hc) -#endif -{ - while (readb((hc->pci_membase)+R_STATUS) & V_BUSY); -} - -/* HFC_IO_MODE_REGIO */ -static void -#ifdef HFC_REGISTER_DEBUG -HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val, - const char *function, int line) -#else -HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val) -#endif -{ - outb(reg, (hc->pci_iobase)+4); - outb(val, hc->pci_iobase); -} -static u_char -#ifdef HFC_REGISTER_DEBUG -HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line) -#else -HFC_inb_regio(struct hfc_multi *hc, u_char reg) -#endif -{ - outb(reg, (hc->pci_iobase)+4); - return inb(hc->pci_iobase); -} -static u_short -#ifdef HFC_REGISTER_DEBUG -HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line) -#else -HFC_inw_regio(struct hfc_multi *hc, u_char reg) -#endif -{ - outb(reg, (hc->pci_iobase)+4); - return inw(hc->pci_iobase); -} -static void -#ifdef HFC_REGISTER_DEBUG -HFC_wait_regio(struct hfc_multi *hc, const char *function, int line) -#else -HFC_wait_regio(struct hfc_multi *hc) -#endif -{ - outb(R_STATUS, (hc->pci_iobase)+4); - while (inb(hc->pci_iobase) & V_BUSY); -} - -#ifdef HFC_REGISTER_DEBUG -static void -HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val, - const char *function, int line) -{ - char regname[256] = "", bits[9] = "xxxxxxxx"; - int i; - - i = -1; - while (hfc_register_names[++i].name) { - if (hfc_register_names[i].reg == reg) - strcat(regname, hfc_register_names[i].name); - } - if (regname[0] == '\0') - strcpy(regname, "register"); - - bits[7] = '0'+(!!(val&1)); - bits[6] = '0'+(!!(val&2)); - bits[5] = '0'+(!!(val&4)); - bits[4] = '0'+(!!(val&8)); - bits[3] = '0'+(!!(val&16)); - bits[2] = '0'+(!!(val&32)); - bits[1] = '0'+(!!(val&64)); - bits[0] = '0'+(!!(val&128)); - printk(KERN_DEBUG - "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n", - hc->id, reg, regname, val, bits, function, line); - HFC_outb_nodebug(hc, reg, val); -} -static u_char -HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line) -{ - char regname[256] = "", bits[9] = "xxxxxxxx"; - u_char val = HFC_inb_nodebug(hc, reg); - int i; - - i = 0; - while (hfc_register_names[i++].name) - ; - while (hfc_register_names[++i].name) { - if (hfc_register_names[i].reg == reg) - strcat(regname, hfc_register_names[i].name); - } - if (regname[0] == '\0') - strcpy(regname, "register"); - - bits[7] = '0'+(!!(val&1)); - bits[6] = '0'+(!!(val&2)); - bits[5] = '0'+(!!(val&4)); - bits[4] = '0'+(!!(val&8)); - bits[3] = '0'+(!!(val&16)); - bits[2] = '0'+(!!(val&32)); - bits[1] = '0'+(!!(val&64)); - bits[0] = '0'+(!!(val&128)); - printk(KERN_DEBUG - "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n", - hc->id, reg, regname, val, bits, function, line); - return val; -} -static u_short -HFC_inw_debug(struct hfc_multi *hc, u_char reg, const char *function, int line) -{ - char regname[256] = ""; - u_short val = HFC_inw_nodebug(hc, reg); - int i; - - i = 0; - while (hfc_register_names[i++].name) - ; - while (hfc_register_names[++i].name) { - if (hfc_register_names[i].reg == reg) - strcat(regname, hfc_register_names[i].name); - } - if (regname[0] == '\0') - strcpy(regname, "register"); - - printk(KERN_DEBUG - "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n", - hc->id, reg, regname, val, function, line); - return val; -} -static void -HFC_wait_debug(struct hfc_multi *hc, const char *function, int line) -{ - printk(KERN_DEBUG "HFC_wait(chip %d); in %s() line %d\n", - hc->id, function, line); - HFC_wait_nodebug(hc); -} -#endif - -/* write fifo data (REGIO) */ -void -write_fifo_regio(struct hfc_multi *hc, u_char *data, int len) -{ - outb(A_FIFO_DATA0, (hc->pci_iobase)+4); - while (len>>2) { - outl(*(u32 *)data, hc->pci_iobase); - data += 4; - len -= 4; - } - while (len>>1) { - outw(*(u16 *)data, hc->pci_iobase); - data += 2; - len -= 2; - } - while (len) { - outb(*data, hc->pci_iobase); - data++; - len--; - } -} -/* write fifo data (PCIMEM) */ -void -write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) -{ - while (len>>2) { - writel(*(u32 *)data, (hc->pci_membase)+A_FIFO_DATA0); - data += 4; - len -= 4; - } - while (len>>1) { - writew(*(u16 *)data, (hc->pci_membase)+A_FIFO_DATA0); - data += 2; - len -= 2; - } - while (len) { - writeb(*data, (hc->pci_membase)+A_FIFO_DATA0); - data++; - len--; - } -} -/* read fifo data (REGIO) */ -void -read_fifo_regio(struct hfc_multi *hc, u_char *data, int len) -{ - outb(A_FIFO_DATA0, (hc->pci_iobase)+4); - while (len>>2) { - *(u32 *)data = inl(hc->pci_iobase); - data += 4; - len -= 4; - } - while (len>>1) { - *(u16 *)data = inw(hc->pci_iobase); - data += 2; - len -= 2; - } - while (len) { - *data = inb(hc->pci_iobase); - data++; - len--; - } -} - -/* read fifo data (PCIMEM) */ -void -read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) -{ - while (len>>2) { - *(u32 *)data = - readl((hc->pci_membase)+A_FIFO_DATA0); - data += 4; - len -= 4; - } - while (len>>1) { - *(u16 *)data = - readw((hc->pci_membase)+A_FIFO_DATA0); - data += 2; - len -= 2; - } - while (len) { - *data = readb((hc->pci_membase)+A_FIFO_DATA0); - data++; - len--; - } -} - - -static void -enable_hwirq(struct hfc_multi *hc) -{ - hc->hw.r_irq_ctrl |= V_GLOB_IRQ_EN; - HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl); -} - -static void -disable_hwirq(struct hfc_multi *hc) -{ - hc->hw.r_irq_ctrl &= ~((u_char)V_GLOB_IRQ_EN); - HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl); -} - -#define NUM_EC 2 -#define MAX_TDM_CHAN 32 - - -inline void -enablepcibridge(struct hfc_multi *c) -{ - HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); /* was _io before */ -} - -inline void -disablepcibridge(struct hfc_multi *c) -{ - HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x2); /* was _io before */ -} - -inline unsigned char -readpcibridge(struct hfc_multi *hc, unsigned char address) -{ - unsigned short cipv; - unsigned char data; - - if (!hc->pci_iobase) - return 0; - - /* slow down a PCI read access by 1 PCI clock cycle */ - HFC_outb(hc, R_CTRL, 0x4); /*was _io before*/ - - if (address == 0) - cipv = 0x4000; - else - cipv = 0x5800; - - /* select local bridge port address by writing to CIP port */ - /* data = HFC_inb(c, cipv); * was _io before */ - outw(cipv, hc->pci_iobase + 4); - data = inb(hc->pci_iobase); - - /* restore R_CTRL for normal PCI read cycle speed */ - HFC_outb(hc, R_CTRL, 0x0); /* was _io before */ - - return data; -} - -inline void -writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data) -{ - unsigned short cipv; - unsigned int datav; - - if (!hc->pci_iobase) - return; - - if (address == 0) - cipv = 0x4000; - else - cipv = 0x5800; - - /* select local bridge port address by writing to CIP port */ - outw(cipv, hc->pci_iobase + 4); - /* define a 32 bit dword with 4 identical bytes for write sequence */ - datav = data | ((__u32) data << 8) | ((__u32) data << 16) | - ((__u32) data << 24); - - /* - * write this 32 bit dword to the bridge data port - * this will initiate a write sequence of up to 4 writes to the same - * address on the local bus interface the number of write accesses - * is undefined but >=1 and depends on the next PCI transaction - * during write sequence on the local bus - */ - outl(datav, hc->pci_iobase); -} - -inline void -cpld_set_reg(struct hfc_multi *hc, unsigned char reg) -{ - /* Do data pin read low byte */ - HFC_outb(hc, R_GPIO_OUT1, reg); -} - -inline void -cpld_write_reg(struct hfc_multi *hc, unsigned char reg, unsigned char val) -{ - cpld_set_reg(hc, reg); - - enablepcibridge(hc); - writepcibridge(hc, 1, val); - disablepcibridge(hc); - - return; -} - -inline unsigned char -cpld_read_reg(struct hfc_multi *hc, unsigned char reg) -{ - unsigned char bytein; - - cpld_set_reg(hc, reg); - - /* Do data pin read low byte */ - HFC_outb(hc, R_GPIO_OUT1, reg); - - enablepcibridge(hc); - bytein = readpcibridge(hc, 1); - disablepcibridge(hc); - - return bytein; -} - -inline void -vpm_write_address(struct hfc_multi *hc, unsigned short addr) -{ - cpld_write_reg(hc, 0, 0xff & addr); - cpld_write_reg(hc, 1, 0x01 & (addr >> 8)); -} - -inline unsigned short -vpm_read_address(struct hfc_multi *c) -{ - unsigned short addr; - unsigned short highbit; - - addr = cpld_read_reg(c, 0); - highbit = cpld_read_reg(c, 1); - - addr = addr | (highbit << 8); - - return addr & 0x1ff; -} - -inline unsigned char -vpm_in(struct hfc_multi *c, int which, unsigned short addr) -{ - unsigned char res; - - vpm_write_address(c, addr); - - if (!which) - cpld_set_reg(c, 2); - else - cpld_set_reg(c, 3); - - enablepcibridge(c); - res = readpcibridge(c, 1); - disablepcibridge(c); - - cpld_set_reg(c, 0); - - return res; -} - -inline void -vpm_out(struct hfc_multi *c, int which, unsigned short addr, - unsigned char data) -{ - vpm_write_address(c, addr); - - enablepcibridge(c); - - if (!which) - cpld_set_reg(c, 2); - else - cpld_set_reg(c, 3); - - writepcibridge(c, 1, data); - - cpld_set_reg(c, 0); - - disablepcibridge(c); - - { - unsigned char regin; - regin = vpm_in(c, which, addr); - if (regin != data) - printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back " - "0x%x\n", data, addr, regin); - } - -} - - -void -vpm_init(struct hfc_multi *wc) -{ - unsigned char reg; - unsigned int mask; - unsigned int i, x, y; - unsigned int ver; - - for (x = 0; x < NUM_EC; x++) { - /* Setup GPIO's */ - if (!x) { - ver = vpm_in(wc, x, 0x1a0); - printk(KERN_DEBUG "VPM: Chip %d: ver %02x\n", x, ver); - } - - for (y = 0; y < 4; y++) { - vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */ - vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */ - vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */ - } - - /* Setup TDM path - sets fsync and tdm_clk as inputs */ - reg = vpm_in(wc, x, 0x1a3); /* misc_con */ - vpm_out(wc, x, 0x1a3, reg & ~2); - - /* Setup Echo length (256 taps) */ - vpm_out(wc, x, 0x022, 1); - vpm_out(wc, x, 0x023, 0xff); - - /* Setup timeslots */ - vpm_out(wc, x, 0x02f, 0x00); - mask = 0x02020202 << (x * 4); - - /* Setup the tdm channel masks for all chips */ - for (i = 0; i < 4; i++) - vpm_out(wc, x, 0x33 - i, (mask >> (i << 3)) & 0xff); - - /* Setup convergence rate */ - printk(KERN_DEBUG "VPM: A-law mode\n"); - reg = 0x00 | 0x10 | 0x01; - vpm_out(wc, x, 0x20, reg); - printk(KERN_DEBUG "VPM reg 0x20 is %x\n", reg); - /*vpm_out(wc, x, 0x20, (0x00 | 0x08 | 0x20 | 0x10)); */ - - vpm_out(wc, x, 0x24, 0x02); - reg = vpm_in(wc, x, 0x24); - printk(KERN_DEBUG "NLP Thresh is set to %d (0x%x)\n", reg, reg); - - /* Initialize echo cans */ - for (i = 0; i < MAX_TDM_CHAN; i++) { - if (mask & (0x00000001 << i)) - vpm_out(wc, x, i, 0x00); - } - - /* - * ARM arch at least disallows a udelay of - * more than 2ms... it gives a fake "__bad_udelay" - * reference at link-time. - * long delays in kernel code are pretty sucky anyway - * for now work around it using 5 x 2ms instead of 1 x 10ms - */ - - udelay(2000); - udelay(2000); - udelay(2000); - udelay(2000); - udelay(2000); - - /* Put in bypass mode */ - for (i = 0; i < MAX_TDM_CHAN; i++) { - if (mask & (0x00000001 << i)) - vpm_out(wc, x, i, 0x01); - } - - /* Enable bypass */ - for (i = 0; i < MAX_TDM_CHAN; i++) { - if (mask & (0x00000001 << i)) - vpm_out(wc, x, 0x78 + i, 0x01); - } - - } -} - -void -vpm_check(struct hfc_multi *hctmp) -{ - unsigned char gpi2; - - gpi2 = HFC_inb(hctmp, R_GPI_IN2); - - if ((gpi2 & 0x3) != 0x3) - printk(KERN_DEBUG "Got interrupt 0x%x from VPM!\n", gpi2); -} - - -/* - * Interface to enable/disable the HW Echocan - * - * these functions are called within a spin_lock_irqsave on - * the channel instance lock, so we are not disturbed by irqs - * - * we can later easily change the interface to make other - * things configurable, for now we configure the taps - * - */ - -void -vpm_echocan_on(struct hfc_multi *hc, int ch, int taps) -{ - unsigned int timeslot; - unsigned int unit; - struct bchannel *bch = hc->chan[ch].bch; -#ifdef TXADJ - int txadj = -4; - struct sk_buff *skb; -#endif - if (hc->chan[ch].protocol != ISDN_P_B_RAW) - return; - - if (!bch) - return; - -#ifdef TXADJ - skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX, - sizeof(int), &txadj, GFP_ATOMIC); - if (skb) - recv_Bchannel_skb(bch, skb); -#endif - - timeslot = ((ch/4)*8) + ((ch%4)*4) + 1; - unit = ch % 4; - - printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n", - taps, timeslot); - - vpm_out(hc, unit, timeslot, 0x7e); -} - -void -vpm_echocan_off(struct hfc_multi *hc, int ch) -{ - unsigned int timeslot; - unsigned int unit; - struct bchannel *bch = hc->chan[ch].bch; -#ifdef TXADJ - int txadj = 0; - struct sk_buff *skb; -#endif - - if (hc->chan[ch].protocol != ISDN_P_B_RAW) - return; - - if (!bch) - return; - -#ifdef TXADJ - skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX, - sizeof(int), &txadj, GFP_ATOMIC); - if (skb) - recv_Bchannel_skb(bch, skb); -#endif - - timeslot = ((ch/4)*8) + ((ch%4)*4) + 1; - unit = ch % 4; - - printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n", - timeslot); - /* FILLME */ - vpm_out(hc, unit, timeslot, 0x01); -} - - -/* - * Speech Design resync feature - * NOTE: This is called sometimes outside interrupt handler. - * We must lock irqsave, so no other interrupt (other card) will occurr! - * Also multiple interrupts may nest, so must lock each access (lists, card)! - */ -static inline void -hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) -{ - struct hfc_multi *hc, *next, *pcmmaster = 0; - u_int *plx_acc_32, pv; - u_long flags; - - spin_lock_irqsave(&HFClock, flags); - spin_lock(&plx_lock); /* must be locked inside other locks */ - - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n", - __func__, syncmaster); - - /* select new master */ - if (newmaster) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "using provided controller\n"); - } else { - list_for_each_entry_safe(hc, next, &HFClist, list) { - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - if (hc->syncronized) { - newmaster = hc; - break; - } - } - } - } - - /* Disable sync of all cards */ - list_for_each_entry_safe(hc, next, &HFClist, list) { - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - plx_acc_32 = (u_int *)(hc->plx_membase+PLX_GPIOC); - pv = readl(plx_acc_32); - pv &= ~PLX_SYNC_O_EN; - writel(pv, plx_acc_32); - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { - pcmmaster = hc; - if (hc->type == 1) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG - "Schedule SYNC_I\n"); - hc->e1_resync |= 1; /* get SYNC_I */ - } - } - } - } - - if (newmaster) { - hc = newmaster; - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "id=%d (0x%p) = syncronized with " - "interface.\n", hc->id, hc); - /* Enable new sync master */ - plx_acc_32 = (u_int *)(hc->plx_membase+PLX_GPIOC); - pv = readl(plx_acc_32); - pv |= PLX_SYNC_O_EN; - writel(pv, plx_acc_32); - /* switch to jatt PLL, if not disabled by RX_SYNC */ - if (hc->type == 1 && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "Schedule jatt PLL\n"); - hc->e1_resync |= 2; /* switch to jatt */ - } - } else { - if (pcmmaster) { - hc = pcmmaster; - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG - "id=%d (0x%p) = PCM master syncronized " - "with QUARTZ\n", hc->id, hc); - if (hc->type == 1) { - /* Use the crystal clock for the PCM - master card */ - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG - "Schedule QUARTZ for HFC-E1\n"); - hc->e1_resync |= 4; /* switch quartz */ - } else { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG - "QUARTZ is automatically " - "enabled by HFC-%dS\n", hc->type); - } - plx_acc_32 = (u_int *)(hc->plx_membase+PLX_GPIOC); - pv = readl(plx_acc_32); - pv |= PLX_SYNC_O_EN; - writel(pv, plx_acc_32); - } else - if (!rm) - printk(KERN_ERR "%s no pcm master, this MUST " - "not happen!\n", __func__); - } - syncmaster = newmaster; - - spin_unlock(&plx_lock); - spin_unlock_irqrestore(&HFClock, flags); -} - -/* This must be called AND hc must be locked irqsave!!! */ -inline void -plxsd_checksync(struct hfc_multi *hc, int rm) -{ - if (hc->syncronized) { - if (syncmaster == NULL) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_WARNING "%s: GOT sync on card %d" - " (id=%d)\n", __func__, hc->id + 1, - hc->id); - hfcmulti_resync(hc, hc, rm); - } - } else { - if (syncmaster == hc) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_WARNING "%s: LOST sync on card %d" - " (id=%d)\n", __func__, hc->id + 1, - hc->id); - hfcmulti_resync(hc, NULL, rm); - } - } -} - - -/* - * free hardware resources used by driver - */ -static void -release_io_hfcmulti(struct hfc_multi *hc) -{ - u_int *plx_acc_32, pv; - u_long plx_flags; - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: entered\n", __func__); - - /* soft reset also masks all interrupts */ - hc->hw.r_cirm |= V_SRES; - HFC_outb(hc, R_CIRM, hc->hw.r_cirm); - udelay(1000); - hc->hw.r_cirm &= ~V_SRES; - HFC_outb(hc, R_CIRM, hc->hw.r_cirm); - udelay(1000); /* instead of 'wait' that may cause locking */ - - /* release Speech Design card, if PLX was initialized */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "%s: release PLXSD card %d\n", - __func__, hc->id + 1); - spin_lock_irqsave(&plx_lock, plx_flags); - plx_acc_32 = (u_int *)(hc->plx_membase+PLX_GPIOC); - writel(PLX_GPIOC_INIT, plx_acc_32); - pv = readl(plx_acc_32); - /* Termination off */ - pv &= ~PLX_TERM_ON; - /* Disconnect the PCM */ - pv |= PLX_SLAVE_EN_N; - pv &= ~PLX_MASTER_EN; - pv &= ~PLX_SYNC_O_EN; - /* Put the DSP in Reset */ - pv &= ~PLX_DSP_RES_N; - writel(pv, plx_acc_32); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: PCM off: PLX_GPIO=%x\n", - __func__, pv); - spin_unlock_irqrestore(&plx_lock, plx_flags); - } - - /* disable memory mapped ports / io ports */ - test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */ - pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0); - if (hc->pci_membase) - iounmap((void *)hc->pci_membase); - if (hc->plx_membase) - iounmap((void *)hc->plx_membase); - if (hc->pci_iobase) - release_region(hc->pci_iobase, 8); - - if (hc->pci_dev) { - pci_disable_device(hc->pci_dev); - pci_set_drvdata(hc->pci_dev, NULL); - } - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: done\n", __func__); -} - -/* - * function called to reset the HFC chip. A complete software reset of chip - * and fifos is done. All configuration of the chip is done. - */ - -static int -init_chip(struct hfc_multi *hc) -{ - u_long flags, val, val2 = 0, rev; - int i, err = 0; - u_char r_conf_en, rval; - u_int *plx_acc_32, pv; - u_long plx_flags, hfc_flags; - int plx_count; - struct hfc_multi *pos, *next, *plx_last_hc; - - spin_lock_irqsave(&hc->lock, flags); - /* reset all registers */ - memset(&hc->hw, 0, sizeof(struct hfcm_hw)); - - /* revision check */ - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: entered\n", __func__); - val = HFC_inb(hc, R_CHIP_ID)>>4; - if (val != 0x8 && val != 0xc && val != 0xe) { - printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val); - err = -EIO; - goto out; - } - rev = HFC_inb(hc, R_CHIP_RV); - printk(KERN_INFO - "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n", - val, rev, (rev == 0) ? " (old FIFO handling)" : ""); - if (rev == 0) { - test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip); - printk(KERN_WARNING - "HFC_multi: NOTE: Your chip is revision 0, " - "ask Cologne Chip for update. Newer chips " - "have a better FIFO handling. Old chips " - "still work but may have slightly lower " - "HDLC transmit performance.\n"); - } - if (rev > 1) { - printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't " - "consider chip revision = %ld. The chip / " - "bridge may not work.\n", rev); - } - - /* set s-ram size */ - hc->Flen = 0x10; - hc->Zmin = 0x80; - hc->Zlen = 384; - hc->DTMFbase = 0x1000; - if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: changing to 128K extenal RAM\n", - __func__); - hc->hw.r_ctrl |= V_EXT_RAM; - hc->hw.r_ram_sz = 1; - hc->Flen = 0x20; - hc->Zmin = 0xc0; - hc->Zlen = 1856; - hc->DTMFbase = 0x2000; - } - if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: changing to 512K extenal RAM\n", - __func__); - hc->hw.r_ctrl |= V_EXT_RAM; - hc->hw.r_ram_sz = 2; - hc->Flen = 0x20; - hc->Zmin = 0xc0; - hc->Zlen = 8000; - hc->DTMFbase = 0x2000; - } - hc->max_trans = poll << 1; - if (hc->max_trans > hc->Zlen) - hc->max_trans = hc->Zlen; - - /* Speech Design PLX bridge */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "%s: initializing PLXSD card %d\n", - __func__, hc->id + 1); - spin_lock_irqsave(&plx_lock, plx_flags); - plx_acc_32 = (u_int *)(hc->plx_membase+PLX_GPIOC); - writel(PLX_GPIOC_INIT, plx_acc_32); - pv = readl(plx_acc_32); - /* The first and the last cards are terminating the PCM bus */ - pv |= PLX_TERM_ON; /* hc is currently the last */ - /* Disconnect the PCM */ - pv |= PLX_SLAVE_EN_N; - pv &= ~PLX_MASTER_EN; - pv &= ~PLX_SYNC_O_EN; - /* Put the DSP in Reset */ - pv &= ~PLX_DSP_RES_N; - writel(pv, plx_acc_32); - spin_unlock_irqrestore(&plx_lock, plx_flags); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: slave/term: PLX_GPIO=%x\n", - __func__, pv); - /* - * If we are the 3rd PLXSD card or higher, we must turn - * termination of last PLXSD card off. - */ - spin_lock_irqsave(&HFClock, hfc_flags); - plx_count = 0; - plx_last_hc = NULL; - list_for_each_entry_safe(pos, next, &HFClist, list) { - if (test_bit(HFC_CHIP_PLXSD, &pos->chip)) { - plx_count++; - if (pos != hc) - plx_last_hc = pos; - } - } - if (plx_count >= 3) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "%s: card %d is between, so " - "we disable termination\n", - __func__, plx_last_hc->id + 1); - spin_lock_irqsave(&plx_lock, plx_flags); - plx_acc_32 = (u_int *)(plx_last_hc->plx_membase - + PLX_GPIOC); - pv = readl(plx_acc_32); - pv &= ~PLX_TERM_ON; - writel(pv, plx_acc_32); - spin_unlock_irqrestore(&plx_lock, plx_flags); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: term off: PLX_GPIO=%x\n", - __func__, pv); - } - spin_unlock_irqrestore(&HFClock, hfc_flags); - hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ - } - - /* we only want the real Z2 read-pointer for revision > 0 */ - if (!test_bit(HFC_CHIP_REVISION0, &hc->chip)) - hc->hw.r_ram_sz |= V_FZ_MD; - - /* select pcm mode */ - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: setting PCM into slave mode\n", - __func__); - } else - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: setting PCM into master mode\n", - __func__); - hc->hw.r_pcm_md0 |= V_PCM_MD; - } else { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: performing PCM auto detect\n", - __func__); - } - - /* soft reset */ - HFC_outb(hc, R_CTRL, hc->hw.r_ctrl); - HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); - HFC_outb(hc, R_FIFO_MD, 0); - hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES | V_RLD_EPR; - HFC_outb(hc, R_CIRM, hc->hw.r_cirm); - udelay(100); - hc->hw.r_cirm = 0; - HFC_outb(hc, R_CIRM, hc->hw.r_cirm); - udelay(100); - HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); - - /* Speech Design PLX bridge pcm and sync mode */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - spin_lock_irqsave(&plx_lock, plx_flags); - plx_acc_32 = (u_int *)(hc->plx_membase+PLX_GPIOC); - pv = readl(plx_acc_32); - /* Connect PCM */ - if (hc->hw.r_pcm_md0 & V_PCM_MD) { - pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N; - pv |= PLX_SYNC_O_EN; - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: master: PLX_GPIO=%x\n", - __func__, pv); - } else { - pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N); - pv &= ~PLX_SYNC_O_EN; - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: slave: PLX_GPIO=%x\n", - __func__, pv); - } - writel(pv, plx_acc_32); - spin_unlock_irqrestore(&plx_lock, plx_flags); - } - - /* PCM setup */ - HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x90); - if (hc->slots == 32) - HFC_outb(hc, R_PCM_MD1, 0x00); - if (hc->slots == 64) - HFC_outb(hc, R_PCM_MD1, 0x10); - if (hc->slots == 128) - HFC_outb(hc, R_PCM_MD1, 0x20); - HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0); - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) - HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */ - else - HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */ - HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); - for (i = 0; i < 256; i++) { - HFC_outb_nodebug(hc, R_SLOT, i); - HFC_outb_nodebug(hc, A_SL_CFG, 0); - HFC_outb_nodebug(hc, A_CONF, 0); - hc->slot_owner[i] = -1; - } - - /* set clock speed */ - if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: setting double clock\n", __func__); - HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); - } - - /* B410P GPIO */ - if (test_bit(HFC_CHIP_B410P, &hc->chip)) { - printk(KERN_NOTICE "Setting GPIOs\n"); - HFC_outb(hc, R_GPIO_SEL, 0x30); - HFC_outb(hc, R_GPIO_EN1, 0x3); - udelay(1000); - printk(KERN_NOTICE "calling vpm_init\n"); - vpm_init(hc); - } - - /* check if R_F0_CNT counts (8 kHz frame count) */ - val = HFC_inb(hc, R_F0_CNTL); - val += HFC_inb(hc, R_F0_CNTH) << 8; - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "HFC_multi F0_CNT %ld after reset\n", val); - spin_unlock_irqrestore(&hc->lock, flags); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((HZ/100)?:1); /* Timeout minimum 10ms */ - spin_lock_irqsave(&hc->lock, flags); - val2 = HFC_inb(hc, R_F0_CNTL); - val2 += HFC_inb(hc, R_F0_CNTH) << 8; - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "HFC_multi F0_CNT %ld after 10 ms (1st try)\n", - val2); - if (val2 >= val+8) { /* 1 ms */ - /* it counts, so we keep the pcm mode */ - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) - printk(KERN_INFO "controller is PCM bus MASTER\n"); - else - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) - printk(KERN_INFO "controller is PCM bus SLAVE\n"); - else { - test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); - printk(KERN_INFO "controller is PCM bus SLAVE " - "(auto detected)\n"); - } - } else { - /* does not count */ - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { -controller_fail: - printk(KERN_ERR "HFC_multi ERROR, getting no 125us " - "pulse. Seems that controller fails.\n"); - err = -EIO; - goto out; - } - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { - printk(KERN_INFO "controller is PCM bus SLAVE " - "(ignoring missing PCM clock)\n"); - } else { - /* only one pcm master */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip) - && plxsd_master) { - printk(KERN_ERR "HFC_multi ERROR, no clock " - "on another Speech Design card found. " - "Please be sure to connect PCM cable.\n"); - err = -EIO; - goto out; - } - /* retry with master clock */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - spin_lock_irqsave(&plx_lock, plx_flags); - plx_acc_32 = (u_int *)(hc->plx_membase + - PLX_GPIOC); - pv = readl(plx_acc_32); - pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N; - pv |= PLX_SYNC_O_EN; - writel(pv, plx_acc_32); - spin_unlock_irqrestore(&plx_lock, plx_flags); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: master: PLX_GPIO" - "=%x\n", __func__, pv); - } - hc->hw.r_pcm_md0 |= V_PCM_MD; - HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); - spin_unlock_irqrestore(&hc->lock, flags); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((HZ/100)?:1); /* Timeout min. 10ms */ - spin_lock_irqsave(&hc->lock, flags); - val2 = HFC_inb(hc, R_F0_CNTL); - val2 += HFC_inb(hc, R_F0_CNTH) << 8; - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "HFC_multi F0_CNT %ld after " - "10 ms (2nd try)\n", val2); - if (val2 >= val+8) { /* 1 ms */ - test_and_set_bit(HFC_CHIP_PCM_MASTER, - &hc->chip); - printk(KERN_INFO "controller is PCM bus MASTER " - "(auto detected)\n"); - } else - goto controller_fail; - } - } - - /* Release the DSP Reset */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) - plxsd_master = 1; - spin_lock_irqsave(&plx_lock, plx_flags); - plx_acc_32 = (u_int *)(hc->plx_membase+PLX_GPIOC); - pv = readl(plx_acc_32); - pv |= PLX_DSP_RES_N; - writel(pv, plx_acc_32); - spin_unlock_irqrestore(&plx_lock, plx_flags); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: reset off: PLX_GPIO=%x\n", - __func__, pv); - } - - /* pcm id */ - if (hc->pcm) - printk(KERN_INFO "controller has given PCM BUS ID %d\n", - hc->pcm); - else { - if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) - || test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - PCM_cnt++; /* SD has proprietary bridging */ - } - hc->pcm = PCM_cnt; - printk(KERN_INFO "controller has PCM BUS ID %d " - "(auto selected)\n", hc->pcm); - } - - /* set up timer */ - HFC_outb(hc, R_TI_WD, poll_timer); - hc->hw.r_irqmsk_misc |= V_TI_IRQMSK; - - /* - * set up 125us interrupt, only if function pointer is available - * and module parameter timer is set - */ - if (timer && hfc_interrupt && register_interrupt) { - /* only one chip should use this interrupt */ - timer = 0; - interrupt_registered = 1; - hc->hw.r_irqmsk_misc |= V_PROC_IRQMSK; - /* deactivate other interrupts in ztdummy */ - register_interrupt(); - } - - /* set E1 state machine IRQ */ - if (hc->type == 1) - hc->hw.r_irqmsk_misc |= V_STA_IRQMSK; - - /* set DTMF detection */ - if (test_bit(HFC_CHIP_DTMF, &hc->chip)) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: enabling DTMF detection " - "for all B-channel\n", __func__); - hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP; - if (test_bit(HFC_CHIP_ULAW, &hc->chip)) - hc->hw.r_dtmf |= V_ULAW_SEL; - HFC_outb(hc, R_DTMF_N, 102 - 1); - hc->hw.r_irqmsk_misc |= V_DTMF_IRQMSK; - } - - /* conference engine */ - if (test_bit(HFC_CHIP_ULAW, &hc->chip)) - r_conf_en = V_CONF_EN | V_ULAW; - else - r_conf_en = V_CONF_EN; - HFC_outb(hc, R_CONF_EN, r_conf_en); - - /* setting leds */ - switch (hc->leds) { - case 1: /* HFC-E1 OEM */ - if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip)) - HFC_outb(hc, R_GPIO_SEL, 0x32); - else - HFC_outb(hc, R_GPIO_SEL, 0x30); - - HFC_outb(hc, R_GPIO_EN1, 0x0f); - HFC_outb(hc, R_GPIO_OUT1, 0x00); - - HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3); - break; - - case 2: /* HFC-4S OEM */ - case 3: - HFC_outb(hc, R_GPIO_SEL, 0xf0); - HFC_outb(hc, R_GPIO_EN1, 0xff); - HFC_outb(hc, R_GPIO_OUT1, 0x00); - break; - } - - /* set master clock */ - if (hc->masterclk >= 0) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: setting ST master clock " - "to port %d (0..%d)\n", - __func__, hc->masterclk, hc->ports-1); - hc->hw.r_st_sync = hc->masterclk | V_AUTO_SYNC; - HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); - } - - /* setting misc irq */ - HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n", - hc->hw.r_irqmsk_misc); - - /* RAM access test */ - HFC_outb(hc, R_RAM_ADDR0, 0); - HFC_outb(hc, R_RAM_ADDR1, 0); - HFC_outb(hc, R_RAM_ADDR2, 0); - for (i = 0; i < 256; i++) { - HFC_outb_nodebug(hc, R_RAM_ADDR0, i); - HFC_outb_nodebug(hc, R_RAM_DATA, ((i*3)&0xff)); - } - for (i = 0; i < 256; i++) { - HFC_outb_nodebug(hc, R_RAM_ADDR0, i); - HFC_inb_nodebug(hc, R_RAM_DATA); - rval = HFC_inb_nodebug(hc, R_INT_DATA); - if (rval != ((i * 3) & 0xff)) { - printk(KERN_DEBUG - "addr:%x val:%x should:%x\n", i, rval, - (i * 3) & 0xff); - err++; - } - } - if (err) { - printk(KERN_DEBUG "aborting - %d RAM access errors\n", err); - err = -EIO; - goto out; - } - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: done\n", __func__); -out: - spin_unlock_irqrestore(&hc->lock, flags); - return err; -} - - -/* - * control the watchdog - */ -static void -hfcmulti_watchdog(struct hfc_multi *hc) -{ - hc->wdcount++; - - if (hc->wdcount > 10) { - hc->wdcount = 0; - hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ? - V_GPIO_OUT3 : V_GPIO_OUT2; - - /* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */ - HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3); - HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte); - } -} - - - -/* - * output leds - */ -static void -hfcmulti_leds(struct hfc_multi *hc) -{ - unsigned long lled; - unsigned long leddw; - int i, state, active, leds; - struct dchannel *dch; - int led[4]; - - hc->ledcount += poll; - if (hc->ledcount > 4096) { - hc->ledcount -= 4096; - hc->ledstate = 0xAFFEAFFE; - } - - switch (hc->leds) { - case 1: /* HFC-E1 OEM */ - /* 2 red blinking: NT mode deactivate - * 2 red steady: TE mode deactivate - * left green: L1 active - * left red: frame sync, but no L1 - * right green: L2 active - */ - if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */ - if (hc->chan[hc->dslot].dch->dev.D.protocol - != ISDN_P_NT_E1) { - led[0] = 1; - led[1] = 1; - } else if (hc->ledcount>>11) { - led[0] = 1; - led[1] = 1; - } else { - led[0] = 0; - led[1] = 0; - } - led[2] = 0; - led[3] = 0; - } else { /* with frame sync */ - /* TODO make it work */ - led[0] = 0; - led[1] = 0; - led[2] = 0; - led[3] = 1; - } - leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF; - /* leds are inverted */ - if (leds != (int)hc->ledstate) { - HFC_outb_nodebug(hc, R_GPIO_OUT1, leds); - hc->ledstate = leds; - } - break; - - case 2: /* HFC-4S OEM */ - /* red blinking = PH_DEACTIVATE NT Mode - * red steady = PH_DEACTIVATE TE Mode - * green steady = PH_ACTIVATE - */ - for (i = 0; i < 4; i++) { - state = 0; - active = -1; - dch = hc->chan[(i << 2) | 2].dch; - if (dch) { - state = dch->state; - if (dch->dev.D.protocol == ISDN_P_NT_S0) - active = 3; - else - active = 7; - } - if (state) { - if (state == active) { - led[i] = 1; /* led green */ - } else - if (dch->dev.D.protocol == ISDN_P_TE_S0) - /* TE mode: led red */ - led[i] = 2; - else - if (hc->ledcount>>11) - /* led red */ - led[i] = 2; - else - /* led off */ - led[i] = 0; - } else - led[i] = 0; /* led off */ - } - if (test_bit(HFC_CHIP_B410P, &hc->chip)) { - leds = 0; - for (i = 0; i < 4; i++) { - if (led[i] == 1) { - /*green*/ - leds |= (0x2 << (i * 2)); - } else if (led[i] == 2) { - /*red*/ - leds |= (0x1 << (i * 2)); - } - } - if (leds != (int)hc->ledstate) { - vpm_out(hc, 0, 0x1a8 + 3, leds); - hc->ledstate = leds; - } - } else { - leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) | - ((led[0] > 0) << 2) | ((led[2] > 0) << 3) | - ((led[3] & 1) << 4) | ((led[1] & 1) << 5) | - ((led[0] & 1) << 6) | ((led[2] & 1) << 7); - if (leds != (int)hc->ledstate) { - HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F); - HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4); - hc->ledstate = leds; - } - } - break; - - case 3: /* HFC 1S/2S Beronet */ - /* red blinking = PH_DEACTIVATE NT Mode - * red steady = PH_DEACTIVATE TE Mode - * green steady = PH_ACTIVATE - */ - for (i = 0; i < 2; i++) { - state = 0; - active = -1; - dch = hc->chan[(i << 2) | 2].dch; - if (dch) { - state = dch->state; - if (dch->dev.D.protocol == ISDN_P_NT_S0) - active = 3; - else - active = 7; - } - if (state) { - if (state == active) { - led[i] = 1; /* led green */ - } else - if (dch->dev.D.protocol == ISDN_P_TE_S0) - /* TE mode: led red */ - led[i] = 2; - else - if (hc->ledcount >> 11) - /* led red */ - led[i] = 2; - else - /* led off */ - led[i] = 0; - } else - led[i] = 0; /* led off */ - } - - - leds = (led[0] > 0) | ((led[1] > 0)<<1) | ((led[0]&1)<<2) - | ((led[1]&1)<<3); - if (leds != (int)hc->ledstate) { - HFC_outb_nodebug(hc, R_GPIO_EN1, - ((led[0] > 0) << 2) | ((led[1] > 0) << 3)); - HFC_outb_nodebug(hc, R_GPIO_OUT1, - ((led[0] & 1) << 2) | ((led[1] & 1) << 3)); - hc->ledstate = leds; - } - break; - case 8: /* HFC 8S+ Beronet */ - lled = 0; - - for (i = 0; i < 8; i++) { - state = 0; - active = -1; - dch = hc->chan[(i << 2) | 2].dch; - if (dch) { - state = dch->state; - if (dch->dev.D.protocol == ISDN_P_NT_S0) - active = 3; - else - active = 7; - } - if (state) { - if (state == active) { - lled |= 0 << i; - } else - if (hc->ledcount >> 11) - lled |= 0 << i; - else - lled |= 1 << i; - } else - lled |= 1 << i; - } - leddw = lled << 24 | lled << 16 | lled << 8 | lled; - if (leddw != hc->ledstate) { - /* HFC_outb(hc, R_BRG_PCM_CFG, 1); - HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */ - /* was _io before */ - HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK); - outw(0x4000, hc->pci_iobase + 4); - outl(leddw, hc->pci_iobase); - HFC_outb_nodebug(hc, R_BRG_PCM_CFG, V_PCM_CLK); - hc->ledstate = leddw; - } - break; - } -} -/* - * read dtmf coefficients - */ - -static void -hfcmulti_dtmf(struct hfc_multi *hc) -{ - s32 *coeff; - u_int mantissa; - int co, ch; - struct bchannel *bch = NULL; - u8 exponent; - int dtmf = 0; - int addr; - u16 w_float; - struct sk_buff *skb; - struct mISDNhead *hh; - - if (debug & DEBUG_HFCMULTI_DTMF) - printk(KERN_DEBUG "%s: dtmf detection irq\n", __func__); - for (ch = 0; ch <= 31; ch++) { - /* only process enabled B-channels */ - bch = hc->chan[ch].bch; - if (!bch) - continue; - if (!hc->created[hc->chan[ch].port]) - continue; - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - continue; - if (debug & DEBUG_HFCMULTI_DTMF) - printk(KERN_DEBUG "%s: dtmf channel %d:", - __func__, ch); - coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]); - dtmf = 1; - for (co = 0; co < 8; co++) { - /* read W(n-1) coefficient */ - addr = hc->DTMFbase + ((co<<7) | (ch<<2)); - HFC_outb_nodebug(hc, R_RAM_ADDR0, addr); - HFC_outb_nodebug(hc, R_RAM_ADDR1, addr>>8); - HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr>>16) - | V_ADDR_INC); - w_float = HFC_inb_nodebug(hc, R_RAM_DATA); - w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8); - if (debug & DEBUG_HFCMULTI_DTMF) - printk(" %04x", w_float); - - /* decode float (see chip doc) */ - mantissa = w_float & 0x0fff; - if (w_float & 0x8000) - mantissa |= 0xfffff000; - exponent = (w_float>>12) & 0x7; - if (exponent) { - mantissa ^= 0x1000; - mantissa <<= (exponent-1); - } - - /* store coefficient */ - coeff[co<<1] = mantissa; - - /* read W(n) coefficient */ - w_float = HFC_inb_nodebug(hc, R_RAM_DATA); - w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8); - if (debug & DEBUG_HFCMULTI_DTMF) - printk(" %04x", w_float); - - /* decode float (see chip doc) */ - mantissa = w_float & 0x0fff; - if (w_float & 0x8000) - mantissa |= 0xfffff000; - exponent = (w_float>>12) & 0x7; - if (exponent) { - mantissa ^= 0x1000; - mantissa <<= (exponent-1); - } - - /* store coefficient */ - coeff[(co<<1)|1] = mantissa; - } - if (debug & DEBUG_HFCMULTI_DTMF) - printk("%s: DTMF ready %08x %08x %08x %08x " - "%08x %08x %08x %08x\n", __func__, - coeff[0], coeff[1], coeff[2], coeff[3], - coeff[4], coeff[5], coeff[6], coeff[7]); - hc->chan[ch].coeff_count++; - if (hc->chan[ch].coeff_count == 8) { - hc->chan[ch].coeff_count = 0; - skb = mI_alloc_skb(512, GFP_ATOMIC); - if (!skb) { - printk(KERN_WARNING "%s: No memory for skb\n", - __func__); - continue; - } - hh = mISDN_HEAD_P(skb); - hh->prim = PH_CONTROL_IND; - hh->id = DTMF_HFC_COEF; - memcpy(skb_put(skb, 512), hc->chan[ch].coeff, 512); - recv_Bchannel_skb(bch, skb); - } - } - - /* restart DTMF processing */ - hc->dtmf = dtmf; - if (dtmf) - HFC_outb_nodebug(hc, R_DTMF, hc->hw.r_dtmf | V_RST_DTMF); -} - - -/* - * fill fifo as much as possible - */ - -static void -hfcmulti_tx(struct hfc_multi *hc, int ch) -{ - int i, ii, temp, len = 0; - int Zspace, z1, z2; /* must be int for calculation */ - int Fspace, f1, f2; - u_char *d; - int *txpending, slot_tx; - struct bchannel *bch; - struct dchannel *dch; - struct sk_buff **sp = NULL; - int *idxp; - - bch = hc->chan[ch].bch; - dch = hc->chan[ch].dch; - if ((!dch) && (!bch)) - return; - - txpending = &hc->chan[ch].txpending; - slot_tx = hc->chan[ch].slot_tx; - if (dch) { - if (!test_bit(FLG_ACTIVE, &dch->Flags)) - return; - sp = &dch->tx_skb; - idxp = &dch->tx_idx; - } else { - if (!test_bit(FLG_ACTIVE, &bch->Flags)) - return; - sp = &bch->tx_skb; - idxp = &bch->tx_idx; - } - if (*sp) - len = (*sp)->len; - - if ((!len) && *txpending != 1) - return; /* no data */ - - if (test_bit(HFC_CHIP_B410P, &hc->chip) && - (hc->chan[ch].protocol == ISDN_P_B_RAW) && - (hc->chan[ch].slot_rx < 0) && - (hc->chan[ch].slot_tx < 0)) - HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1)); - else - HFC_outb_nodebug(hc, R_FIFO, ch << 1); - HFC_wait_nodebug(hc); - - if (*txpending == 2) { - /* reset fifo */ - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait_nodebug(hc); - HFC_outb(hc, A_SUBCH_CFG, 0); - *txpending = 1; - } -next_frame: - if (dch || test_bit(FLG_HDLC, &bch->Flags)) { - f1 = HFC_inb_nodebug(hc, A_F1); - f2 = HFC_inb_nodebug(hc, A_F2); - while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) { - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG - "%s(card %d): reread f2 because %d!=%d\n", - __func__, hc->id + 1, temp, f2); - f2 = temp; /* repeat until F2 is equal */ - } - Fspace = f2 - f1 - 1; - if (Fspace < 0) - Fspace += hc->Flen; - /* - * Old FIFO handling doesn't give us the current Z2 read - * pointer, so we cannot send the next frame before the fifo - * is empty. It makes no difference except for a slightly - * lower performance. - */ - if (test_bit(HFC_CHIP_REVISION0, &hc->chip)) { - if (f1 != f2) - Fspace = 0; - else - Fspace = 1; - } - /* one frame only for ST D-channels, to allow resending */ - if (hc->type != 1 && dch) { - if (f1 != f2) - Fspace = 0; - } - /* F-counter full condition */ - if (Fspace == 0) - return; - } - z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin; - z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin; - while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) { - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG "%s(card %d): reread z2 because " - "%d!=%d\n", __func__, hc->id + 1, temp, z2); - z2 = temp; /* repeat unti Z2 is equal */ - } - Zspace = z2 - z1; - if (Zspace <= 0) - Zspace += hc->Zlen; - Zspace -= 4; /* keep not too full, so pointers will not overrun */ - /* fill transparent data only to maxinum transparent load (minus 4) */ - if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) - Zspace = Zspace - hc->Zlen + hc->max_trans; - if (Zspace <= 0) /* no space of 4 bytes */ - return; - - /* if no data */ - if (!len) { - if (z1 == z2) { /* empty */ - /* if done with FIFO audio data during PCM connection */ - if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && - *txpending && slot_tx >= 0) { - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG - "%s: reconnecting PCM due to no " - "more FIFO data: channel %d " - "slot_tx %d\n", - __func__, ch, slot_tx); - /* connect slot */ - HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | - V_HDLC_TRP | V_IFF); - HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); - HFC_wait_nodebug(hc); - HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | - V_HDLC_TRP | V_IFF); - HFC_outb_nodebug(hc, R_FIFO, ch<<1); - HFC_wait_nodebug(hc); - } - *txpending = 0; - } - return; /* no data */ - } - - /* if audio data and connected slot */ - if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending) - && slot_tx >= 0) { - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG "%s: disconnecting PCM due to " - "FIFO data: channel %d slot_tx %d\n", - __func__, ch, slot_tx); - /* disconnect slot */ - HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF); - HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); - HFC_wait_nodebug(hc); - HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF); - HFC_outb_nodebug(hc, R_FIFO, ch<<1); - HFC_wait_nodebug(hc); - } - *txpending = 1; - - /* show activity */ - hc->activity[hc->chan[ch].port] = 1; - - /* fill fifo to what we have left */ - ii = len; - if (dch || test_bit(FLG_HDLC, &bch->Flags)) - temp = 1; - else - temp = 0; - i = *idxp; - d = (*sp)->data + i; - if (ii - i > Zspace) - ii = Zspace + i; - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space " - "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n", - __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i, - temp ? "HDLC":"TRANS"); - - - /* Have to prep the audio data */ - hc->write_fifo(hc, d, ii - i); - *idxp = ii; - - /* if not all data has been written */ - if (ii != len) { - /* NOTE: fifo is started by the calling function */ - return; - } - - /* if all data has been written, terminate frame */ - if (dch || test_bit(FLG_HDLC, &bch->Flags)) { - /* increment f-counter */ - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F); - HFC_wait_nodebug(hc); - } - - /* send confirm, since get_net_bframe will not do it with trans */ - if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) - confirm_Bsend(bch); - - /* check for next frame */ - dev_kfree_skb(*sp); - if (bch && get_next_bframe(bch)) { /* hdlc is confirmed here */ - len = (*sp)->len; - goto next_frame; - } - if (dch && get_next_dframe(dch)) { - len = (*sp)->len; - goto next_frame; - } - - /* - * now we have no more data, so in case of transparent, - * we set the last byte in fifo to 'silence' in case we will get - * no more data at all. this prevents sending an undefined value. - */ - if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) - HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); -} - - -/* NOTE: only called if E1 card is in active state */ -static void -hfcmulti_rx(struct hfc_multi *hc, int ch) -{ - int temp; - int Zsize, z1, z2 = 0; /* = 0, to make GCC happy */ - int f1 = 0, f2 = 0; /* = 0, to make GCC happy */ - int again = 0; - struct bchannel *bch; - struct dchannel *dch; - struct sk_buff *skb, **sp = NULL; - int maxlen; - - bch = hc->chan[ch].bch; - dch = hc->chan[ch].dch; - if ((!dch) && (!bch)) - return; - if (dch) { - if (!test_bit(FLG_ACTIVE, &dch->Flags)) - return; - sp = &dch->rx_skb; - maxlen = dch->maxlen; - } else { - if (!test_bit(FLG_ACTIVE, &bch->Flags)) - return; - sp = &bch->rx_skb; - maxlen = bch->maxlen; - } -next_frame: - /* on first AND before getting next valid frame, R_FIFO must be written - to. */ - if (test_bit(HFC_CHIP_B410P, &hc->chip) && - (hc->chan[ch].protocol == ISDN_P_B_RAW) && - (hc->chan[ch].slot_rx < 0) && - (hc->chan[ch].slot_tx < 0)) - HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch<<1) | 1); - else - HFC_outb_nodebug(hc, R_FIFO, (ch<<1)|1); - HFC_wait_nodebug(hc); - - /* ignore if rx is off BUT change fifo (above) to start pending TX */ - if (hc->chan[ch].rx_off) - return; - - if (dch || test_bit(FLG_HDLC, &bch->Flags)) { - f1 = HFC_inb_nodebug(hc, A_F1); - while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) { - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG - "%s(card %d): reread f1 because %d!=%d\n", - __func__, hc->id + 1, temp, f1); - f1 = temp; /* repeat until F1 is equal */ - } - f2 = HFC_inb_nodebug(hc, A_F2); - } - z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin; - while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) { - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG "%s(card %d): reread z2 because " - "%d!=%d\n", __func__, hc->id + 1, temp, z2); - z1 = temp; /* repeat until Z1 is equal */ - } - z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin; - Zsize = z1 - z2; - if ((dch || test_bit(FLG_HDLC, &bch->Flags)) && f1 != f2) - /* complete hdlc frame */ - Zsize++; - if (Zsize < 0) - Zsize += hc->Zlen; - /* if buffer is empty */ - if (Zsize <= 0) - return; - - if (*sp == NULL) { - *sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC); - if (*sp == NULL) { - printk(KERN_DEBUG "%s: No mem for rx_skb\n", - __func__); - return; - } - } - /* show activity */ - hc->activity[hc->chan[ch].port] = 1; - - /* empty fifo with what we have */ - if (dch || test_bit(FLG_HDLC, &bch->Flags)) { - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d " - "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) " - "got=%d (again %d)\n", __func__, hc->id + 1, ch, - Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE", - f1, f2, Zsize + (*sp)->len, again); - /* HDLC */ - if ((Zsize + (*sp)->len) > (maxlen + 3)) { - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG - "%s(card %d): hdlc-frame too large.\n", - __func__, hc->id + 1); - skb_trim(*sp, 0); - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait_nodebug(hc); - return; - } - - hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize); - - if (f1 != f2) { - /* increment Z2,F2-counter */ - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F); - HFC_wait_nodebug(hc); - /* check size */ - if ((*sp)->len < 4) { - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG - "%s(card %d): Frame below minimum " - "size\n", __func__, hc->id + 1); - skb_trim(*sp, 0); - goto next_frame; - } - /* there is at least one complete frame, check crc */ - if ((*sp)->data[(*sp)->len - 1]) { - if (debug & DEBUG_HFCMULTI_CRC) - printk(KERN_DEBUG - "%s: CRC-error\n", __func__); - skb_trim(*sp, 0); - goto next_frame; - } - skb_trim(*sp, (*sp)->len - 3); - if ((*sp)->len < MISDN_COPY_SIZE) { - skb = *sp; - *sp = mI_alloc_skb(skb->len, GFP_ATOMIC); - if (*sp) { - memcpy(skb_put(*sp, skb->len), - skb->data, skb->len); - skb_trim(skb, 0); - } else { - printk(KERN_DEBUG "%s: No mem\n", - __func__); - *sp = skb; - skb = NULL; - } - } else { - skb = NULL; - } - if (debug & DEBUG_HFCMULTI_FIFO) { - printk(KERN_DEBUG "%s(card %d):", - __func__, hc->id + 1); - temp = 0; - while (temp < (*sp)->len) - printk(" %02x", (*sp)->data[temp++]); - printk("\n"); - } - if (dch) - recv_Dchannel(dch); - else - recv_Bchannel(bch); - *sp = skb; - again++; - goto next_frame; - } - /* there is an incomplete frame */ - } else { - /* transparent */ - if (Zsize > skb_tailroom(*sp)) - Zsize = skb_tailroom(*sp); - hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize); - if (((*sp)->len) < MISDN_COPY_SIZE) { - skb = *sp; - *sp = mI_alloc_skb(skb->len, GFP_ATOMIC); - if (*sp) { - memcpy(skb_put(*sp, skb->len), - skb->data, skb->len); - skb_trim(skb, 0); - } else { - printk(KERN_DEBUG "%s: No mem\n", __func__); - *sp = skb; - skb = NULL; - } - } else { - skb = NULL; - } - if (debug & DEBUG_HFCMULTI_FIFO) - printk(KERN_DEBUG - "%s(card %d): fifo(%d) reading %d bytes " - "(z1=%04x, z2=%04x) TRANS\n", - __func__, hc->id + 1, ch, Zsize, z1, z2); - /* only bch is transparent */ - recv_Bchannel(bch); - *sp = skb; - } -} - - -/* - * Interrupt handler - */ -static void -signal_state_up(struct dchannel *dch, int info, char *msg) -{ - struct sk_buff *skb; - int id, data = info; - - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG "%s: %s\n", __func__, msg); - - id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */ - - skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data, - GFP_ATOMIC); - if (!skb) - return; - recv_Dchannel_skb(dch, skb); -} - -static inline void -handle_timer_irq(struct hfc_multi *hc) -{ - int ch, temp; - struct dchannel *dch; - u_long flags; - - /* process queued resync jobs */ - if (hc->e1_resync) { - /* lock, so e1_resync gets not changed */ - spin_lock_irqsave(&HFClock, flags); - if (hc->e1_resync & 1) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "Enable SYNC_I\n"); - HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC); - /* disable JATT, if RX_SYNC is set */ - if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) - HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX); - } - if (hc->e1_resync & 2) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG "Enable jatt PLL\n"); - HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS); - } - if (hc->e1_resync & 4) { - if (debug & DEBUG_HFCMULTI_PLXSD) - printk(KERN_DEBUG - "Enable QUARTZ for HFC-E1\n"); - /* set jatt to quartz */ - HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC - | V_JATT_OFF); - /* switch to JATT, in case it is not already */ - HFC_outb(hc, R_SYNC_OUT, 0); - } - hc->e1_resync = 0; - spin_unlock_irqrestore(&HFClock, flags); - } - - if (hc->type != 1 || hc->e1_state == 1) - for (ch = 0; ch <= 31; ch++) { - if (hc->created[hc->chan[ch].port]) { - hfcmulti_tx(hc, ch); - /* fifo is started when switching to rx-fifo */ - hfcmulti_rx(hc, ch); - if (hc->chan[ch].dch && - hc->chan[ch].nt_timer > -1) { - dch = hc->chan[ch].dch; - if (!(--hc->chan[ch].nt_timer)) { - schedule_event(dch, - FLG_PHCHANGE); - if (debug & - DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG - "%s: nt_timer at " - "state %x\n", - __func__, - dch->state); - } - } - } - } - if (hc->type == 1 && hc->created[0]) { - dch = hc->chan[hc->dslot].dch; - if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { - /* LOS */ - temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS; - if (!temp && hc->chan[hc->dslot].los) - signal_state_up(dch, L1_SIGNAL_LOS_ON, - "LOS detected"); - if (temp && !hc->chan[hc->dslot].los) - signal_state_up(dch, L1_SIGNAL_LOS_OFF, - "LOS gone"); - hc->chan[hc->dslot].los = temp; - } - if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) { - /* AIS */ - temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS; - if (!temp && hc->chan[hc->dslot].ais) - signal_state_up(dch, L1_SIGNAL_AIS_ON, - "AIS detected"); - if (temp && !hc->chan[hc->dslot].ais) - signal_state_up(dch, L1_SIGNAL_AIS_OFF, - "AIS gone"); - hc->chan[hc->dslot].ais = temp; - } - if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) { - /* SLIP */ - temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX; - if (!temp && hc->chan[hc->dslot].slip_rx) - signal_state_up(dch, L1_SIGNAL_SLIP_RX, - " bit SLIP detected RX"); - hc->chan[hc->dslot].slip_rx = temp; - temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX; - if (!temp && hc->chan[hc->dslot].slip_tx) - signal_state_up(dch, L1_SIGNAL_SLIP_TX, - " bit SLIP detected TX"); - hc->chan[hc->dslot].slip_tx = temp; - } - if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) { - /* RDI */ - temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A; - if (!temp && hc->chan[hc->dslot].rdi) - signal_state_up(dch, L1_SIGNAL_RDI_ON, - "RDI detected"); - if (temp && !hc->chan[hc->dslot].rdi) - signal_state_up(dch, L1_SIGNAL_RDI_OFF, - "RDI gone"); - hc->chan[hc->dslot].rdi = temp; - } - temp = HFC_inb_nodebug(hc, R_JATT_DIR); - switch (hc->chan[hc->dslot].sync) { - case 0: - if ((temp & 0x60) == 0x60) { - if (debug & DEBUG_HFCMULTI_SYNC) - printk(KERN_DEBUG - "%s: (id=%d) E1 now " - "in clock sync\n", - __func__, hc->id); - HFC_outb(hc, R_RX_OFF, - hc->chan[hc->dslot].jitter | V_RX_INIT); - HFC_outb(hc, R_TX_OFF, - hc->chan[hc->dslot].jitter | V_RX_INIT); - hc->chan[hc->dslot].sync = 1; - goto check_framesync; - } - break; - case 1: - if ((temp & 0x60) != 0x60) { - if (debug & DEBUG_HFCMULTI_SYNC) - printk(KERN_DEBUG - "%s: (id=%d) E1 " - "lost clock sync\n", - __func__, hc->id); - hc->chan[hc->dslot].sync = 0; - break; - } -check_framesync: - temp = HFC_inb_nodebug(hc, R_SYNC_STA); - if (temp == 0x27) { - if (debug & DEBUG_HFCMULTI_SYNC) - printk(KERN_DEBUG - "%s: (id=%d) E1 " - "now in frame sync\n", - __func__, hc->id); - hc->chan[hc->dslot].sync = 2; - } - break; - case 2: - if ((temp & 0x60) != 0x60) { - if (debug & DEBUG_HFCMULTI_SYNC) - printk(KERN_DEBUG - "%s: (id=%d) E1 lost " - "clock & frame sync\n", - __func__, hc->id); - hc->chan[hc->dslot].sync = 0; - break; - } - temp = HFC_inb_nodebug(hc, R_SYNC_STA); - if (temp != 0x27) { - if (debug & DEBUG_HFCMULTI_SYNC) - printk(KERN_DEBUG - "%s: (id=%d) E1 " - "lost frame sync\n", - __func__, hc->id); - hc->chan[hc->dslot].sync = 1; - } - break; - } - } - - if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip)) - hfcmulti_watchdog(hc); - - if (hc->leds) - hfcmulti_leds(hc); -} - -static void -ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech) -{ - struct dchannel *dch; - int ch; - int active; - u_char st_status, temp; - - /* state machine */ - for (ch = 0; ch <= 31; ch++) { - if (hc->chan[ch].dch) { - dch = hc->chan[ch].dch; - if (r_irq_statech & 1) { - HFC_outb_nodebug(hc, R_ST_SEL, - hc->chan[ch].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - /* undocumented: status changes during read */ - st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE); - while (st_status != (temp = - HFC_inb_nodebug(hc, A_ST_RD_STATE))) { - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG "%s: reread " - "STATE because %d!=%d\n", - __func__, temp, - st_status); - st_status = temp; /* repeat */ - } - - /* Speech Design TE-sync indication */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && - dch->dev.D.protocol == ISDN_P_TE_S0) { - if (st_status & V_FR_SYNC_ST) - hc->syncronized |= - (1 << hc->chan[ch].port); - else - hc->syncronized &= - ~(1 << hc->chan[ch].port); - } - dch->state = st_status & 0x0f; - if (dch->dev.D.protocol == ISDN_P_NT_S0) - active = 3; - else - active = 7; - if (dch->state == active) { - HFC_outb_nodebug(hc, R_FIFO, - (ch << 1) | 1); - HFC_wait_nodebug(hc); - HFC_outb_nodebug(hc, - R_INC_RES_FIFO, V_RES_F); - HFC_wait_nodebug(hc); - dch->tx_idx = 0; - } - schedule_event(dch, FLG_PHCHANGE); - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG - "%s: S/T newstate %x port %d\n", - __func__, dch->state, - hc->chan[ch].port); - } - r_irq_statech >>= 1; - } - } - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) - plxsd_checksync(hc, 0); -} - -static void -fifo_irq(struct hfc_multi *hc, int block) -{ - int ch, j; - struct dchannel *dch; - struct bchannel *bch; - u_char r_irq_fifo_bl; - - r_irq_fifo_bl = HFC_inb_nodebug(hc, R_IRQ_FIFO_BL0 + block); - j = 0; - while (j < 8) { - ch = (block << 2) + (j >> 1); - dch = hc->chan[ch].dch; - bch = hc->chan[ch].bch; - if (((!dch) && (!bch)) || (!hc->created[hc->chan[ch].port])) { - j += 2; - continue; - } - if (dch && (r_irq_fifo_bl & (1 << j)) && - test_bit(FLG_ACTIVE, &dch->Flags)) { - hfcmulti_tx(hc, ch); - /* start fifo */ - HFC_outb_nodebug(hc, R_FIFO, 0); - HFC_wait_nodebug(hc); - } - if (bch && (r_irq_fifo_bl & (1 << j)) && - test_bit(FLG_ACTIVE, &bch->Flags)) { - hfcmulti_tx(hc, ch); - /* start fifo */ - HFC_outb_nodebug(hc, R_FIFO, 0); - HFC_wait_nodebug(hc); - } - j++; - if (dch && (r_irq_fifo_bl & (1 << j)) && - test_bit(FLG_ACTIVE, &dch->Flags)) { - hfcmulti_rx(hc, ch); - } - if (bch && (r_irq_fifo_bl & (1 << j)) && - test_bit(FLG_ACTIVE, &bch->Flags)) { - hfcmulti_rx(hc, ch); - } - j++; - } -} - -#ifdef IRQ_DEBUG -int irqsem; -#endif -static irqreturn_t -hfcmulti_interrupt(int intno, void *dev_id) -{ -#ifdef IRQCOUNT_DEBUG - static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0, - iq5 = 0, iq6 = 0, iqcnt = 0; -#endif - static int count; - struct hfc_multi *hc = dev_id; - struct dchannel *dch; - u_char r_irq_statech, status, r_irq_misc, r_irq_oview; - int i; - u_short *plx_acc, wval; - u_char e1_syncsta, temp; - u_long flags; - - if (!hc) { - printk(KERN_ERR "HFC-multi: Spurious interrupt!\n"); - return IRQ_NONE; - } - - spin_lock(&hc->lock); - -#ifdef IRQ_DEBUG - if (irqsem) - printk(KERN_ERR "irq for card %d during irq from " - "card %d, this is no bug.\n", hc->id + 1, irqsem); - irqsem = hc->id + 1; -#endif - - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - spin_lock_irqsave(&plx_lock, flags); - plx_acc = (u_short *)(hc->plx_membase + PLX_INTCSR); - wval = readw(plx_acc); - spin_unlock_irqrestore(&plx_lock, flags); - if (!(wval & PLX_INTCSR_LINTI1_STATUS)) - goto irq_notforus; - } - - status = HFC_inb_nodebug(hc, R_STATUS); - r_irq_statech = HFC_inb_nodebug(hc, R_IRQ_STATECH); -#ifdef IRQCOUNT_DEBUG - if (r_irq_statech) - iq1++; - if (status & V_DTMF_STA) - iq2++; - if (status & V_LOST_STA) - iq3++; - if (status & V_EXT_IRQSTA) - iq4++; - if (status & V_MISC_IRQSTA) - iq5++; - if (status & V_FR_IRQSTA) - iq6++; - if (iqcnt++ > 5000) { - printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n", - iq1, iq2, iq3, iq4, iq5, iq6); - iqcnt = 0; - } -#endif - if (!r_irq_statech && - !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA | - V_MISC_IRQSTA | V_FR_IRQSTA))) { - /* irq is not for us */ - goto irq_notforus; - } - hc->irqcnt++; - if (r_irq_statech) { - if (hc->type != 1) - ph_state_irq(hc, r_irq_statech); - } - if (status & V_EXT_IRQSTA) - ; /* external IRQ */ - if (status & V_LOST_STA) { - /* LOST IRQ */ - HFC_outb(hc, R_INC_RES_FIFO, V_RES_LOST); /* clear irq! */ - } - if (status & V_MISC_IRQSTA) { - /* misc IRQ */ - r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC); - if (r_irq_misc & V_STA_IRQ) { - if (hc->type == 1) { - /* state machine */ - dch = hc->chan[hc->dslot].dch; - e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA); - if (test_bit(HFC_CHIP_PLXSD, &hc->chip) - && hc->e1_getclock) { - if (e1_syncsta & V_FR_SYNC_E1) - hc->syncronized = 1; - else - hc->syncronized = 0; - } - /* undocumented: status changes during read */ - dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA); - while (dch->state != (temp = - HFC_inb_nodebug(hc, R_E1_RD_STA))) { - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG "%s: reread " - "STATE because %d!=%d\n", - __func__, temp, - dch->state); - dch->state = temp; /* repeat */ - } - dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA) - & 0x7; - schedule_event(dch, FLG_PHCHANGE); - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG - "%s: E1 (id=%d) newstate %x\n", - __func__, hc->id, dch->state); - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) - plxsd_checksync(hc, 0); - } - } - if (r_irq_misc & V_TI_IRQ) - handle_timer_irq(hc); - - if (r_irq_misc & V_DTMF_IRQ) { - /* -> DTMF IRQ */ - hfcmulti_dtmf(hc); - } - /* TODO: REPLACE !!!! 125 us Interrupts are not acceptable */ - if (r_irq_misc & V_IRQ_PROC) { - /* IRQ every 125us */ - count++; - /* generate 1kHz signal */ - if (count == 8) { - if (hfc_interrupt) - hfc_interrupt(); - count = 0; - } - } - - } - if (status & V_FR_IRQSTA) { - /* FIFO IRQ */ - r_irq_oview = HFC_inb_nodebug(hc, R_IRQ_OVIEW); - for (i = 0; i < 8; i++) { - if (r_irq_oview & (1 << i)) - fifo_irq(hc, i); - } - } - -#ifdef IRQ_DEBUG - irqsem = 0; -#endif - spin_unlock(&hc->lock); - return IRQ_HANDLED; - -irq_notforus: -#ifdef IRQ_DEBUG - irqsem = 0; -#endif - spin_unlock(&hc->lock); - return IRQ_NONE; -} - - -/* - * timer callback for D-chan busy resolution. Currently no function - */ - -static void -hfcmulti_dbusy_timer(struct hfc_multi *hc) -{ -} - - -/* - * activate/deactivate hardware for selected channels and mode - * - * configure B-channel with the given protocol - * ch eqals to the HFC-channel (0-31) - * ch is the number of channel (0-4,4-7,8-11,12-15,16-19,20-23,24-27,28-31 - * for S/T, 1-31 for E1) - * the hdlc interrupts will be set/unset - */ -static int -mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, - int bank_tx, int slot_rx, int bank_rx) -{ - int flow_tx = 0, flow_rx = 0, routing = 0; - int oslot_tx, oslot_rx; - int conf; - - if (ch < 0 || ch > 31) - return EINVAL; - oslot_tx = hc->chan[ch].slot_tx; - oslot_rx = hc->chan[ch].slot_rx; - conf = hc->chan[ch].conf; - - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG - "%s: card %d channel %d protocol %x slot old=%d new=%d " - "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n", - __func__, hc->id, ch, protocol, oslot_tx, slot_tx, - bank_tx, oslot_rx, slot_rx, bank_rx); - - if (oslot_tx >= 0 && slot_tx != oslot_tx) { - /* remove from slot */ - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG "%s: remove from slot %d (TX)\n", - __func__, oslot_tx); - if (hc->slot_owner[oslot_tx<<1] == ch) { - HFC_outb(hc, R_SLOT, oslot_tx << 1); - HFC_outb(hc, A_SL_CFG, 0); - HFC_outb(hc, A_CONF, 0); - hc->slot_owner[oslot_tx<<1] = -1; - } else { - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG - "%s: we are not owner of this tx slot " - "anymore, channel %d is.\n", - __func__, hc->slot_owner[oslot_tx<<1]); - } - } - - if (oslot_rx >= 0 && slot_rx != oslot_rx) { - /* remove from slot */ - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG - "%s: remove from slot %d (RX)\n", - __func__, oslot_rx); - if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) { - HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR); - HFC_outb(hc, A_SL_CFG, 0); - hc->slot_owner[(oslot_rx << 1) | 1] = -1; - } else { - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG - "%s: we are not owner of this rx slot " - "anymore, channel %d is.\n", - __func__, - hc->slot_owner[(oslot_rx << 1) | 1]); - } - } - - if (slot_tx < 0) { - flow_tx = 0x80; /* FIFO->ST */ - /* disable pcm slot */ - hc->chan[ch].slot_tx = -1; - hc->chan[ch].bank_tx = 0; - } else { - /* set pcm slot */ - if (hc->chan[ch].txpending) - flow_tx = 0x80; /* FIFO->ST */ - else - flow_tx = 0xc0; /* PCM->ST */ - /* put on slot */ - routing = bank_tx ? 0xc0 : 0x80; - if (conf >= 0 || bank_tx > 1) - routing = 0x40; /* loop */ - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG "%s: put channel %d to slot %d bank" - " %d flow %02x routing %02x conf %d (TX)\n", - __func__, ch, slot_tx, bank_tx, - flow_tx, routing, conf); - HFC_outb(hc, R_SLOT, slot_tx << 1); - HFC_outb(hc, A_SL_CFG, (ch<<1) | routing); - HFC_outb(hc, A_CONF, (conf < 0) ? 0 : (conf | V_CONF_SL)); - hc->slot_owner[slot_tx << 1] = ch; - hc->chan[ch].slot_tx = slot_tx; - hc->chan[ch].bank_tx = bank_tx; - } - if (slot_rx < 0) { - /* disable pcm slot */ - flow_rx = 0x80; /* ST->FIFO */ - hc->chan[ch].slot_rx = -1; - hc->chan[ch].bank_rx = 0; - } else { - /* set pcm slot */ - if (hc->chan[ch].txpending) - flow_rx = 0x80; /* ST->FIFO */ - else - flow_rx = 0xc0; /* ST->(FIFO,PCM) */ - /* put on slot */ - routing = bank_rx?0x80:0xc0; /* reversed */ - if (conf >= 0 || bank_rx > 1) - routing = 0x40; /* loop */ - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_DEBUG "%s: put channel %d to slot %d bank" - " %d flow %02x routing %02x conf %d (RX)\n", - __func__, ch, slot_rx, bank_rx, - flow_rx, routing, conf); - HFC_outb(hc, R_SLOT, (slot_rx<<1) | V_SL_DIR); - HFC_outb(hc, A_SL_CFG, (ch<<1) | V_CH_DIR | routing); - hc->slot_owner[(slot_rx<<1)|1] = ch; - hc->chan[ch].slot_rx = slot_rx; - hc->chan[ch].bank_rx = bank_rx; - } - - switch (protocol) { - case (ISDN_P_NONE): - /* disable TX fifo */ - HFC_outb(hc, R_FIFO, ch << 1); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | V_IFF); - HFC_outb(hc, A_SUBCH_CFG, 0); - HFC_outb(hc, A_IRQ_MSK, 0); - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait(hc); - /* disable RX fifo */ - HFC_outb(hc, R_FIFO, (ch<<1)|1); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00); - HFC_outb(hc, A_SUBCH_CFG, 0); - HFC_outb(hc, A_IRQ_MSK, 0); - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait(hc); - if (hc->chan[ch].bch && hc->type != 1) { - hc->hw.a_st_ctrl0[hc->chan[ch].port] &= - ((ch & 0x3) == 0)? ~V_B1_EN: ~V_B2_EN; - HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_CTRL0, - hc->hw.a_st_ctrl0[hc->chan[ch].port]); - } - if (hc->chan[ch].bch) { - test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); - test_and_clear_bit(FLG_TRANSPARENT, - &hc->chan[ch].bch->Flags); - } - break; - case (ISDN_P_B_RAW): /* B-channel */ - - if (test_bit(HFC_CHIP_B410P, &hc->chip) && - (hc->chan[ch].slot_rx < 0) && - (hc->chan[ch].slot_tx < 0)) { - - printk(KERN_DEBUG - "Setting B-channel %d to echo cancelable " - "state on PCM slot %d\n", ch, - ((ch / 4) * 8) + ((ch % 4) * 4) + 1); - printk(KERN_DEBUG - "Enabling pass through for channel\n"); - vpm_out(hc, ch, ((ch / 4) * 8) + - ((ch % 4) * 4) + 1, 0x01); - /* rx path */ - /* S/T -> PCM */ - HFC_outb(hc, R_FIFO, (ch << 1)); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF); - HFC_outb(hc, R_SLOT, (((ch / 4) * 8) + - ((ch % 4) * 4) + 1) << 1); - HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1)); - - /* PCM -> FIFO */ - HFC_outb(hc, R_FIFO, 0x20 | (ch << 1) | 1); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF); - HFC_outb(hc, A_SUBCH_CFG, 0); - HFC_outb(hc, A_IRQ_MSK, 0); - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait(hc); - HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) + - ((ch % 4) * 4) + 1) << 1) | 1); - HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1); - - /* tx path */ - /* PCM -> S/T */ - HFC_outb(hc, R_FIFO, (ch << 1) | 1); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF); - HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) + - ((ch % 4) * 4)) << 1) | 1); - HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1); - - /* FIFO -> PCM */ - HFC_outb(hc, R_FIFO, 0x20 | (ch << 1)); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF); - HFC_outb(hc, A_SUBCH_CFG, 0); - HFC_outb(hc, A_IRQ_MSK, 0); - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait(hc); - /* tx silence */ - HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); - HFC_outb(hc, R_SLOT, (((ch / 4) * 8) + - ((ch % 4) * 4)) << 1); - HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1)); - } else { - /* enable TX fifo */ - HFC_outb(hc, R_FIFO, ch << 1); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | - V_HDLC_TRP | V_IFF); - HFC_outb(hc, A_SUBCH_CFG, 0); - HFC_outb(hc, A_IRQ_MSK, 0); - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait(hc); - /* tx silence */ - HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); - /* enable RX fifo */ - HFC_outb(hc, R_FIFO, (ch<<1)|1); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | V_HDLC_TRP); - HFC_outb(hc, A_SUBCH_CFG, 0); - HFC_outb(hc, A_IRQ_MSK, 0); - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait(hc); - } - if (hc->type != 1) { - hc->hw.a_st_ctrl0[hc->chan[ch].port] |= - ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN; - HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_CTRL0, - hc->hw.a_st_ctrl0[hc->chan[ch].port]); - } - if (hc->chan[ch].bch) - test_and_set_bit(FLG_TRANSPARENT, - &hc->chan[ch].bch->Flags); - break; - case (ISDN_P_B_HDLC): /* B-channel */ - case (ISDN_P_TE_S0): /* D-channel */ - case (ISDN_P_NT_S0): - case (ISDN_P_TE_E1): - case (ISDN_P_NT_E1): - /* enable TX fifo */ - HFC_outb(hc, R_FIFO, ch<<1); - HFC_wait(hc); - if (hc->type == 1 || hc->chan[ch].bch) { - /* E1 or B-channel */ - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04); - HFC_outb(hc, A_SUBCH_CFG, 0); - } else { - /* D-Channel without HDLC fill flags */ - HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04 | V_IFF); - HFC_outb(hc, A_SUBCH_CFG, 2); - } - HFC_outb(hc, A_IRQ_MSK, V_IRQ); - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait(hc); - /* enable RX fifo */ - HFC_outb(hc, R_FIFO, (ch<<1)|1); - HFC_wait(hc); - HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04); - if (hc->type == 1 || hc->chan[ch].bch) - HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */ - else - HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */ - HFC_outb(hc, A_IRQ_MSK, V_IRQ); - HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait(hc); - if (hc->chan[ch].bch) { - test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); - if (hc->type != 1) { - hc->hw.a_st_ctrl0[hc->chan[ch].port] |= - ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN; - HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_CTRL0, - hc->hw.a_st_ctrl0[hc->chan[ch].port]); - } - } - break; - default: - printk(KERN_DEBUG "%s: protocol not known %x\n", - __func__, protocol); - hc->chan[ch].protocol = ISDN_P_NONE; - return -ENOPROTOOPT; - } - hc->chan[ch].protocol = protocol; - return 0; -} - - -/* - * connect/disconnect PCM - */ - -static void -hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx, - int slot_rx, int bank_rx) -{ - if (slot_rx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) { - /* disable PCM */ - mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0); - return; - } - - /* enable pcm */ - mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx, - slot_rx, bank_rx); -} - -/* - * set/disable conference - */ - -static void -hfcmulti_conf(struct hfc_multi *hc, int ch, int num) -{ - if (num >= 0 && num <= 7) - hc->chan[ch].conf = num; - else - hc->chan[ch].conf = -1; - mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx, - hc->chan[ch].bank_tx, hc->chan[ch].slot_rx, - hc->chan[ch].bank_rx); -} - - -/* - * set/disable sample loop - */ - -/* NOTE: this function is experimental and therefore disabled */ - -/* - * Layer 1 callback function - */ -static int -hfcm_l1callback(struct dchannel *dch, u_int cmd) -{ - struct hfc_multi *hc = dch->hw; - u_long flags; - - switch (cmd) { - case INFO3_P8: - case INFO3_P10: - break; - case HW_RESET_REQ: - /* start activation */ - spin_lock_irqsave(&hc->lock, flags); - if (hc->type == 1) { - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG - "%s: HW_RESET_REQ no BRI\n", - __func__); - } else { - HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */ - udelay(6); /* wait at least 5,21us */ - HFC_outb(hc, A_ST_WR_STATE, 3); - HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT*3)); - /* activate */ - } - spin_unlock_irqrestore(&hc->lock, flags); - l1_event(dch->l1, HW_POWERUP_IND); - break; - case HW_DEACT_REQ: - /* start deactivation */ - spin_lock_irqsave(&hc->lock, flags); - if (hc->type == 1) { - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG - "%s: HW_DEACT_REQ no BRI\n", - __func__); - } else { - HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT*2); - /* deactivate */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - hc->syncronized &= - ~(1 << hc->chan[dch->slot].port); - plxsd_checksync(hc, 0); - } - } - skb_queue_purge(&dch->squeue); - if (dch->tx_skb) { - dev_kfree_skb(dch->tx_skb); - dch->tx_skb = NULL; - } - dch->tx_idx = 0; - if (dch->rx_skb) { - dev_kfree_skb(dch->rx_skb); - dch->rx_skb = NULL; - } - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) - del_timer(&dch->timer); - spin_unlock_irqrestore(&hc->lock, flags); - break; - case HW_POWERUP_REQ: - spin_lock_irqsave(&hc->lock, flags); - if (hc->type == 1) { - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG - "%s: HW_POWERUP_REQ no BRI\n", - __func__); - } else { - HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_WR_STATE, 3 | 0x10); /* activate */ - udelay(6); /* wait at least 5,21us */ - HFC_outb(hc, A_ST_WR_STATE, 3); /* activate */ - } - spin_unlock_irqrestore(&hc->lock, flags); - break; - case PH_ACTIVATE_IND: - test_and_set_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, - GFP_ATOMIC); - break; - case PH_DEACTIVATE_IND: - test_and_clear_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, - GFP_ATOMIC); - break; - default: - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: unknown command %x\n", - __func__, cmd); - return -1; - } - return 0; -} - -/* - * Layer2 -> Layer 1 Transfer - */ - -static int -handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); - struct dchannel *dch = container_of(dev, struct dchannel, dev); - struct hfc_multi *hc = dch->hw; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - int ret = -EINVAL; - unsigned int id; - u_long flags; - - switch (hh->prim) { - case PH_DATA_REQ: - if (skb->len < 1) - break; - spin_lock_irqsave(&hc->lock, flags); - ret = dchannel_senddata(dch, skb); - if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ - hfcmulti_tx(hc, dch->slot); - ret = 0; - /* start fifo */ - HFC_outb(hc, R_FIFO, 0); - HFC_wait(hc); - spin_unlock_irqrestore(&hc->lock, flags); - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&hc->lock, flags); - return ret; - case PH_ACTIVATE_REQ: - if (dch->dev.D.protocol != ISDN_P_TE_S0) { - spin_lock_irqsave(&hc->lock, flags); - ret = 0; - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG - "%s: PH_ACTIVATE port %d (0..%d)\n", - __func__, hc->chan[dch->slot].port, - hc->ports-1); - /* start activation */ - if (hc->type == 1) { - ph_state_change(dch); - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG - "%s: E1 report state %x \n", - __func__, dch->state); - } else { - HFC_outb(hc, R_ST_SEL, - hc->chan[dch->slot].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1); - /* G1 */ - udelay(6); /* wait at least 5,21us */ - HFC_outb(hc, A_ST_WR_STATE, 1); - HFC_outb(hc, A_ST_WR_STATE, 1 | - (V_ST_ACT*3)); /* activate */ - dch->state = 1; - } - spin_unlock_irqrestore(&hc->lock, flags); - } else - ret = l1_event(dch->l1, hh->prim); - break; - case PH_DEACTIVATE_REQ: - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); - if (dch->dev.D.protocol != ISDN_P_TE_S0) { - spin_lock_irqsave(&hc->lock, flags); - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG - "%s: PH_DEACTIVATE port %d (0..%d)\n", - __func__, hc->chan[dch->slot].port, - hc->ports-1); - /* start deactivation */ - if (hc->type == 1) { - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG - "%s: PH_DEACTIVATE no BRI\n", - __func__); - } else { - HFC_outb(hc, R_ST_SEL, - hc->chan[dch->slot].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2); - /* deactivate */ - dch->state = 1; - } - skb_queue_purge(&dch->squeue); - if (dch->tx_skb) { - dev_kfree_skb(dch->tx_skb); - dch->tx_skb = NULL; - } - dch->tx_idx = 0; - if (dch->rx_skb) { - dev_kfree_skb(dch->rx_skb); - dch->rx_skb = NULL; - } - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) - del_timer(&dch->timer); -#ifdef FIXME - if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) - dchannel_sched_event(&hc->dch, D_CLEARBUSY); -#endif - ret = 0; - spin_unlock_irqrestore(&hc->lock, flags); - } else - ret = l1_event(dch->l1, hh->prim); - break; - } - if (!ret) - dev_kfree_skb(skb); - return ret; -} - -static void -deactivate_bchannel(struct bchannel *bch) -{ - struct hfc_multi *hc = bch->hw; - u_long flags; - - spin_lock_irqsave(&hc->lock, flags); - if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) { - dev_kfree_skb(bch->next_skb); - bch->next_skb = NULL; - } - if (bch->tx_skb) { - dev_kfree_skb(bch->tx_skb); - bch->tx_skb = NULL; - } - bch->tx_idx = 0; - if (bch->rx_skb) { - dev_kfree_skb(bch->rx_skb); - bch->rx_skb = NULL; - } - hc->chan[bch->slot].coeff_count = 0; - test_and_clear_bit(FLG_ACTIVE, &bch->Flags); - test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); - hc->chan[bch->slot].rx_off = 0; - hc->chan[bch->slot].conf = -1; - mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0); - spin_unlock_irqrestore(&hc->lock, flags); -} - -static int -handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct bchannel *bch = container_of(ch, struct bchannel, ch); - struct hfc_multi *hc = bch->hw; - int ret = -EINVAL; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned int id; - u_long flags; - - switch (hh->prim) { - case PH_DATA_REQ: - if (!skb->len) - break; - spin_lock_irqsave(&hc->lock, flags); - ret = bchannel_senddata(bch, skb); - if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ - hfcmulti_tx(hc, bch->slot); - ret = 0; - /* start fifo */ - HFC_outb_nodebug(hc, R_FIFO, 0); - HFC_wait_nodebug(hc); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) { - spin_unlock_irqrestore(&hc->lock, flags); - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&hc->lock, flags); - } else - spin_unlock_irqrestore(&hc->lock, flags); - return ret; - case PH_ACTIVATE_REQ: - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n", - __func__, bch->slot); - spin_lock_irqsave(&hc->lock, flags); - /* activate B-channel if not already activated */ - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) { - hc->chan[bch->slot].txpending = 0; - ret = mode_hfcmulti(hc, bch->slot, - ch->protocol, - hc->chan[bch->slot].slot_tx, - hc->chan[bch->slot].bank_tx, - hc->chan[bch->slot].slot_rx, - hc->chan[bch->slot].bank_rx); - if (!ret) { - if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf - && test_bit(HFC_CHIP_DTMF, &hc->chip)) { - /* start decoder */ - hc->dtmf = 1; - if (debug & DEBUG_HFCMULTI_DTMF) - printk(KERN_DEBUG - "%s: start dtmf decoder\n", - __func__); - HFC_outb(hc, R_DTMF, hc->hw.r_dtmf | - V_RST_DTMF); - } - } - } else - ret = 0; - spin_unlock_irqrestore(&hc->lock, flags); - if (!ret) - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL, - GFP_KERNEL); - break; - case PH_CONTROL_REQ: - spin_lock_irqsave(&hc->lock, flags); - switch (hh->id) { - case HFC_SPL_LOOP_ON: /* set sample loop */ - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG - "%s: HFC_SPL_LOOP_ON (len = %d)\n", - __func__, skb->len); - ret = 0; - break; - case HFC_SPL_LOOP_OFF: /* set silence */ - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n", - __func__); - ret = 0; - break; - default: - printk(KERN_ERR - "%s: unknown PH_CONTROL_REQ info %x\n", - __func__, hh->id); - ret = -EINVAL; - } - spin_unlock_irqrestore(&hc->lock, flags); - break; - case PH_DEACTIVATE_REQ: - deactivate_bchannel(bch); /* locked there */ - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL, - GFP_KERNEL); - ret = 0; - break; - } - if (!ret) - dev_kfree_skb(skb); - return ret; -} - -/* - * bchannel control function - */ -static int -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) -{ - int ret = 0; - struct dsp_features *features = - (struct dsp_features *)(*((u_long *)&cq->p1)); - struct hfc_multi *hc = bch->hw; - int slot_tx; - int bank_tx; - int slot_rx; - int bank_rx; - int num; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP - | MISDN_CTRL_RX_OFF; - break; - case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ - hc->chan[bch->slot].rx_off = !!cq->p1; - if (!hc->chan[bch->slot].rx_off) { - /* reset fifo on rx on */ - HFC_outb_nodebug(hc, R_FIFO, (bch->slot << 1) | 1); - HFC_wait_nodebug(hc); - HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); - HFC_wait_nodebug(hc); - } - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n", - __func__, bch->nr, hc->chan[bch->slot].rx_off); - break; - case MISDN_CTRL_HW_FEATURES: /* fill features structure */ - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: HW_FEATURE request\n", - __func__); - /* create confirm */ - features->hfc_id = hc->id; - if (test_bit(HFC_CHIP_DTMF, &hc->chip)) - features->hfc_dtmf = 1; - features->hfc_loops = 0; - if (test_bit(HFC_CHIP_B410P, &hc->chip)) { - features->hfc_echocanhw = 1; - } else { - features->pcm_id = hc->pcm; - features->pcm_slots = hc->slots; - features->pcm_banks = 2; - } - break; - case MISDN_CTRL_HFC_PCM_CONN: /* connect to pcm timeslot (0..N) */ - slot_tx = cq->p1 & 0xff; - bank_tx = cq->p1 >> 8; - slot_rx = cq->p2 & 0xff; - bank_rx = cq->p2 >> 8; - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG - "%s: HFC_PCM_CONN slot %d bank %d (TX) " - "slot %d bank %d (RX)\n", - __func__, slot_tx, bank_tx, - slot_rx, bank_rx); - if (slot_tx < hc->slots && bank_tx <= 2 && - slot_rx < hc->slots && bank_rx <= 2) - hfcmulti_pcm(hc, bch->slot, - slot_tx, bank_tx, slot_rx, bank_rx); - else { - printk(KERN_WARNING - "%s: HFC_PCM_CONN slot %d bank %d (TX) " - "slot %d bank %d (RX) out of range\n", - __func__, slot_tx, bank_tx, - slot_rx, bank_rx); - ret = -EINVAL; - } - break; - case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */ - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: HFC_PCM_DISC\n", - __func__); - hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0); - break; - case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */ - num = cq->p1 & 0xff; - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n", - __func__, num); - if (num <= 7) - hfcmulti_conf(hc, bch->slot, num); - else { - printk(KERN_WARNING - "%s: HW_CONF_JOIN conf %d out of range\n", - __func__, num); - ret = -EINVAL; - } - break; - case MISDN_CTRL_HFC_CONF_SPLIT: /* split conference */ - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: HFC_CONF_SPLIT\n", __func__); - hfcmulti_conf(hc, bch->slot, -1); - break; - case MISDN_CTRL_HFC_ECHOCAN_ON: - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: HFC_ECHOCAN_ON\n", __func__); - if (test_bit(HFC_CHIP_B410P, &hc->chip)) - vpm_echocan_on(hc, bch->slot, cq->p1); - else - ret = -EINVAL; - break; - - case MISDN_CTRL_HFC_ECHOCAN_OFF: - if (debug & DEBUG_HFCMULTI_MSG) - printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n", - __func__); - if (test_bit(HFC_CHIP_B410P, &hc->chip)) - vpm_echocan_off(hc, bch->slot); - else - ret = -EINVAL; - break; - default: - printk(KERN_WARNING "%s: unknown Op %x\n", - __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; -} - -static int -hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct bchannel *bch = container_of(ch, struct bchannel, ch); - struct hfc_multi *hc = bch->hw; - int err = -EINVAL; - u_long flags; - - if (bch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: cmd:%x %p\n", - __func__, cmd, arg); - switch (cmd) { - case CLOSE_CHANNEL: - test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) - deactivate_bchannel(bch); /* locked there */ - ch->protocol = ISDN_P_NONE; - ch->peer = NULL; - module_put(THIS_MODULE); - err = 0; - break; - case CONTROL_CHANNEL: - spin_lock_irqsave(&hc->lock, flags); - err = channel_bctrl(bch, arg); - spin_unlock_irqrestore(&hc->lock, flags); - break; - default: - printk(KERN_WARNING "%s: unknown prim(%x)\n", - __func__, cmd); - } - return err; -} - -/* - * handle D-channel events - * - * handle state change event - */ -static void -ph_state_change(struct dchannel *dch) -{ - struct hfc_multi *hc = dch->hw; - int ch, i; - - if (!dch) { - printk(KERN_WARNING "%s: ERROR given dch is NULL\n", - __func__); - return; - } - ch = dch->slot; - - if (hc->type == 1) { - if (dch->dev.D.protocol == ISDN_P_TE_E1) { - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG - "%s: E1 TE (id=%d) newstate %x\n", - __func__, hc->id, dch->state); - } else { - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG - "%s: E1 NT (id=%d) newstate %x\n", - __func__, hc->id, dch->state); - } - switch (dch->state) { - case (1): - if (hc->e1_state != 1) { - for (i = 1; i <= 31; i++) { - /* reset fifos on e1 activation */ - HFC_outb_nodebug(hc, R_FIFO, (i << 1) | 1); - HFC_wait_nodebug(hc); - HFC_outb_nodebug(hc, - R_INC_RES_FIFO, V_RES_F); - HFC_wait_nodebug(hc); - } - } - test_and_set_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); - break; - - default: - if (hc->e1_state != 1) - return; - test_and_clear_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); - } - hc->e1_state = dch->state; - } else { - if (dch->dev.D.protocol == ISDN_P_TE_S0) { - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG - "%s: S/T TE newstate %x\n", - __func__, dch->state); - switch (dch->state) { - case (0): - l1_event(dch->l1, HW_RESET_IND); - break; - case (3): - l1_event(dch->l1, HW_DEACT_IND); - break; - case (5): - case (8): - l1_event(dch->l1, ANYSIGNAL); - break; - case (6): - l1_event(dch->l1, INFO2); - break; - case (7): - l1_event(dch->l1, INFO4_P8); - break; - } - } else { - if (debug & DEBUG_HFCMULTI_STATE) - printk(KERN_DEBUG "%s: S/T NT newstate %x\n", - __func__, dch->state); - switch (dch->state) { - case (2): - if (hc->chan[ch].nt_timer == 0) { - hc->chan[ch].nt_timer = -1; - HFC_outb(hc, R_ST_SEL, - hc->chan[ch].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - HFC_outb(hc, A_ST_WR_STATE, 4 | - V_ST_LD_STA); /* G4 */ - udelay(6); /* wait at least 5,21us */ - HFC_outb(hc, A_ST_WR_STATE, 4); - dch->state = 4; - } else { - /* one extra count for the next event */ - hc->chan[ch].nt_timer = - nt_t1_count[poll_timer] + 1; - HFC_outb(hc, R_ST_SEL, - hc->chan[ch].port); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - /* allow G2 -> G3 transition */ - HFC_outb(hc, A_ST_WR_STATE, 2 | - V_SET_G2_G3); - } - break; - case (1): - hc->chan[ch].nt_timer = -1; - test_and_clear_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); - break; - case (4): - hc->chan[ch].nt_timer = -1; - break; - case (3): - hc->chan[ch].nt_timer = -1; - test_and_set_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); - break; - } - } - } -} - -/* - * called for card mode init message - */ - -static void -hfcmulti_initmode(struct dchannel *dch) -{ - struct hfc_multi *hc = dch->hw; - u_char a_st_wr_state, r_e1_wr_sta; - int i, pt; - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: entered\n", __func__); - - if (hc->type == 1) { - hc->chan[hc->dslot].slot_tx = -1; - hc->chan[hc->dslot].slot_rx = -1; - hc->chan[hc->dslot].conf = -1; - if (hc->dslot) { - mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol, - -1, 0, -1, 0); - dch->timer.function = (void *) hfcmulti_dbusy_timer; - dch->timer.data = (long) dch; - init_timer(&dch->timer); - } - for (i = 1; i <= 31; i++) { - if (i == hc->dslot) - continue; - hc->chan[i].slot_tx = -1; - hc->chan[i].slot_rx = -1; - hc->chan[i].conf = -1; - mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0); - } - /* E1 */ - if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { - HFC_outb(hc, R_LOS0, 255); /* 2 ms */ - HFC_outb(hc, R_LOS1, 255); /* 512 ms */ - } - if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) { - HFC_outb(hc, R_RX0, 0); - hc->hw.r_tx0 = 0 | V_OUT_EN; - } else { - HFC_outb(hc, R_RX0, 1); - hc->hw.r_tx0 = 1 | V_OUT_EN; - } - hc->hw.r_tx1 = V_ATX | V_NTRI; - HFC_outb(hc, R_TX0, hc->hw.r_tx0); - HFC_outb(hc, R_TX1, hc->hw.r_tx1); - HFC_outb(hc, R_TX_FR0, 0x00); - HFC_outb(hc, R_TX_FR1, 0xf8); - - if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg)) - HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E); - - HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0); - - if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg)) - HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC); - - if (dch->dev.D.protocol == ISDN_P_NT_E1) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: E1 port is NT-mode\n", - __func__); - r_e1_wr_sta = 0; /* G0 */ - hc->e1_getclock = 0; - } else { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: E1 port is TE-mode\n", - __func__); - r_e1_wr_sta = 0; /* F0 */ - hc->e1_getclock = 1; - } - if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) - HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX); - else - HFC_outb(hc, R_SYNC_OUT, 0); - if (test_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip)) - hc->e1_getclock = 1; - if (test_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip)) - hc->e1_getclock = 0; - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { - /* SLAVE (clock master) */ - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: E1 port is clock master " - "(clock from PCM)\n", __func__); - HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC); - } else { - if (hc->e1_getclock) { - /* MASTER (clock slave) */ - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: E1 port is clock slave " - "(clock to PCM)\n", __func__); - HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS); - } else { - /* MASTER (clock master) */ - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: E1 port is " - "clock master " - "(clock from QUARTZ)\n", - __func__); - HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | - V_PCM_SYNC | V_JATT_OFF); - HFC_outb(hc, R_SYNC_OUT, 0); - } - } - HFC_outb(hc, R_JATT_ATT, 0x9c); /* undoc register */ - HFC_outb(hc, R_PWM_MD, V_PWM0_MD); - HFC_outb(hc, R_PWM0, 0x50); - HFC_outb(hc, R_PWM1, 0xff); - /* state machine setup */ - HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta | V_E1_LD_STA); - udelay(6); /* wait at least 5,21us */ - HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta); - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - hc->syncronized = 0; - plxsd_checksync(hc, 0); - } - } else { - i = dch->slot; - hc->chan[i].slot_tx = -1; - hc->chan[i].slot_rx = -1; - hc->chan[i].conf = -1; - mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0); - dch->timer.function = (void *)hfcmulti_dbusy_timer; - dch->timer.data = (long) dch; - init_timer(&dch->timer); - hc->chan[i - 2].slot_tx = -1; - hc->chan[i - 2].slot_rx = -1; - hc->chan[i - 2].conf = -1; - mode_hfcmulti(hc, i - 2, ISDN_P_NONE, -1, 0, -1, 0); - hc->chan[i - 1].slot_tx = -1; - hc->chan[i - 1].slot_rx = -1; - hc->chan[i - 1].conf = -1; - mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0); - /* ST */ - pt = hc->chan[i].port; - /* select interface */ - HFC_outb(hc, R_ST_SEL, pt); - /* undocumented: delay after R_ST_SEL */ - udelay(1); - if (dch->dev.D.protocol == ISDN_P_NT_S0) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: ST port %d is NT-mode\n", - __func__, pt); - /* clock delay */ - HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt); - a_st_wr_state = 1; /* G1 */ - hc->hw.a_st_ctrl0[pt] = V_ST_MD; - } else { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: ST port %d is TE-mode\n", - __func__, pt); - /* clock delay */ - HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te); - a_st_wr_state = 2; /* F2 */ - hc->hw.a_st_ctrl0[pt] = 0; - } - if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg)) - hc->hw.a_st_ctrl0[pt] |= V_TX_LI; - /* line setup */ - HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]); - /* disable E-channel */ - if ((dch->dev.D.protocol == ISDN_P_NT_S0) || - test_bit(HFC_CFG_DIS_ECHANNEL, &hc->chan[i].cfg)) - HFC_outb(hc, A_ST_CTRL1, V_E_IGNO); - else - HFC_outb(hc, A_ST_CTRL1, 0); - /* enable B-channel receive */ - HFC_outb(hc, A_ST_CTRL2, V_B1_RX_EN | V_B2_RX_EN); - /* state machine setup */ - HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state | V_ST_LD_STA); - udelay(6); /* wait at least 5,21us */ - HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state); - hc->hw.r_sci_msk |= 1 << pt; - /* state machine interrupts */ - HFC_outb(hc, R_SCI_MSK, hc->hw.r_sci_msk); - /* unset sync on port */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - hc->syncronized &= - ~(1 << hc->chan[dch->slot].port); - plxsd_checksync(hc, 0); - } - } - if (debug & DEBUG_HFCMULTI_INIT) - printk("%s: done\n", __func__); -} - - -static int -open_dchannel(struct hfc_multi *hc, struct dchannel *dch, - struct channel_req *rq) -{ - int err = 0; - u_long flags; - - if (debug & DEBUG_HW_OPEN) - printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__, - dch->dev.id, __builtin_return_address(0)); - if (rq->protocol == ISDN_P_NONE) - return -EINVAL; - if ((dch->dev.D.protocol != ISDN_P_NONE) && - (dch->dev.D.protocol != rq->protocol)) { - if (debug & DEBUG_HFCMULTI_MODE) - printk(KERN_WARNING "%s: change protocol %x to %x\n", - __func__, dch->dev.D.protocol, rq->protocol); - } - if ((dch->dev.D.protocol == ISDN_P_TE_S0) - && (rq->protocol != ISDN_P_TE_S0)) - l1_event(dch->l1, CLOSE_CHANNEL); - if (dch->dev.D.protocol != rq->protocol) { - if (rq->protocol == ISDN_P_TE_S0) { - err = create_l1(dch, hfcm_l1callback); - if (err) - return err; - } - dch->dev.D.protocol = rq->protocol; - spin_lock_irqsave(&hc->lock, flags); - hfcmulti_initmode(dch); - spin_unlock_irqrestore(&hc->lock, flags); - } - - if (((rq->protocol == ISDN_P_NT_S0) && (dch->state == 3)) || - ((rq->protocol == ISDN_P_TE_S0) && (dch->state == 7)) || - ((rq->protocol == ISDN_P_NT_E1) && (dch->state == 1)) || - ((rq->protocol == ISDN_P_TE_E1) && (dch->state == 1))) { - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, - 0, NULL, GFP_KERNEL); - } - rq->ch = &dch->dev.D; - if (!try_module_get(THIS_MODULE)) - printk(KERN_WARNING "%s:cannot get module\n", __func__); - return 0; -} - -static int -open_bchannel(struct hfc_multi *hc, struct dchannel *dch, - struct channel_req *rq) -{ - struct bchannel *bch; - int ch; - - if (!test_bit(rq->adr.channel, &dch->dev.channelmap[0])) - return -EINVAL; - if (rq->protocol == ISDN_P_NONE) - return -EINVAL; - if (hc->type == 1) - ch = rq->adr.channel; - else - ch = (rq->adr.channel - 1) + (dch->slot - 2); - bch = hc->chan[ch].bch; - if (!bch) { - printk(KERN_ERR "%s:internal error ch %d has no bch\n", - __func__, ch); - return -EINVAL; - } - if (test_and_set_bit(FLG_OPEN, &bch->Flags)) - return -EBUSY; /* b-channel can be only open once */ - bch->ch.protocol = rq->protocol; - hc->chan[ch].rx_off = 0; - rq->ch = &bch->ch; - if (!try_module_get(THIS_MODULE)) - printk(KERN_WARNING "%s:cannot get module\n", __func__); - return 0; -} - -/* - * device control function - */ -static int -channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) -{ - int ret = 0; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = 0; - break; - default: - printk(KERN_WARNING "%s: unknown Op %x\n", - __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; -} - -static int -hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); - struct dchannel *dch = container_of(dev, struct dchannel, dev); - struct hfc_multi *hc = dch->hw; - struct channel_req *rq; - int err = 0; - u_long flags; - - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: cmd:%x %p\n", - __func__, cmd, arg); - switch (cmd) { - case OPEN_CHANNEL: - rq = arg; - switch (rq->protocol) { - case ISDN_P_TE_S0: - case ISDN_P_NT_S0: - if (hc->type == 1) { - err = -EINVAL; - break; - } - err = open_dchannel(hc, dch, rq); /* locked there */ - break; - case ISDN_P_TE_E1: - case ISDN_P_NT_E1: - if (hc->type != 1) { - err = -EINVAL; - break; - } - err = open_dchannel(hc, dch, rq); /* locked there */ - break; - default: - spin_lock_irqsave(&hc->lock, flags); - err = open_bchannel(hc, dch, rq); - spin_unlock_irqrestore(&hc->lock, flags); - } - break; - case CLOSE_CHANNEL: - if (debug & DEBUG_HW_OPEN) - printk(KERN_DEBUG "%s: dev(%d) close from %p\n", - __func__, dch->dev.id, - __builtin_return_address(0)); - module_put(THIS_MODULE); - break; - case CONTROL_CHANNEL: - spin_lock_irqsave(&hc->lock, flags); - err = channel_dctrl(dch, arg); - spin_unlock_irqrestore(&hc->lock, flags); - break; - default: - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: unknown command %x\n", - __func__, cmd); - err = -EINVAL; - } - return err; -} - -/* - * initialize the card - */ - -/* - * start timer irq, wait some time and check if we have interrupts. - * if not, reset chip and try again. - */ -static int -init_card(struct hfc_multi *hc) -{ - int err = -EIO; - u_long flags; - u_short *plx_acc; - u_long plx_flags; - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: entered\n", __func__); - - spin_lock_irqsave(&hc->lock, flags); - /* set interrupts but leave global interrupt disabled */ - hc->hw.r_irq_ctrl = V_FIFO_IRQ; - disable_hwirq(hc); - spin_unlock_irqrestore(&hc->lock, flags); - - if (request_irq(hc->pci_dev->irq, hfcmulti_interrupt, IRQF_SHARED, - "HFC-multi", hc)) { - printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n", - hc->pci_dev->irq); - return -EIO; - } - hc->irq = hc->pci_dev->irq; - - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - spin_lock_irqsave(&plx_lock, plx_flags); - plx_acc = (u_short *)(hc->plx_membase+PLX_INTCSR); - writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE), - plx_acc); /* enable PCI & LINT1 irq */ - spin_unlock_irqrestore(&plx_lock, plx_flags); - } - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: IRQ %d count %d\n", - __func__, hc->irq, hc->irqcnt); - err = init_chip(hc); - if (err) - goto error; - /* - * Finally enable IRQ output - * this is only allowed, if an IRQ routine is allready - * established for this HFC, so don't do that earlier - */ - spin_lock_irqsave(&hc->lock, flags); - enable_hwirq(hc); - spin_unlock_irqrestore(&hc->lock, flags); - /* printk(KERN_DEBUG "no master irq set!!!\n"); */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((100*HZ)/1000); /* Timeout 100ms */ - /* turn IRQ off until chip is completely initialized */ - spin_lock_irqsave(&hc->lock, flags); - disable_hwirq(hc); - spin_unlock_irqrestore(&hc->lock, flags); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: IRQ %d count %d\n", - __func__, hc->irq, hc->irqcnt); - if (hc->irqcnt) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: done\n", __func__); - - return 0; - } - if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { - printk(KERN_INFO "ignoring missing interrupts\n"); - return 0; - } - - printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n", - hc->irq); - - err = -EIO; - -error: - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - spin_lock_irqsave(&plx_lock, plx_flags); - plx_acc = (u_short *)(hc->plx_membase+PLX_INTCSR); - writew(0x00, plx_acc); /*disable IRQs*/ - spin_unlock_irqrestore(&plx_lock, plx_flags); - } - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: free irq %d\n", __func__, hc->irq); - if (hc->irq) { - free_irq(hc->irq, hc); - hc->irq = 0; - } - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: done (err=%d)\n", __func__, err); - return err; -} - -/* - * find pci device and set it up - */ - -static int -setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct hm_map *m = (struct hm_map *)ent->driver_data; - - printk(KERN_INFO - "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n", - m->vendor_name, m->card_name, m->clock2 ? "double" : "normal"); - - hc->pci_dev = pdev; - if (m->clock2) - test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip); - - if (ent->device == 0xB410) { - test_and_set_bit(HFC_CHIP_B410P, &hc->chip); - test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip); - test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); - hc->slots = 32; - } - - if (hc->pci_dev->irq <= 0) { - printk(KERN_WARNING "HFC-multi: No IRQ for PCI card found.\n"); - return -EIO; - } - if (pci_enable_device(hc->pci_dev)) { - printk(KERN_WARNING "HFC-multi: Error enabling PCI card.\n"); - return -EIO; - } - hc->leds = m->leds; - hc->ledstate = 0xAFFEAFFE; - hc->opticalsupport = m->opticalsupport; - - /* set memory access methods */ - if (m->io_mode) /* use mode from card config */ - hc->io_mode = m->io_mode; - switch (hc->io_mode) { - case HFC_IO_MODE_PLXSD: - test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip); - hc->slots = 128; /* required */ - /* fall through */ - case HFC_IO_MODE_PCIMEM: - hc->HFC_outb = HFC_outb_pcimem; - hc->HFC_inb = HFC_inb_pcimem; - hc->HFC_inw = HFC_inw_pcimem; - hc->HFC_wait = HFC_wait_pcimem; - hc->read_fifo = read_fifo_pcimem; - hc->write_fifo = write_fifo_pcimem; - break; - case HFC_IO_MODE_REGIO: - hc->HFC_outb = HFC_outb_regio; - hc->HFC_inb = HFC_inb_regio; - hc->HFC_inw = HFC_inw_regio; - hc->HFC_wait = HFC_wait_regio; - hc->read_fifo = read_fifo_regio; - hc->write_fifo = write_fifo_regio; - break; - default: - printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - hc->HFC_outb_nodebug = hc->HFC_outb; - hc->HFC_inb_nodebug = hc->HFC_inb; - hc->HFC_inw_nodebug = hc->HFC_inw; - hc->HFC_wait_nodebug = hc->HFC_wait; -#ifdef HFC_REGISTER_DEBUG - hc->HFC_outb = HFC_outb_debug; - hc->HFC_inb = HFC_inb_debug; - hc->HFC_inw = HFC_inw_debug; - hc->HFC_wait = HFC_wait_debug; -#endif - hc->pci_iobase = 0; - hc->pci_membase = NULL; - hc->plx_membase = NULL; - - switch (hc->io_mode) { - case HFC_IO_MODE_PLXSD: - hc->plx_origmembase = hc->pci_dev->resource[0].start; - /* MEMBASE 1 is PLX PCI Bridge */ - - if (!hc->plx_origmembase) { - printk(KERN_WARNING - "HFC-multi: No IO-Memory for PCI PLX bridge found\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - - hc->plx_membase = ioremap(hc->plx_origmembase, 0x80); - if (!hc->plx_membase) { - printk(KERN_WARNING - "HFC-multi: failed to remap plx address space. " - "(internal error)\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - printk(KERN_INFO - "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n", - (u_long)hc->plx_membase, hc->plx_origmembase); - - hc->pci_origmembase = hc->pci_dev->resource[2].start; - /* MEMBASE 1 is PLX PCI Bridge */ - if (!hc->pci_origmembase) { - printk(KERN_WARNING - "HFC-multi: No IO-Memory for PCI card found\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - - hc->pci_membase = ioremap(hc->pci_origmembase, 0x400); - if (!hc->pci_membase) { - printk(KERN_WARNING "HFC-multi: failed to remap io " - "address space. (internal error)\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - - printk(KERN_INFO - "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d " - "leds-type %d\n", - hc->id, (u_long)hc->pci_membase, hc->pci_origmembase, - hc->pci_dev->irq, HZ, hc->leds); - pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); - break; - case HFC_IO_MODE_PCIMEM: - hc->pci_origmembase = hc->pci_dev->resource[1].start; - if (!hc->pci_origmembase) { - printk(KERN_WARNING - "HFC-multi: No IO-Memory for PCI card found\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - - hc->pci_membase = ioremap(hc->pci_origmembase, 256); - if (!hc->pci_membase) { - printk(KERN_WARNING - "HFC-multi: failed to remap io address space. " - "(internal error)\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d " - "HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase, - hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds); - pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); - break; - case HFC_IO_MODE_REGIO: - hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start; - if (!hc->pci_iobase) { - printk(KERN_WARNING - "HFC-multi: No IO for PCI card found\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - - if (!request_region(hc->pci_iobase, 8, "hfcmulti")) { - printk(KERN_WARNING "HFC-multi: failed to request " - "address space at 0x%08lx (internal error)\n", - hc->pci_iobase); - pci_disable_device(hc->pci_dev); - return -EIO; - } - - printk(KERN_INFO - "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n", - m->vendor_name, m->card_name, (u_int) hc->pci_iobase, - hc->pci_dev->irq, HZ, hc->leds); - pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO); - break; - default: - printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); - pci_disable_device(hc->pci_dev); - return -EIO; - } - - pci_set_drvdata(hc->pci_dev, hc); - - /* At this point the needed PCI config is done */ - /* fifos are still not enabled */ - return 0; -} - - -/* - * remove port - */ - -static void -release_port(struct hfc_multi *hc, struct dchannel *dch) -{ - int pt, ci, i = 0; - u_long flags; - struct bchannel *pb; - - ci = dch->slot; - pt = hc->chan[ci].port; - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: entered for port %d\n", - __func__, pt + 1); - - if (pt >= hc->ports) { - printk(KERN_WARNING "%s: ERROR port out of range (%d).\n", - __func__, pt + 1); - return; - } - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: releasing port=%d\n", - __func__, pt + 1); - - if (dch->dev.D.protocol == ISDN_P_TE_S0) - l1_event(dch->l1, CLOSE_CHANNEL); - - hc->chan[ci].dch = NULL; - - if (hc->created[pt]) { - hc->created[pt] = 0; - mISDN_unregister_device(&dch->dev); - } - - spin_lock_irqsave(&hc->lock, flags); - - if (dch->timer.function) { - del_timer(&dch->timer); - dch->timer.function = NULL; - } - - if (hc->type == 1) { /* E1 */ - /* remove sync */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - hc->syncronized = 0; - plxsd_checksync(hc, 1); - } - /* free channels */ - for (i = 0; i <= 31; i++) { - if (hc->chan[i].bch) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: free port %d channel %d\n", - __func__, hc->chan[i].port+1, i); - pb = hc->chan[i].bch; - hc->chan[i].bch = NULL; - spin_unlock_irqrestore(&hc->lock, flags); - mISDN_freebchannel(pb); - kfree(pb); - kfree(hc->chan[i].coeff); - spin_lock_irqsave(&hc->lock, flags); - } - } - } else { - /* remove sync */ - if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { - hc->syncronized &= - ~(1 << hc->chan[ci].port); - plxsd_checksync(hc, 1); - } - /* free channels */ - if (hc->chan[ci - 2].bch) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: free port %d channel %d\n", - __func__, hc->chan[ci - 2].port+1, - ci - 2); - pb = hc->chan[ci - 2].bch; - hc->chan[ci - 2].bch = NULL; - spin_unlock_irqrestore(&hc->lock, flags); - mISDN_freebchannel(pb); - kfree(pb); - kfree(hc->chan[ci - 2].coeff); - spin_lock_irqsave(&hc->lock, flags); - } - if (hc->chan[ci - 1].bch) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: free port %d channel %d\n", - __func__, hc->chan[ci - 1].port+1, - ci - 1); - pb = hc->chan[ci - 1].bch; - hc->chan[ci - 1].bch = NULL; - spin_unlock_irqrestore(&hc->lock, flags); - mISDN_freebchannel(pb); - kfree(pb); - kfree(hc->chan[ci - 1].coeff); - spin_lock_irqsave(&hc->lock, flags); - } - } - - spin_unlock_irqrestore(&hc->lock, flags); - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: free port %d channel D\n", __func__, pt); - mISDN_freedchannel(dch); - kfree(dch); - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: done!\n", __func__); -} - -static void -release_card(struct hfc_multi *hc) -{ - u_long flags; - int ch; - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: release card (%d) entered\n", - __func__, hc->id); - - spin_lock_irqsave(&hc->lock, flags); - disable_hwirq(hc); - spin_unlock_irqrestore(&hc->lock, flags); - - udelay(1000); - - /* dimm leds */ - if (hc->leds) - hfcmulti_leds(hc); - - /* disable D-channels & B-channels */ - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: disable all channels (d and b)\n", - __func__); - for (ch = 0; ch <= 31; ch++) { - if (hc->chan[ch].dch) - release_port(hc, hc->chan[ch].dch); - } - - /* release hardware & irq */ - if (hc->irq) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: free irq %d\n", - __func__, hc->irq); - free_irq(hc->irq, hc); - hc->irq = 0; - - } - release_io_hfcmulti(hc); - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: remove instance from list\n", - __func__); - list_del(&hc->list); - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: delete instance\n", __func__); - if (hc == syncmaster) - syncmaster = NULL; - kfree(hc); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_WARNING "%s: card successfully removed\n", - __func__); -} - -static int -init_e1_port(struct hfc_multi *hc, struct hm_map *m) -{ - struct dchannel *dch; - struct bchannel *bch; - int ch, ret = 0; - char name[MISDN_MAX_IDLEN]; - - dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); - if (!dch) - return -ENOMEM; - dch->debug = debug; - mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change); - dch->hw = hc; - dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1); - dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); - dch->dev.D.send = handle_dmsg; - dch->dev.D.ctrl = hfcm_dctrl; - dch->dev.nrbchan = (hc->dslot)?30:31; - dch->slot = hc->dslot; - hc->chan[hc->dslot].dch = dch; - hc->chan[hc->dslot].port = 0; - hc->chan[hc->dslot].nt_timer = -1; - for (ch = 1; ch <= 31; ch++) { - if (ch == hc->dslot) /* skip dchannel */ - continue; - bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); - if (!bch) { - printk(KERN_ERR "%s: no memory for bchannel\n", - __func__); - ret = -ENOMEM; - goto free_chan; - } - hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL); - if (!hc->chan[ch].coeff) { - printk(KERN_ERR "%s: no memory for coeffs\n", - __func__); - ret = -ENOMEM; - goto free_chan; - } - bch->nr = ch; - bch->slot = ch; - bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM); - bch->hw = hc; - bch->ch.send = handle_bmsg; - bch->ch.ctrl = hfcm_bctrl; - bch->ch.nr = ch; - list_add(&bch->ch.list, &dch->dev.bchannels); - hc->chan[ch].bch = bch; - hc->chan[ch].port = 0; - test_and_set_bit(bch->nr, &dch->dev.channelmap[0]); - } - /* set optical line type */ - if (port[Port_cnt] & 0x001) { - if (!m->opticalsupport) { - printk(KERN_INFO - "This board has no optical " - "support\n"); - } else { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: PORT set optical " - "interfacs: card(%d) " - "port(%d)\n", - __func__, - HFC_cnt + 1, 1); - test_and_set_bit(HFC_CFG_OPTICAL, - &hc->chan[hc->dslot].cfg); - } - } - /* set LOS report */ - if (port[Port_cnt] & 0x004) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: PORT set " - "LOS report: card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - test_and_set_bit(HFC_CFG_REPORT_LOS, - &hc->chan[hc->dslot].cfg); - } - /* set AIS report */ - if (port[Port_cnt] & 0x008) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: PORT set " - "AIS report: card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - test_and_set_bit(HFC_CFG_REPORT_AIS, - &hc->chan[hc->dslot].cfg); - } - /* set SLIP report */ - if (port[Port_cnt] & 0x010) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: PORT set SLIP report: " - "card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - test_and_set_bit(HFC_CFG_REPORT_SLIP, - &hc->chan[hc->dslot].cfg); - } - /* set RDI report */ - if (port[Port_cnt] & 0x020) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: PORT set RDI report: " - "card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - test_and_set_bit(HFC_CFG_REPORT_RDI, - &hc->chan[hc->dslot].cfg); - } - /* set CRC-4 Mode */ - if (!(port[Port_cnt] & 0x100)) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: PORT turn on CRC4 report:" - " card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - test_and_set_bit(HFC_CFG_CRC4, - &hc->chan[hc->dslot].cfg); - } else { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: PORT turn off CRC4" - " report: card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - } - /* set forced clock */ - if (port[Port_cnt] & 0x0200) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: PORT force getting clock from " - "E1: card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip); - } else - if (port[Port_cnt] & 0x0400) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: PORT force putting clock to " - "E1: card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip); - } - /* set JATT PLL */ - if (port[Port_cnt] & 0x0800) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: PORT disable JATT PLL on " - "E1: card(%d) port(%d)\n", - __func__, HFC_cnt + 1, 1); - test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip); - } - /* set elastic jitter buffer */ - if (port[Port_cnt] & 0x3000) { - hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3; - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: PORT set elastic " - "buffer to %d: card(%d) port(%d)\n", - __func__, hc->chan[hc->dslot].jitter, - HFC_cnt + 1, 1); - } else - hc->chan[hc->dslot].jitter = 2; /* default */ - snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1); - ret = mISDN_register_device(&dch->dev, name); - if (ret) - goto free_chan; - hc->created[0] = 1; - return ret; -free_chan: - release_port(hc, dch); - return ret; -} - -static int -init_multi_port(struct hfc_multi *hc, int pt) -{ - struct dchannel *dch; - struct bchannel *bch; - int ch, i, ret = 0; - char name[MISDN_MAX_IDLEN]; - - dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); - if (!dch) - return -ENOMEM; - dch->debug = debug; - mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change); - dch->hw = hc; - dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0); - dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); - dch->dev.D.send = handle_dmsg; - dch->dev.D.ctrl = hfcm_dctrl; - dch->dev.nrbchan = 2; - i = pt << 2; - dch->slot = i + 2; - hc->chan[i + 2].dch = dch; - hc->chan[i + 2].port = pt; - hc->chan[i + 2].nt_timer = -1; - for (ch = 0; ch < dch->dev.nrbchan; ch++) { - bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); - if (!bch) { - printk(KERN_ERR "%s: no memory for bchannel\n", - __func__); - ret = -ENOMEM; - goto free_chan; - } - hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL); - if (!hc->chan[i + ch].coeff) { - printk(KERN_ERR "%s: no memory for coeffs\n", - __func__); - ret = -ENOMEM; - goto free_chan; - } - bch->nr = ch + 1; - bch->slot = i + ch; - bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM); - bch->hw = hc; - bch->ch.send = handle_bmsg; - bch->ch.ctrl = hfcm_bctrl; - bch->ch.nr = ch + 1; - list_add(&bch->ch.list, &dch->dev.bchannels); - hc->chan[i + ch].bch = bch; - hc->chan[i + ch].port = pt; - test_and_set_bit(bch->nr, &dch->dev.channelmap[0]); - } - /* set master clock */ - if (port[Port_cnt] & 0x001) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: PROTOCOL set master clock: " - "card(%d) port(%d)\n", - __func__, HFC_cnt + 1, pt + 1); - if (dch->dev.D.protocol != ISDN_P_TE_S0) { - printk(KERN_ERR "Error: Master clock " - "for port(%d) of card(%d) is only" - " possible with TE-mode\n", - pt + 1, HFC_cnt + 1); - ret = -EINVAL; - goto free_chan; - } - if (hc->masterclk >= 0) { - printk(KERN_ERR "Error: Master clock " - "for port(%d) of card(%d) already " - "defined for port(%d)\n", - pt + 1, HFC_cnt + 1, hc->masterclk+1); - ret = -EINVAL; - goto free_chan; - } - hc->masterclk = pt; - } - /* set transmitter line to non capacitive */ - if (port[Port_cnt] & 0x002) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: PROTOCOL set non capacitive " - "transmitter: card(%d) port(%d)\n", - __func__, HFC_cnt + 1, pt + 1); - test_and_set_bit(HFC_CFG_NONCAP_TX, - &hc->chan[i + 2].cfg); - } - /* disable E-channel */ - if (port[Port_cnt] & 0x004) { - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: PROTOCOL disable E-channel: " - "card(%d) port(%d)\n", - __func__, HFC_cnt + 1, pt + 1); - test_and_set_bit(HFC_CFG_DIS_ECHANNEL, - &hc->chan[i + 2].cfg); - } - snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d/%d", - hc->type, HFC_cnt + 1, pt + 1); - ret = mISDN_register_device(&dch->dev, name); - if (ret) - goto free_chan; - hc->created[pt] = 1; - return ret; -free_chan: - release_port(hc, dch); - return ret; -} - -static int -hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct hm_map *m = (struct hm_map *)ent->driver_data; - int ret_err = 0; - int pt; - struct hfc_multi *hc; - u_long flags; - u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */ - - if (HFC_cnt >= MAX_CARDS) { - printk(KERN_ERR "too many cards (max=%d).\n", - MAX_CARDS); - return -EINVAL; - } - if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) { - printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but " - "type[%d] %d was supplied as module parameter\n", - m->vendor_name, m->card_name, m->type, HFC_cnt, - type[HFC_cnt] & 0xff); - printk(KERN_WARNING "HFC-MULTI: Load module without parameters " - "first, to see cards and their types."); - return -EINVAL; - } - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n", - __func__, m->vendor_name, m->card_name, m->type, - type[HFC_cnt]); - - /* allocate card+fifo structure */ - hc = kzalloc(sizeof(struct hfc_multi), GFP_KERNEL); - if (!hc) { - printk(KERN_ERR "No kmem for HFC-Multi card\n"); - return -ENOMEM; - } - spin_lock_init(&hc->lock); - hc->mtyp = m; - hc->type = m->type; - hc->ports = m->ports; - hc->id = HFC_cnt; - hc->pcm = pcm[HFC_cnt]; - hc->io_mode = iomode[HFC_cnt]; - if (dslot[HFC_cnt] < 0) { - hc->dslot = 0; - printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " - "31 B-channels\n"); - } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32) { - hc->dslot = dslot[HFC_cnt]; - printk(KERN_INFO "HFC-E1 card has alternating D-channel on " - "time slot %d\n", dslot[HFC_cnt]); - } else - hc->dslot = 16; - - /* set chip specific features */ - hc->masterclk = -1; - if (type[HFC_cnt] & 0x100) { - test_and_set_bit(HFC_CHIP_ULAW, &hc->chip); - silence = 0xff; /* ulaw silence */ - } else - silence = 0x2a; /* alaw silence */ - if (!(type[HFC_cnt] & 0x200)) - test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); - - if (type[HFC_cnt] & 0x800) - test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); - if (type[HFC_cnt] & 0x1000) { - test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip); - test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); - } - if (type[HFC_cnt] & 0x4000) - test_and_set_bit(HFC_CHIP_EXRAM_128, &hc->chip); - if (type[HFC_cnt] & 0x8000) - test_and_set_bit(HFC_CHIP_EXRAM_512, &hc->chip); - hc->slots = 32; - if (type[HFC_cnt] & 0x10000) - hc->slots = 64; - if (type[HFC_cnt] & 0x20000) - hc->slots = 128; - if (type[HFC_cnt] & 0x80000) { - test_and_set_bit(HFC_CHIP_WATCHDOG, &hc->chip); - hc->wdcount = 0; - hc->wdbyte = V_GPIO_OUT2; - printk(KERN_NOTICE "Watchdog enabled\n"); - } - - /* setup pci, hc->slots may change due to PLXSD */ - ret_err = setup_pci(hc, pdev, ent); - if (ret_err) { - if (hc == syncmaster) - syncmaster = NULL; - kfree(hc); - return ret_err; - } - - /* crate channels */ - for (pt = 0; pt < hc->ports; pt++) { - if (Port_cnt >= MAX_PORTS) { - printk(KERN_ERR "too many ports (max=%d).\n", - MAX_PORTS); - ret_err = -EINVAL; - goto free_card; - } - if (hc->type == 1) - ret_err = init_e1_port(hc, m); - else - ret_err = init_multi_port(hc, pt); - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG - "%s: Registering D-channel, card(%d) port(%d)" - "result %d\n", - __func__, HFC_cnt + 1, pt, ret_err); - - if (ret_err) { - while (pt) { /* release already registered ports */ - pt--; - release_port(hc, hc->chan[(pt << 2) + 2].dch); - } - goto free_card; - } - Port_cnt++; - } - - /* disp switches */ - switch (m->dip_type) { - case DIP_4S: - /* - * get DIP Setting for beroNet 1S/2S/4S cards - * check if Port Jumper config matches - * module param 'protocol' - * DIP Setting: (collect GPIO 13/14/15 (R_GPIO_IN1) + - * GPI 19/23 (R_GPI_IN2)) - */ - dips = ((~HFC_inb(hc, R_GPIO_IN1) & 0xE0) >> 5) | - ((~HFC_inb(hc, R_GPI_IN2) & 0x80) >> 3) | - (~HFC_inb(hc, R_GPI_IN2) & 0x08); - - /* Port mode (TE/NT) jumpers */ - pmj = ((HFC_inb(hc, R_GPI_IN3) >> 4) & 0xf); - - if (test_bit(HFC_CHIP_B410P, &hc->chip)) - pmj = ~pmj & 0xf; - - printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n", - m->vendor_name, m->card_name, dips, pmj); - break; - case DIP_8S: - /* - * get DIP Setting for beroNet 8S0+ cards - * - * enable PCI auxbridge function - */ - HFC_outb(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK); - /* prepare access to auxport */ - outw(0x4000, hc->pci_iobase + 4); - /* - * some dummy reads are required to - * read valid DIP switch data - */ - dips = inb(hc->pci_iobase); - dips = inb(hc->pci_iobase); - dips = inb(hc->pci_iobase); - dips = ~inb(hc->pci_iobase) & 0x3F; - outw(0x0, hc->pci_iobase + 4); - /* disable PCI auxbridge function */ - HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); - printk(KERN_INFO "%s: %s DIPs(0x%x)\n", - m->vendor_name, m->card_name, dips); - break; - case DIP_E1: - /* - * get DIP Setting for beroNet E1 cards - * DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0) - */ - dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0)>>4; - printk(KERN_INFO "%s: %s DIPs(0x%x)\n", - m->vendor_name, m->card_name, dips); - break; - } - - /* add to list */ - spin_lock_irqsave(&HFClock, flags); - list_add_tail(&hc->list, &HFClist); - spin_unlock_irqrestore(&HFClock, flags); - - /* initialize hardware */ - ret_err = init_card(hc); - if (ret_err) { - printk(KERN_ERR "init card returns %d\n", ret_err); - release_card(hc); - return ret_err; - } - - /* start IRQ and return */ - spin_lock_irqsave(&hc->lock, flags); - enable_hwirq(hc); - spin_unlock_irqrestore(&hc->lock, flags); - return 0; - -free_card: - release_io_hfcmulti(hc); - if (hc == syncmaster) - syncmaster = NULL; - kfree(hc); - return ret_err; -} - -static void __devexit hfc_remove_pci(struct pci_dev *pdev) -{ - struct hfc_multi *card = pci_get_drvdata(pdev); - u_long flags; - - if (debug) - printk(KERN_INFO "removing hfc_multi card vendor:%x " - "device:%x subvendor:%x subdevice:%x\n", - pdev->vendor, pdev->device, - pdev->subsystem_vendor, pdev->subsystem_device); - - if (card) { - spin_lock_irqsave(&HFClock, flags); - release_card(card); - spin_unlock_irqrestore(&HFClock, flags); - } else { - if (debug) - printk(KERN_WARNING "%s: drvdata allready removed\n", - __func__); - } -} - -#define VENDOR_CCD "Cologne Chip AG" -#define VENDOR_BN "beroNet GmbH" -#define VENDOR_DIG "Digium Inc." -#define VENDOR_JH "Junghanns.NET GmbH" -#define VENDOR_PRIM "PrimuX" - -static const struct hm_map hfcm_map[] = { -/*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0}, -/*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S}, -/*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0}, -/*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0}, -/*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0}, -/*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0}, -/*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, 0, 0}, -/*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0}, -/*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO}, -/*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0}, -/*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0}, -/*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0}, - -/*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0}, -/*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S, - HFC_IO_MODE_REGIO}, -/*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0}, -/*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0}, - -/*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0}, -/*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0}, -/*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0}, - -/*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0}, -/*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0}, -/*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0}, -/*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0}, - -/*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0}, -/*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0}, -/*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0}, - -/*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0, - HFC_IO_MODE_PLXSD}, -/*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0, - HFC_IO_MODE_PLXSD}, -/*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0}, -/*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0}, -/*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0}, -}; - -#undef H -#define H(x) ((unsigned long)&hfcm_map[x]) -static struct pci_device_id hfmultipci_ids[] __devinitdata = { - - /* Cards with HFC-4S Chip */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */ - { PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, - PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)}, - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)}, - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */ - - /* Cards with HFC-8S Chip */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, - PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, - /* IOB8ST Recording */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */ - - - /* Cards with HFC-E1 Chip */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */ - - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, - PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */ - - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */ - { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD, - PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_ANY_ID, PCI_ANY_ID, - 0, 0, 0}, - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_ANY_ID, PCI_ANY_ID, - 0, 0, 0}, - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_ANY_ID, PCI_ANY_ID, - 0, 0, 0}, - {0, } -}; -#undef H - -MODULE_DEVICE_TABLE(pci, hfmultipci_ids); - -static int -hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct hm_map *m = (struct hm_map *)ent->driver_data; - int ret; - - if (m == NULL) { - if (ent->vendor == PCI_VENDOR_ID_CCD) - if (ent->device == PCI_DEVICE_ID_CCD_HFC4S || - ent->device == PCI_DEVICE_ID_CCD_HFC8S || - ent->device == PCI_DEVICE_ID_CCD_HFCE1) - printk(KERN_ERR - "unknown HFC multiport controller " - "(vendor:%x device:%x subvendor:%x " - "subdevice:%x) Please contact the " - "driver maintainer for support.\n", - ent->vendor, ent->device, - ent->subvendor, ent->subdevice); - return -ENODEV; - } - ret = hfcmulti_init(pdev, ent); - if (ret) - return ret; - HFC_cnt++; - printk(KERN_INFO "%d devices registered\n", HFC_cnt); - return 0; -} - -static struct pci_driver hfcmultipci_driver = { - .name = "hfc_multi", - .probe = hfcmulti_probe, - .remove = __devexit_p(hfc_remove_pci), - .id_table = hfmultipci_ids, -}; - -static void __exit -HFCmulti_cleanup(void) -{ - struct hfc_multi *card, *next; - - /* unload interrupt function symbol */ - if (hfc_interrupt) - symbol_put(ztdummy_extern_interrupt); - if (register_interrupt) - symbol_put(ztdummy_register_interrupt); - if (unregister_interrupt) { - if (interrupt_registered) { - interrupt_registered = 0; - unregister_interrupt(); - } - symbol_put(ztdummy_unregister_interrupt); - } - - list_for_each_entry_safe(card, next, &HFClist, list) - release_card(card); - /* get rid of all devices of this driver */ - pci_unregister_driver(&hfcmultipci_driver); -} - -static int __init -HFCmulti_init(void) -{ - int err; - -#ifdef IRQ_DEBUG - printk(KERN_ERR "%s: IRQ_DEBUG IS ENABLED!\n", __func__); -#endif - - spin_lock_init(&HFClock); - spin_lock_init(&plx_lock); - - if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: init entered\n", __func__); - -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - hfc_interrupt = symbol_get(ztdummy_extern_interrupt); - register_interrupt = symbol_get(ztdummy_register_interrupt); - unregister_interrupt = symbol_get(ztdummy_unregister_interrupt); - printk(KERN_INFO "mISDN: HFC-multi driver %s\n", - hfcmulti_revision); - - switch (poll) { - case 0: - poll_timer = 6; - poll = 128; - break; - /* - * wenn dieses break nochmal verschwindet, - * gibt es heisse ohren :-) - * "without the break you will get hot ears ???" - */ - case 8: - poll_timer = 2; - break; - case 16: - poll_timer = 3; - break; - case 32: - poll_timer = 4; - break; - case 64: - poll_timer = 5; - break; - case 128: - poll_timer = 6; - break; - case 256: - poll_timer = 7; - break; - default: - printk(KERN_ERR - "%s: Wrong poll value (%d).\n", __func__, poll); - err = -EINVAL; - return err; - - } - - err = pci_register_driver(&hfcmultipci_driver); - if (err < 0) { - printk(KERN_ERR "error registering pci driver: %x\n", err); - if (hfc_interrupt) - symbol_put(ztdummy_extern_interrupt); - if (register_interrupt) - symbol_put(ztdummy_register_interrupt); - if (unregister_interrupt) { - if (interrupt_registered) { - interrupt_registered = 0; - unregister_interrupt(); - } - symbol_put(ztdummy_unregister_interrupt); - } - return err; - } - return 0; -} - - -module_init(HFCmulti_init); -module_exit(HFCmulti_cleanup); diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcpci.c b/trunk/drivers/isdn/hardware/mISDN/hfcpci.c deleted file mode 100644 index 917968530e1e..000000000000 --- a/trunk/drivers/isdn/hardware/mISDN/hfcpci.c +++ /dev/null @@ -1,2256 +0,0 @@ -/* - * - * hfcpci.c low level driver for CCD's hfc-pci based cards - * - * Author Werner Cornelius (werner@isdn4linux.de) - * based on existing driver for CCD hfc ISA cards - * type approval valid for HFC-S PCI A based card - * - * Copyright 1999 by Werner Cornelius (werner@isdn-development.de) - * Copyright 2008 by Karsten Keil - * - * 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 -#include - -#include "hfc_pci.h" - -static const char *hfcpci_revision = "2.0"; - -#define MAX_CARDS 8 -static int HFC_cnt; -static uint debug; - -MODULE_AUTHOR("Karsten Keil"); -MODULE_LICENSE("GPL"); -module_param(debug, uint, 0); - -static LIST_HEAD(HFClist); -DEFINE_RWLOCK(HFClock); - -enum { - HFC_CCD_2BD0, - HFC_CCD_B000, - HFC_CCD_B006, - HFC_CCD_B007, - HFC_CCD_B008, - HFC_CCD_B009, - HFC_CCD_B00A, - HFC_CCD_B00B, - HFC_CCD_B00C, - HFC_CCD_B100, - HFC_CCD_B700, - HFC_CCD_B701, - HFC_ASUS_0675, - HFC_BERKOM_A1T, - HFC_BERKOM_TCONCEPT, - HFC_ANIGMA_MC145575, - HFC_ZOLTRIX_2BD0, - HFC_DIGI_DF_M_IOM2_E, - HFC_DIGI_DF_M_E, - HFC_DIGI_DF_M_IOM2_A, - HFC_DIGI_DF_M_A, - HFC_ABOCOM_2BD1, - HFC_SITECOM_DC105V2, -}; - -struct hfcPCI_hw { - unsigned char cirm; - unsigned char ctmt; - unsigned char clkdel; - unsigned char states; - unsigned char conn; - unsigned char mst_m; - unsigned char int_m1; - unsigned char int_m2; - unsigned char sctrl; - unsigned char sctrl_r; - unsigned char sctrl_e; - unsigned char trm; - unsigned char fifo_en; - unsigned char bswapped; - unsigned char protocol; - int nt_timer; - unsigned char *pci_io; /* start of PCI IO memory */ - dma_addr_t dmahandle; - void *fifos; /* FIFO memory */ - int last_bfifo_cnt[2]; - /* marker saving last b-fifo frame count */ - struct timer_list timer; -}; - -#define HFC_CFG_MASTER 1 -#define HFC_CFG_SLAVE 2 -#define HFC_CFG_PCM 3 -#define HFC_CFG_2HFC 4 -#define HFC_CFG_SLAVEHFC 5 -#define HFC_CFG_NEG_F0 6 -#define HFC_CFG_SW_DD_DU 7 - -#define FLG_HFC_TIMER_T1 16 -#define FLG_HFC_TIMER_T3 17 - -#define NT_T1_COUNT 1120 /* number of 3.125ms interrupts (3.5s) */ -#define NT_T3_COUNT 31 /* number of 3.125ms interrupts (97 ms) */ -#define CLKDEL_TE 0x0e /* CLKDEL in TE mode */ -#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */ - - -struct hfc_pci { - struct list_head list; - u_char subtype; - u_char chanlimit; - u_char initdone; - u_long cfg; - u_int irq; - u_int irqcnt; - struct pci_dev *pdev; - struct hfcPCI_hw hw; - spinlock_t lock; /* card lock */ - struct dchannel dch; - struct bchannel bch[2]; -}; - -/* Interface functions */ -static void -enable_hwirq(struct hfc_pci *hc) -{ - hc->hw.int_m2 |= HFCPCI_IRQ_ENABLE; - Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2); -} - -static void -disable_hwirq(struct hfc_pci *hc) -{ - hc->hw.int_m2 &= ~((u_char)HFCPCI_IRQ_ENABLE); - Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2); -} - -/* - * free hardware resources used by driver - */ -static void -release_io_hfcpci(struct hfc_pci *hc) -{ - /* disable memory mapped ports + busmaster */ - pci_write_config_word(hc->pdev, PCI_COMMAND, 0); - del_timer(&hc->hw.timer); - pci_free_consistent(hc->pdev, 0x8000, hc->hw.fifos, hc->hw.dmahandle); - iounmap((void *)hc->hw.pci_io); -} - -/* - * set mode (NT or TE) - */ -static void -hfcpci_setmode(struct hfc_pci *hc) -{ - if (hc->hw.protocol == ISDN_P_NT_S0) { - hc->hw.clkdel = CLKDEL_NT; /* ST-Bit delay for NT-Mode */ - hc->hw.sctrl |= SCTRL_MODE_NT; /* NT-MODE */ - hc->hw.states = 1; /* G1 */ - } else { - hc->hw.clkdel = CLKDEL_TE; /* ST-Bit delay for TE-Mode */ - hc->hw.sctrl &= ~SCTRL_MODE_NT; /* TE-MODE */ - hc->hw.states = 2; /* F2 */ - } - Write_hfc(hc, HFCPCI_CLKDEL, hc->hw.clkdel); - Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | hc->hw.states); - udelay(10); - Write_hfc(hc, HFCPCI_STATES, hc->hw.states | 0x40); /* Deactivate */ - Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl); -} - -/* - * function called to reset the HFC PCI chip. A complete software reset of chip - * and fifos is done. - */ -static void -reset_hfcpci(struct hfc_pci *hc) -{ - u_char val; - int cnt = 0; - - printk(KERN_DEBUG "reset_hfcpci: entered\n"); - val = Read_hfc(hc, HFCPCI_CHIP_ID); - printk(KERN_INFO "HFC_PCI: resetting HFC ChipId(%x)\n", val); - /* enable memory mapped ports, disable busmaster */ - pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO); - disable_hwirq(hc); - /* enable memory ports + busmaster */ - pci_write_config_word(hc->pdev, PCI_COMMAND, - PCI_ENA_MEMIO + PCI_ENA_MASTER); - val = Read_hfc(hc, HFCPCI_STATUS); - printk(KERN_DEBUG "HFC-PCI status(%x) before reset\n", val); - hc->hw.cirm = HFCPCI_RESET; /* Reset On */ - Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm); - set_current_state(TASK_UNINTERRUPTIBLE); - mdelay(10); /* Timeout 10ms */ - hc->hw.cirm = 0; /* Reset Off */ - Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm); - val = Read_hfc(hc, HFCPCI_STATUS); - printk(KERN_DEBUG "HFC-PCI status(%x) after reset\n", val); - while (cnt < 50000) { /* max 50000 us */ - udelay(5); - cnt += 5; - val = Read_hfc(hc, HFCPCI_STATUS); - if (!(val & 2)) - break; - } - printk(KERN_DEBUG "HFC-PCI status(%x) after %dus\n", val, cnt); - - hc->hw.fifo_en = 0x30; /* only D fifos enabled */ - - hc->hw.bswapped = 0; /* no exchange */ - hc->hw.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER; - hc->hw.trm = HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */ - hc->hw.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */ - hc->hw.sctrl_r = 0; - hc->hw.sctrl_e = HFCPCI_AUTO_AWAKE; /* S/T Auto awake */ - hc->hw.mst_m = 0; - if (test_bit(HFC_CFG_MASTER, &hc->cfg)) - hc->hw.mst_m |= HFCPCI_MASTER; /* HFC Master Mode */ - if (test_bit(HFC_CFG_NEG_F0, &hc->cfg)) - hc->hw.mst_m |= HFCPCI_F0_NEGATIV; - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); - Write_hfc(hc, HFCPCI_TRM, hc->hw.trm); - Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e); - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt); - - hc->hw.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC | - HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - - /* Clear already pending ints */ - if (Read_hfc(hc, HFCPCI_INT_S1)); - - /* set NT/TE mode */ - hfcpci_setmode(hc); - - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r); - - /* - * Init GCI/IOM2 in master mode - * Slots 0 and 1 are set for B-chan 1 and 2 - * D- and monitor/CI channel are not enabled - * STIO1 is used as output for data, B1+B2 from ST->IOM+HFC - * STIO2 is used as data input, B1+B2 from IOM->ST - * ST B-channel send disabled -> continous 1s - * The IOM slots are always enabled - */ - if (test_bit(HFC_CFG_PCM, &hc->cfg)) { - /* set data flow directions: connect B1,B2: HFC to/from PCM */ - hc->hw.conn = 0x09; - } else { - hc->hw.conn = 0x36; /* set data flow directions */ - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) { - Write_hfc(hc, HFCPCI_B1_SSL, 0xC0); - Write_hfc(hc, HFCPCI_B2_SSL, 0xC1); - Write_hfc(hc, HFCPCI_B1_RSL, 0xC0); - Write_hfc(hc, HFCPCI_B2_RSL, 0xC1); - } else { - Write_hfc(hc, HFCPCI_B1_SSL, 0x80); - Write_hfc(hc, HFCPCI_B2_SSL, 0x81); - Write_hfc(hc, HFCPCI_B1_RSL, 0x80); - Write_hfc(hc, HFCPCI_B2_RSL, 0x81); - } - } - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); - val = Read_hfc(hc, HFCPCI_INT_S2); -} - -/* - * Timer function called when kernel timer expires - */ -static void -hfcpci_Timer(struct hfc_pci *hc) -{ - hc->hw.timer.expires = jiffies + 75; - /* WD RESET */ -/* - * WriteReg(hc, HFCD_DATA, HFCD_CTMT, hc->hw.ctmt | 0x80); - * add_timer(&hc->hw.timer); - */ -} - - -/* - * select a b-channel entry matching and active - */ -static struct bchannel * -Sel_BCS(struct hfc_pci *hc, int channel) -{ - if (test_bit(FLG_ACTIVE, &hc->bch[0].Flags) && - (hc->bch[0].nr & channel)) - return &hc->bch[0]; - else if (test_bit(FLG_ACTIVE, &hc->bch[1].Flags) && - (hc->bch[1].nr & channel)) - return &hc->bch[1]; - else - return NULL; -} - -/* - * clear the desired B-channel rx fifo - */ -static void -hfcpci_clear_fifo_rx(struct hfc_pci *hc, int fifo) -{ - u_char fifo_state; - struct bzfifo *bzr; - - if (fifo) { - bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; - fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2RX; - } else { - bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1; - fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1RX; - } - if (fifo_state) - hc->hw.fifo_en ^= fifo_state; - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); - hc->hw.last_bfifo_cnt[fifo] = 0; - bzr->f1 = MAX_B_FRAMES; - bzr->f2 = bzr->f1; /* init F pointers to remain constant */ - bzr->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1); - bzr->za[MAX_B_FRAMES].z2 = cpu_to_le16( - le16_to_cpu(bzr->za[MAX_B_FRAMES].z1)); - if (fifo_state) - hc->hw.fifo_en |= fifo_state; - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); -} - -/* - * clear the desired B-channel tx fifo - */ -static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo) -{ - u_char fifo_state; - struct bzfifo *bzt; - - if (fifo) { - bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; - fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2TX; - } else { - bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1; - fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1TX; - } - if (fifo_state) - hc->hw.fifo_en ^= fifo_state; - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); - if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) " - "z1(%x) z2(%x) state(%x)\n", - fifo, bzt->f1, bzt->f2, - le16_to_cpu(bzt->za[MAX_B_FRAMES].z1), - le16_to_cpu(bzt->za[MAX_B_FRAMES].z2), - fifo_state); - bzt->f2 = MAX_B_FRAMES; - bzt->f1 = bzt->f2; /* init F pointers to remain constant */ - bzt->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1); - bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16( - le16_to_cpu(bzt->za[MAX_B_FRAMES].z1 - 1)); - if (fifo_state) - hc->hw.fifo_en |= fifo_state; - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); - if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG - "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) z1(%x) z2(%x)\n", - fifo, bzt->f1, bzt->f2, - le16_to_cpu(bzt->za[MAX_B_FRAMES].z1), - le16_to_cpu(bzt->za[MAX_B_FRAMES].z2)); -} - -/* - * read a complete B-frame out of the buffer - */ -static void -hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz, - u_char *bdata, int count) -{ - u_char *ptr, *ptr1, new_f2; - int total, maxlen, new_z2; - struct zt *zp; - - if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) - printk(KERN_DEBUG "hfcpci_empty_fifo\n"); - zp = &bz->za[bz->f2]; /* point to Z-Regs */ - new_z2 = le16_to_cpu(zp->z2) + count; /* new position in fifo */ - if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z2 -= B_FIFO_SIZE; /* buffer wrap */ - new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; - if ((count > MAX_DATA_SIZE + 3) || (count < 4) || - (*(bdata + (le16_to_cpu(zp->z1) - B_SUB_VAL)))) { - if (bch->debug & DEBUG_HW) - printk(KERN_DEBUG "hfcpci_empty_fifo: incoming packet " - "invalid length %d or crc\n", count); -#ifdef ERROR_STATISTIC - bch->err_inv++; -#endif - bz->za[new_f2].z2 = cpu_to_le16(new_z2); - bz->f2 = new_f2; /* next buffer */ - } else { - bch->rx_skb = mI_alloc_skb(count - 3, GFP_ATOMIC); - if (!bch->rx_skb) { - printk(KERN_WARNING "HFCPCI: receive out of memory\n"); - return; - } - total = count; - count -= 3; - ptr = skb_put(bch->rx_skb, count); - - if (le16_to_cpu(zp->z2) + count <= B_FIFO_SIZE + B_SUB_VAL) - maxlen = count; /* complete transfer */ - else - maxlen = B_FIFO_SIZE + B_SUB_VAL - - le16_to_cpu(zp->z2); /* maximum */ - - ptr1 = bdata + (le16_to_cpu(zp->z2) - B_SUB_VAL); - /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - count -= maxlen; - - if (count) { /* rest remaining */ - ptr += maxlen; - ptr1 = bdata; /* start of buffer */ - memcpy(ptr, ptr1, count); /* rest */ - } - bz->za[new_f2].z2 = cpu_to_le16(new_z2); - bz->f2 = new_f2; /* next buffer */ - recv_Bchannel(bch); - } -} - -/* - * D-channel receive procedure - */ -static int -receive_dmsg(struct hfc_pci *hc) -{ - struct dchannel *dch = &hc->dch; - int maxlen; - int rcnt, total; - int count = 5; - u_char *ptr, *ptr1; - struct dfifo *df; - struct zt *zp; - - df = &((union fifo_area *)(hc->hw.fifos))->d_chan.d_rx; - while (((df->f1 & D_FREG_MASK) != (df->f2 & D_FREG_MASK)) && count--) { - zp = &df->za[df->f2 & D_FREG_MASK]; - rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2); - if (rcnt < 0) - rcnt += D_FIFO_SIZE; - rcnt++; - if (dch->debug & DEBUG_HW_DCHANNEL) - printk(KERN_DEBUG - "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)\n", - df->f1, df->f2, - le16_to_cpu(zp->z1), - le16_to_cpu(zp->z2), - rcnt); - - if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) || - (df->data[le16_to_cpu(zp->z1)])) { - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG - "empty_fifo hfcpci paket inv. len " - "%d or crc %d\n", - rcnt, - df->data[le16_to_cpu(zp->z1)]); -#ifdef ERROR_STATISTIC - cs->err_rx++; -#endif - df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | - (MAX_D_FRAMES + 1); /* next buffer */ - df->za[df->f2 & D_FREG_MASK].z2 = - cpu_to_le16((zp->z2 + rcnt) & (D_FIFO_SIZE - 1)); - } else { - dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC); - if (!dch->rx_skb) { - printk(KERN_WARNING - "HFC-PCI: D receive out of memory\n"); - break; - } - total = rcnt; - rcnt -= 3; - ptr = skb_put(dch->rx_skb, rcnt); - - if (le16_to_cpu(zp->z2) + rcnt <= D_FIFO_SIZE) - maxlen = rcnt; /* complete transfer */ - else - maxlen = D_FIFO_SIZE - le16_to_cpu(zp->z2); - /* maximum */ - - ptr1 = df->data + le16_to_cpu(zp->z2); - /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - rcnt -= maxlen; - - if (rcnt) { /* rest remaining */ - ptr += maxlen; - ptr1 = df->data; /* start of buffer */ - memcpy(ptr, ptr1, rcnt); /* rest */ - } - df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | - (MAX_D_FRAMES + 1); /* next buffer */ - df->za[df->f2 & D_FREG_MASK].z2 = cpu_to_le16(( - le16_to_cpu(zp->z2) + total) & (D_FIFO_SIZE - 1)); - recv_Dchannel(dch); - } - } - return 1; -} - -/* - * check for transparent receive data and read max one threshold size if avail - */ -int -hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) -{ - unsigned short *z1r, *z2r; - int new_z2, fcnt, maxlen; - u_char *ptr, *ptr1; - - z1r = &bz->za[MAX_B_FRAMES].z1; /* pointer to z reg */ - z2r = z1r + 1; - - fcnt = le16_to_cpu(*z1r) - le16_to_cpu(*z2r); - if (!fcnt) - return 0; /* no data avail */ - - if (fcnt <= 0) - fcnt += B_FIFO_SIZE; /* bytes actually buffered */ - if (fcnt > HFCPCI_BTRANS_THRESHOLD) - fcnt = HFCPCI_BTRANS_THRESHOLD; /* limit size */ - - new_z2 = le16_to_cpu(*z2r) + fcnt; /* new position in fifo */ - if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z2 -= B_FIFO_SIZE; /* buffer wrap */ - - bch->rx_skb = mI_alloc_skb(fcnt, GFP_ATOMIC); - if (bch->rx_skb) { - ptr = skb_put(bch->rx_skb, fcnt); - if (le16_to_cpu(*z2r) + fcnt <= B_FIFO_SIZE + B_SUB_VAL) - maxlen = fcnt; /* complete transfer */ - else - maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r); - /* maximum */ - - ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL); - /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - fcnt -= maxlen; - - if (fcnt) { /* rest remaining */ - ptr += maxlen; - ptr1 = bdata; /* start of buffer */ - memcpy(ptr, ptr1, fcnt); /* rest */ - } - recv_Bchannel(bch); - } else - printk(KERN_WARNING "HFCPCI: receive out of memory\n"); - - *z2r = cpu_to_le16(new_z2); /* new position */ - return 1; -} - -/* - * B-channel main receive routine - */ -void -main_rec_hfcpci(struct bchannel *bch) -{ - struct hfc_pci *hc = bch->hw; - int rcnt, real_fifo; - int receive, count = 5; - struct bzfifo *bz; - u_char *bdata; - struct zt *zp; - - - if ((bch->nr & 2) && (!hc->hw.bswapped)) { - bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; - bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2; - real_fifo = 1; - } else { - bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1; - bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1; - real_fifo = 0; - } -Begin: - count--; - if (bz->f1 != bz->f2) { - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n", - bch->nr, bz->f1, bz->f2); - zp = &bz->za[bz->f2]; - - rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2); - if (rcnt < 0) - rcnt += B_FIFO_SIZE; - rcnt++; - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG - "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n", - bch->nr, le16_to_cpu(zp->z1), - le16_to_cpu(zp->z2), rcnt); - hfcpci_empty_bfifo(bch, bz, bdata, rcnt); - rcnt = bz->f1 - bz->f2; - if (rcnt < 0) - rcnt += MAX_B_FRAMES + 1; - if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) { - rcnt = 0; - hfcpci_clear_fifo_rx(hc, real_fifo); - } - hc->hw.last_bfifo_cnt[real_fifo] = rcnt; - if (rcnt > 1) - receive = 1; - else - receive = 0; - } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) - receive = hfcpci_empty_fifo_trans(bch, bz, bdata); - else - receive = 0; - if (count && receive) - goto Begin; - -} - -/* - * D-channel send routine - */ -static void -hfcpci_fill_dfifo(struct hfc_pci *hc) -{ - struct dchannel *dch = &hc->dch; - int fcnt; - int count, new_z1, maxlen; - struct dfifo *df; - u_char *src, *dst, new_f1; - - if ((dch->debug & DEBUG_HW_DCHANNEL) && !(dch->debug & DEBUG_HW_DFIFO)) - printk(KERN_DEBUG "%s\n", __func__); - - if (!dch->tx_skb) - return; - count = dch->tx_skb->len - dch->tx_idx; - if (count <= 0) - return; - df = &((union fifo_area *) (hc->hw.fifos))->d_chan.d_tx; - - if (dch->debug & DEBUG_HW_DFIFO) - printk(KERN_DEBUG "%s:f1(%d) f2(%d) z1(f1)(%x)\n", __func__, - df->f1, df->f2, - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1)); - fcnt = df->f1 - df->f2; /* frame count actually buffered */ - if (fcnt < 0) - fcnt += (MAX_D_FRAMES + 1); /* if wrap around */ - if (fcnt > (MAX_D_FRAMES - 1)) { - if (dch->debug & DEBUG_HW_DCHANNEL) - printk(KERN_DEBUG - "hfcpci_fill_Dfifo more as 14 frames\n"); -#ifdef ERROR_STATISTIC - cs->err_tx++; -#endif - return; - } - /* now determine free bytes in FIFO buffer */ - maxlen = le16_to_cpu(df->za[df->f2 & D_FREG_MASK].z2) - - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) - 1; - if (maxlen <= 0) - maxlen += D_FIFO_SIZE; /* count now contains available bytes */ - - if (dch->debug & DEBUG_HW_DCHANNEL) - printk(KERN_DEBUG "hfcpci_fill_Dfifo count(%d/%d)\n", - count, maxlen); - if (count > maxlen) { - if (dch->debug & DEBUG_HW_DCHANNEL) - printk(KERN_DEBUG "hfcpci_fill_Dfifo no fifo mem\n"); - return; - } - new_z1 = (le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) + count) & - (D_FIFO_SIZE - 1); - new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1); - src = dch->tx_skb->data + dch->tx_idx; /* source pointer */ - dst = df->data + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1); - maxlen = D_FIFO_SIZE - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1); - /* end fifo */ - if (maxlen > count) - maxlen = count; /* limit size */ - memcpy(dst, src, maxlen); /* first copy */ - - count -= maxlen; /* remaining bytes */ - if (count) { - dst = df->data; /* start of buffer */ - src += maxlen; /* new position */ - memcpy(dst, src, count); - } - df->za[new_f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1); - /* for next buffer */ - df->za[df->f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1); - /* new pos actual buffer */ - df->f1 = new_f1; /* next frame */ - dch->tx_idx = dch->tx_skb->len; -} - -/* - * B-channel send routine - */ -static void -hfcpci_fill_fifo(struct bchannel *bch) -{ - struct hfc_pci *hc = bch->hw; - int maxlen, fcnt; - int count, new_z1; - struct bzfifo *bz; - u_char *bdata; - u_char new_f1, *src, *dst; - unsigned short *z1t, *z2t; - - if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) - printk(KERN_DEBUG "%s\n", __func__); - if ((!bch->tx_skb) || bch->tx_skb->len <= 0) - return; - count = bch->tx_skb->len - bch->tx_idx; - if ((bch->nr & 2) && (!hc->hw.bswapped)) { - bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; - bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2; - } else { - bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1; - bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b1; - } - - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { - z1t = &bz->za[MAX_B_FRAMES].z1; - z2t = z1t + 1; - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG "hfcpci_fill_fifo_trans ch(%x) " - "cnt(%d) z1(%x) z2(%x)\n", bch->nr, count, - le16_to_cpu(*z1t), le16_to_cpu(*z2t)); - fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); - if (fcnt <= 0) - fcnt += B_FIFO_SIZE; - /* fcnt contains available bytes in fifo */ - fcnt = B_FIFO_SIZE - fcnt; - /* remaining bytes to send (bytes in fifo) */ -next_t_frame: - count = bch->tx_skb->len - bch->tx_idx; - /* maximum fill shall be HFCPCI_BTRANS_MAX */ - if (count > HFCPCI_BTRANS_MAX - fcnt) - count = HFCPCI_BTRANS_MAX - fcnt; - if (count <= 0) - return; - /* data is suitable for fifo */ - new_z1 = le16_to_cpu(*z1t) + count; - /* new buffer Position */ - if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z1 -= B_FIFO_SIZE; /* buffer wrap */ - src = bch->tx_skb->data + bch->tx_idx; - /* source pointer */ - dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL); - maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t); - /* end of fifo */ - if (bch->debug & DEBUG_HW_BFIFO) - printk(KERN_DEBUG "hfcpci_FFt fcnt(%d) " - "maxl(%d) nz1(%x) dst(%p)\n", - fcnt, maxlen, new_z1, dst); - fcnt += count; - bch->tx_idx += count; - if (maxlen > count) - maxlen = count; /* limit size */ - memcpy(dst, src, maxlen); /* first copy */ - count -= maxlen; /* remaining bytes */ - if (count) { - dst = bdata; /* start of buffer */ - src += maxlen; /* new position */ - memcpy(dst, src, count); - } - *z1t = cpu_to_le16(new_z1); /* now send data */ - if (bch->tx_idx < bch->tx_skb->len) - return; - /* send confirm, on trans, free on hdlc. */ - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) - confirm_Bsend(bch); - dev_kfree_skb(bch->tx_skb); - if (get_next_bframe(bch)) - goto next_t_frame; - return; - } - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG - "%s: ch(%x) f1(%d) f2(%d) z1(f1)(%x)\n", - __func__, bch->nr, bz->f1, bz->f2, - bz->za[bz->f1].z1); - fcnt = bz->f1 - bz->f2; /* frame count actually buffered */ - if (fcnt < 0) - fcnt += (MAX_B_FRAMES + 1); /* if wrap around */ - if (fcnt > (MAX_B_FRAMES - 1)) { - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG - "hfcpci_fill_Bfifo more as 14 frames\n"); - return; - } - /* now determine free bytes in FIFO buffer */ - maxlen = le16_to_cpu(bz->za[bz->f2].z2) - - le16_to_cpu(bz->za[bz->f1].z1) - 1; - if (maxlen <= 0) - maxlen += B_FIFO_SIZE; /* count now contains available bytes */ - - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG "hfcpci_fill_fifo ch(%x) count(%d/%d)\n", - bch->nr, count, maxlen); - - if (maxlen < count) { - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG "hfcpci_fill_fifo no fifo mem\n"); - return; - } - new_z1 = le16_to_cpu(bz->za[bz->f1].z1) + count; - /* new buffer Position */ - if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z1 -= B_FIFO_SIZE; /* buffer wrap */ - - new_f1 = ((bz->f1 + 1) & MAX_B_FRAMES); - src = bch->tx_skb->data + bch->tx_idx; /* source pointer */ - dst = bdata + (le16_to_cpu(bz->za[bz->f1].z1) - B_SUB_VAL); - maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(bz->za[bz->f1].z1); - /* end fifo */ - if (maxlen > count) - maxlen = count; /* limit size */ - memcpy(dst, src, maxlen); /* first copy */ - - count -= maxlen; /* remaining bytes */ - if (count) { - dst = bdata; /* start of buffer */ - src += maxlen; /* new position */ - memcpy(dst, src, count); - } - bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */ - bz->f1 = new_f1; /* next frame */ - dev_kfree_skb(bch->tx_skb); - get_next_bframe(bch); -} - - - -/* - * handle L1 state changes TE - */ - -static void -ph_state_te(struct dchannel *dch) -{ - if (dch->debug) - printk(KERN_DEBUG "%s: TE newstate %x\n", - __func__, dch->state); - switch (dch->state) { - case 0: - l1_event(dch->l1, HW_RESET_IND); - break; - case 3: - l1_event(dch->l1, HW_DEACT_IND); - break; - case 5: - case 8: - l1_event(dch->l1, ANYSIGNAL); - break; - case 6: - l1_event(dch->l1, INFO2); - break; - case 7: - l1_event(dch->l1, INFO4_P8); - break; - } -} - -/* - * handle L1 state changes NT - */ - -static void -handle_nt_timer3(struct dchannel *dch) { - struct hfc_pci *hc = dch->hw; - - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - hc->hw.nt_timer = 0; - test_and_set_bit(FLG_ACTIVE, &dch->Flags); - if (test_bit(HFC_CFG_MASTER, &hc->cfg)) - hc->hw.mst_m |= HFCPCI_MASTER; - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); -} - -static void -ph_state_nt(struct dchannel *dch) -{ - struct hfc_pci *hc = dch->hw; - - if (dch->debug) - printk(KERN_DEBUG "%s: NT newstate %x\n", - __func__, dch->state); - switch (dch->state) { - case 2: - if (hc->hw.nt_timer < 0) { - hc->hw.nt_timer = 0; - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); - test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags); - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - /* Clear already pending ints */ - if (Read_hfc(hc, HFCPCI_INT_S1)); - Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE); - udelay(10); - Write_hfc(hc, HFCPCI_STATES, 4); - dch->state = 4; - } else if (hc->hw.nt_timer == 0) { - hc->hw.int_m1 |= HFCPCI_INTS_TIMER; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - hc->hw.nt_timer = NT_T1_COUNT; - hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER; - hc->hw.ctmt |= HFCPCI_TIM3_125; - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | - HFCPCI_CLTIMER); - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); - test_and_set_bit(FLG_HFC_TIMER_T1, &dch->Flags); - /* allow G2 -> G3 transition */ - Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3); - } else { - Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3); - } - break; - case 1: - hc->hw.nt_timer = 0; - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); - test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags); - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - test_and_clear_bit(FLG_ACTIVE, &dch->Flags); - hc->hw.mst_m &= ~HFCPCI_MASTER; - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); - break; - case 4: - hc->hw.nt_timer = 0; - test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); - test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags); - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - break; - case 3: - if (!test_and_set_bit(FLG_HFC_TIMER_T3, &dch->Flags)) { - if (!test_and_clear_bit(FLG_L2_ACTIVATED, - &dch->Flags)) { - handle_nt_timer3(dch); - break; - } - test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags); - hc->hw.int_m1 |= HFCPCI_INTS_TIMER; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - hc->hw.nt_timer = NT_T3_COUNT; - hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER; - hc->hw.ctmt |= HFCPCI_TIM3_125; - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | - HFCPCI_CLTIMER); - } - break; - } -} - -static void -ph_state(struct dchannel *dch) -{ - struct hfc_pci *hc = dch->hw; - - if (hc->hw.protocol == ISDN_P_NT_S0) { - if (test_bit(FLG_HFC_TIMER_T3, &dch->Flags) && - hc->hw.nt_timer < 0) - handle_nt_timer3(dch); - else - ph_state_nt(dch); - } else - ph_state_te(dch); -} - -/* - * Layer 1 callback function - */ -static int -hfc_l1callback(struct dchannel *dch, u_int cmd) -{ - struct hfc_pci *hc = dch->hw; - - switch (cmd) { - case INFO3_P8: - case INFO3_P10: - if (test_bit(HFC_CFG_MASTER, &hc->cfg)) - hc->hw.mst_m |= HFCPCI_MASTER; - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - break; - case HW_RESET_REQ: - Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3); - /* HFC ST 3 */ - udelay(6); - Write_hfc(hc, HFCPCI_STATES, 3); /* HFC ST 2 */ - if (test_bit(HFC_CFG_MASTER, &hc->cfg)) - hc->hw.mst_m |= HFCPCI_MASTER; - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE | - HFCPCI_DO_ACTION); - l1_event(dch->l1, HW_POWERUP_IND); - break; - case HW_DEACT_REQ: - hc->hw.mst_m &= ~HFCPCI_MASTER; - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - skb_queue_purge(&dch->squeue); - if (dch->tx_skb) { - dev_kfree_skb(dch->tx_skb); - dch->tx_skb = NULL; - } - dch->tx_idx = 0; - if (dch->rx_skb) { - dev_kfree_skb(dch->rx_skb); - dch->rx_skb = NULL; - } - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) - del_timer(&dch->timer); - break; - case HW_POWERUP_REQ: - Write_hfc(hc, HFCPCI_STATES, HFCPCI_DO_ACTION); - break; - case PH_ACTIVATE_IND: - test_and_set_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, - GFP_ATOMIC); - break; - case PH_DEACTIVATE_IND: - test_and_clear_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, - GFP_ATOMIC); - break; - default: - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: unknown command %x\n", - __func__, cmd); - return -1; - } - return 0; -} - -/* - * Interrupt handler - */ -static inline void -tx_birq(struct bchannel *bch) -{ - if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) - hfcpci_fill_fifo(bch); - else { - if (bch->tx_skb) - dev_kfree_skb(bch->tx_skb); - if (get_next_bframe(bch)) - hfcpci_fill_fifo(bch); - } -} - -static inline void -tx_dirq(struct dchannel *dch) -{ - if (dch->tx_skb && dch->tx_idx < dch->tx_skb->len) - hfcpci_fill_dfifo(dch->hw); - else { - if (dch->tx_skb) - dev_kfree_skb(dch->tx_skb); - if (get_next_dframe(dch)) - hfcpci_fill_dfifo(dch->hw); - } -} - -static irqreturn_t -hfcpci_int(int intno, void *dev_id) -{ - struct hfc_pci *hc = dev_id; - u_char exval; - struct bchannel *bch; - u_char val, stat; - - spin_lock(&hc->lock); - if (!(hc->hw.int_m2 & 0x08)) { - spin_unlock(&hc->lock); - return IRQ_NONE; /* not initialised */ - } - stat = Read_hfc(hc, HFCPCI_STATUS); - if (HFCPCI_ANYINT & stat) { - val = Read_hfc(hc, HFCPCI_INT_S1); - if (hc->dch.debug & DEBUG_HW_DCHANNEL) - printk(KERN_DEBUG - "HFC-PCI: stat(%02x) s1(%02x)\n", stat, val); - } else { - /* shared */ - spin_unlock(&hc->lock); - return IRQ_NONE; - } - hc->irqcnt++; - - if (hc->dch.debug & DEBUG_HW_DCHANNEL) - printk(KERN_DEBUG "HFC-PCI irq %x\n", val); - val &= hc->hw.int_m1; - if (val & 0x40) { /* state machine irq */ - exval = Read_hfc(hc, HFCPCI_STATES) & 0xf; - if (hc->dch.debug & DEBUG_HW_DCHANNEL) - printk(KERN_DEBUG "ph_state chg %d->%d\n", - hc->dch.state, exval); - hc->dch.state = exval; - schedule_event(&hc->dch, FLG_PHCHANGE); - val &= ~0x40; - } - if (val & 0x80) { /* timer irq */ - if (hc->hw.protocol == ISDN_P_NT_S0) { - if ((--hc->hw.nt_timer) < 0) - schedule_event(&hc->dch, FLG_PHCHANGE); - } - val &= ~0x80; - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER); - } - if (val & 0x08) { - bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); - if (bch) - main_rec_hfcpci(bch); - else if (hc->dch.debug) - printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n"); - } - if (val & 0x10) { - bch = Sel_BCS(hc, 2); - if (bch) - main_rec_hfcpci(bch); - else if (hc->dch.debug) - printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n"); - } - if (val & 0x01) { - bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); - if (bch) - tx_birq(bch); - else if (hc->dch.debug) - printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n"); - } - if (val & 0x02) { - bch = Sel_BCS(hc, 2); - if (bch) - tx_birq(bch); - else if (hc->dch.debug) - printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n"); - } - if (val & 0x20) - receive_dmsg(hc); - if (val & 0x04) { /* dframe transmitted */ - if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags)) - del_timer(&hc->dch.timer); - tx_dirq(&hc->dch); - } - spin_unlock(&hc->lock); - return IRQ_HANDLED; -} - -/* - * timer callback for D-chan busy resolution. Currently no function - */ -static void -hfcpci_dbusy_timer(struct hfc_pci *hc) -{ -} - -/* - * activate/deactivate hardware for selected channels and mode - */ -static int -mode_hfcpci(struct bchannel *bch, int bc, int protocol) -{ - struct hfc_pci *hc = bch->hw; - int fifo2; - u_char rx_slot = 0, tx_slot = 0, pcm_mode; - - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG - "HFCPCI bchannel protocol %x-->%x ch %x-->%x\n", - bch->state, protocol, bch->nr, bc); - - fifo2 = bc; - pcm_mode = (bc>>24) & 0xff; - if (pcm_mode) { /* PCM SLOT USE */ - if (!test_bit(HFC_CFG_PCM, &hc->cfg)) - printk(KERN_WARNING - "%s: pcm channel id without HFC_CFG_PCM\n", - __func__); - rx_slot = (bc>>8) & 0xff; - tx_slot = (bc>>16) & 0xff; - bc = bc & 0xff; - } else if (test_bit(HFC_CFG_PCM, &hc->cfg) && - (protocol > ISDN_P_NONE)) - printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n", - __func__); - if (hc->chanlimit > 1) { - hc->hw.bswapped = 0; /* B1 and B2 normal mode */ - hc->hw.sctrl_e &= ~0x80; - } else { - if (bc & 2) { - if (protocol != ISDN_P_NONE) { - hc->hw.bswapped = 1; /* B1 and B2 exchanged */ - hc->hw.sctrl_e |= 0x80; - } else { - hc->hw.bswapped = 0; /* B1 and B2 normal mode */ - hc->hw.sctrl_e &= ~0x80; - } - fifo2 = 1; - } else { - hc->hw.bswapped = 0; /* B1 and B2 normal mode */ - hc->hw.sctrl_e &= ~0x80; - } - } - switch (protocol) { - case (-1): /* used for init */ - bch->state = -1; - bch->nr = bc; - case (ISDN_P_NONE): - if (bch->state == ISDN_P_NONE) - return 0; - if (bc & 2) { - hc->hw.sctrl &= ~SCTRL_B2_ENA; - hc->hw.sctrl_r &= ~SCTRL_B2_ENA; - } else { - hc->hw.sctrl &= ~SCTRL_B1_ENA; - hc->hw.sctrl_r &= ~SCTRL_B1_ENA; - } - if (fifo2 & 2) { - hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B2; - hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS + - HFCPCI_INTS_B2REC); - } else { - hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B1; - hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS + - HFCPCI_INTS_B1REC); - } -#ifdef REVERSE_BITORDER - if (bch->nr & 2) - hc->hw.cirm &= 0x7f; - else - hc->hw.cirm &= 0xbf; -#endif - bch->state = ISDN_P_NONE; - bch->nr = bc; - test_and_clear_bit(FLG_HDLC, &bch->Flags); - test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags); - break; - case (ISDN_P_B_RAW): - bch->state = protocol; - bch->nr = bc; - hfcpci_clear_fifo_rx(hc, (fifo2 & 2)?1:0); - hfcpci_clear_fifo_tx(hc, (fifo2 & 2)?1:0); - if (bc & 2) { - hc->hw.sctrl |= SCTRL_B2_ENA; - hc->hw.sctrl_r |= SCTRL_B2_ENA; -#ifdef REVERSE_BITORDER - hc->hw.cirm |= 0x80; -#endif - } else { - hc->hw.sctrl |= SCTRL_B1_ENA; - hc->hw.sctrl_r |= SCTRL_B1_ENA; -#ifdef REVERSE_BITORDER - hc->hw.cirm |= 0x40; -#endif - } - if (fifo2 & 2) { - hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; - hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + - HFCPCI_INTS_B2REC); - hc->hw.ctmt |= 2; - hc->hw.conn &= ~0x18; - } else { - hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; - hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS + - HFCPCI_INTS_B1REC); - hc->hw.ctmt |= 1; - hc->hw.conn &= ~0x03; - } - test_and_set_bit(FLG_TRANSPARENT, &bch->Flags); - break; - case (ISDN_P_B_HDLC): - bch->state = protocol; - bch->nr = bc; - hfcpci_clear_fifo_rx(hc, (fifo2 & 2)?1:0); - hfcpci_clear_fifo_tx(hc, (fifo2 & 2)?1:0); - if (bc & 2) { - hc->hw.sctrl |= SCTRL_B2_ENA; - hc->hw.sctrl_r |= SCTRL_B2_ENA; - } else { - hc->hw.sctrl |= SCTRL_B1_ENA; - hc->hw.sctrl_r |= SCTRL_B1_ENA; - } - if (fifo2 & 2) { - hc->hw.last_bfifo_cnt[1] = 0; - hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; - hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + - HFCPCI_INTS_B2REC); - hc->hw.ctmt &= ~2; - hc->hw.conn &= ~0x18; - } else { - hc->hw.last_bfifo_cnt[0] = 0; - hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; - hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS + - HFCPCI_INTS_B1REC); - hc->hw.ctmt &= ~1; - hc->hw.conn &= ~0x03; - } - test_and_set_bit(FLG_HDLC, &bch->Flags); - break; - default: - printk(KERN_DEBUG "prot not known %x\n", protocol); - return -ENOPROTOOPT; - } - if (test_bit(HFC_CFG_PCM, &hc->cfg)) { - if ((protocol == ISDN_P_NONE) || - (protocol == -1)) { /* init case */ - rx_slot = 0; - tx_slot = 0; - } else { - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) { - rx_slot |= 0xC0; - tx_slot |= 0xC0; - } else { - rx_slot |= 0x80; - tx_slot |= 0x80; - } - } - if (bc & 2) { - hc->hw.conn &= 0xc7; - hc->hw.conn |= 0x08; - printk(KERN_DEBUG "%s: Write_hfc: B2_SSL 0x%x\n", - __func__, tx_slot); - printk(KERN_DEBUG "%s: Write_hfc: B2_RSL 0x%x\n", - __func__, rx_slot); - Write_hfc(hc, HFCPCI_B2_SSL, tx_slot); - Write_hfc(hc, HFCPCI_B2_RSL, rx_slot); - } else { - hc->hw.conn &= 0xf8; - hc->hw.conn |= 0x01; - printk(KERN_DEBUG "%s: Write_hfc: B1_SSL 0x%x\n", - __func__, tx_slot); - printk(KERN_DEBUG "%s: Write_hfc: B1_RSL 0x%x\n", - __func__, rx_slot); - Write_hfc(hc, HFCPCI_B1_SSL, tx_slot); - Write_hfc(hc, HFCPCI_B1_RSL, rx_slot); - } - } - Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e); - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); - Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl); - Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r); - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt); - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); -#ifdef REVERSE_BITORDER - Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm); -#endif - return 0; -} - -static int -set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan) -{ - struct hfc_pci *hc = bch->hw; - - if (bch->debug & DEBUG_HW_BCHANNEL) - printk(KERN_DEBUG - "HFCPCI bchannel test rx protocol %x-->%x ch %x-->%x\n", - bch->state, protocol, bch->nr, chan); - if (bch->nr != chan) { - printk(KERN_DEBUG - "HFCPCI rxtest wrong channel parameter %x/%x\n", - bch->nr, chan); - return -EINVAL; - } - switch (protocol) { - case (ISDN_P_B_RAW): - bch->state = protocol; - hfcpci_clear_fifo_rx(hc, (chan & 2)?1:0); - if (chan & 2) { - hc->hw.sctrl_r |= SCTRL_B2_ENA; - hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; - hc->hw.int_m1 |= HFCPCI_INTS_B2REC; - hc->hw.ctmt |= 2; - hc->hw.conn &= ~0x18; -#ifdef REVERSE_BITORDER - hc->hw.cirm |= 0x80; -#endif - } else { - hc->hw.sctrl_r |= SCTRL_B1_ENA; - hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX; - hc->hw.int_m1 |= HFCPCI_INTS_B1REC; - hc->hw.ctmt |= 1; - hc->hw.conn &= ~0x03; -#ifdef REVERSE_BITORDER - hc->hw.cirm |= 0x40; -#endif - } - break; - case (ISDN_P_B_HDLC): - bch->state = protocol; - hfcpci_clear_fifo_rx(hc, (chan & 2)?1:0); - if (chan & 2) { - hc->hw.sctrl_r |= SCTRL_B2_ENA; - hc->hw.last_bfifo_cnt[1] = 0; - hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; - hc->hw.int_m1 |= HFCPCI_INTS_B2REC; - hc->hw.ctmt &= ~2; - hc->hw.conn &= ~0x18; - } else { - hc->hw.sctrl_r |= SCTRL_B1_ENA; - hc->hw.last_bfifo_cnt[0] = 0; - hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX; - hc->hw.int_m1 |= HFCPCI_INTS_B1REC; - hc->hw.ctmt &= ~1; - hc->hw.conn &= ~0x03; - } - break; - default: - printk(KERN_DEBUG "prot not known %x\n", protocol); - return -ENOPROTOOPT; - } - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); - Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r); - Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt); - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); -#ifdef REVERSE_BITORDER - Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm); -#endif - return 0; -} - -static void -deactivate_bchannel(struct bchannel *bch) -{ - struct hfc_pci *hc = bch->hw; - u_long flags; - - spin_lock_irqsave(&hc->lock, flags); - if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) { - dev_kfree_skb(bch->next_skb); - bch->next_skb = NULL; - } - if (bch->tx_skb) { - dev_kfree_skb(bch->tx_skb); - bch->tx_skb = NULL; - } - bch->tx_idx = 0; - if (bch->rx_skb) { - dev_kfree_skb(bch->rx_skb); - bch->rx_skb = NULL; - } - mode_hfcpci(bch, bch->nr, ISDN_P_NONE); - test_and_clear_bit(FLG_ACTIVE, &bch->Flags); - test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); - spin_unlock_irqrestore(&hc->lock, flags); -} - -/* - * Layer 1 B-channel hardware access - */ -static int -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) -{ - int ret = 0; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = 0; - break; - default: - printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; -} -static int -hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct bchannel *bch = container_of(ch, struct bchannel, ch); - struct hfc_pci *hc = bch->hw; - int ret = -EINVAL; - u_long flags; - - if (bch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg); - switch (cmd) { - case HW_TESTRX_RAW: - spin_lock_irqsave(&hc->lock, flags); - ret = set_hfcpci_rxtest(bch, ISDN_P_B_RAW, (int)(long)arg); - spin_unlock_irqrestore(&hc->lock, flags); - break; - case HW_TESTRX_HDLC: - spin_lock_irqsave(&hc->lock, flags); - ret = set_hfcpci_rxtest(bch, ISDN_P_B_HDLC, (int)(long)arg); - spin_unlock_irqrestore(&hc->lock, flags); - break; - case HW_TESTRX_OFF: - spin_lock_irqsave(&hc->lock, flags); - mode_hfcpci(bch, bch->nr, ISDN_P_NONE); - spin_unlock_irqrestore(&hc->lock, flags); - ret = 0; - break; - case CLOSE_CHANNEL: - test_and_clear_bit(FLG_OPEN, &bch->Flags); - if (test_bit(FLG_ACTIVE, &bch->Flags)) - deactivate_bchannel(bch); - ch->protocol = ISDN_P_NONE; - ch->peer = NULL; - module_put(THIS_MODULE); - ret = 0; - break; - case CONTROL_CHANNEL: - ret = channel_bctrl(bch, arg); - break; - default: - printk(KERN_WARNING "%s: unknown prim(%x)\n", - __func__, cmd); - } - return ret; -} - -/* - * Layer2 -> Layer 1 Dchannel data - */ -static int -hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); - struct dchannel *dch = container_of(dev, struct dchannel, dev); - struct hfc_pci *hc = dch->hw; - int ret = -EINVAL; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned int id; - u_long flags; - - switch (hh->prim) { - case PH_DATA_REQ: - spin_lock_irqsave(&hc->lock, flags); - ret = dchannel_senddata(dch, skb); - if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ - hfcpci_fill_dfifo(dch->hw); - ret = 0; - spin_unlock_irqrestore(&hc->lock, flags); - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&hc->lock, flags); - return ret; - case PH_ACTIVATE_REQ: - spin_lock_irqsave(&hc->lock, flags); - if (hc->hw.protocol == ISDN_P_NT_S0) { - ret = 0; - if (test_bit(HFC_CFG_MASTER, &hc->cfg)) - hc->hw.mst_m |= HFCPCI_MASTER; - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - if (test_bit(FLG_ACTIVE, &dch->Flags)) { - spin_unlock_irqrestore(&hc->lock, flags); - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, - MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); - break; - } - test_and_set_bit(FLG_L2_ACTIVATED, &dch->Flags); - Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE | - HFCPCI_DO_ACTION | 1); - } else - ret = l1_event(dch->l1, hh->prim); - spin_unlock_irqrestore(&hc->lock, flags); - break; - case PH_DEACTIVATE_REQ: - test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); - spin_lock_irqsave(&hc->lock, flags); - if (hc->hw.protocol == ISDN_P_NT_S0) { - /* prepare deactivation */ - Write_hfc(hc, HFCPCI_STATES, 0x40); - skb_queue_purge(&dch->squeue); - if (dch->tx_skb) { - dev_kfree_skb(dch->tx_skb); - dch->tx_skb = NULL; - } - dch->tx_idx = 0; - if (dch->rx_skb) { - dev_kfree_skb(dch->rx_skb); - dch->rx_skb = NULL; - } - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); - if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) - del_timer(&dch->timer); -#ifdef FIXME - if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) - dchannel_sched_event(&hc->dch, D_CLEARBUSY); -#endif - hc->hw.mst_m &= ~HFCPCI_MASTER; - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - ret = 0; - } else { - ret = l1_event(dch->l1, hh->prim); - } - spin_unlock_irqrestore(&hc->lock, flags); - break; - } - if (!ret) - dev_kfree_skb(skb); - return ret; -} - -/* - * Layer2 -> Layer 1 Bchannel data - */ -static int -hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct bchannel *bch = container_of(ch, struct bchannel, ch); - struct hfc_pci *hc = bch->hw; - int ret = -EINVAL; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned int id; - u_long flags; - - switch (hh->prim) { - case PH_DATA_REQ: - spin_lock_irqsave(&hc->lock, flags); - ret = bchannel_senddata(bch, skb); - if (ret > 0) { /* direct TX */ - id = hh->id; /* skb can be freed */ - hfcpci_fill_fifo(bch); - ret = 0; - spin_unlock_irqrestore(&hc->lock, flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - queue_ch_frame(ch, PH_DATA_CNF, id, NULL); - } else - spin_unlock_irqrestore(&hc->lock, flags); - return ret; - case PH_ACTIVATE_REQ: - spin_lock_irqsave(&hc->lock, flags); - if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) - ret = mode_hfcpci(bch, bch->nr, ch->protocol); - else - ret = 0; - spin_unlock_irqrestore(&hc->lock, flags); - if (!ret) - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, - NULL, GFP_KERNEL); - break; - case PH_DEACTIVATE_REQ: - deactivate_bchannel(bch); - _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, - NULL, GFP_KERNEL); - ret = 0; - break; - } - if (!ret) - dev_kfree_skb(skb); - return ret; -} - -/* - * called for card init message - */ - -void -inithfcpci(struct hfc_pci *hc) -{ - printk(KERN_DEBUG "inithfcpci: entered\n"); - hc->dch.timer.function = (void *) hfcpci_dbusy_timer; - hc->dch.timer.data = (long) &hc->dch; - init_timer(&hc->dch.timer); - hc->chanlimit = 2; - mode_hfcpci(&hc->bch[0], 1, -1); - mode_hfcpci(&hc->bch[1], 2, -1); -} - - -static int -init_card(struct hfc_pci *hc) -{ - int cnt = 3; - u_long flags; - - printk(KERN_DEBUG "init_card: entered\n"); - - - spin_lock_irqsave(&hc->lock, flags); - disable_hwirq(hc); - spin_unlock_irqrestore(&hc->lock, flags); - if (request_irq(hc->irq, hfcpci_int, IRQF_SHARED, "HFC PCI", hc)) { - printk(KERN_WARNING - "mISDN: couldn't get interrupt %d\n", hc->irq); - return -EIO; - } - spin_lock_irqsave(&hc->lock, flags); - reset_hfcpci(hc); - while (cnt) { - inithfcpci(hc); - /* - * Finally enable IRQ output - * this is only allowed, if an IRQ routine is allready - * established for this HFC, so don't do that earlier - */ - enable_hwirq(hc); - spin_unlock_irqrestore(&hc->lock, flags); - /* Timeout 80ms */ - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout((80*HZ)/1000); - printk(KERN_INFO "HFC PCI: IRQ %d count %d\n", - hc->irq, hc->irqcnt); - /* now switch timer interrupt off */ - spin_lock_irqsave(&hc->lock, flags); - hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - /* reinit mode reg */ - Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); - if (!hc->irqcnt) { - printk(KERN_WARNING - "HFC PCI: IRQ(%d) getting no interrupts " - "during init %d\n", hc->irq, 4 - cnt); - if (cnt == 1) { - spin_unlock_irqrestore(&hc->lock, flags); - return -EIO; - } else { - reset_hfcpci(hc); - cnt--; - } - } else { - spin_unlock_irqrestore(&hc->lock, flags); - hc->initdone = 1; - return 0; - } - } - disable_hwirq(hc); - spin_unlock_irqrestore(&hc->lock, flags); - free_irq(hc->irq, hc); - return -EIO; -} - -static int -channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq) -{ - int ret = 0; - u_char slot; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT | - MISDN_CTRL_DISCONNECT; - break; - case MISDN_CTRL_LOOP: - /* channel 0 disabled loop */ - if (cq->channel < 0 || cq->channel > 2) { - ret = -EINVAL; - break; - } - if (cq->channel & 1) { - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) - slot = 0xC0; - else - slot = 0x80; - printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n", - __func__, slot); - Write_hfc(hc, HFCPCI_B1_SSL, slot); - Write_hfc(hc, HFCPCI_B1_RSL, slot); - hc->hw.conn = (hc->hw.conn & ~7) | 6; - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); - } - if (cq->channel & 2) { - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) - slot = 0xC1; - else - slot = 0x81; - printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n", - __func__, slot); - Write_hfc(hc, HFCPCI_B2_SSL, slot); - Write_hfc(hc, HFCPCI_B2_RSL, slot); - hc->hw.conn = (hc->hw.conn & ~0x38) | 0x30; - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); - } - if (cq->channel & 3) - hc->hw.trm |= 0x80; /* enable IOM-loop */ - else { - hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09; - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); - hc->hw.trm &= 0x7f; /* disable IOM-loop */ - } - Write_hfc(hc, HFCPCI_TRM, hc->hw.trm); - break; - case MISDN_CTRL_CONNECT: - if (cq->channel == cq->p1) { - ret = -EINVAL; - break; - } - if (cq->channel < 1 || cq->channel > 2 || - cq->p1 < 1 || cq->p1 > 2) { - ret = -EINVAL; - break; - } - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) - slot = 0xC0; - else - slot = 0x80; - printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n", - __func__, slot); - Write_hfc(hc, HFCPCI_B1_SSL, slot); - Write_hfc(hc, HFCPCI_B2_RSL, slot); - if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) - slot = 0xC1; - else - slot = 0x81; - printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n", - __func__, slot); - Write_hfc(hc, HFCPCI_B2_SSL, slot); - Write_hfc(hc, HFCPCI_B1_RSL, slot); - hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x36; - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); - hc->hw.trm |= 0x80; - Write_hfc(hc, HFCPCI_TRM, hc->hw.trm); - break; - case MISDN_CTRL_DISCONNECT: - hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09; - Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); - hc->hw.trm &= 0x7f; /* disable IOM-loop */ - break; - default: - printk(KERN_WARNING "%s: unknown Op %x\n", - __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; -} - -static int -open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch, - struct channel_req *rq) -{ - int err = 0; - - if (debug & DEBUG_HW_OPEN) - printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__, - hc->dch.dev.id, __builtin_return_address(0)); - if (rq->protocol == ISDN_P_NONE) - return -EINVAL; - if (!hc->initdone) { - if (rq->protocol == ISDN_P_TE_S0) { - err = create_l1(&hc->dch, hfc_l1callback); - if (err) - return err; - } - hc->hw.protocol = rq->protocol; - ch->protocol = rq->protocol; - err = init_card(hc); - if (err) - return err; - } else { - if (rq->protocol != ch->protocol) { - if (hc->hw.protocol == ISDN_P_TE_S0) - l1_event(hc->dch.l1, CLOSE_CHANNEL); - hc->hw.protocol = rq->protocol; - ch->protocol = rq->protocol; - hfcpci_setmode(hc); - } - } - - if (((ch->protocol == ISDN_P_NT_S0) && (hc->dch.state == 3)) || - ((ch->protocol == ISDN_P_TE_S0) && (hc->dch.state == 7))) { - _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, - 0, NULL, GFP_KERNEL); - } - rq->ch = ch; - if (!try_module_get(THIS_MODULE)) - printk(KERN_WARNING "%s:cannot get module\n", __func__); - return 0; -} - -static int -open_bchannel(struct hfc_pci *hc, struct channel_req *rq) -{ - struct bchannel *bch; - - if (rq->adr.channel > 2) - return -EINVAL; - if (rq->protocol == ISDN_P_NONE) - return -EINVAL; - bch = &hc->bch[rq->adr.channel - 1]; - if (test_and_set_bit(FLG_OPEN, &bch->Flags)) - return -EBUSY; /* b-channel can be only open once */ - bch->ch.protocol = rq->protocol; - rq->ch = &bch->ch; /* TODO: E-channel */ - if (!try_module_get(THIS_MODULE)) - printk(KERN_WARNING "%s:cannot get module\n", __func__); - return 0; -} - -/* - * device control function - */ -static int -hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); - struct dchannel *dch = container_of(dev, struct dchannel, dev); - struct hfc_pci *hc = dch->hw; - struct channel_req *rq; - int err = 0; - - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: cmd:%x %p\n", - __func__, cmd, arg); - switch (cmd) { - case OPEN_CHANNEL: - rq = arg; - if (rq->adr.channel == 0) - err = open_dchannel(hc, ch, rq); - else - err = open_bchannel(hc, rq); - break; - case CLOSE_CHANNEL: - if (debug & DEBUG_HW_OPEN) - printk(KERN_DEBUG "%s: dev(%d) close from %p\n", - __func__, hc->dch.dev.id, - __builtin_return_address(0)); - module_put(THIS_MODULE); - break; - case CONTROL_CHANNEL: - err = channel_ctrl(hc, arg); - break; - default: - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: unknown command %x\n", - __func__, cmd); - return -EINVAL; - } - return err; -} - -static int -setup_hw(struct hfc_pci *hc) -{ - void *buffer; - - printk(KERN_INFO "mISDN: HFC-PCI driver %s\n", hfcpci_revision); - hc->hw.cirm = 0; - hc->dch.state = 0; - pci_set_master(hc->pdev); - if (!hc->irq) { - printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); - return 1; - } - hc->hw.pci_io = (char *)(ulong)hc->pdev->resource[1].start; - - if (!hc->hw.pci_io) { - printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); - return 1; - } - /* Allocate memory for FIFOS */ - /* the memory needs to be on a 32k boundary within the first 4G */ - pci_set_dma_mask(hc->pdev, 0xFFFF8000); - buffer = pci_alloc_consistent(hc->pdev, 0x8000, &hc->hw.dmahandle); - /* We silently assume the address is okay if nonzero */ - if (!buffer) { - printk(KERN_WARNING - "HFC-PCI: Error allocating memory for FIFO!\n"); - return 1; - } - hc->hw.fifos = buffer; - pci_write_config_dword(hc->pdev, 0x80, hc->hw.dmahandle); - hc->hw.pci_io = ioremap((ulong) hc->hw.pci_io, 256); - printk(KERN_INFO - "HFC-PCI: defined at mem %#lx fifo %#lx(%#lx) IRQ %d HZ %d\n", - (u_long) hc->hw.pci_io, (u_long) hc->hw.fifos, - (u_long) virt_to_bus(hc->hw.fifos), - hc->irq, HZ); - /* enable memory mapped ports, disable busmaster */ - pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO); - hc->hw.int_m2 = 0; - disable_hwirq(hc); - hc->hw.int_m1 = 0; - Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); - /* At this point the needed PCI config is done */ - /* fifos are still not enabled */ - hc->hw.timer.function = (void *) hfcpci_Timer; - hc->hw.timer.data = (long) hc; - init_timer(&hc->hw.timer); - /* default PCM master */ - test_and_set_bit(HFC_CFG_MASTER, &hc->cfg); - return 0; -} - -static void -release_card(struct hfc_pci *hc) { - u_long flags; - - spin_lock_irqsave(&hc->lock, flags); - hc->hw.int_m2 = 0; /* interrupt output off ! */ - disable_hwirq(hc); - mode_hfcpci(&hc->bch[0], 1, ISDN_P_NONE); - mode_hfcpci(&hc->bch[1], 2, ISDN_P_NONE); - if (hc->dch.timer.function != NULL) { - del_timer(&hc->dch.timer); - hc->dch.timer.function = NULL; - } - spin_unlock_irqrestore(&hc->lock, flags); - if (hc->hw.protocol == ISDN_P_TE_S0) - l1_event(hc->dch.l1, CLOSE_CHANNEL); - if (hc->initdone) - free_irq(hc->irq, hc); - release_io_hfcpci(hc); /* must release after free_irq! */ - mISDN_unregister_device(&hc->dch.dev); - mISDN_freebchannel(&hc->bch[1]); - mISDN_freebchannel(&hc->bch[0]); - mISDN_freedchannel(&hc->dch); - list_del(&hc->list); - pci_set_drvdata(hc->pdev, NULL); - kfree(hc); -} - -static int -setup_card(struct hfc_pci *card) -{ - int err = -EINVAL; - u_int i; - u_long flags; - char name[MISDN_MAX_IDLEN]; - - if (HFC_cnt >= MAX_CARDS) - return -EINVAL; /* maybe better value */ - - card->dch.debug = debug; - spin_lock_init(&card->lock); - mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, ph_state); - card->dch.hw = card; - card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0); - card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); - card->dch.dev.D.send = hfcpci_l2l1D; - card->dch.dev.D.ctrl = hfc_dctrl; - card->dch.dev.nrbchan = 2; - for (i = 0; i < 2; i++) { - card->bch[i].nr = i + 1; - test_and_set_bit(i + 1, &card->dch.dev.channelmap[0]); - card->bch[i].debug = debug; - mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); - card->bch[i].hw = card; - card->bch[i].ch.send = hfcpci_l2l1B; - card->bch[i].ch.ctrl = hfc_bctrl; - card->bch[i].ch.nr = i + 1; - list_add(&card->bch[i].ch.list, &card->dch.dev.bchannels); - } - err = setup_hw(card); - if (err) - goto error; - snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1); - err = mISDN_register_device(&card->dch.dev, name); - if (err) - goto error; - HFC_cnt++; - write_lock_irqsave(&HFClock, flags); - list_add_tail(&card->list, &HFClist); - write_unlock_irqrestore(&HFClock, flags); - printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt); - return 0; -error: - mISDN_freebchannel(&card->bch[1]); - mISDN_freebchannel(&card->bch[0]); - mISDN_freedchannel(&card->dch); - kfree(card); - return err; -} - -/* private data in the PCI devices list */ -struct _hfc_map { - u_int subtype; - u_int flag; - char *name; -}; - -static const struct _hfc_map hfc_map[] = -{ - {HFC_CCD_2BD0, 0, "CCD/Billion/Asuscom 2BD0"}, - {HFC_CCD_B000, 0, "Billion B000"}, - {HFC_CCD_B006, 0, "Billion B006"}, - {HFC_CCD_B007, 0, "Billion B007"}, - {HFC_CCD_B008, 0, "Billion B008"}, - {HFC_CCD_B009, 0, "Billion B009"}, - {HFC_CCD_B00A, 0, "Billion B00A"}, - {HFC_CCD_B00B, 0, "Billion B00B"}, - {HFC_CCD_B00C, 0, "Billion B00C"}, - {HFC_CCD_B100, 0, "Seyeon B100"}, - {HFC_CCD_B700, 0, "Primux II S0 B700"}, - {HFC_CCD_B701, 0, "Primux II S0 NT B701"}, - {HFC_ABOCOM_2BD1, 0, "Abocom/Magitek 2BD1"}, - {HFC_ASUS_0675, 0, "Asuscom/Askey 675"}, - {HFC_BERKOM_TCONCEPT, 0, "German telekom T-Concept"}, - {HFC_BERKOM_A1T, 0, "German telekom A1T"}, - {HFC_ANIGMA_MC145575, 0, "Motorola MC145575"}, - {HFC_ZOLTRIX_2BD0, 0, "Zoltrix 2BD0"}, - {HFC_DIGI_DF_M_IOM2_E, 0, - "Digi International DataFire Micro V IOM2 (Europe)"}, - {HFC_DIGI_DF_M_E, 0, - "Digi International DataFire Micro V (Europe)"}, - {HFC_DIGI_DF_M_IOM2_A, 0, - "Digi International DataFire Micro V IOM2 (North America)"}, - {HFC_DIGI_DF_M_A, 0, - "Digi International DataFire Micro V (North America)"}, - {HFC_SITECOM_DC105V2, 0, "Sitecom Connectivity DC-105 ISDN TA"}, - {}, -}; - -static struct pci_device_id hfc_ids[] = -{ - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[0]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[1]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[2]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[3]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[4]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[5]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[6]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[7]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[8]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[9]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[10]}, - {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[11]}, - {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[12]}, - {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[13]}, - {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[14]}, - {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[15]}, - {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[16]}, - {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[17]}, - {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[18]}, - {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[19]}, - {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[20]}, - {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[21]}, - {PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &hfc_map[22]}, - {}, -}; - -static int __devinit -hfc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int err = -ENOMEM; - struct hfc_pci *card; - struct _hfc_map *m = (struct _hfc_map *)ent->driver_data; - - card = kzalloc(sizeof(struct hfc_pci), GFP_ATOMIC); - if (!card) { - printk(KERN_ERR "No kmem for HFC card\n"); - return err; - } - card->pdev = pdev; - card->subtype = m->subtype; - err = pci_enable_device(pdev); - if (err) { - kfree(card); - return err; - } - - printk(KERN_INFO "mISDN_hfcpci: found adapter %s at %s\n", - m->name, pci_name(pdev)); - - card->irq = pdev->irq; - pci_set_drvdata(pdev, card); - err = setup_card(card); - if (err) - pci_set_drvdata(pdev, NULL); - return err; -} - -static void __devexit -hfc_remove_pci(struct pci_dev *pdev) -{ - struct hfc_pci *card = pci_get_drvdata(pdev); - u_long flags; - - if (card) { - write_lock_irqsave(&HFClock, flags); - release_card(card); - write_unlock_irqrestore(&HFClock, flags); - } else - if (debug) - printk(KERN_WARNING "%s: drvdata allready removed\n", - __func__); -} - - -static struct pci_driver hfc_driver = { - .name = "hfcpci", - .probe = hfc_probe, - .remove = __devexit_p(hfc_remove_pci), - .id_table = hfc_ids, -}; - -static int __init -HFC_init(void) -{ - int err; - - err = pci_register_driver(&hfc_driver); - return err; -} - -static void __exit -HFC_cleanup(void) -{ - struct hfc_pci *card, *next; - - list_for_each_entry_safe(card, next, &HFClist, list) { - release_card(card); - } - pci_unregister_driver(&hfc_driver); -} - -module_init(HFC_init); -module_exit(HFC_cleanup); diff --git a/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c b/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c index 1925118122f8..c0b4db2f8364 100644 --- a/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -974,6 +974,8 @@ static struct pnp_driver fcpnp_driver = { .remove = __devexit_p(fcpnp_remove), .id_table = fcpnp_ids, }; +#else +static struct pnp_driver fcpnp_driver; #endif static void __devexit fcpci_remove(struct pci_dev *pdev) diff --git a/trunk/drivers/isdn/mISDN/Kconfig b/trunk/drivers/isdn/mISDN/Kconfig deleted file mode 100644 index 4938355c4072..000000000000 --- a/trunk/drivers/isdn/mISDN/Kconfig +++ /dev/null @@ -1,44 +0,0 @@ -# -# modularer ISDN driver -# - -menuconfig MISDN - tristate "Modular ISDN driver" - help - Enable support for the modular ISDN driver. - -if MISDN != n - -config MISDN_DSP - tristate "Digital Audio Processing of transparent data" - depends on MISDN - help - Enable support for digital audio processing capability. - This module may be used for special applications that require - cross connecting of bchannels, conferencing, dtmf decoding - echo cancelation, tone generation, and Blowfish encryption and - decryption. - It may use hardware features if available. - E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu - and get more informations about this module and it's usage. - If unsure, say 'N'. - -config MISDN_L1OIP - tristate "ISDN over IP tunnel" - depends on MISDN - help - Enable support for ISDN over IP tunnel. - - It features: - - dynamic IP exchange, if one or both peers have dynamic IPs - - BRI (S0) and PRI (S2M) interface - - layer 1 control via network keepalive frames - - direct tunneling of physical interface via IP - - NOTE: This protocol is called 'Layer 1 over IP' and is not - compatible with ISDNoIP (Agfeo) or TDMoIP. Protocol description is - provided in the source code. - -source "drivers/isdn/hardware/mISDN/Kconfig" - -endif #MISDN diff --git a/trunk/drivers/isdn/mISDN/Makefile b/trunk/drivers/isdn/mISDN/Makefile deleted file mode 100644 index 1cb5e633cf75..000000000000 --- a/trunk/drivers/isdn/mISDN/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for the modular ISDN driver -# - -obj-$(CONFIG_MISDN) += mISDN_core.o -obj-$(CONFIG_MISDN_DSP) += mISDN_dsp.o -obj-$(CONFIG_MISDN_L1OIP) += l1oip.o - -# multi objects - -mISDN_core-objs := core.o fsm.o socket.o hwchannel.o stack.o layer1.o layer2.o tei.o timerdev.o -mISDN_dsp-objs := dsp_core.o dsp_cmx.o dsp_tones.o dsp_dtmf.o dsp_audio.o dsp_blowfish.o dsp_pipeline.o dsp_hwec.o -l1oip-objs := l1oip_core.o l1oip_codec.o diff --git a/trunk/drivers/isdn/mISDN/core.c b/trunk/drivers/isdn/mISDN/core.c deleted file mode 100644 index 33068177b7c9..000000000000 --- a/trunk/drivers/isdn/mISDN/core.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include "core.h" - -static u_int debug; - -MODULE_AUTHOR("Karsten Keil"); -MODULE_LICENSE("GPL"); -module_param(debug, uint, S_IRUGO | S_IWUSR); - -static LIST_HEAD(devices); -DEFINE_RWLOCK(device_lock); -static u64 device_ids; -#define MAX_DEVICE_ID 63 - -static LIST_HEAD(Bprotocols); -DEFINE_RWLOCK(bp_lock); - -struct mISDNdevice -*get_mdevice(u_int id) -{ - struct mISDNdevice *dev; - - read_lock(&device_lock); - list_for_each_entry(dev, &devices, D.list) - if (dev->id == id) { - read_unlock(&device_lock); - return dev; - } - read_unlock(&device_lock); - return NULL; -} - -int -get_mdevice_count(void) -{ - struct mISDNdevice *dev; - int cnt = 0; - - read_lock(&device_lock); - list_for_each_entry(dev, &devices, D.list) - cnt++; - read_unlock(&device_lock); - return cnt; -} - -static int -get_free_devid(void) -{ - u_int i; - - for (i = 0; i <= MAX_DEVICE_ID; i++) - if (!test_and_set_bit(i, (u_long *)&device_ids)) - return i; - return -1; -} - -int -mISDN_register_device(struct mISDNdevice *dev, char *name) -{ - u_long flags; - int err; - - dev->id = get_free_devid(); - if (dev->id < 0) - return -EBUSY; - if (name && name[0]) - strcpy(dev->name, name); - else - sprintf(dev->name, "mISDN%d", dev->id); - if (debug & DEBUG_CORE) - printk(KERN_DEBUG "mISDN_register %s %d\n", - dev->name, dev->id); - err = create_stack(dev); - if (err) - return err; - write_lock_irqsave(&device_lock, flags); - list_add_tail(&dev->D.list, &devices); - write_unlock_irqrestore(&device_lock, flags); - return 0; -} -EXPORT_SYMBOL(mISDN_register_device); - -void -mISDN_unregister_device(struct mISDNdevice *dev) { - u_long flags; - - if (debug & DEBUG_CORE) - printk(KERN_DEBUG "mISDN_unregister %s %d\n", - dev->name, dev->id); - write_lock_irqsave(&device_lock, flags); - list_del(&dev->D.list); - write_unlock_irqrestore(&device_lock, flags); - test_and_clear_bit(dev->id, (u_long *)&device_ids); - delete_stack(dev); -} -EXPORT_SYMBOL(mISDN_unregister_device); - -u_int -get_all_Bprotocols(void) -{ - struct Bprotocol *bp; - u_int m = 0; - - read_lock(&bp_lock); - list_for_each_entry(bp, &Bprotocols, list) - m |= bp->Bprotocols; - read_unlock(&bp_lock); - return m; -} - -struct Bprotocol * -get_Bprotocol4mask(u_int m) -{ - struct Bprotocol *bp; - - read_lock(&bp_lock); - list_for_each_entry(bp, &Bprotocols, list) - if (bp->Bprotocols & m) { - read_unlock(&bp_lock); - return bp; - } - read_unlock(&bp_lock); - return NULL; -} - -struct Bprotocol * -get_Bprotocol4id(u_int id) -{ - u_int m; - - if (id < ISDN_P_B_START || id > 63) { - printk(KERN_WARNING "%s id not in range %d\n", - __func__, id); - return NULL; - } - m = 1 << (id & ISDN_P_B_MASK); - return get_Bprotocol4mask(m); -} - -int -mISDN_register_Bprotocol(struct Bprotocol *bp) -{ - u_long flags; - struct Bprotocol *old; - - if (debug & DEBUG_CORE) - printk(KERN_DEBUG "%s: %s/%x\n", __func__, - bp->name, bp->Bprotocols); - old = get_Bprotocol4mask(bp->Bprotocols); - if (old) { - printk(KERN_WARNING - "register duplicate protocol old %s/%x new %s/%x\n", - old->name, old->Bprotocols, bp->name, bp->Bprotocols); - return -EBUSY; - } - write_lock_irqsave(&bp_lock, flags); - list_add_tail(&bp->list, &Bprotocols); - write_unlock_irqrestore(&bp_lock, flags); - return 0; -} -EXPORT_SYMBOL(mISDN_register_Bprotocol); - -void -mISDN_unregister_Bprotocol(struct Bprotocol *bp) -{ - u_long flags; - - if (debug & DEBUG_CORE) - printk(KERN_DEBUG "%s: %s/%x\n", __func__, bp->name, - bp->Bprotocols); - write_lock_irqsave(&bp_lock, flags); - list_del(&bp->list); - write_unlock_irqrestore(&bp_lock, flags); -} -EXPORT_SYMBOL(mISDN_unregister_Bprotocol); - -int -mISDNInit(void) -{ - int err; - - printk(KERN_INFO "Modular ISDN core version %d.%d.%d\n", - MISDN_MAJOR_VERSION, MISDN_MINOR_VERSION, MISDN_RELEASE); - mISDN_initstack(&debug); - err = mISDN_inittimer(&debug); - if (err) - goto error; - err = l1_init(&debug); - if (err) { - mISDN_timer_cleanup(); - goto error; - } - err = Isdnl2_Init(&debug); - if (err) { - mISDN_timer_cleanup(); - l1_cleanup(); - goto error; - } - err = misdn_sock_init(&debug); - if (err) { - mISDN_timer_cleanup(); - l1_cleanup(); - Isdnl2_cleanup(); - } -error: - return err; -} - -void mISDN_cleanup(void) -{ - misdn_sock_cleanup(); - mISDN_timer_cleanup(); - l1_cleanup(); - Isdnl2_cleanup(); - - if (!list_empty(&devices)) - printk(KERN_ERR "%s devices still registered\n", __func__); - - if (!list_empty(&Bprotocols)) - printk(KERN_ERR "%s Bprotocols still registered\n", __func__); - printk(KERN_DEBUG "mISDNcore unloaded\n"); -} - -module_init(mISDNInit); -module_exit(mISDN_cleanup); - diff --git a/trunk/drivers/isdn/mISDN/core.h b/trunk/drivers/isdn/mISDN/core.h deleted file mode 100644 index 7da7233b4c1a..000000000000 --- a/trunk/drivers/isdn/mISDN/core.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#ifndef mISDN_CORE_H -#define mISDN_CORE_H - -extern struct mISDNdevice *get_mdevice(u_int); -extern int get_mdevice_count(void); - -/* stack status flag */ -#define mISDN_STACK_ACTION_MASK 0x0000ffff -#define mISDN_STACK_COMMAND_MASK 0x000f0000 -#define mISDN_STACK_STATUS_MASK 0xfff00000 -/* action bits 0-15 */ -#define mISDN_STACK_WORK 0 -#define mISDN_STACK_SETUP 1 -#define mISDN_STACK_CLEARING 2 -#define mISDN_STACK_RESTART 3 -#define mISDN_STACK_WAKEUP 4 -#define mISDN_STACK_ABORT 15 -/* command bits 16-19 */ -#define mISDN_STACK_STOPPED 16 -#define mISDN_STACK_INIT 17 -#define mISDN_STACK_THREADSTART 18 -/* status bits 20-31 */ -#define mISDN_STACK_BCHANNEL 20 -#define mISDN_STACK_ACTIVE 29 -#define mISDN_STACK_RUNNING 30 -#define mISDN_STACK_KILLED 31 - - -/* manager options */ -#define MGR_OPT_USER 24 -#define MGR_OPT_NETWORK 25 - -extern int connect_Bstack(struct mISDNdevice *, struct mISDNchannel *, - u_int, struct sockaddr_mISDN *); -extern int connect_layer1(struct mISDNdevice *, struct mISDNchannel *, - u_int, struct sockaddr_mISDN *); -extern int create_l2entity(struct mISDNdevice *, struct mISDNchannel *, - u_int, struct sockaddr_mISDN *); - -extern int create_stack(struct mISDNdevice *); -extern int create_teimanager(struct mISDNdevice *); -extern void delete_teimanager(struct mISDNchannel *); -extern void delete_channel(struct mISDNchannel *); -extern void delete_stack(struct mISDNdevice *); -extern void mISDN_initstack(u_int *); -extern int misdn_sock_init(u_int *); -extern void misdn_sock_cleanup(void); -extern void add_layer2(struct mISDNchannel *, struct mISDNstack *); -extern void __add_layer2(struct mISDNchannel *, struct mISDNstack *); - -extern u_int get_all_Bprotocols(void); -struct Bprotocol *get_Bprotocol4mask(u_int); -struct Bprotocol *get_Bprotocol4id(u_int); - -extern int mISDN_inittimer(u_int *); -extern void mISDN_timer_cleanup(void); - -extern int l1_init(u_int *); -extern void l1_cleanup(void); -extern int Isdnl2_Init(u_int *); -extern void Isdnl2_cleanup(void); - -#endif diff --git a/trunk/drivers/isdn/mISDN/dsp.h b/trunk/drivers/isdn/mISDN/dsp.h deleted file mode 100644 index 6c3fed6b8d4f..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Audio support data for ISDN4Linux. - * - * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu) - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#define DEBUG_DSP_CTRL 0x0001 -#define DEBUG_DSP_CORE 0x0002 -#define DEBUG_DSP_DTMF 0x0004 -#define DEBUG_DSP_CMX 0x0010 -#define DEBUG_DSP_TONE 0x0020 -#define DEBUG_DSP_BLOWFISH 0x0040 -#define DEBUG_DSP_DELAY 0x0100 -#define DEBUG_DSP_DTMFCOEFF 0x8000 /* heavy output */ - -/* options may be: - * - * bit 0 = use ulaw instead of alaw - * bit 1 = enable hfc hardware accelleration for all channels - * - */ -#define DSP_OPT_ULAW (1<<0) -#define DSP_OPT_NOHARDWARE (1<<1) - -#include -#include - -#include "dsp_ecdis.h" - -extern int dsp_options; -extern int dsp_debug; -extern int dsp_poll; -extern int dsp_tics; -extern spinlock_t dsp_lock; -extern struct work_struct dsp_workq; -extern u32 dsp_poll_diff; /* calculated fix-comma corrected poll value */ - -/*************** - * audio stuff * - ***************/ - -extern s32 dsp_audio_alaw_to_s32[256]; -extern s32 dsp_audio_ulaw_to_s32[256]; -extern s32 *dsp_audio_law_to_s32; -extern u8 dsp_audio_s16_to_law[65536]; -extern u8 dsp_audio_alaw_to_ulaw[256]; -extern u8 dsp_audio_mix_law[65536]; -extern u8 dsp_audio_seven2law[128]; -extern u8 dsp_audio_law2seven[256]; -extern void dsp_audio_generate_law_tables(void); -extern void dsp_audio_generate_s2law_table(void); -extern void dsp_audio_generate_seven(void); -extern void dsp_audio_generate_mix_table(void); -extern void dsp_audio_generate_ulaw_samples(void); -extern void dsp_audio_generate_volume_changes(void); -extern u8 dsp_silence; - - -/************* - * cmx stuff * - *************/ - -#define MAX_POLL 256 /* maximum number of send-chunks */ - -#define CMX_BUFF_SIZE 0x8000 /* must be 2**n (0x1000 about 1/2 second) */ -#define CMX_BUFF_HALF 0x4000 /* CMX_BUFF_SIZE / 2 */ -#define CMX_BUFF_MASK 0x7fff /* CMX_BUFF_SIZE - 1 */ - -/* how many seconds will we check the lowest delay until the jitter buffer - is reduced by that delay */ -#define MAX_SECONDS_JITTER_CHECK 5 - -extern struct timer_list dsp_spl_tl; -extern u32 dsp_spl_jiffies; - -/* the structure of conferences: - * - * each conference has a unique number, given by user space. - * the conferences are linked in a chain. - * each conference has members linked in a chain. - * each dsplayer points to a member, each member points to a dsplayer. - */ - -/* all members within a conference (this is linked 1:1 with the dsp) */ -struct dsp; -struct dsp_conf_member { - struct list_head list; - struct dsp *dsp; -}; - -/* the list of all conferences */ -struct dsp_conf { - struct list_head list; - u32 id; - /* all cmx stacks with the same ID are - connected */ - struct list_head mlist; - int software; /* conf is processed by software */ - int hardware; /* conf is processed by hardware */ - /* note: if both unset, has only one member */ -}; - - -/************** - * DTMF stuff * - **************/ - -#define DSP_DTMF_NPOINTS 102 - -#define ECHOCAN_BUFLEN (4*128) - -struct dsp_dtmf { - int treshold; /* above this is dtmf (square of) */ - int software; /* dtmf uses software decoding */ - int hardware; /* dtmf uses hardware decoding */ - int size; /* number of bytes in buffer */ - signed short buffer[DSP_DTMF_NPOINTS]; - /* buffers one full dtmf frame */ - u8 lastwhat, lastdigit; - int count; - u8 digits[16]; /* just the dtmf result */ -}; - - -/****************** - * pipeline stuff * - ******************/ -struct dsp_pipeline { - rwlock_t lock; - struct list_head list; - int inuse; -}; - -/*************** - * tones stuff * - ***************/ - -struct dsp_tone { - int software; /* tones are generated by software */ - int hardware; /* tones are generated by hardware */ - int tone; - void *pattern; - int count; - int index; - struct timer_list tl; -}; - -/***************** - * general stuff * - *****************/ - -struct dsp { - struct list_head list; - struct mISDNchannel ch; - struct mISDNchannel *up; - unsigned char name[64]; - int b_active; - int echo; /* echo is enabled */ - int rx_disabled; /* what the user wants */ - int rx_is_off; /* what the card is */ - int tx_mix; - struct dsp_tone tone; - struct dsp_dtmf dtmf; - int tx_volume, rx_volume; - - /* queue for sending frames */ - struct work_struct workq; - struct sk_buff_head sendq; - int hdlc; /* if mode is hdlc */ - int data_pending; /* currently an unconfirmed frame */ - - /* conference stuff */ - u32 conf_id; - struct dsp_conf *conf; - struct dsp_conf_member - *member; - - /* buffer stuff */ - int rx_W; /* current write pos for data without timestamp */ - int rx_R; /* current read pos for transmit clock */ - int rx_init; /* if set, pointers will be adjusted first */ - int tx_W; /* current write pos for transmit data */ - int tx_R; /* current read pos for transmit clock */ - int rx_delay[MAX_SECONDS_JITTER_CHECK]; - int tx_delay[MAX_SECONDS_JITTER_CHECK]; - u8 tx_buff[CMX_BUFF_SIZE]; - u8 rx_buff[CMX_BUFF_SIZE]; - int last_tx; /* if set, we transmitted last poll interval */ - int cmx_delay; /* initial delay of buffers, - or 0 for dynamic jitter buffer */ - int tx_dejitter; /* if set, dejitter tx buffer */ - int tx_data; /* enables tx-data of CMX to upper layer */ - - /* hardware stuff */ - struct dsp_features features; - int features_rx_off; /* set if rx_off is featured */ - int pcm_slot_rx; /* current PCM slot (or -1) */ - int pcm_bank_rx; - int pcm_slot_tx; - int pcm_bank_tx; - int hfc_conf; /* unique id of current conference (or -1) */ - - /* encryption stuff */ - int bf_enable; - u32 bf_p[18]; - u32 bf_s[1024]; - int bf_crypt_pos; - u8 bf_data_in[9]; - u8 bf_crypt_out[9]; - int bf_decrypt_in_pos; - int bf_decrypt_out_pos; - u8 bf_crypt_inring[16]; - u8 bf_data_out[9]; - int bf_sync; - - struct dsp_pipeline - pipeline; -}; - -/* functions */ - -extern void dsp_change_volume(struct sk_buff *skb, int volume); - -extern struct list_head dsp_ilist; -extern struct list_head conf_ilist; -extern void dsp_cmx_debug(struct dsp *dsp); -extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp); -extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id); -extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb); -extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb); -extern void dsp_cmx_send(void *arg); -extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb); -extern int dsp_cmx_del_conf_member(struct dsp *dsp); -extern int dsp_cmx_del_conf(struct dsp_conf *conf); - -extern void dsp_dtmf_goertzel_init(struct dsp *dsp); -extern void dsp_dtmf_hardware(struct dsp *dsp); -extern u8 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len, - int fmt); - -extern int dsp_tone(struct dsp *dsp, int tone); -extern void dsp_tone_copy(struct dsp *dsp, u8 *data, int len); -extern void dsp_tone_timeout(void *arg); - -extern void dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len); -extern void dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len); -extern int dsp_bf_init(struct dsp *dsp, const u8 *key, unsigned int keylen); -extern void dsp_bf_cleanup(struct dsp *dsp); - -extern int dsp_pipeline_module_init(void); -extern void dsp_pipeline_module_exit(void); -extern int dsp_pipeline_init(struct dsp_pipeline *pipeline); -extern void dsp_pipeline_destroy(struct dsp_pipeline *pipeline); -extern int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg); -extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, - int len); -extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, - int len); - diff --git a/trunk/drivers/isdn/mISDN/dsp_audio.c b/trunk/drivers/isdn/mISDN/dsp_audio.c deleted file mode 100644 index 1c2dd5694773..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_audio.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Audio support data for mISDN_dsp. - * - * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu) - * Rewritten by Peter - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include -#include -#include -#include "core.h" -#include "dsp.h" - -/* ulaw[unsigned char] -> signed 16-bit */ -s32 dsp_audio_ulaw_to_s32[256]; -/* alaw[unsigned char] -> signed 16-bit */ -s32 dsp_audio_alaw_to_s32[256]; - -s32 *dsp_audio_law_to_s32; -EXPORT_SYMBOL(dsp_audio_law_to_s32); - -/* signed 16-bit -> law */ -u8 dsp_audio_s16_to_law[65536]; -EXPORT_SYMBOL(dsp_audio_s16_to_law); - -/* alaw -> ulaw */ -u8 dsp_audio_alaw_to_ulaw[256]; -/* ulaw -> alaw */ -u8 dsp_audio_ulaw_to_alaw[256]; -u8 dsp_silence; - - -/***************************************************** - * generate table for conversion of s16 to alaw/ulaw * - *****************************************************/ - -#define AMI_MASK 0x55 - -static inline unsigned char linear2alaw(short int linear) -{ - int mask; - int seg; - int pcm_val; - static int seg_end[8] = { - 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF - }; - - pcm_val = linear; - if (pcm_val >= 0) { - /* Sign (7th) bit = 1 */ - mask = AMI_MASK | 0x80; - } else { - /* Sign bit = 0 */ - mask = AMI_MASK; - pcm_val = -pcm_val; - } - - /* Convert the scaled magnitude to segment number. */ - for (seg = 0; seg < 8; seg++) { - if (pcm_val <= seg_end[seg]) - break; - } - /* Combine the sign, segment, and quantization bits. */ - return ((seg << 4) | - ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask; -} - - -static inline short int alaw2linear(unsigned char alaw) -{ - int i; - int seg; - - alaw ^= AMI_MASK; - i = ((alaw & 0x0F) << 4) + 8 /* rounding error */; - seg = (((int) alaw & 0x70) >> 4); - if (seg) - i = (i + 0x100) << (seg - 1); - return (short int) ((alaw & 0x80) ? i : -i); -} - -static inline short int ulaw2linear(unsigned char ulaw) -{ - short mu, e, f, y; - static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764}; - - mu = 255 - ulaw; - e = (mu & 0x70) / 16; - f = mu & 0x0f; - y = f * (1 << (e + 3)); - y += etab[e]; - if (mu & 0x80) - y = -y; - return y; -} - -#define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */ - -static unsigned char linear2ulaw(short sample) -{ - static int exp_lut[256] = { - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; - int sign, exponent, mantissa; - unsigned char ulawbyte; - - /* Get the sample into sign-magnitude. */ - sign = (sample >> 8) & 0x80; /* set aside the sign */ - if (sign != 0) - sample = -sample; /* get magnitude */ - - /* Convert from 16 bit linear to ulaw. */ - sample = sample + BIAS; - exponent = exp_lut[(sample >> 7) & 0xFF]; - mantissa = (sample >> (exponent + 3)) & 0x0F; - ulawbyte = ~(sign | (exponent << 4) | mantissa); - - return ulawbyte; -} - -static int reverse_bits(int i) -{ - int z, j; - z = 0; - - for (j = 0; j < 8; j++) { - if ((i & (1 << j)) != 0) - z |= 1 << (7 - j); - } - return z; -} - - -void dsp_audio_generate_law_tables(void) -{ - int i; - for (i = 0; i < 256; i++) - dsp_audio_alaw_to_s32[i] = alaw2linear(reverse_bits(i)); - - for (i = 0; i < 256; i++) - dsp_audio_ulaw_to_s32[i] = ulaw2linear(reverse_bits(i)); - - for (i = 0; i < 256; i++) { - dsp_audio_alaw_to_ulaw[i] = - linear2ulaw(dsp_audio_alaw_to_s32[i]); - dsp_audio_ulaw_to_alaw[i] = - linear2alaw(dsp_audio_ulaw_to_s32[i]); - } -} - -void -dsp_audio_generate_s2law_table(void) -{ - int i; - - if (dsp_options & DSP_OPT_ULAW) { - /* generating ulaw-table */ - for (i = -32768; i < 32768; i++) { - dsp_audio_s16_to_law[i & 0xffff] = - reverse_bits(linear2ulaw(i)); - } - } else { - /* generating alaw-table */ - for (i = -32768; i < 32768; i++) { - dsp_audio_s16_to_law[i & 0xffff] = - reverse_bits(linear2alaw(i)); - } - } -} - - -/* - * the seven bit sample is the number of every second alaw-sample ordered by - * aplitude. 0x00 is negative, 0x7f is positive amplitude. - */ -u8 dsp_audio_seven2law[128]; -u8 dsp_audio_law2seven[256]; - -/******************************************************************** - * generate table for conversion law from/to 7-bit alaw-like sample * - ********************************************************************/ - -void -dsp_audio_generate_seven(void) -{ - int i, j, k; - u8 spl; - u8 sorted_alaw[256]; - - /* generate alaw table, sorted by the linear value */ - for (i = 0; i < 256; i++) { - j = 0; - for (k = 0; k < 256; k++) { - if (dsp_audio_alaw_to_s32[k] - < dsp_audio_alaw_to_s32[i]) { - j++; - } - } - sorted_alaw[j] = i; - } - - /* generate tabels */ - for (i = 0; i < 256; i++) { - /* spl is the source: the law-sample (converted to alaw) */ - spl = i; - if (dsp_options & DSP_OPT_ULAW) - spl = dsp_audio_ulaw_to_alaw[i]; - /* find the 7-bit-sample */ - for (j = 0; j < 256; j++) { - if (sorted_alaw[j] == spl) - break; - } - /* write 7-bit audio value */ - dsp_audio_law2seven[i] = j >> 1; - } - for (i = 0; i < 128; i++) { - spl = sorted_alaw[i << 1]; - if (dsp_options & DSP_OPT_ULAW) - spl = dsp_audio_alaw_to_ulaw[spl]; - dsp_audio_seven2law[i] = spl; - } -} - - -/* mix 2*law -> law */ -u8 dsp_audio_mix_law[65536]; - -/****************************************************** - * generate mix table to mix two law samples into one * - ******************************************************/ - -void -dsp_audio_generate_mix_table(void) -{ - int i, j; - s32 sample; - - i = 0; - while (i < 256) { - j = 0; - while (j < 256) { - sample = dsp_audio_law_to_s32[i]; - sample += dsp_audio_law_to_s32[j]; - if (sample > 32767) - sample = 32767; - if (sample < -32768) - sample = -32768; - dsp_audio_mix_law[(i<<8)|j] = - dsp_audio_s16_to_law[sample & 0xffff]; - j++; - } - i++; - } -} - - -/************************************* - * generate different volume changes * - *************************************/ - -static u8 dsp_audio_reduce8[256]; -static u8 dsp_audio_reduce7[256]; -static u8 dsp_audio_reduce6[256]; -static u8 dsp_audio_reduce5[256]; -static u8 dsp_audio_reduce4[256]; -static u8 dsp_audio_reduce3[256]; -static u8 dsp_audio_reduce2[256]; -static u8 dsp_audio_reduce1[256]; -static u8 dsp_audio_increase1[256]; -static u8 dsp_audio_increase2[256]; -static u8 dsp_audio_increase3[256]; -static u8 dsp_audio_increase4[256]; -static u8 dsp_audio_increase5[256]; -static u8 dsp_audio_increase6[256]; -static u8 dsp_audio_increase7[256]; -static u8 dsp_audio_increase8[256]; - -static u8 *dsp_audio_volume_change[16] = { - dsp_audio_reduce8, - dsp_audio_reduce7, - dsp_audio_reduce6, - dsp_audio_reduce5, - dsp_audio_reduce4, - dsp_audio_reduce3, - dsp_audio_reduce2, - dsp_audio_reduce1, - dsp_audio_increase1, - dsp_audio_increase2, - dsp_audio_increase3, - dsp_audio_increase4, - dsp_audio_increase5, - dsp_audio_increase6, - dsp_audio_increase7, - dsp_audio_increase8, -}; - -void -dsp_audio_generate_volume_changes(void) -{ - register s32 sample; - int i; - int num[] = { 110, 125, 150, 175, 200, 300, 400, 500 }; - int denum[] = { 100, 100, 100, 100, 100, 100, 100, 100 }; - - i = 0; - while (i < 256) { - dsp_audio_reduce8[i] = dsp_audio_s16_to_law[ - (dsp_audio_law_to_s32[i] * denum[7] / num[7]) & 0xffff]; - dsp_audio_reduce7[i] = dsp_audio_s16_to_law[ - (dsp_audio_law_to_s32[i] * denum[6] / num[6]) & 0xffff]; - dsp_audio_reduce6[i] = dsp_audio_s16_to_law[ - (dsp_audio_law_to_s32[i] * denum[5] / num[5]) & 0xffff]; - dsp_audio_reduce5[i] = dsp_audio_s16_to_law[ - (dsp_audio_law_to_s32[i] * denum[4] / num[4]) & 0xffff]; - dsp_audio_reduce4[i] = dsp_audio_s16_to_law[ - (dsp_audio_law_to_s32[i] * denum[3] / num[3]) & 0xffff]; - dsp_audio_reduce3[i] = dsp_audio_s16_to_law[ - (dsp_audio_law_to_s32[i] * denum[2] / num[2]) & 0xffff]; - dsp_audio_reduce2[i] = dsp_audio_s16_to_law[ - (dsp_audio_law_to_s32[i] * denum[1] / num[1]) & 0xffff]; - dsp_audio_reduce1[i] = dsp_audio_s16_to_law[ - (dsp_audio_law_to_s32[i] * denum[0] / num[0]) & 0xffff]; - sample = dsp_audio_law_to_s32[i] * num[0] / denum[0]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - dsp_audio_increase1[i] = dsp_audio_s16_to_law[sample & 0xffff]; - sample = dsp_audio_law_to_s32[i] * num[1] / denum[1]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - dsp_audio_increase2[i] = dsp_audio_s16_to_law[sample & 0xffff]; - sample = dsp_audio_law_to_s32[i] * num[2] / denum[2]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - dsp_audio_increase3[i] = dsp_audio_s16_to_law[sample & 0xffff]; - sample = dsp_audio_law_to_s32[i] * num[3] / denum[3]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - dsp_audio_increase4[i] = dsp_audio_s16_to_law[sample & 0xffff]; - sample = dsp_audio_law_to_s32[i] * num[4] / denum[4]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - dsp_audio_increase5[i] = dsp_audio_s16_to_law[sample & 0xffff]; - sample = dsp_audio_law_to_s32[i] * num[5] / denum[5]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - dsp_audio_increase6[i] = dsp_audio_s16_to_law[sample & 0xffff]; - sample = dsp_audio_law_to_s32[i] * num[6] / denum[6]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - dsp_audio_increase7[i] = dsp_audio_s16_to_law[sample & 0xffff]; - sample = dsp_audio_law_to_s32[i] * num[7] / denum[7]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - dsp_audio_increase8[i] = dsp_audio_s16_to_law[sample & 0xffff]; - - i++; - } -} - - -/************************************** - * change the volume of the given skb * - **************************************/ - -/* this is a helper function for changing volume of skb. the range may be - * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8 - */ -void -dsp_change_volume(struct sk_buff *skb, int volume) -{ - u8 *volume_change; - int i, ii; - u8 *p; - int shift; - - if (volume == 0) - return; - - /* get correct conversion table */ - if (volume < 0) { - shift = volume + 8; - if (shift < 0) - shift = 0; - } else { - shift = volume + 7; - if (shift > 15) - shift = 15; - } - volume_change = dsp_audio_volume_change[shift]; - i = 0; - ii = skb->len; - p = skb->data; - /* change volume */ - while (i < ii) { - *p = volume_change[*p]; - p++; - i++; - } -} - diff --git a/trunk/drivers/isdn/mISDN/dsp_biquad.h b/trunk/drivers/isdn/mISDN/dsp_biquad.h deleted file mode 100644 index 038191bc45f5..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_biquad.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * biquad.h - General telephony bi-quad section routines (currently this just - * handles canonic/type 2 form) - * - * Written by Steve Underwood - * - * Copyright (C) 2001 Steve Underwood - * - * 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; 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -struct biquad2_state { - int32_t gain; - int32_t a1; - int32_t a2; - int32_t b1; - int32_t b2; - - int32_t z1; - int32_t z2; -}; - -static inline void biquad2_init(struct biquad2_state *bq, - int32_t gain, int32_t a1, int32_t a2, int32_t b1, int32_t b2) -{ - bq->gain = gain; - bq->a1 = a1; - bq->a2 = a2; - bq->b1 = b1; - bq->b2 = b2; - - bq->z1 = 0; - bq->z2 = 0; -} - -static inline int16_t biquad2(struct biquad2_state *bq, int16_t sample) -{ - int32_t y; - int32_t z0; - - z0 = sample*bq->gain + bq->z1*bq->a1 + bq->z2*bq->a2; - y = z0 + bq->z1*bq->b1 + bq->z2*bq->b2; - - bq->z2 = bq->z1; - bq->z1 = z0 >> 15; - y >>= 15; - return y; -} diff --git a/trunk/drivers/isdn/mISDN/dsp_blowfish.c b/trunk/drivers/isdn/mISDN/dsp_blowfish.c deleted file mode 100644 index 18e411e95bba..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_blowfish.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * Blowfish encryption/decryption for mISDN_dsp. - * - * Copyright Andreas Eversberg (jolly@eversberg.eu) - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include -#include -#include "core.h" -#include "dsp.h" - -/* - * how to encode a sample stream to 64-bit blocks that will be encryped - * - * first of all, data is collected until a block of 9 samples are received. - * of course, a packet may have much more than 9 sample, but is may have - * not excacly the multiple of 9 samples. if there is a rest, the next - * received data will complete the block. - * - * the block is then converted to 9 uLAW samples without the least sigificant - * bit. the result is a 7-bit encoded sample. - * - * the samples will be reoganised to form 8 bytes of data: - * (5(6) means: encoded sample no. 5, bit 6) - * - * 0(6) 0(5) 0(4) 0(3) 0(2) 0(1) 0(0) 1(6) - * 1(5) 1(4) 1(3) 1(2) 1(1) 1(0) 2(6) 2(5) - * 2(4) 2(3) 2(2) 2(1) 2(0) 3(6) 3(5) 3(4) - * 3(3) 3(2) 3(1) 3(0) 4(6) 4(5) 4(4) 4(3) - * 4(2) 4(1) 4(0) 5(6) 5(5) 5(4) 5(3) 5(2) - * 5(1) 5(0) 6(6) 6(5) 6(4) 6(3) 6(2) 6(1) - * 6(0) 7(6) 7(5) 7(4) 7(3) 7(2) 7(1) 7(0) - * 8(6) 8(5) 8(4) 8(3) 8(2) 8(1) 8(0) - * - * the missing bit 0 of the last byte is filled with some - * random noise, to fill all 8 bytes. - * - * the 8 bytes will be encrypted using blowfish. - * - * the result will be converted into 9 bytes. the bit 7 is used for - * checksumme (CS) for sync (0, 1) and for the last bit: - * (5(6) means: crypted byte 5, bit 6) - * - * 1 0(7) 0(6) 0(5) 0(4) 0(3) 0(2) 0(1) - * 0 0(0) 1(7) 1(6) 1(5) 1(4) 1(3) 1(2) - * 0 1(1) 1(0) 2(7) 2(6) 2(5) 2(4) 2(3) - * 0 2(2) 2(1) 2(0) 3(7) 3(6) 3(5) 3(4) - * 0 3(3) 3(2) 3(1) 3(0) 4(7) 4(6) 4(5) - * CS 4(4) 4(3) 4(2) 4(1) 4(0) 5(7) 5(6) - * CS 5(5) 5(4) 5(3) 5(2) 5(1) 5(0) 6(7) - * CS 6(6) 6(5) 6(4) 6(3) 6(2) 6(1) 6(0) - * 7(0) 7(6) 7(5) 7(4) 7(3) 7(2) 7(1) 7(0) - * - * the checksum is used to detect transmission errors and frame drops. - * - * synchronisation of received block is done by shifting the upper bit of each - * byte (bit 7) to a shift register. if the rigister has the first five bits - * (10000), this is used to find the sync. only if sync has been found, the - * current block of 9 received bytes are decrypted. before that the check - * sum is calculated. if it is incorrect the block is dropped. - * this will avoid loud noise due to corrupt encrypted data. - * - * if the last block is corrupt, the current decoded block is repeated - * until a valid block has been received. - */ - -/* - * some blowfish parts are taken from the - * crypto-api for faster implementation - */ - -struct bf_ctx { - u32 p[18]; - u32 s[1024]; -}; - -static const u32 bf_pbox[16 + 2] = { - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, - 0x9216d5d9, 0x8979fb1b, -}; - -static const u32 bf_sbox[256 * 4] = { - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, - 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, - 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, - 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, - 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, - 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, - 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, - 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, - 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, - 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, - 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, - 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, - 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, - 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, - 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, - 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, - 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, - 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, - 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, - 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, - 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, - 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, - 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, - 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, - 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, - 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, - 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, - 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, - 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, - 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, - 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, - 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, - 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, - 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, - 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, - 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, - 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, - 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, - 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, - 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, - 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, - 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, - 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, - 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, - 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, - 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, - 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, - 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, - 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, - 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, - 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, - 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, - 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, - 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, - 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, - 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, - 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, - 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, - 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, - 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, - 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, - 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, - 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, - 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, - 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, - 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, - 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, - 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, -}; - -/* - * Round loop unrolling macros, S is a pointer to a S-Box array - * organized in 4 unsigned longs at a row. - */ -#define GET32_3(x) (((x) & 0xff)) -#define GET32_2(x) (((x) >> (8)) & (0xff)) -#define GET32_1(x) (((x) >> (16)) & (0xff)) -#define GET32_0(x) (((x) >> (24)) & (0xff)) - -#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \ - S[512 + GET32_2(x)]) + S[768 + GET32_3(x)]) - -#define EROUND(a, b, n) do { b ^= P[n]; a ^= bf_F(b); } while (0) -#define DROUND(a, b, n) do { a ^= bf_F(b); b ^= P[n]; } while (0) - - -/* - * encrypt isdn data frame - * every block with 9 samples is encrypted - */ -void -dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len) -{ - int i = 0, j = dsp->bf_crypt_pos; - u8 *bf_data_in = dsp->bf_data_in; - u8 *bf_crypt_out = dsp->bf_crypt_out; - u32 *P = dsp->bf_p; - u32 *S = dsp->bf_s; - u32 yl, yr; - u32 cs; - u8 nibble; - - while (i < len) { - /* collect a block of 9 samples */ - if (j < 9) { - bf_data_in[j] = *data; - *data++ = bf_crypt_out[j++]; - i++; - continue; - } - j = 0; - /* transcode 9 samples xlaw to 8 bytes */ - yl = dsp_audio_law2seven[bf_data_in[0]]; - yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[1]]; - yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[2]]; - yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[3]]; - nibble = dsp_audio_law2seven[bf_data_in[4]]; - yr = nibble; - yl = (yl<<4) | (nibble>>3); - yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[5]]; - yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[6]]; - yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[7]]; - yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[8]]; - yr = (yr<<1) | (bf_data_in[0] & 1); - - /* fill unused bit with random noise of audio input */ - /* encrypt */ - - EROUND(yr, yl, 0); - EROUND(yl, yr, 1); - EROUND(yr, yl, 2); - EROUND(yl, yr, 3); - EROUND(yr, yl, 4); - EROUND(yl, yr, 5); - EROUND(yr, yl, 6); - EROUND(yl, yr, 7); - EROUND(yr, yl, 8); - EROUND(yl, yr, 9); - EROUND(yr, yl, 10); - EROUND(yl, yr, 11); - EROUND(yr, yl, 12); - EROUND(yl, yr, 13); - EROUND(yr, yl, 14); - EROUND(yl, yr, 15); - yl ^= P[16]; - yr ^= P[17]; - - /* calculate 3-bit checksumme */ - cs = yl ^ (yl>>3) ^ (yl>>6) ^ (yl>>9) ^ (yl>>12) ^ (yl>>15) - ^ (yl>>18) ^ (yl>>21) ^ (yl>>24) ^ (yl>>27) ^ (yl>>30) - ^ (yr<<2) ^ (yr>>1) ^ (yr>>4) ^ (yr>>7) ^ (yr>>10) - ^ (yr>>13) ^ (yr>>16) ^ (yr>>19) ^ (yr>>22) ^ (yr>>25) - ^ (yr>>28) ^ (yr>>31); - - /* - * transcode 8 crypted bytes to 9 data bytes with sync - * and checksum information - */ - bf_crypt_out[0] = (yl>>25) | 0x80; - bf_crypt_out[1] = (yl>>18) & 0x7f; - bf_crypt_out[2] = (yl>>11) & 0x7f; - bf_crypt_out[3] = (yl>>4) & 0x7f; - bf_crypt_out[4] = ((yl<<3) & 0x78) | ((yr>>29) & 0x07); - bf_crypt_out[5] = ((yr>>22) & 0x7f) | ((cs<<5) & 0x80); - bf_crypt_out[6] = ((yr>>15) & 0x7f) | ((cs<<6) & 0x80); - bf_crypt_out[7] = ((yr>>8) & 0x7f) | (cs<<7); - bf_crypt_out[8] = yr; - } - - /* write current count */ - dsp->bf_crypt_pos = j; - -} - - -/* - * decrypt isdn data frame - * every block with 9 bytes is decrypted - */ -void -dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len) -{ - int i = 0; - u8 j = dsp->bf_decrypt_in_pos; - u8 k = dsp->bf_decrypt_out_pos; - u8 *bf_crypt_inring = dsp->bf_crypt_inring; - u8 *bf_data_out = dsp->bf_data_out; - u16 sync = dsp->bf_sync; - u32 *P = dsp->bf_p; - u32 *S = dsp->bf_s; - u32 yl, yr; - u8 nibble; - u8 cs, cs0, cs1, cs2; - - while (i < len) { - /* - * shift upper bit and rotate data to buffer ring - * send current decrypted data - */ - sync = (sync<<1) | ((*data)>>7); - bf_crypt_inring[j++ & 15] = *data; - *data++ = bf_data_out[k++]; - i++; - if (k == 9) - k = 0; /* repeat if no sync has been found */ - /* check if not in sync */ - if ((sync&0x1f0) != 0x100) - continue; - j -= 9; - /* transcode receive data to 64 bit block of encrypted data */ - yl = bf_crypt_inring[j++ & 15]; - yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */ - yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */ - yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */ - nibble = bf_crypt_inring[j++ & 15]; /* bit7 = 0 */ - yr = nibble; - yl = (yl<<4) | (nibble>>3); - cs2 = bf_crypt_inring[j++ & 15]; - yr = (yr<<7) | (cs2 & 0x7f); - cs1 = bf_crypt_inring[j++ & 15]; - yr = (yr<<7) | (cs1 & 0x7f); - cs0 = bf_crypt_inring[j++ & 15]; - yr = (yr<<7) | (cs0 & 0x7f); - yr = (yr<<8) | bf_crypt_inring[j++ & 15]; - - /* calculate 3-bit checksumme */ - cs = yl ^ (yl>>3) ^ (yl>>6) ^ (yl>>9) ^ (yl>>12) ^ (yl>>15) - ^ (yl>>18) ^ (yl>>21) ^ (yl>>24) ^ (yl>>27) ^ (yl>>30) - ^ (yr<<2) ^ (yr>>1) ^ (yr>>4) ^ (yr>>7) ^ (yr>>10) - ^ (yr>>13) ^ (yr>>16) ^ (yr>>19) ^ (yr>>22) ^ (yr>>25) - ^ (yr>>28) ^ (yr>>31); - - /* check if frame is valid */ - if ((cs&0x7) != (((cs2>>5)&4) | ((cs1>>6)&2) | (cs0 >> 7))) { - if (dsp_debug & DEBUG_DSP_BLOWFISH) - printk(KERN_DEBUG - "DSP BLOWFISH: received corrupt frame, " - "checksumme is not correct\n"); - continue; - } - - /* decrypt */ - yr ^= P[17]; - yl ^= P[16]; - DROUND(yl, yr, 15); - DROUND(yr, yl, 14); - DROUND(yl, yr, 13); - DROUND(yr, yl, 12); - DROUND(yl, yr, 11); - DROUND(yr, yl, 10); - DROUND(yl, yr, 9); - DROUND(yr, yl, 8); - DROUND(yl, yr, 7); - DROUND(yr, yl, 6); - DROUND(yl, yr, 5); - DROUND(yr, yl, 4); - DROUND(yl, yr, 3); - DROUND(yr, yl, 2); - DROUND(yl, yr, 1); - DROUND(yr, yl, 0); - - /* transcode 8 crypted bytes to 9 sample bytes */ - bf_data_out[0] = dsp_audio_seven2law[(yl>>25) & 0x7f]; - bf_data_out[1] = dsp_audio_seven2law[(yl>>18) & 0x7f]; - bf_data_out[2] = dsp_audio_seven2law[(yl>>11) & 0x7f]; - bf_data_out[3] = dsp_audio_seven2law[(yl>>4) & 0x7f]; - bf_data_out[4] = dsp_audio_seven2law[((yl<<3) & 0x78) | - ((yr>>29) & 0x07)]; - - bf_data_out[5] = dsp_audio_seven2law[(yr>>22) & 0x7f]; - bf_data_out[6] = dsp_audio_seven2law[(yr>>15) & 0x7f]; - bf_data_out[7] = dsp_audio_seven2law[(yr>>8) & 0x7f]; - bf_data_out[8] = dsp_audio_seven2law[(yr>>1) & 0x7f]; - k = 0; /* start with new decoded frame */ - } - - /* write current count and sync */ - dsp->bf_decrypt_in_pos = j; - dsp->bf_decrypt_out_pos = k; - dsp->bf_sync = sync; -} - - -/* used to encrypt S and P boxes */ -static inline void -encrypt_block(const u32 *P, const u32 *S, u32 *dst, u32 *src) -{ - u32 yl = src[0]; - u32 yr = src[1]; - - EROUND(yr, yl, 0); - EROUND(yl, yr, 1); - EROUND(yr, yl, 2); - EROUND(yl, yr, 3); - EROUND(yr, yl, 4); - EROUND(yl, yr, 5); - EROUND(yr, yl, 6); - EROUND(yl, yr, 7); - EROUND(yr, yl, 8); - EROUND(yl, yr, 9); - EROUND(yr, yl, 10); - EROUND(yl, yr, 11); - EROUND(yr, yl, 12); - EROUND(yl, yr, 13); - EROUND(yr, yl, 14); - EROUND(yl, yr, 15); - - yl ^= P[16]; - yr ^= P[17]; - - dst[0] = yr; - dst[1] = yl; -} - -/* - * initialize the dsp for encryption and decryption using the same key - * Calculates the blowfish S and P boxes for encryption and decryption. - * The margin of keylen must be 4-56 bytes. - * returns 0 if ok. - */ -int -dsp_bf_init(struct dsp *dsp, const u8 *key, uint keylen) -{ - short i, j, count; - u32 data[2], temp; - u32 *P = (u32 *)dsp->bf_p; - u32 *S = (u32 *)dsp->bf_s; - - if (keylen < 4 || keylen > 56) - return 1; - - /* Set dsp states */ - i = 0; - while (i < 9) { - dsp->bf_crypt_out[i] = 0xff; - dsp->bf_data_out[i] = dsp_silence; - i++; - } - dsp->bf_crypt_pos = 0; - dsp->bf_decrypt_in_pos = 0; - dsp->bf_decrypt_out_pos = 0; - dsp->bf_sync = 0x1ff; - dsp->bf_enable = 1; - - /* Copy the initialization s-boxes */ - for (i = 0, count = 0; i < 256; i++) - for (j = 0; j < 4; j++, count++) - S[count] = bf_sbox[count]; - - /* Set the p-boxes */ - for (i = 0; i < 16 + 2; i++) - P[i] = bf_pbox[i]; - - /* Actual subkey generation */ - for (j = 0, i = 0; i < 16 + 2; i++) { - temp = (((u32)key[j] << 24) | - ((u32)key[(j + 1) % keylen] << 16) | - ((u32)key[(j + 2) % keylen] << 8) | - ((u32)key[(j + 3) % keylen])); - - P[i] = P[i] ^ temp; - j = (j + 4) % keylen; - } - - data[0] = 0x00000000; - data[1] = 0x00000000; - - for (i = 0; i < 16 + 2; i += 2) { - encrypt_block(P, S, data, data); - - P[i] = data[0]; - P[i + 1] = data[1]; - } - - for (i = 0; i < 4; i++) { - for (j = 0, count = i * 256; j < 256; j += 2, count += 2) { - encrypt_block(P, S, data, data); - - S[count] = data[0]; - S[count + 1] = data[1]; - } - } - - return 0; -} - - -/* - * turn encryption off - */ -void -dsp_bf_cleanup(struct dsp *dsp) -{ - dsp->bf_enable = 0; -} diff --git a/trunk/drivers/isdn/mISDN/dsp_cmx.c b/trunk/drivers/isdn/mISDN/dsp_cmx.c deleted file mode 100644 index e92b1ba4b45e..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_cmx.c +++ /dev/null @@ -1,1886 +0,0 @@ -/* - * Audio crossconnecting/conferrencing (hardware level). - * - * Copyright 2002 by Andreas Eversberg (jolly@eversberg.eu) - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -/* - * The process of adding and removing parties to/from a conference: - * - * There is a chain of struct dsp_conf which has one or more members in a chain - * of struct dsp_conf_member. - * - * After a party is added, the conference is checked for hardware capability. - * Also if a party is removed, the conference is checked again. - * - * There are 3 different solutions: -1 = software, 0 = hardware-crossconnect - * 1-n = hardware-conference. The n will give the conference number. - * - * Depending on the change after removal or insertion of a party, hardware - * commands are given. - * - * The current solution is stored within the struct dsp_conf entry. - */ - -/* - * HOW THE CMX WORKS: - * - * There are 3 types of interaction: One member is alone, in this case only - * data flow from upper to lower layer is done. - * Two members will also exchange their data so they are crossconnected. - * Three or more members will be added in a conference and will hear each - * other but will not receive their own speech (echo) if not enabled. - * - * Features of CMX are: - * - Crossconnecting or even conference, if more than two members are together. - * - Force mixing of transmit data with other crossconnect/conference members. - * - Echo generation to benchmark the delay of audio processing. - * - Use hardware to minimize cpu load, disable FIFO load and minimize delay. - * - Dejittering and clock generation. - * - * There are 2 buffers: - * - * - * RX-Buffer - * R W - * | | - * ----------------+-------------+------------------- - * - * The rx-buffer is a ring buffer used to store the received data for each - * individual member. This is only the case if data needs to be dejittered - * or in case of a conference where different clocks require reclocking. - * The transmit-clock (R) will read the buffer. - * If the clock overruns the write-pointer, we will have a buffer underrun. - * If the write pointer always has a certain distance from the transmit- - * clock, we will have a delay. The delay will dynamically be increased and - * reduced. - * - * - * TX-Buffer - * R W - * | | - * -----------------+--------+----------------------- - * - * The tx-buffer is a ring buffer to queue the transmit data from user space - * until it will be mixed or sent. There are two pointers, R and W. If the write - * pointer W would reach or overrun R, the buffer would overrun. In this case - * (some) data is dropped so that it will not overrun. - * Additionally a dynamic dejittering can be enabled. this allows data from - * user space that have jitter and different clock source. - * - * - * Clock: - * - * A Clock is not required, if the data source has exactly one clock. In this - * case the data source is forwarded to the destination. - * - * A Clock is required, because the data source - * - has multiple clocks. - * - has no usable clock due to jitter or packet loss (VoIP). - * In this case the system's clock is used. The clock resolution depends on - * the jiffie resolution. - * - * If a member joins a conference: - * - * - If a member joins, its rx_buff is set to silence and change read pointer - * to transmit clock. - * - * The procedure of received data from card is explained in cmx_receive. - * The procedure of received data from user space is explained in cmx_transmit. - * The procedure of transmit data to card is cmx_send. - * - * - * Interaction with other features: - * - * DTMF: - * DTMF decoding is done before the data is crossconnected. - * - * Volume change: - * Changing rx-volume is done before the data is crossconnected. The tx-volume - * must be changed whenever data is transmitted to the card by the cmx. - * - * Tones: - * If a tone is enabled, it will be processed whenever data is transmitted to - * the card. It will replace the tx-data from the user space. - * If tones are generated by hardware, this conference member is removed for - * this time. - * - * Disable rx-data: - * If cmx is realized in hardware, rx data will be disabled if requested by - * the upper layer. If dtmf decoding is done by software and enabled, rx data - * will not be diabled but blocked to the upper layer. - * - * HFC conference engine: - * If it is possible to realize all features using hardware, hardware will be - * used if not forbidden by control command. Disabling rx-data provides - * absolutely traffic free audio processing. (except for the quick 1-frame - * upload of a tone loop, only once for a new tone) - * - */ - -/* delay.h is required for hw_lock.h */ - -#include -#include -#include -#include "core.h" -#include "dsp.h" -/* - * debugging of multi party conference, - * by using conference even with two members - */ - -/* #define CMX_CONF_DEBUG */ - -/*#define CMX_DEBUG * massive read/write pointer output */ -/*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */ - -static inline int -count_list_member(struct list_head *head) -{ - int cnt = 0; - struct list_head *m; - - list_for_each(m, head) - cnt++; - return cnt; -} - -/* - * debug cmx memory structure - */ -void -dsp_cmx_debug(struct dsp *dsp) -{ - struct dsp_conf *conf; - struct dsp_conf_member *member; - struct dsp *odsp; - - printk(KERN_DEBUG "-----Current DSP\n"); - list_for_each_entry(odsp, &dsp_ilist, list) { - printk(KERN_DEBUG "* %s echo=%d txmix=%d", - odsp->name, odsp->echo, odsp->tx_mix); - if (odsp->conf) - printk(" (Conf %d)", odsp->conf->id); - if (dsp == odsp) - printk(" *this*"); - printk("\n"); - } - printk(KERN_DEBUG "-----Current Conf:\n"); - list_for_each_entry(conf, &conf_ilist, list) { - printk(KERN_DEBUG "* Conf %d (%p)\n", conf->id, conf); - list_for_each_entry(member, &conf->mlist, list) { - printk(KERN_DEBUG - " - member = %s (slot_tx %d, bank_tx %d, " - "slot_rx %d, bank_rx %d hfc_conf %d)%s\n", - member->dsp->name, member->dsp->pcm_slot_tx, - member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx, - member->dsp->pcm_bank_rx, member->dsp->hfc_conf, - (member->dsp == dsp) ? " *this*" : ""); - } - } - printk(KERN_DEBUG "-----end\n"); -} - -/* - * search conference - */ -static struct dsp_conf * -dsp_cmx_search_conf(u32 id) -{ - struct dsp_conf *conf; - - if (!id) { - printk(KERN_WARNING "%s: conference ID is 0.\n", __func__); - return NULL; - } - - /* search conference */ - list_for_each_entry(conf, &conf_ilist, list) - if (conf->id == id) - return conf; - - return NULL; -} - - -/* - * add member to conference - */ -static int -dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf) -{ - struct dsp_conf_member *member; - - if (!conf || !dsp) { - printk(KERN_WARNING "%s: conf or dsp is 0.\n", __func__); - return -EINVAL; - } - if (dsp->member) { - printk(KERN_WARNING "%s: dsp is already member in a conf.\n", - __func__); - return -EINVAL; - } - - if (dsp->conf) { - printk(KERN_WARNING "%s: dsp is already in a conf.\n", - __func__); - return -EINVAL; - } - - member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC); - if (!member) { - printk(KERN_ERR "kmalloc struct dsp_conf_member failed\n"); - return -ENOMEM; - } - member->dsp = dsp; - /* clear rx buffer */ - memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); - dsp->rx_init = 1; /* rx_W and rx_R will be adjusted on first frame */ - dsp->rx_W = 0; - dsp->rx_R = 0; - - list_add_tail(&member->list, &conf->mlist); - - dsp->conf = conf; - dsp->member = member; - - return 0; -} - - -/* - * del member from conference - */ -int -dsp_cmx_del_conf_member(struct dsp *dsp) -{ - struct dsp_conf_member *member; - - if (!dsp) { - printk(KERN_WARNING "%s: dsp is 0.\n", - __func__); - return -EINVAL; - } - - if (!dsp->conf) { - printk(KERN_WARNING "%s: dsp is not in a conf.\n", - __func__); - return -EINVAL; - } - - if (list_empty(&dsp->conf->mlist)) { - printk(KERN_WARNING "%s: dsp has linked an empty conf.\n", - __func__); - return -EINVAL; - } - - /* find us in conf */ - list_for_each_entry(member, &dsp->conf->mlist, list) { - if (member->dsp == dsp) { - list_del(&member->list); - dsp->conf = NULL; - dsp->member = NULL; - kfree(member); - return 0; - } - } - printk(KERN_WARNING - "%s: dsp is not present in its own conf_meber list.\n", - __func__); - - return -EINVAL; -} - - -/* - * new conference - */ -static struct dsp_conf -*dsp_cmx_new_conf(u32 id) -{ - struct dsp_conf *conf; - - if (!id) { - printk(KERN_WARNING "%s: id is 0.\n", - __func__); - return NULL; - } - - conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC); - if (!conf) { - printk(KERN_ERR "kmalloc struct dsp_conf failed\n"); - return NULL; - } - INIT_LIST_HEAD(&conf->mlist); - conf->id = id; - - list_add_tail(&conf->list, &conf_ilist); - - return conf; -} - - -/* - * del conference - */ -int -dsp_cmx_del_conf(struct dsp_conf *conf) -{ - if (!conf) { - printk(KERN_WARNING "%s: conf is null.\n", - __func__); - return -EINVAL; - } - - if (!list_empty(&conf->mlist)) { - printk(KERN_WARNING "%s: conf not empty.\n", - __func__); - return -EINVAL; - } - list_del(&conf->list); - kfree(conf); - - return 0; -} - - -/* - * send HW message to hfc card - */ -static void -dsp_cmx_hw_message(struct dsp *dsp, u32 message, u32 param1, u32 param2, - u32 param3, u32 param4) -{ - struct mISDN_ctrl_req cq; - - memset(&cq, 0, sizeof(cq)); - cq.op = message; - cq.p1 = param1 | (param2 << 8); - cq.p2 = param3 | (param4 << 8); - if (dsp->ch.peer) - dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq); -} - - -/* - * do hardware update and set the software/hardware flag - * - * either a conference or a dsp instance can be given - * if only dsp instance is given, the instance is not associated with a conf - * and therefore removed. if a conference is given, the dsp is expected to - * be member of that conference. - */ -void -dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp) -{ - struct dsp_conf_member *member, *nextm; - struct dsp *finddsp; - int memb = 0, i, ii, i1, i2; - int freeunits[8]; - u_char freeslots[256]; - int same_hfc = -1, same_pcm = -1, current_conf = -1, - all_conf = 1; - - /* dsp gets updated (no conf) */ - if (!conf) { - if (!dsp) - return; - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s checking dsp %s\n", - __func__, dsp->name); -one_member: - /* remove HFC conference if enabled */ - if (dsp->hfc_conf >= 0) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s removing %s from HFC conf %d " - "because dsp is split\n", __func__, - dsp->name, dsp->hfc_conf); - dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_CONF_SPLIT, - 0, 0, 0, 0); - dsp->hfc_conf = -1; - } - /* process hw echo */ - if (dsp->features.pcm_banks < 1) - return; - if (!dsp->echo) { - /* NO ECHO: remove PCM slot if assigned */ - if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s removing %s from" - " PCM slot %d (TX) %d (RX) because" - " dsp is split (no echo)\n", - __func__, dsp->name, - dsp->pcm_slot_tx, dsp->pcm_slot_rx); - dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_DISC, - 0, 0, 0, 0); - dsp->pcm_slot_tx = -1; - dsp->pcm_bank_tx = -1; - dsp->pcm_slot_rx = -1; - dsp->pcm_bank_rx = -1; - } - return; - } - /* ECHO: already echo */ - if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 && - dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) - return; - /* ECHO: if slot already assigned */ - if (dsp->pcm_slot_tx >= 0) { - dsp->pcm_slot_rx = dsp->pcm_slot_tx; - dsp->pcm_bank_tx = 2; /* 2 means loop */ - dsp->pcm_bank_rx = 2; - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s refresh %s for echo using slot %d\n", - __func__, dsp->name, - dsp->pcm_slot_tx); - dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN, - dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); - return; - } - /* ECHO: find slot */ - dsp->pcm_slot_tx = -1; - dsp->pcm_slot_rx = -1; - memset(freeslots, 1, sizeof(freeslots)); - list_for_each_entry(finddsp, &dsp_ilist, list) { - if (finddsp->features.pcm_id == dsp->features.pcm_id) { - if (finddsp->pcm_slot_rx >= 0 && - finddsp->pcm_slot_rx < sizeof(freeslots)) - freeslots[finddsp->pcm_slot_tx] = 0; - if (finddsp->pcm_slot_tx >= 0 && - finddsp->pcm_slot_tx < sizeof(freeslots)) - freeslots[finddsp->pcm_slot_rx] = 0; - } - } - i = 0; - ii = dsp->features.pcm_slots; - while (i < ii) { - if (freeslots[i]) - break; - i++; - } - if (i == ii) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s no slot available for echo\n", - __func__); - /* no more slots available */ - return; - } - /* assign free slot */ - dsp->pcm_slot_tx = i; - dsp->pcm_slot_rx = i; - dsp->pcm_bank_tx = 2; /* loop */ - dsp->pcm_bank_rx = 2; - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s assign echo for %s using slot %d\n", - __func__, dsp->name, dsp->pcm_slot_tx); - dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN, - dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); - return; - } - - /* conf gets updated (all members) */ - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s checking conference %d\n", - __func__, conf->id); - - if (list_empty(&conf->mlist)) { - printk(KERN_ERR "%s: conference whithout members\n", - __func__); - return; - } - member = list_entry(conf->mlist.next, struct dsp_conf_member, list); - same_hfc = member->dsp->features.hfc_id; - same_pcm = member->dsp->features.pcm_id; - /* check all members in our conference */ - list_for_each_entry(member, &conf->mlist, list) { - /* check if member uses mixing */ - if (member->dsp->tx_mix) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "tx_mix is turned on\n", __func__, - member->dsp->name); -conf_software: - list_for_each_entry(member, &conf->mlist, list) { - dsp = member->dsp; - /* remove HFC conference if enabled */ - if (dsp->hfc_conf >= 0) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s removing %s from HFC " - "conf %d because not " - "possible with hardware\n", - __func__, - dsp->name, - dsp->hfc_conf); - dsp_cmx_hw_message(dsp, - MISDN_CTRL_HFC_CONF_SPLIT, - 0, 0, 0, 0); - dsp->hfc_conf = -1; - } - /* remove PCM slot if assigned */ - if (dsp->pcm_slot_tx >= 0 || - dsp->pcm_slot_rx >= 0) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s removing " - "%s from PCM slot %d (TX)" - " slot %d (RX) because not" - " possible with hardware\n", - __func__, - dsp->name, - dsp->pcm_slot_tx, - dsp->pcm_slot_rx); - dsp_cmx_hw_message(dsp, - MISDN_CTRL_HFC_PCM_DISC, - 0, 0, 0, 0); - dsp->pcm_slot_tx = -1; - dsp->pcm_bank_tx = -1; - dsp->pcm_slot_rx = -1; - dsp->pcm_bank_rx = -1; - } - } - conf->hardware = 0; - conf->software = 1; - return; - } - /* check if member has echo turned on */ - if (member->dsp->echo) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "echo is turned on\n", __func__, - member->dsp->name); - goto conf_software; - } - /* check if member has tx_mix turned on */ - if (member->dsp->tx_mix) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "tx_mix is turned on\n", - __func__, member->dsp->name); - goto conf_software; - } - /* check if member changes volume at an not suppoted level */ - if (member->dsp->tx_volume) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "tx_volume is changed\n", - __func__, member->dsp->name); - goto conf_software; - } - if (member->dsp->rx_volume) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "rx_volume is changed\n", - __func__, member->dsp->name); - goto conf_software; - } - /* check if tx-data turned on */ - if (member->dsp->tx_data) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "tx_data is turned on\n", - __func__, member->dsp->name); - goto conf_software; - } - /* check if pipeline exists */ - if (member->dsp->pipeline.inuse) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "pipeline exists\n", __func__, - member->dsp->name); - goto conf_software; - } - /* check if encryption is enabled */ - if (member->dsp->bf_enable) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s dsp %s cannot form a " - "conf, because encryption is enabled\n", - __func__, member->dsp->name); - goto conf_software; - } - /* check if member is on a card with PCM support */ - if (member->dsp->features.pcm_id < 0) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "dsp has no PCM bus\n", - __func__, member->dsp->name); - goto conf_software; - } - /* check if relations are on the same PCM bus */ - if (member->dsp->features.pcm_id != same_pcm) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s cannot form a conf, because " - "dsp is on a different PCM bus than the " - "first dsp\n", - __func__, member->dsp->name); - goto conf_software; - } - /* determine if members are on the same hfc chip */ - if (same_hfc != member->dsp->features.hfc_id) - same_hfc = -1; - /* if there are members already in a conference */ - if (current_conf < 0 && member->dsp->hfc_conf >= 0) - current_conf = member->dsp->hfc_conf; - /* if any member is not in a conference */ - if (member->dsp->hfc_conf < 0) - all_conf = 0; - - memb++; - } - - /* if no member, this is an error */ - if (memb < 1) - return; - - /* one member */ - if (memb == 1) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s conf %d cannot form a HW conference, " - "because dsp is alone\n", __func__, conf->id); - conf->hardware = 0; - conf->software = 0; - member = list_entry(conf->mlist.next, struct dsp_conf_member, - list); - dsp = member->dsp; - goto one_member; - } - - /* - * ok, now we are sure that all members are on the same pcm. - * now we will see if we have only two members, so we can do - * crossconnections, which don't have any limitations. - */ - - /* if we have only two members */ - if (memb == 2) { - member = list_entry(conf->mlist.next, struct dsp_conf_member, - list); - nextm = list_entry(member->list.next, struct dsp_conf_member, - list); - /* remove HFC conference if enabled */ - if (member->dsp->hfc_conf >= 0) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s removing %s from HFC conf %d because " - "two parties require only a PCM slot\n", - __func__, member->dsp->name, - member->dsp->hfc_conf); - dsp_cmx_hw_message(member->dsp, - MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0); - member->dsp->hfc_conf = -1; - } - if (nextm->dsp->hfc_conf >= 0) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s removing %s from HFC conf %d because " - "two parties require only a PCM slot\n", - __func__, nextm->dsp->name, - nextm->dsp->hfc_conf); - dsp_cmx_hw_message(nextm->dsp, - MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0); - nextm->dsp->hfc_conf = -1; - } - /* if members have two banks (and not on the same chip) */ - if (member->dsp->features.pcm_banks > 1 && - nextm->dsp->features.pcm_banks > 1 && - member->dsp->features.hfc_id != - nextm->dsp->features.hfc_id) { - /* if both members have same slots with crossed banks */ - if (member->dsp->pcm_slot_tx >= 0 && - member->dsp->pcm_slot_rx >= 0 && - nextm->dsp->pcm_slot_tx >= 0 && - nextm->dsp->pcm_slot_rx >= 0 && - nextm->dsp->pcm_slot_tx == - member->dsp->pcm_slot_rx && - nextm->dsp->pcm_slot_rx == - member->dsp->pcm_slot_tx && - nextm->dsp->pcm_slot_tx == - member->dsp->pcm_slot_tx && - member->dsp->pcm_bank_tx != - member->dsp->pcm_bank_rx && - nextm->dsp->pcm_bank_tx != - nextm->dsp->pcm_bank_rx) { - /* all members have same slot */ - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s & %s stay joined on " - "PCM slot %d bank %d (TX) bank %d " - "(RX) (on different chips)\n", - __func__, - member->dsp->name, - nextm->dsp->name, - member->dsp->pcm_slot_tx, - member->dsp->pcm_bank_tx, - member->dsp->pcm_bank_rx); - conf->hardware = 0; - conf->software = 1; - return; - } - /* find a new slot */ - memset(freeslots, 1, sizeof(freeslots)); - list_for_each_entry(dsp, &dsp_ilist, list) { - if (dsp != member->dsp && - dsp != nextm->dsp && - member->dsp->features.pcm_id == - dsp->features.pcm_id) { - if (dsp->pcm_slot_rx >= 0 && - dsp->pcm_slot_rx < - sizeof(freeslots)) - freeslots[dsp->pcm_slot_tx] = 0; - if (dsp->pcm_slot_tx >= 0 && - dsp->pcm_slot_tx < - sizeof(freeslots)) - freeslots[dsp->pcm_slot_rx] = 0; - } - } - i = 0; - ii = member->dsp->features.pcm_slots; - while (i < ii) { - if (freeslots[i]) - break; - i++; - } - if (i == ii) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s no slot available for " - "%s & %s\n", __func__, - member->dsp->name, - nextm->dsp->name); - /* no more slots available */ - goto conf_software; - } - /* assign free slot */ - member->dsp->pcm_slot_tx = i; - member->dsp->pcm_slot_rx = i; - nextm->dsp->pcm_slot_tx = i; - nextm->dsp->pcm_slot_rx = i; - member->dsp->pcm_bank_rx = 0; - member->dsp->pcm_bank_tx = 1; - nextm->dsp->pcm_bank_rx = 1; - nextm->dsp->pcm_bank_tx = 0; - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s adding %s & %s to new PCM slot %d " - "(TX and RX on different chips) because " - "both members have not same slots\n", - __func__, - member->dsp->name, - nextm->dsp->name, - member->dsp->pcm_slot_tx); - dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, - member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, - member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); - dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN, - nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, - nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); - conf->hardware = 1; - conf->software = 0; - return; - /* if members have one bank (or on the same chip) */ - } else { - /* if both members have different crossed slots */ - if (member->dsp->pcm_slot_tx >= 0 && - member->dsp->pcm_slot_rx >= 0 && - nextm->dsp->pcm_slot_tx >= 0 && - nextm->dsp->pcm_slot_rx >= 0 && - nextm->dsp->pcm_slot_tx == - member->dsp->pcm_slot_rx && - nextm->dsp->pcm_slot_rx == - member->dsp->pcm_slot_tx && - member->dsp->pcm_slot_tx != - member->dsp->pcm_slot_rx && - member->dsp->pcm_bank_tx == 0 && - member->dsp->pcm_bank_rx == 0 && - nextm->dsp->pcm_bank_tx == 0 && - nextm->dsp->pcm_bank_rx == 0) { - /* all members have same slot */ - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s dsp %s & %s stay joined on PCM " - "slot %d (TX) %d (RX) on same chip " - "or one bank PCM)\n", __func__, - member->dsp->name, - nextm->dsp->name, - member->dsp->pcm_slot_tx, - member->dsp->pcm_slot_rx); - conf->hardware = 0; - conf->software = 1; - return; - } - /* find two new slot */ - memset(freeslots, 1, sizeof(freeslots)); - list_for_each_entry(dsp, &dsp_ilist, list) { - if (dsp != member->dsp && - dsp != nextm->dsp && - member->dsp->features.pcm_id == - dsp->features.pcm_id) { - if (dsp->pcm_slot_rx >= 0 && - dsp->pcm_slot_rx < - sizeof(freeslots)) - freeslots[dsp->pcm_slot_tx] = 0; - if (dsp->pcm_slot_tx >= 0 && - dsp->pcm_slot_tx < - sizeof(freeslots)) - freeslots[dsp->pcm_slot_rx] = 0; - } - } - i1 = 0; - ii = member->dsp->features.pcm_slots; - while (i1 < ii) { - if (freeslots[i1]) - break; - i1++; - } - if (i1 == ii) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s no slot available " - "for %s & %s\n", __func__, - member->dsp->name, - nextm->dsp->name); - /* no more slots available */ - goto conf_software; - } - i2 = i1+1; - while (i2 < ii) { - if (freeslots[i2]) - break; - i2++; - } - if (i2 == ii) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s no slot available " - "for %s & %s\n", - __func__, - member->dsp->name, - nextm->dsp->name); - /* no more slots available */ - goto conf_software; - } - /* assign free slots */ - member->dsp->pcm_slot_tx = i1; - member->dsp->pcm_slot_rx = i2; - nextm->dsp->pcm_slot_tx = i2; - nextm->dsp->pcm_slot_rx = i1; - member->dsp->pcm_bank_rx = 0; - member->dsp->pcm_bank_tx = 0; - nextm->dsp->pcm_bank_rx = 0; - nextm->dsp->pcm_bank_tx = 0; - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s adding %s & %s to new PCM slot %d " - "(TX) %d (RX) on same chip or one bank " - "PCM, because both members have not " - "crossed slots\n", __func__, - member->dsp->name, - nextm->dsp->name, - member->dsp->pcm_slot_tx, - member->dsp->pcm_slot_rx); - dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, - member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, - member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); - dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN, - nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, - nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); - conf->hardware = 1; - conf->software = 0; - return; - } - } - - /* - * if we have more than two, we may check if we have a conference - * unit available on the chip. also all members must be on the same - */ - - /* if not the same HFC chip */ - if (same_hfc < 0) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s conference %d cannot be formed, because " - "members are on different chips or not " - "on HFC chip\n", - __func__, conf->id); - goto conf_software; - } - - /* for more than two members.. */ - - /* in case of hdlc, we change to software */ - if (dsp->hdlc) - goto conf_software; - - /* if all members already have the same conference */ - if (all_conf) - return; - - /* - * if there is an existing conference, but not all members have joined - */ - if (current_conf >= 0) { -join_members: - list_for_each_entry(member, &conf->mlist, list) { - /* join to current conference */ - if (member->dsp->hfc_conf == current_conf) - continue; - /* get a free timeslot first */ - memset(freeslots, 1, sizeof(freeslots)); - list_for_each_entry(dsp, &dsp_ilist, list) { - /* - * not checking current member, because - * slot will be overwritten. - */ - if ( - dsp != member->dsp && - /* dsp must be on the same PCM */ - member->dsp->features.pcm_id == - dsp->features.pcm_id) { - /* dsp must be on a slot */ - if (dsp->pcm_slot_tx >= 0 && - dsp->pcm_slot_tx < - sizeof(freeslots)) - freeslots[dsp->pcm_slot_tx] = 0; - if (dsp->pcm_slot_rx >= 0 && - dsp->pcm_slot_rx < - sizeof(freeslots)) - freeslots[dsp->pcm_slot_rx] = 0; - } - } - i = 0; - ii = member->dsp->features.pcm_slots; - while (i < ii) { - if (freeslots[i]) - break; - i++; - } - if (i == ii) { - /* no more slots available */ - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s conference %d cannot be formed," - " because no slot free\n", - __func__, conf->id); - goto conf_software; - } - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s changing dsp %s to HW conference " - "%d slot %d\n", __func__, - member->dsp->name, current_conf, i); - /* assign free slot & set PCM & join conf */ - member->dsp->pcm_slot_tx = i; - member->dsp->pcm_slot_rx = i; - member->dsp->pcm_bank_tx = 2; /* loop */ - member->dsp->pcm_bank_rx = 2; - member->dsp->hfc_conf = current_conf; - dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, - i, 2, i, 2); - dsp_cmx_hw_message(member->dsp, - MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0); - } - return; - } - - /* - * no member is in a conference yet, so we find a free one - */ - memset(freeunits, 1, sizeof(freeunits)); - list_for_each_entry(dsp, &dsp_ilist, list) { - /* dsp must be on the same chip */ - if (dsp->features.hfc_id == same_hfc && - /* dsp must have joined a HW conference */ - dsp->hfc_conf >= 0 && - /* slot must be within range */ - dsp->hfc_conf < 8) - freeunits[dsp->hfc_conf] = 0; - } - i = 0; - ii = 8; - while (i < ii) { - if (freeunits[i]) - break; - i++; - } - if (i == ii) { - /* no more conferences available */ - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s conference %d cannot be formed, because " - "no conference number free\n", - __func__, conf->id); - goto conf_software; - } - /* join all members */ - current_conf = i; - goto join_members; -} - - -/* - * conf_id != 0: join or change conference - * conf_id == 0: split from conference if not already - */ -int -dsp_cmx_conf(struct dsp *dsp, u32 conf_id) -{ - int err; - struct dsp_conf *conf; - struct dsp_conf_member *member; - - /* if conference doesn't change */ - if (dsp->conf_id == conf_id) - return 0; - - /* first remove us from current conf */ - if (dsp->conf_id) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "removing us from conference %d\n", - dsp->conf->id); - /* remove us from conf */ - conf = dsp->conf; - err = dsp_cmx_del_conf_member(dsp); - if (err) - return err; - dsp->conf_id = 0; - - /* update hardware */ - dsp_cmx_hardware(NULL, dsp); - - /* conf now empty? */ - if (list_empty(&conf->mlist)) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "conference is empty, so we remove it.\n"); - err = dsp_cmx_del_conf(conf); - if (err) - return err; - } else { - /* update members left on conf */ - dsp_cmx_hardware(conf, NULL); - } - } - - /* if split */ - if (!conf_id) - return 0; - - /* now add us to conf */ - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "searching conference %d\n", - conf_id); - conf = dsp_cmx_search_conf(conf_id); - if (!conf) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "conference doesn't exist yet, creating.\n"); - /* the conference doesn't exist, so we create */ - conf = dsp_cmx_new_conf(conf_id); - if (!conf) - return -EINVAL; - } else if (!list_empty(&conf->mlist)) { - member = list_entry(conf->mlist.next, struct dsp_conf_member, - list); - if (dsp->hdlc && !member->dsp->hdlc) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "cannot join transparent conference.\n"); - return -EINVAL; - } - if (!dsp->hdlc && member->dsp->hdlc) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "cannot join hdlc conference.\n"); - return -EINVAL; - } - } - /* add conference member */ - err = dsp_cmx_add_conf_member(dsp, conf); - if (err) - return err; - dsp->conf_id = conf_id; - - /* if we are alone, we do nothing! */ - if (list_empty(&conf->mlist)) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "we are alone in this conference, so exit.\n"); - /* update hardware */ - dsp_cmx_hardware(NULL, dsp); - return 0; - } - - /* update members on conf */ - dsp_cmx_hardware(conf, NULL); - - return 0; -} - - -/* - * audio data is received from card - */ -void -dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb) -{ - u8 *d, *p; - int len = skb->len; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - int w, i, ii; - - /* check if we have sompen */ - if (len < 1) - return; - - /* half of the buffer should be larger than maximum packet size */ - if (len >= CMX_BUFF_HALF) { - printk(KERN_ERR - "%s line %d: packet from card is too large (%d bytes). " - "please make card send smaller packets OR increase " - "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len); - return; - } - - /* - * initialize pointers if not already - - * also add delay if requested by PH_SIGNAL - */ - if (dsp->rx_init) { - dsp->rx_init = 0; - if (dsp->features.unordered) { - dsp->rx_R = (hh->id & CMX_BUFF_MASK); - dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) - & CMX_BUFF_MASK; - } else { - dsp->rx_R = 0; - dsp->rx_W = dsp->cmx_delay; - } - } - /* if frame contains time code, write directly */ - if (dsp->features.unordered) { - dsp->rx_W = (hh->id & CMX_BUFF_MASK); - /* printk(KERN_DEBUG "%s %08x\n", dsp->name, hh->id); */ - } - /* - * if we underrun (or maybe overrun), - * we set our new read pointer, and write silence to buffer - */ - if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "cmx_receive(dsp=%lx): UNDERRUN (or overrun the " - "maximum delay), adjusting read pointer! " - "(inst %s)\n", (u_long)dsp, dsp->name); - /* flush buffer */ - if (dsp->features.unordered) { - dsp->rx_R = (hh->id & CMX_BUFF_MASK); - dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) - & CMX_BUFF_MASK; - } else { - dsp->rx_R = 0; - dsp->rx_W = dsp->cmx_delay; - } - memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); - } - /* if we have reached double delay, jump back to middle */ - if (dsp->cmx_delay) - if (((dsp->rx_W - dsp->rx_R) & CMX_BUFF_MASK) >= - (dsp->cmx_delay << 1)) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "cmx_receive(dsp=%lx): OVERRUN (because " - "twice the delay is reached), adjusting " - "read pointer! (inst %s)\n", - (u_long)dsp, dsp->name); - /* flush buffer */ - if (dsp->features.unordered) { - dsp->rx_R = (hh->id & CMX_BUFF_MASK); - dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) - & CMX_BUFF_MASK; - } else { - dsp->rx_R = 0; - dsp->rx_W = dsp->cmx_delay; - } - memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); - } - - /* show where to write */ -#ifdef CMX_DEBUG - printk(KERN_DEBUG - "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n", - (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name); -#endif - - /* write data into rx_buffer */ - p = skb->data; - d = dsp->rx_buff; - w = dsp->rx_W; - i = 0; - ii = len; - while (i < ii) { - d[w++ & CMX_BUFF_MASK] = *p++; - i++; - } - - /* increase write-pointer */ - dsp->rx_W = ((dsp->rx_W+len) & CMX_BUFF_MASK); -} - - -/* - * send (mixed) audio data to card and control jitter - */ -static void -dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) -{ - struct dsp_conf *conf = dsp->conf; - struct dsp *member, *other; - register s32 sample; - u8 *d, *p, *q, *o_q; - struct sk_buff *nskb, *txskb; - int r, rr, t, tt, o_r, o_rr; - int preload = 0; - struct mISDNhead *hh, *thh; - - /* don't process if: */ - if (!dsp->b_active) { /* if not active */ - dsp->last_tx = 0; - return; - } - if (dsp->pcm_slot_tx >= 0 && /* connected to pcm slot */ - dsp->tx_R == dsp->tx_W && /* AND no tx-data */ - !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */ - dsp->last_tx = 0; - return; - } - -#ifdef CMX_DEBUG - printk(KERN_DEBUG - "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n", - members, dsp->name, conf, dsp->rx_R, dsp->rx_W); -#endif - - /* preload if we have delay set */ - if (dsp->cmx_delay && !dsp->last_tx) { - preload = len; - if (preload < 128) - preload = 128; - } - - /* PREPARE RESULT */ - nskb = mI_alloc_skb(len + preload, GFP_ATOMIC); - if (!nskb) { - printk(KERN_ERR - "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n", - len + preload); - return; - } - hh = mISDN_HEAD_P(nskb); - hh->prim = PH_DATA_REQ; - hh->id = 0; - dsp->last_tx = 1; - - /* set pointers, indexes and stuff */ - member = dsp; - p = dsp->tx_buff; /* transmit data */ - q = dsp->rx_buff; /* received data */ - d = skb_put(nskb, preload + len); /* result */ - t = dsp->tx_R; /* tx-pointers */ - tt = dsp->tx_W; - r = dsp->rx_R; /* rx-pointers */ - rr = (r + len) & CMX_BUFF_MASK; - - /* preload with silence, if required */ - if (preload) { - memset(d, dsp_silence, preload); - d += preload; - } - - /* PROCESS TONES/TX-DATA ONLY */ - if (dsp->tone.tone && dsp->tone.software) { - /* -> copy tone */ - dsp_tone_copy(dsp, d, len); - dsp->tx_R = 0; /* clear tx buffer */ - dsp->tx_W = 0; - goto send_packet; - } - /* if we have tx-data but do not use mixing */ - if (!dsp->tx_mix && t != tt) { - /* -> send tx-data and continue when not enough */ -#ifdef CMX_TX_DEBUG - sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p); -#endif - while (r != rr && t != tt) { -#ifdef CMX_TX_DEBUG - if (strlen(debugbuf) < 48) - sprintf(debugbuf+strlen(debugbuf), " %02x", p[t]); -#endif - *d++ = p[t]; /* write tx_buff */ - t = (t+1) & CMX_BUFF_MASK; - r = (r+1) & CMX_BUFF_MASK; - } - if (r == rr) { - dsp->tx_R = t; -#ifdef CMX_TX_DEBUG - printk(KERN_DEBUG "%s\n", debugbuf); -#endif - goto send_packet; - } - } -#ifdef CMX_TX_DEBUG - printk(KERN_DEBUG "%s\n", debugbuf); -#endif - - /* PROCESS DATA (one member / no conf) */ - if (!conf || members <= 1) { - /* -> if echo is NOT enabled */ - if (!dsp->echo) { - /* -> send tx-data if available or use 0-volume */ - while (r != rr && t != tt) { - *d++ = p[t]; /* write tx_buff */ - t = (t+1) & CMX_BUFF_MASK; - r = (r+1) & CMX_BUFF_MASK; - } - if (r != rr) - memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK); - /* -> if echo is enabled */ - } else { - /* - * -> mix tx-data with echo if available, - * or use echo only - */ - while (r != rr && t != tt) { - *d++ = dsp_audio_mix_law[(p[t]<<8)|q[r]]; - t = (t+1) & CMX_BUFF_MASK; - r = (r+1) & CMX_BUFF_MASK; - } - while (r != rr) { - *d++ = q[r]; /* echo */ - r = (r+1) & CMX_BUFF_MASK; - } - } - dsp->tx_R = t; - goto send_packet; - } - /* PROCESS DATA (two members) */ -#ifdef CMX_CONF_DEBUG - if (0) { -#else - if (members == 2) { -#endif - /* "other" becomes other party */ - other = (list_entry(conf->mlist.next, - struct dsp_conf_member, list))->dsp; - if (other == member) - other = (list_entry(conf->mlist.prev, - struct dsp_conf_member, list))->dsp; - o_q = other->rx_buff; /* received data */ - o_rr = (other->rx_R + len) & CMX_BUFF_MASK; - /* end of rx-pointer */ - o_r = (o_rr - rr + r) & CMX_BUFF_MASK; - /* start rx-pointer at current read position*/ - /* -> if echo is NOT enabled */ - if (!dsp->echo) { - /* - * -> copy other member's rx-data, - * if tx-data is available, mix - */ - while (o_r != o_rr && t != tt) { - *d++ = dsp_audio_mix_law[(p[t]<<8)|o_q[o_r]]; - t = (t+1) & CMX_BUFF_MASK; - o_r = (o_r+1) & CMX_BUFF_MASK; - } - while (o_r != o_rr) { - *d++ = o_q[o_r]; - o_r = (o_r+1) & CMX_BUFF_MASK; - } - /* -> if echo is enabled */ - } else { - /* - * -> mix other member's rx-data with echo, - * if tx-data is available, mix - */ - while (r != rr && t != tt) { - sample = dsp_audio_law_to_s32[p[t]] + - dsp_audio_law_to_s32[q[r]] + - dsp_audio_law_to_s32[o_q[o_r]]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - *d++ = dsp_audio_s16_to_law[sample & 0xffff]; - /* tx-data + rx_data + echo */ - t = (t+1) & CMX_BUFF_MASK; - r = (r+1) & CMX_BUFF_MASK; - o_r = (o_r+1) & CMX_BUFF_MASK; - } - while (r != rr) { - *d++ = dsp_audio_mix_law[(q[r]<<8)|o_q[o_r]]; - r = (r+1) & CMX_BUFF_MASK; - o_r = (o_r+1) & CMX_BUFF_MASK; - } - } - dsp->tx_R = t; - goto send_packet; - } -#ifdef DSP_NEVER_DEFINED - } -#endif - /* PROCESS DATA (three or more members) */ - /* -> if echo is NOT enabled */ - if (!dsp->echo) { - /* - * -> substract rx-data from conf-data, - * if tx-data is available, mix - */ - while (r != rr && t != tt) { - sample = dsp_audio_law_to_s32[p[t]] + *c++ - - dsp_audio_law_to_s32[q[r]]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - *d++ = dsp_audio_s16_to_law[sample & 0xffff]; - /* conf-rx+tx */ - r = (r+1) & CMX_BUFF_MASK; - t = (t+1) & CMX_BUFF_MASK; - } - while (r != rr) { - sample = *c++ - dsp_audio_law_to_s32[q[r]]; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - *d++ = dsp_audio_s16_to_law[sample & 0xffff]; - /* conf-rx */ - r = (r+1) & CMX_BUFF_MASK; - } - /* -> if echo is enabled */ - } else { - /* - * -> encode conf-data, if tx-data - * is available, mix - */ - while (r != rr && t != tt) { - sample = dsp_audio_law_to_s32[p[t]] + *c++; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - *d++ = dsp_audio_s16_to_law[sample & 0xffff]; - /* conf(echo)+tx */ - t = (t+1) & CMX_BUFF_MASK; - r = (r+1) & CMX_BUFF_MASK; - } - while (r != rr) { - sample = *c++; - if (sample < -32768) - sample = -32768; - else if (sample > 32767) - sample = 32767; - *d++ = dsp_audio_s16_to_law[sample & 0xffff]; - /* conf(echo) */ - r = (r+1) & CMX_BUFF_MASK; - } - } - dsp->tx_R = t; - goto send_packet; - -send_packet: - /* - * send tx-data if enabled - don't filter, - * becuase we want what we send, not what we filtered - */ - if (dsp->tx_data) { - /* PREPARE RESULT */ - txskb = mI_alloc_skb(len, GFP_ATOMIC); - if (!txskb) { - printk(KERN_ERR - "FATAL ERROR in mISDN_dsp.o: " - "cannot alloc %d bytes\n", len); - } else { - thh = mISDN_HEAD_P(txskb); - thh->prim = DL_DATA_REQ; - thh->id = 0; - memcpy(skb_put(txskb, len), nskb->data+preload, len); - /* queue (trigger later) */ - skb_queue_tail(&dsp->sendq, txskb); - } - } - /* adjust volume */ - if (dsp->tx_volume) - dsp_change_volume(nskb, dsp->tx_volume); - /* pipeline */ - if (dsp->pipeline.inuse) - dsp_pipeline_process_tx(&dsp->pipeline, nskb->data, nskb->len); - /* crypt */ - if (dsp->bf_enable) - dsp_bf_encrypt(dsp, nskb->data, nskb->len); - /* queue and trigger */ - skb_queue_tail(&dsp->sendq, nskb); - schedule_work(&dsp->workq); -} - -u32 samplecount; -struct timer_list dsp_spl_tl; -u32 dsp_spl_jiffies; /* calculate the next time to fire */ -u32 dsp_start_jiffies; /* jiffies at the time, the calculation begins */ -struct timeval dsp_start_tv; /* time at start of calculation */ - -void -dsp_cmx_send(void *arg) -{ - struct dsp_conf *conf; - struct dsp_conf_member *member; - struct dsp *dsp; - int mustmix, members; - s32 mixbuffer[MAX_POLL+100], *c; - u8 *p, *q; - int r, rr; - int jittercheck = 0, delay, i; - u_long flags; - struct timeval tv; - u32 elapsed; - s16 length; - - /* lock */ - spin_lock_irqsave(&dsp_lock, flags); - - if (!dsp_start_tv.tv_sec) { - do_gettimeofday(&dsp_start_tv); - length = dsp_poll; - } else { - do_gettimeofday(&tv); - elapsed = ((tv.tv_sec - dsp_start_tv.tv_sec) * 8000) - + ((s32)(tv.tv_usec / 125) - (dsp_start_tv.tv_usec / 125)); - dsp_start_tv.tv_sec = tv.tv_sec; - dsp_start_tv.tv_usec = tv.tv_usec; - length = elapsed; - } - if (length > MAX_POLL + 100) - length = MAX_POLL + 100; -/* printk(KERN_DEBUG "len=%d dsp_count=0x%x.%04x dsp_poll_diff=0x%x.%04x\n", - length, dsp_count >> 16, dsp_count & 0xffff, dsp_poll_diff >> 16, - dsp_poll_diff & 0xffff); - */ - - /* - * check if jitter needs to be checked - * (this is about every second = 8192 samples) - */ - samplecount += length; - if ((samplecount & 8191) < length) - jittercheck = 1; - - /* loop all members that do not require conference mixing */ - list_for_each_entry(dsp, &dsp_ilist, list) { - if (dsp->hdlc) - continue; - conf = dsp->conf; - mustmix = 0; - members = 0; - if (conf) { - members = count_list_member(&conf->mlist); -#ifdef CMX_CONF_DEBUG - if (conf->software && members > 1) -#else - if (conf->software && members > 2) -#endif - mustmix = 1; - } - - /* transmission required */ - if (!mustmix) { - dsp_cmx_send_member(dsp, length, mixbuffer, members); - - /* - * unused mixbuffer is given to prevent a - * potential null-pointer-bug - */ - } - } - - /* loop all members that require conference mixing */ - list_for_each_entry(conf, &conf_ilist, list) { - /* count members and check hardware */ - members = count_list_member(&conf->mlist); -#ifdef CMX_CONF_DEBUG - if (conf->software && members > 1) { -#else - if (conf->software && members > 2) { -#endif - /* check for hdlc conf */ - member = list_entry(conf->mlist.next, - struct dsp_conf_member, list); - if (member->dsp->hdlc) - continue; - /* mix all data */ - memset(mixbuffer, 0, length*sizeof(s32)); - list_for_each_entry(member, &conf->mlist, list) { - dsp = member->dsp; - /* get range of data to mix */ - c = mixbuffer; - q = dsp->rx_buff; - r = dsp->rx_R; - rr = (r + length) & CMX_BUFF_MASK; - /* add member's data */ - while (r != rr) { - *c++ += dsp_audio_law_to_s32[q[r]]; - r = (r+1) & CMX_BUFF_MASK; - } - } - - /* process each member */ - list_for_each_entry(member, &conf->mlist, list) { - /* transmission */ - dsp_cmx_send_member(member->dsp, length, - mixbuffer, members); - } - } - } - - /* delete rx-data, increment buffers, change pointers */ - list_for_each_entry(dsp, &dsp_ilist, list) { - if (dsp->hdlc) - continue; - p = dsp->rx_buff; - q = dsp->tx_buff; - r = dsp->rx_R; - /* move receive pointer when receiving */ - if (!dsp->rx_is_off) { - rr = (r + length) & CMX_BUFF_MASK; - /* delete rx-data */ - while (r != rr) { - p[r] = dsp_silence; - r = (r+1) & CMX_BUFF_MASK; - } - /* increment rx-buffer pointer */ - dsp->rx_R = r; /* write incremented read pointer */ - } - - /* check current rx_delay */ - delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK; - if (delay >= CMX_BUFF_HALF) - delay = 0; /* will be the delay before next write */ - /* check for lower delay */ - if (delay < dsp->rx_delay[0]) - dsp->rx_delay[0] = delay; - /* check current tx_delay */ - delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK; - if (delay >= CMX_BUFF_HALF) - delay = 0; /* will be the delay before next write */ - /* check for lower delay */ - if (delay < dsp->tx_delay[0]) - dsp->tx_delay[0] = delay; - if (jittercheck) { - /* find the lowest of all rx_delays */ - delay = dsp->rx_delay[0]; - i = 1; - while (i < MAX_SECONDS_JITTER_CHECK) { - if (delay > dsp->rx_delay[i]) - delay = dsp->rx_delay[i]; - i++; - } - /* - * remove rx_delay only if we have delay AND we - * have not preset cmx_delay - */ - if (delay && !dsp->cmx_delay) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s lowest rx_delay of %d bytes for" - " dsp %s are now removed.\n", - __func__, delay, - dsp->name); - r = dsp->rx_R; - rr = (r + delay) & CMX_BUFF_MASK; - /* delete rx-data */ - while (r != rr) { - p[r] = dsp_silence; - r = (r+1) & CMX_BUFF_MASK; - } - /* increment rx-buffer pointer */ - dsp->rx_R = r; - /* write incremented read pointer */ - } - /* find the lowest of all tx_delays */ - delay = dsp->tx_delay[0]; - i = 1; - while (i < MAX_SECONDS_JITTER_CHECK) { - if (delay > dsp->tx_delay[i]) - delay = dsp->tx_delay[i]; - i++; - } - /* - * remove delay only if we have delay AND we - * have enabled tx_dejitter - */ - if (delay && dsp->tx_dejitter) { - if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG - "%s lowest tx_delay of %d bytes for" - " dsp %s are now removed.\n", - __func__, delay, - dsp->name); - r = dsp->tx_R; - rr = (r + delay) & CMX_BUFF_MASK; - /* delete tx-data */ - while (r != rr) { - q[r] = dsp_silence; - r = (r+1) & CMX_BUFF_MASK; - } - /* increment rx-buffer pointer */ - dsp->tx_R = r; - /* write incremented read pointer */ - } - /* scroll up delays */ - i = MAX_SECONDS_JITTER_CHECK - 1; - while (i) { - dsp->rx_delay[i] = dsp->rx_delay[i-1]; - dsp->tx_delay[i] = dsp->tx_delay[i-1]; - i--; - } - dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */ - dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */ - } - } - - /* if next event would be in the past ... */ - if ((s32)(dsp_spl_jiffies+dsp_tics-jiffies) <= 0) - dsp_spl_jiffies = jiffies + 1; - else - dsp_spl_jiffies += dsp_tics; - - dsp_spl_tl.expires = dsp_spl_jiffies; - add_timer(&dsp_spl_tl); - - /* unlock */ - spin_unlock_irqrestore(&dsp_lock, flags); -} - -/* - * audio data is transmitted from upper layer to the dsp - */ -void -dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb) -{ - u_int w, ww; - u8 *d, *p; - int space; /* todo: , l = skb->len; */ -#ifdef CMX_TX_DEBUG - char debugbuf[256] = ""; -#endif - - /* check if there is enough space, and then copy */ - w = dsp->tx_W; - ww = dsp->tx_R; - p = dsp->tx_buff; - d = skb->data; - space = ww-w; - if (space <= 0) - space += CMX_BUFF_SIZE; - /* write-pointer should not overrun nor reach read pointer */ - if (space-1 < skb->len) - /* write to the space we have left */ - ww = (ww - 1) & CMX_BUFF_MASK; - else - /* write until all byte are copied */ - ww = (w + skb->len) & CMX_BUFF_MASK; - dsp->tx_W = ww; - - /* show current buffer */ -#ifdef CMX_DEBUG - printk(KERN_DEBUG - "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n", - (u_long)dsp, (ww-w)&CMX_BUFF_MASK, w, ww, dsp->name); -#endif - - /* copy transmit data to tx-buffer */ -#ifdef CMX_TX_DEBUG - sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p); -#endif - while (w != ww) { -#ifdef CMX_TX_DEBUG - if (strlen(debugbuf) < 48) - sprintf(debugbuf+strlen(debugbuf), " %02x", *d); -#endif - p[w] = *d++; - w = (w+1) & CMX_BUFF_MASK; - } -#ifdef CMX_TX_DEBUG - printk(KERN_DEBUG "%s\n", debugbuf); -#endif - -} - -/* - * hdlc data is received from card and sent to all members. - */ -void -dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb) -{ - struct sk_buff *nskb = NULL; - struct dsp_conf_member *member; - struct mISDNhead *hh; - - /* not if not active */ - if (!dsp->b_active) - return; - - /* check if we have sompen */ - if (skb->len < 1) - return; - - /* no conf */ - if (!dsp->conf) { - /* in case of hardware (echo) */ - if (dsp->pcm_slot_tx >= 0) - return; - if (dsp->echo) - nskb = skb_clone(skb, GFP_ATOMIC); - if (nskb) { - hh = mISDN_HEAD_P(nskb); - hh->prim = PH_DATA_REQ; - hh->id = 0; - skb_queue_tail(&dsp->sendq, nskb); - schedule_work(&dsp->workq); - } - return; - } - /* in case of hardware conference */ - if (dsp->conf->hardware) - return; - list_for_each_entry(member, &dsp->conf->mlist, list) { - if (dsp->echo || member->dsp != dsp) { - nskb = skb_clone(skb, GFP_ATOMIC); - if (nskb) { - hh = mISDN_HEAD_P(nskb); - hh->prim = PH_DATA_REQ; - hh->id = 0; - skb_queue_tail(&member->dsp->sendq, nskb); - schedule_work(&member->dsp->workq); - } - } - } -} - - diff --git a/trunk/drivers/isdn/mISDN/dsp_core.c b/trunk/drivers/isdn/mISDN/dsp_core.c deleted file mode 100644 index 2f10ed82c0db..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_core.c +++ /dev/null @@ -1,1191 +0,0 @@ -/* - * Author Andreas Eversberg (jolly@eversberg.eu) - * Based on source code structure by - * Karsten Keil (keil@isdn4linux.de) - * - * This file is (c) under GNU PUBLIC LICENSE - * For changes and modifications please read - * ../../../Documentation/isdn/mISDN.cert - * - * Thanks to Karsten Keil (great drivers) - * Cologne Chip (great chips) - * - * This module does: - * Real-time tone generation - * DTMF detection - * Real-time cross-connection and conferrence - * Compensate jitter due to system load and hardware fault. - * All features are done in kernel space and will be realized - * using hardware, if available and supported by chip set. - * Blowfish encryption/decryption - */ - -/* STRUCTURE: - * - * The dsp module provides layer 2 for b-channels (64kbit). It provides - * transparent audio forwarding with special digital signal processing: - * - * - (1) generation of tones - * - (2) detection of dtmf tones - * - (3) crossconnecting and conferences (clocking) - * - (4) echo generation for delay test - * - (5) volume control - * - (6) disable receive data - * - (7) pipeline - * - (8) encryption/decryption - * - * Look: - * TX RX - * ------upper layer------ - * | ^ - * | |(6) - * v | - * +-----+-------------+-----+ - * |(3)(4) | - * | CMX | - * | | - * | +-------------+ - * | | ^ - * | | | - * |+---------+| +----+----+ - * ||(1) || |(2) | - * || || | | - * || Tones || | DTMF | - * || || | | - * || || | | - * |+----+----+| +----+----+ - * +-----+-----+ ^ - * | | - * v | - * +----+----+ +----+----+ - * |(5) | |(5) | - * | | | | - * |TX Volume| |RX Volume| - * | | | | - * | | | | - * +----+----+ +----+----+ - * | ^ - * | | - * v | - * +----+-------------+----+ - * |(7) | - * | | - * | Pipeline Processing | - * | | - * | | - * +----+-------------+----+ - * | ^ - * | | - * v | - * +----+----+ +----+----+ - * |(8) | |(8) | - * | | | | - * | Encrypt | | Decrypt | - * | | | | - * | | | | - * +----+----+ +----+----+ - * | ^ - * | | - * v | - * ------card layer------ - * TX RX - * - * Above you can see the logical data flow. If software is used to do the - * process, it is actually the real data flow. If hardware is used, data - * may not flow, but hardware commands to the card, to provide the data flow - * as shown. - * - * NOTE: The channel must be activated in order to make dsp work, even if - * no data flow to the upper layer is intended. Activation can be done - * after and before controlling the setting using PH_CONTROL requests. - * - * DTMF: Will be detected by hardware if possible. It is done before CMX - * processing. - * - * Tones: Will be generated via software if endless looped audio fifos are - * not supported by hardware. Tones will override all data from CMX. - * It is not required to join a conference to use tones at any time. - * - * CMX: Is transparent when not used. When it is used, it will do - * crossconnections and conferences via software if not possible through - * hardware. If hardware capability is available, hardware is used. - * - * Echo: Is generated by CMX and is used to check performane of hard and - * software CMX. - * - * The CMX has special functions for conferences with one, two and more - * members. It will allow different types of data flow. Receive and transmit - * data to/form upper layer may be swithed on/off individually without loosing - * features of CMX, Tones and DTMF. - * - * Echo Cancellation: Sometimes we like to cancel echo from the interface. - * Note that a VoIP call may not have echo caused by the IP phone. The echo - * is generated by the telephone line connected to it. Because the delay - * is high, it becomes an echo. RESULT: Echo Cachelation is required if - * both echo AND delay is applied to an interface. - * Remember that software CMX always generates a more or less delay. - * - * If all used features can be realized in hardware, and if transmit and/or - * receive data ist disabled, the card may not send/receive any data at all. - * Not receiving is usefull if only announcements are played. Not sending is - * usefull if an answering machine records audio. Not sending and receiving is - * usefull during most states of the call. If supported by hardware, tones - * will be played without cpu load. Small PBXs and NT-Mode applications will - * not need expensive hardware when processing calls. - * - * - * LOCKING: - * - * When data is received from upper or lower layer (card), the complete dsp - * module is locked by a global lock. This lock MUST lock irq, because it - * must lock timer events by DSP poll timer. - * When data is ready to be transmitted down, the data is queued and sent - * outside lock and timer event. - * PH_CONTROL must not change any settings, join or split conference members - * during process of data. - * - * HDLC: - * - * It works quite the same as transparent, except that HDLC data is forwarded - * to all other conference members if no hardware bridging is possible. - * Send data will be writte to sendq. Sendq will be sent if confirm is received. - * Conference cannot join, if one member is not hdlc. - * - */ - -#include -#include -#include -#include -#include -#include "core.h" -#include "dsp.h" - -const char *mISDN_dsp_revision = "2.0"; - -static int debug; -static int options; -static int poll; -static int dtmfthreshold = 100; - -MODULE_AUTHOR("Andreas Eversberg"); -module_param(debug, uint, S_IRUGO | S_IWUSR); -module_param(options, uint, S_IRUGO | S_IWUSR); -module_param(poll, uint, S_IRUGO | S_IWUSR); -module_param(dtmfthreshold, uint, S_IRUGO | S_IWUSR); -MODULE_LICENSE("GPL"); - -/*int spinnest = 0;*/ - -spinlock_t dsp_lock; /* global dsp lock */ -struct list_head dsp_ilist; -struct list_head conf_ilist; -int dsp_debug; -int dsp_options; -int dsp_poll, dsp_tics; - -/* check if rx may be turned off or must be turned on */ -static void -dsp_rx_off_member(struct dsp *dsp) -{ - struct mISDN_ctrl_req cq; - int rx_off = 1; - - if (!dsp->features_rx_off) - return; - - /* not disabled */ - if (!dsp->rx_disabled) - rx_off = 0; - /* software dtmf */ - else if (dsp->dtmf.software) - rx_off = 0; - /* echo in software */ - else if (dsp->echo && dsp->pcm_slot_tx < 0) - rx_off = 0; - /* bridge in software */ - else if (dsp->conf) { - if (dsp->conf->software) - rx_off = 0; - } - - if (rx_off == dsp->rx_is_off) - return; - - if (!dsp->ch.peer) { - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: no peer, no rx_off\n", - __func__); - return; - } - cq.op = MISDN_CTRL_RX_OFF; - cq.p1 = rx_off; - if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) { - printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n", - __func__); - return; - } - dsp->rx_is_off = rx_off; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: %s set rx_off = %d\n", - __func__, dsp->name, rx_off); -} -static void -dsp_rx_off(struct dsp *dsp) -{ - struct dsp_conf_member *member; - - if (dsp_options & DSP_OPT_NOHARDWARE) - return; - - /* no conf */ - if (!dsp->conf) { - dsp_rx_off_member(dsp); - return; - } - /* check all members in conf */ - list_for_each_entry(member, &dsp->conf->mlist, list) { - dsp_rx_off_member(member->dsp); - } -} - -static int -dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) -{ - struct sk_buff *nskb; - int ret = 0; - int cont; - u8 *data; - int len; - - if (skb->len < sizeof(int)) - printk(KERN_ERR "%s: PH_CONTROL message too short\n", __func__); - cont = *((int *)skb->data); - len = skb->len - sizeof(int); - data = skb->data + sizeof(int); - - switch (cont) { - case DTMF_TONE_START: /* turn on DTMF */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: start dtmf\n", __func__); - if (len == sizeof(int)) { - printk(KERN_NOTICE "changing DTMF Threshold " - "to %d\n", *((int *)data)); - dsp->dtmf.treshold = (*(int *)data) * 10000; - } - /* init goertzel */ - dsp_dtmf_goertzel_init(dsp); - - /* check dtmf hardware */ - dsp_dtmf_hardware(dsp); - break; - case DTMF_TONE_STOP: /* turn off DTMF */ - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: stop dtmf\n", __func__); - dsp->dtmf.hardware = 0; - dsp->dtmf.software = 0; - break; - case DSP_CONF_JOIN: /* join / update conference */ - if (len < sizeof(int)) { - ret = -EINVAL; - break; - } - if (*((u32 *)data) == 0) - goto conf_split; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: join conference %d\n", - __func__, *((u32 *)data)); - ret = dsp_cmx_conf(dsp, *((u32 *)data)); - /* dsp_cmx_hardware will also be called here */ - dsp_rx_off(dsp); - if (dsp_debug & DEBUG_DSP_CMX) - dsp_cmx_debug(dsp); - break; - case DSP_CONF_SPLIT: /* remove from conference */ -conf_split: - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: release conference\n", __func__); - ret = dsp_cmx_conf(dsp, 0); - /* dsp_cmx_hardware will also be called here */ - if (dsp_debug & DEBUG_DSP_CMX) - dsp_cmx_debug(dsp); - dsp_rx_off(dsp); - break; - case DSP_TONE_PATT_ON: /* play tone */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (len < sizeof(int)) { - ret = -EINVAL; - break; - } - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: turn tone 0x%x on\n", - __func__, *((int *)skb->data)); - ret = dsp_tone(dsp, *((int *)data)); - if (!ret) { - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - } - if (!dsp->tone.tone) - goto tone_off; - break; - case DSP_TONE_PATT_OFF: /* stop tone */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: turn tone off\n", __func__); - dsp_tone(dsp, 0); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - /* reset tx buffers (user space data) */ -tone_off: - dsp->rx_W = 0; - dsp->rx_R = 0; - break; - case DSP_VOL_CHANGE_TX: /* change volume */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (len < sizeof(int)) { - ret = -EINVAL; - break; - } - dsp->tx_volume = *((int *)data); - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: change tx vol to %d\n", - __func__, dsp->tx_volume); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_dtmf_hardware(dsp); - dsp_rx_off(dsp); - break; - case DSP_VOL_CHANGE_RX: /* change volume */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (len < sizeof(int)) { - ret = -EINVAL; - break; - } - dsp->rx_volume = *((int *)data); - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: change rx vol to %d\n", - __func__, dsp->tx_volume); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_dtmf_hardware(dsp); - dsp_rx_off(dsp); - break; - case DSP_ECHO_ON: /* enable echo */ - dsp->echo = 1; /* soft echo */ - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - if (dsp_debug & DEBUG_DSP_CMX) - dsp_cmx_debug(dsp); - break; - case DSP_ECHO_OFF: /* disable echo */ - dsp->echo = 0; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - if (dsp_debug & DEBUG_DSP_CMX) - dsp_cmx_debug(dsp); - break; - case DSP_RECEIVE_ON: /* enable receive to user space */ - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: enable receive to user " - "space\n", __func__); - dsp->rx_disabled = 0; - dsp_rx_off(dsp); - break; - case DSP_RECEIVE_OFF: /* disable receive to user space */ - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: disable receive to " - "user space\n", __func__); - dsp->rx_disabled = 1; - dsp_rx_off(dsp); - break; - case DSP_MIX_ON: /* enable mixing of tx data */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: enable mixing of " - "tx-data with conf mebers\n", __func__); - dsp->tx_mix = 1; - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - if (dsp_debug & DEBUG_DSP_CMX) - dsp_cmx_debug(dsp); - break; - case DSP_MIX_OFF: /* disable mixing of tx data */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: disable mixing of " - "tx-data with conf mebers\n", __func__); - dsp->tx_mix = 0; - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - if (dsp_debug & DEBUG_DSP_CMX) - dsp_cmx_debug(dsp); - break; - case DSP_TXDATA_ON: /* enable txdata */ - dsp->tx_data = 1; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: enable tx-data\n", __func__); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - if (dsp_debug & DEBUG_DSP_CMX) - dsp_cmx_debug(dsp); - break; - case DSP_TXDATA_OFF: /* disable txdata */ - dsp->tx_data = 0; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: disable tx-data\n", __func__); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - if (dsp_debug & DEBUG_DSP_CMX) - dsp_cmx_debug(dsp); - break; - case DSP_DELAY: /* use delay algorithm instead of dynamic - jitter algorithm */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (len < sizeof(int)) { - ret = -EINVAL; - break; - } - dsp->cmx_delay = (*((int *)data)) << 3; - /* miliseconds to samples */ - if (dsp->cmx_delay >= (CMX_BUFF_HALF>>1)) - /* clip to half of maximum usable buffer - (half of half buffer) */ - dsp->cmx_delay = (CMX_BUFF_HALF>>1) - 1; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: use delay algorithm to " - "compensate jitter (%d samples)\n", - __func__, dsp->cmx_delay); - break; - case DSP_JITTER: /* use dynamic jitter algorithm instead of - delay algorithm */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - dsp->cmx_delay = 0; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: use jitter algorithm to " - "compensate jitter\n", __func__); - break; - case DSP_TX_DEJITTER: /* use dynamic jitter algorithm for tx-buffer */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - dsp->tx_dejitter = 1; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: use dejitter on TX " - "buffer\n", __func__); - break; - case DSP_TX_DEJ_OFF: /* use tx-buffer without dejittering*/ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - dsp->tx_dejitter = 0; - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: use TX buffer without " - "dejittering\n", __func__); - break; - case DSP_PIPELINE_CFG: - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (len > 0 && ((char *)data)[len - 1]) { - printk(KERN_DEBUG "%s: pipeline config string " - "is not NULL terminated!\n", __func__); - ret = -EINVAL; - } else { - dsp->pipeline.inuse = 1; - dsp_cmx_hardware(dsp->conf, dsp); - ret = dsp_pipeline_build(&dsp->pipeline, - len > 0 ? (char *)data : NULL); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - } - break; - case DSP_BF_ENABLE_KEY: /* turn blowfish on */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (len < 4 || len > 56) { - ret = -EINVAL; - break; - } - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: turn blowfish on (key " - "not shown)\n", __func__); - ret = dsp_bf_init(dsp, (u8 *)data, len); - /* set new cont */ - if (!ret) - cont = DSP_BF_ACCEPT; - else - cont = DSP_BF_REJECT; - /* send indication if it worked to set it */ - nskb = _alloc_mISDN_skb(PH_CONTROL_IND, MISDN_ID_ANY, - sizeof(int), &cont, GFP_ATOMIC); - if (nskb) { - if (dsp->up) { - if (dsp->up->send(dsp->up, nskb)) - dev_kfree_skb(nskb); - } else - dev_kfree_skb(nskb); - } - if (!ret) { - dsp_cmx_hardware(dsp->conf, dsp); - dsp_dtmf_hardware(dsp); - dsp_rx_off(dsp); - } - break; - case DSP_BF_DISABLE: /* turn blowfish off */ - if (dsp->hdlc) { - ret = -EINVAL; - break; - } - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: turn blowfish off\n", __func__); - dsp_bf_cleanup(dsp); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_dtmf_hardware(dsp); - dsp_rx_off(dsp); - break; - default: - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: ctrl req %x unhandled\n", - __func__, cont); - ret = -EINVAL; - } - return ret; -} - -static void -get_features(struct mISDNchannel *ch) -{ - struct dsp *dsp = container_of(ch, struct dsp, ch); - struct mISDN_ctrl_req cq; - - if (dsp_options & DSP_OPT_NOHARDWARE) - return; - if (!ch->peer) { - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: no peer, no features\n", - __func__); - return; - } - memset(&cq, 0, sizeof(cq)); - cq.op = MISDN_CTRL_GETOP; - if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq) < 0) { - printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", - __func__); - return; - } - if (cq.op & MISDN_CTRL_RX_OFF) - dsp->features_rx_off = 1; - if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) { - cq.op = MISDN_CTRL_HW_FEATURES; - *((u_long *)&cq.p1) = (u_long)&dsp->features; - if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq)) { - printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n", - __func__); - } - } else - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: features not supported for %s\n", - __func__, dsp->name); -} - -static int -dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct dsp *dsp = container_of(ch, struct dsp, ch); - struct mISDNhead *hh; - int ret = 0; - u8 *digits; - int cont; - struct sk_buff *nskb; - u_long flags; - - hh = mISDN_HEAD_P(skb); - switch (hh->prim) { - /* FROM DOWN */ - case (PH_DATA_CNF): - dsp->data_pending = 0; - /* trigger next hdlc frame, if any */ - if (dsp->hdlc) { - spin_lock_irqsave(&dsp_lock, flags); - if (dsp->b_active) - schedule_work(&dsp->workq); - spin_unlock_irqrestore(&dsp_lock, flags); - } - break; - case (PH_DATA_IND): - case (DL_DATA_IND): - if (skb->len < 1) { - ret = -EINVAL; - break; - } - if (dsp->rx_is_off) { - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: rx-data during rx_off" - " for %s\n", - __func__, dsp->name); - } - if (dsp->hdlc) { - /* hdlc */ - spin_lock_irqsave(&dsp_lock, flags); - dsp_cmx_hdlc(dsp, skb); - spin_unlock_irqrestore(&dsp_lock, flags); - if (dsp->rx_disabled) { - /* if receive is not allowed */ - break; - } - hh->prim = DL_DATA_IND; - if (dsp->up) - return dsp->up->send(dsp->up, skb); - break; - } - - /* decrypt if enabled */ - if (dsp->bf_enable) - dsp_bf_decrypt(dsp, skb->data, skb->len); - /* pipeline */ - if (dsp->pipeline.inuse) - dsp_pipeline_process_rx(&dsp->pipeline, skb->data, - skb->len); - /* change volume if requested */ - if (dsp->rx_volume) - dsp_change_volume(skb, dsp->rx_volume); - - /* check if dtmf soft decoding is turned on */ - if (dsp->dtmf.software) { - digits = dsp_dtmf_goertzel_decode(dsp, skb->data, - skb->len, (dsp_options&DSP_OPT_ULAW)?1:0); - while (*digits) { - if (dsp_debug & DEBUG_DSP_DTMF) - printk(KERN_DEBUG "%s: digit" - "(%c) to layer %s\n", - __func__, *digits, dsp->name); - cont = DTMF_TONE_VAL | *digits; - nskb = _alloc_mISDN_skb(PH_CONTROL_IND, - MISDN_ID_ANY, sizeof(int), &cont, - GFP_ATOMIC); - if (nskb) { - if (dsp->up) { - if (dsp->up->send( - dsp->up, nskb)) - dev_kfree_skb(nskb); - } else - dev_kfree_skb(nskb); - } - digits++; - } - } - /* we need to process receive data if software */ - spin_lock_irqsave(&dsp_lock, flags); - if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) { - /* process data from card at cmx */ - dsp_cmx_receive(dsp, skb); - } - spin_unlock_irqrestore(&dsp_lock, flags); - - if (dsp->rx_disabled) { - /* if receive is not allowed */ - break; - } - hh->prim = DL_DATA_IND; - if (dsp->up) - return dsp->up->send(dsp->up, skb); - break; - case (PH_CONTROL_IND): - if (dsp_debug & DEBUG_DSP_DTMFCOEFF) - printk(KERN_DEBUG "%s: PH_CONTROL INDICATION " - "received: %x (len %d) %s\n", __func__, - hh->id, skb->len, dsp->name); - switch (hh->id) { - case (DTMF_HFC_COEF): /* getting coefficients */ - if (!dsp->dtmf.hardware) { - if (dsp_debug & DEBUG_DSP_DTMFCOEFF) - printk(KERN_DEBUG "%s: ignoring DTMF " - "coefficients from HFC\n", - __func__); - break; - } - digits = dsp_dtmf_goertzel_decode(dsp, skb->data, - skb->len, 2); - while (*digits) { - int k; - struct sk_buff *nskb; - if (dsp_debug & DEBUG_DSP_DTMF) - printk(KERN_DEBUG "%s: digit" - "(%c) to layer %s\n", - __func__, *digits, dsp->name); - k = *digits | DTMF_TONE_VAL; - nskb = _alloc_mISDN_skb(PH_CONTROL_IND, - MISDN_ID_ANY, sizeof(int), &k, - GFP_ATOMIC); - if (nskb) { - if (dsp->up) { - if (dsp->up->send( - dsp->up, nskb)) - dev_kfree_skb(nskb); - } else - dev_kfree_skb(nskb); - } - digits++; - } - break; - case (HFC_VOL_CHANGE_TX): /* change volume */ - if (skb->len != sizeof(int)) { - ret = -EINVAL; - break; - } - spin_lock_irqsave(&dsp_lock, flags); - dsp->tx_volume = *((int *)skb->data); - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: change tx volume to " - "%d\n", __func__, dsp->tx_volume); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_dtmf_hardware(dsp); - dsp_rx_off(dsp); - spin_unlock_irqrestore(&dsp_lock, flags); - break; - default: - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: ctrl ind %x unhandled " - "%s\n", __func__, hh->id, dsp->name); - ret = -EINVAL; - } - break; - case (PH_ACTIVATE_IND): - case (PH_ACTIVATE_CNF): - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: b_channel is now active %s\n", - __func__, dsp->name); - /* bchannel now active */ - spin_lock_irqsave(&dsp_lock, flags); - dsp->b_active = 1; - dsp->data_pending = 0; - dsp->rx_init = 1; - /* rx_W and rx_R will be adjusted on first frame */ - dsp->rx_W = 0; - dsp->rx_R = 0; - memset(dsp->rx_buff, 0, sizeof(dsp->rx_buff)); - dsp_cmx_hardware(dsp->conf, dsp); - dsp_dtmf_hardware(dsp); - dsp_rx_off(dsp); - spin_unlock_irqrestore(&dsp_lock, flags); - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: done with activation, sending " - "confirm to user space. %s\n", __func__, - dsp->name); - /* send activation to upper layer */ - hh->prim = DL_ESTABLISH_CNF; - if (dsp->up) - return dsp->up->send(dsp->up, skb); - break; - case (PH_DEACTIVATE_IND): - case (PH_DEACTIVATE_CNF): - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: b_channel is now inactive %s\n", - __func__, dsp->name); - /* bchannel now inactive */ - spin_lock_irqsave(&dsp_lock, flags); - dsp->b_active = 0; - dsp->data_pending = 0; - dsp_cmx_hardware(dsp->conf, dsp); - dsp_rx_off(dsp); - spin_unlock_irqrestore(&dsp_lock, flags); - hh->prim = DL_RELEASE_CNF; - if (dsp->up) - return dsp->up->send(dsp->up, skb); - break; - /* FROM UP */ - case (DL_DATA_REQ): - case (PH_DATA_REQ): - if (skb->len < 1) { - ret = -EINVAL; - break; - } - if (dsp->hdlc) { - /* hdlc */ - spin_lock_irqsave(&dsp_lock, flags); - if (dsp->b_active) { - skb_queue_tail(&dsp->sendq, skb); - schedule_work(&dsp->workq); - } - spin_unlock_irqrestore(&dsp_lock, flags); - return 0; - } - /* send data to tx-buffer (if no tone is played) */ - if (!dsp->tone.tone) { - spin_lock_irqsave(&dsp_lock, flags); - dsp_cmx_transmit(dsp, skb); - spin_unlock_irqrestore(&dsp_lock, flags); - } - break; - case (PH_CONTROL_REQ): - spin_lock_irqsave(&dsp_lock, flags); - ret = dsp_control_req(dsp, hh, skb); - spin_unlock_irqrestore(&dsp_lock, flags); - break; - case (DL_ESTABLISH_REQ): - case (PH_ACTIVATE_REQ): - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: activating b_channel %s\n", - __func__, dsp->name); - if (dsp->dtmf.hardware || dsp->dtmf.software) - dsp_dtmf_goertzel_init(dsp); - get_features(ch); - /* send ph_activate */ - hh->prim = PH_ACTIVATE_REQ; - if (ch->peer) - return ch->recv(ch->peer, skb); - break; - case (DL_RELEASE_REQ): - case (PH_DEACTIVATE_REQ): - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: releasing b_channel %s\n", - __func__, dsp->name); - spin_lock_irqsave(&dsp_lock, flags); - dsp->tone.tone = 0; - dsp->tone.hardware = 0; - dsp->tone.software = 0; - if (timer_pending(&dsp->tone.tl)) - del_timer(&dsp->tone.tl); - if (dsp->conf) - dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be - called here */ - skb_queue_purge(&dsp->sendq); - spin_unlock_irqrestore(&dsp_lock, flags); - hh->prim = PH_DEACTIVATE_REQ; - if (ch->peer) - return ch->recv(ch->peer, skb); - break; - default: - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: msg %x unhandled %s\n", - __func__, hh->prim, dsp->name); - ret = -EINVAL; - } - if (!ret) - dev_kfree_skb(skb); - return ret; -} - -static int -dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct dsp *dsp = container_of(ch, struct dsp, ch); - u_long flags; - int err = 0; - - if (debug & DEBUG_DSP_CTRL) - printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd); - - switch (cmd) { - case OPEN_CHANNEL: - break; - case CLOSE_CHANNEL: - if (dsp->ch.peer) - dsp->ch.peer->ctrl(dsp->ch.peer, CLOSE_CHANNEL, NULL); - - /* wait until workqueue has finished, - * must lock here, or we may hit send-process currently - * queueing. */ - spin_lock_irqsave(&dsp_lock, flags); - dsp->b_active = 0; - spin_unlock_irqrestore(&dsp_lock, flags); - /* MUST not be locked, because it waits until queue is done. */ - cancel_work_sync(&dsp->workq); - spin_lock_irqsave(&dsp_lock, flags); - if (timer_pending(&dsp->tone.tl)) - del_timer(&dsp->tone.tl); - skb_queue_purge(&dsp->sendq); - if (dsp_debug & DEBUG_DSP_CTRL) - printk(KERN_DEBUG "%s: releasing member %s\n", - __func__, dsp->name); - dsp->b_active = 0; - dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be called - here */ - dsp_pipeline_destroy(&dsp->pipeline); - - if (dsp_debug & DEBUG_DSP_CTRL) - printk(KERN_DEBUG "%s: remove & destroy object %s\n", - __func__, dsp->name); - list_del(&dsp->list); - spin_unlock_irqrestore(&dsp_lock, flags); - - if (dsp_debug & DEBUG_DSP_CTRL) - printk(KERN_DEBUG "%s: dsp instance released\n", - __func__); - vfree(dsp); - module_put(THIS_MODULE); - break; - } - return err; -} - -static void -dsp_send_bh(struct work_struct *work) -{ - struct dsp *dsp = container_of(work, struct dsp, workq); - struct sk_buff *skb; - struct mISDNhead *hh; - - if (dsp->hdlc && dsp->data_pending) - return; /* wait until data has been acknowledged */ - - /* send queued data */ - while ((skb = skb_dequeue(&dsp->sendq))) { - /* in locked date, we must have still data in queue */ - if (dsp->data_pending) { - if (dsp_debug & DEBUG_DSP_CORE) - printk(KERN_DEBUG "%s: fifo full %s, this is " - "no bug!\n", __func__, dsp->name); - /* flush transparent data, if not acked */ - dev_kfree_skb(skb); - continue; - } - hh = mISDN_HEAD_P(skb); - if (hh->prim == DL_DATA_REQ) { - /* send packet up */ - if (dsp->up) { - if (dsp->up->send(dsp->up, skb)) - dev_kfree_skb(skb); - } else - dev_kfree_skb(skb); - } else { - /* send packet down */ - if (dsp->ch.peer) { - dsp->data_pending = 1; - if (dsp->ch.recv(dsp->ch.peer, skb)) { - dev_kfree_skb(skb); - dsp->data_pending = 0; - } - } else - dev_kfree_skb(skb); - } - } -} - -static int -dspcreate(struct channel_req *crq) -{ - struct dsp *ndsp; - u_long flags; - - if (crq->protocol != ISDN_P_B_L2DSP - && crq->protocol != ISDN_P_B_L2DSPHDLC) - return -EPROTONOSUPPORT; - ndsp = vmalloc(sizeof(struct dsp)); - if (!ndsp) { - printk(KERN_ERR "%s: vmalloc struct dsp failed\n", __func__); - return -ENOMEM; - } - memset(ndsp, 0, sizeof(struct dsp)); - if (dsp_debug & DEBUG_DSP_CTRL) - printk(KERN_DEBUG "%s: creating new dsp instance\n", __func__); - - /* default enabled */ - INIT_WORK(&ndsp->workq, (void *)dsp_send_bh); - skb_queue_head_init(&ndsp->sendq); - ndsp->ch.send = dsp_function; - ndsp->ch.ctrl = dsp_ctrl; - ndsp->up = crq->ch; - crq->ch = &ndsp->ch; - if (crq->protocol == ISDN_P_B_L2DSP) { - crq->protocol = ISDN_P_B_RAW; - ndsp->hdlc = 0; - } else { - crq->protocol = ISDN_P_B_HDLC; - ndsp->hdlc = 1; - } - if (!try_module_get(THIS_MODULE)) - printk(KERN_WARNING "%s:cannot get module\n", - __func__); - - sprintf(ndsp->name, "DSP_C%x(0x%p)", - ndsp->up->st->dev->id + 1, ndsp); - /* set frame size to start */ - ndsp->features.hfc_id = -1; /* current PCM id */ - ndsp->features.pcm_id = -1; /* current PCM id */ - ndsp->pcm_slot_rx = -1; /* current CPM slot */ - ndsp->pcm_slot_tx = -1; - ndsp->pcm_bank_rx = -1; - ndsp->pcm_bank_tx = -1; - ndsp->hfc_conf = -1; /* current conference number */ - /* set tone timer */ - ndsp->tone.tl.function = (void *)dsp_tone_timeout; - ndsp->tone.tl.data = (long) ndsp; - init_timer(&ndsp->tone.tl); - - if (dtmfthreshold < 20 || dtmfthreshold > 500) - dtmfthreshold = 200; - ndsp->dtmf.treshold = dtmfthreshold*10000; - - /* init pipeline append to list */ - spin_lock_irqsave(&dsp_lock, flags); - dsp_pipeline_init(&ndsp->pipeline); - list_add_tail(&ndsp->list, &dsp_ilist); - spin_unlock_irqrestore(&dsp_lock, flags); - - return 0; -} - - -static struct Bprotocol DSP = { - .Bprotocols = (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK)) - | (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)), - .name = "dsp", - .create = dspcreate -}; - -static int dsp_init(void) -{ - int err; - int tics; - - printk(KERN_INFO "DSP modul %s\n", mISDN_dsp_revision); - - dsp_options = options; - dsp_debug = debug; - - /* set packet size */ - dsp_poll = poll; - if (dsp_poll) { - if (dsp_poll > MAX_POLL) { - printk(KERN_ERR "%s: Wrong poll value (%d), use %d " - "maximum.\n", __func__, poll, MAX_POLL); - err = -EINVAL; - return err; - } - if (dsp_poll < 8) { - printk(KERN_ERR "%s: Wrong poll value (%d), use 8 " - "minimum.\n", __func__, dsp_poll); - err = -EINVAL; - return err; - } - dsp_tics = poll * HZ / 8000; - if (dsp_tics * 8000 != poll * HZ) { - printk(KERN_INFO "mISDN_dsp: Cannot clock every %d " - "samples (0,125 ms). It is not a multiple of " - "%d HZ.\n", poll, HZ); - err = -EINVAL; - return err; - } - } else { - poll = 8; - while (poll <= MAX_POLL) { - tics = poll * HZ / 8000; - if (tics * 8000 == poll * HZ) { - dsp_tics = tics; - dsp_poll = poll; - if (poll >= 64) - break; - } - poll++; - } - } - if (dsp_poll == 0) { - printk(KERN_INFO "mISDN_dsp: There is no multiple of kernel " - "clock that equals exactly the duration of 8-256 " - "samples. (Choose kernel clock speed like 100, 250, " - "300, 1000)\n"); - err = -EINVAL; - return err; - } - printk(KERN_INFO "mISDN_dsp: DSP clocks every %d samples. This equals " - "%d jiffies.\n", dsp_poll, dsp_tics); - - spin_lock_init(&dsp_lock); - INIT_LIST_HEAD(&dsp_ilist); - INIT_LIST_HEAD(&conf_ilist); - - /* init conversion tables */ - dsp_audio_generate_law_tables(); - dsp_silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a; - dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW)?dsp_audio_ulaw_to_s32: - dsp_audio_alaw_to_s32; - dsp_audio_generate_s2law_table(); - dsp_audio_generate_seven(); - dsp_audio_generate_mix_table(); - if (dsp_options & DSP_OPT_ULAW) - dsp_audio_generate_ulaw_samples(); - dsp_audio_generate_volume_changes(); - - err = dsp_pipeline_module_init(); - if (err) { - printk(KERN_ERR "mISDN_dsp: Can't initialize pipeline, " - "error(%d)\n", err); - return err; - } - - err = mISDN_register_Bprotocol(&DSP); - if (err) { - printk(KERN_ERR "Can't register %s error(%d)\n", DSP.name, err); - return err; - } - - /* set sample timer */ - dsp_spl_tl.function = (void *)dsp_cmx_send; - dsp_spl_tl.data = 0; - init_timer(&dsp_spl_tl); - dsp_spl_tl.expires = jiffies + dsp_tics; - dsp_spl_jiffies = dsp_spl_tl.expires; - add_timer(&dsp_spl_tl); - - return 0; -} - - -static void dsp_cleanup(void) -{ - mISDN_unregister_Bprotocol(&DSP); - - if (timer_pending(&dsp_spl_tl)) - del_timer(&dsp_spl_tl); - - if (!list_empty(&dsp_ilist)) { - printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not " - "empty.\n"); - } - if (!list_empty(&conf_ilist)) { - printk(KERN_ERR "mISDN_dsp: Conference list not empty. Not " - "all memory freed.\n"); - } - - dsp_pipeline_module_exit(); -} - -module_init(dsp_init); -module_exit(dsp_cleanup); - diff --git a/trunk/drivers/isdn/mISDN/dsp_dtmf.c b/trunk/drivers/isdn/mISDN/dsp_dtmf.c deleted file mode 100644 index efc371c1f0dc..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_dtmf.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * DTMF decoder. - * - * Copyright by Andreas Eversberg (jolly@eversberg.eu) - * based on different decoders such as ISDN4Linux - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include -#include -#include "core.h" -#include "dsp.h" - -#define NCOEFF 8 /* number of frequencies to be analyzed */ - -/* For DTMF recognition: - * 2 * cos(2 * PI * k / N) precalculated for all k - */ -static u64 cos2pik[NCOEFF] = -{ - /* k << 15 (source: hfc-4s/8s documentation (www.colognechip.de)) */ - 55960, 53912, 51402, 48438, 38146, 32650, 26170, 18630 -}; - -/* digit matrix */ -static char dtmf_matrix[4][4] = -{ - {'1', '2', '3', 'A'}, - {'4', '5', '6', 'B'}, - {'7', '8', '9', 'C'}, - {'*', '0', '#', 'D'} -}; - -/* dtmf detection using goertzel algorithm - * init function - */ -void dsp_dtmf_goertzel_init(struct dsp *dsp) -{ - dsp->dtmf.size = 0; - dsp->dtmf.lastwhat = '\0'; - dsp->dtmf.lastdigit = '\0'; - dsp->dtmf.count = 0; -} - -/* check for hardware or software features - */ -void dsp_dtmf_hardware(struct dsp *dsp) -{ - int hardware = 1; - - if (!dsp->features.hfc_dtmf) - hardware = 0; - - /* check for volume change */ - if (dsp->tx_volume) { - if (dsp_debug & DEBUG_DSP_DTMF) - printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, " - "because tx_volume is changed\n", - __func__, dsp->name); - hardware = 0; - } - if (dsp->rx_volume) { - if (dsp_debug & DEBUG_DSP_DTMF) - printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, " - "because rx_volume is changed\n", - __func__, dsp->name); - hardware = 0; - } - /* check if encryption is enabled */ - if (dsp->bf_enable) { - if (dsp_debug & DEBUG_DSP_DTMF) - printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, " - "because encryption is enabled\n", - __func__, dsp->name); - hardware = 0; - } - /* check if pipeline exists */ - if (dsp->pipeline.inuse) { - if (dsp_debug & DEBUG_DSP_DTMF) - printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, " - "because pipeline exists.\n", - __func__, dsp->name); - hardware = 0; - } - - dsp->dtmf.hardware = hardware; - dsp->dtmf.software = !hardware; -} - - -/************************************************************* - * calculate the coefficients of the given sample and decode * - *************************************************************/ - -/* the given sample is decoded. if the sample is not long enough for a - * complete frame, the decoding is finished and continued with the next - * call of this function. - * - * the algorithm is very good for detection with a minimum of errors. i - * tested it allot. it even works with very short tones (40ms). the only - * disadvantage is, that it doesn't work good with different volumes of both - * tones. this will happen, if accoustically coupled dialers are used. - * it sometimes detects tones during speach, which is normal for decoders. - * use sequences to given commands during calls. - * - * dtmf - points to a structure of the current dtmf state - * spl and len - the sample - * fmt - 0 = alaw, 1 = ulaw, 2 = coefficients from HFC DTMF hw-decoder - */ - -u8 -*dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len, int fmt) -{ - u8 what; - int size; - signed short *buf; - s32 sk, sk1, sk2; - int k, n, i; - s32 *hfccoeff; - s32 result[NCOEFF], tresh, treshl; - int lowgroup, highgroup; - s64 cos2pik_; - - dsp->dtmf.digits[0] = '\0'; - - /* Note: The function will loop until the buffer has not enough samples - * left to decode a full frame. - */ -again: - /* convert samples */ - size = dsp->dtmf.size; - buf = dsp->dtmf.buffer; - switch (fmt) { - case 0: /* alaw */ - case 1: /* ulaw */ - while (size < DSP_DTMF_NPOINTS && len) { - buf[size++] = dsp_audio_law_to_s32[*data++]; - len--; - } - break; - - case 2: /* HFC coefficients */ - default: - if (len < 64) { - if (len > 0) - printk(KERN_ERR "%s: coefficients have invalid " - "size. (is=%d < must=%d)\n", - __func__, len, 64); - return dsp->dtmf.digits; - } - hfccoeff = (s32 *)data; - for (k = 0; k < NCOEFF; k++) { - sk2 = (*hfccoeff++)>>4; - sk = (*hfccoeff++)>>4; - if (sk > 32767 || sk < -32767 || sk2 > 32767 - || sk2 < -32767) - printk(KERN_WARNING - "DTMF-Detection overflow\n"); - /* compute |X(k)|**2 */ - result[k] = - (sk * sk) - - (((cos2pik[k] * sk) >> 15) * sk2) + - (sk2 * sk2); - } - data += 64; - len -= 64; - goto coefficients; - break; - } - dsp->dtmf.size = size; - - if (size < DSP_DTMF_NPOINTS) - return dsp->dtmf.digits; - - dsp->dtmf.size = 0; - - /* now we have a full buffer of signed long samples - we do goertzel */ - for (k = 0; k < NCOEFF; k++) { - sk = 0; - sk1 = 0; - sk2 = 0; - buf = dsp->dtmf.buffer; - cos2pik_ = cos2pik[k]; - for (n = 0; n < DSP_DTMF_NPOINTS; n++) { - sk = ((cos2pik_*sk1)>>15) - sk2 + (*buf++); - sk2 = sk1; - sk1 = sk; - } - sk >>= 8; - sk2 >>= 8; - if (sk > 32767 || sk < -32767 || sk2 > 32767 || sk2 < -32767) - printk(KERN_WARNING "DTMF-Detection overflow\n"); - /* compute |X(k)|**2 */ - result[k] = - (sk * sk) - - (((cos2pik[k] * sk) >> 15) * sk2) + - (sk2 * sk2); - } - - /* our (squared) coefficients have been calculated, we need to process - * them. - */ -coefficients: - tresh = 0; - for (i = 0; i < NCOEFF; i++) { - if (result[i] < 0) - result[i] = 0; - if (result[i] > dsp->dtmf.treshold) { - if (result[i] > tresh) - tresh = result[i]; - } - } - - if (tresh == 0) { - what = 0; - goto storedigit; - } - - if (dsp_debug & DEBUG_DSP_DTMFCOEFF) - printk(KERN_DEBUG "a %3d %3d %3d %3d %3d %3d %3d %3d" - " tr:%3d r %3d %3d %3d %3d %3d %3d %3d %3d\n", - result[0]/10000, result[1]/10000, result[2]/10000, - result[3]/10000, result[4]/10000, result[5]/10000, - result[6]/10000, result[7]/10000, tresh/10000, - result[0]/(tresh/100), result[1]/(tresh/100), - result[2]/(tresh/100), result[3]/(tresh/100), - result[4]/(tresh/100), result[5]/(tresh/100), - result[6]/(tresh/100), result[7]/(tresh/100)); - - /* calc digit (lowgroup/highgroup) */ - lowgroup = -1; - highgroup = -1; - treshl = tresh >> 3; /* tones which are not on, must be below 9 dB */ - tresh = tresh >> 2; /* touchtones must match within 6 dB */ - for (i = 0; i < NCOEFF; i++) { - if (result[i] < treshl) - continue; /* ignore */ - if (result[i] < tresh) { - lowgroup = -1; - highgroup = -1; - break; /* noise inbetween */ - } - /* good level found. This is allowed only one time per group */ - if (i < NCOEFF/2) { - /* lowgroup */ - if (lowgroup >= 0) { - /* Bad. Another tone found. */ - lowgroup = -1; - break; - } else - lowgroup = i; - } else { - /* higroup */ - if (highgroup >= 0) { - /* Bad. Another tone found. */ - highgroup = -1; - break; - } else - highgroup = i-(NCOEFF/2); - } - } - - /* get digit or null */ - what = 0; - if (lowgroup >= 0 && highgroup >= 0) - what = dtmf_matrix[lowgroup][highgroup]; - -storedigit: - if (what && (dsp_debug & DEBUG_DSP_DTMF)) - printk(KERN_DEBUG "DTMF what: %c\n", what); - - if (dsp->dtmf.lastwhat != what) - dsp->dtmf.count = 0; - - /* the tone (or no tone) must remain 3 times without change */ - if (dsp->dtmf.count == 2) { - if (dsp->dtmf.lastdigit != what) { - dsp->dtmf.lastdigit = what; - if (what) { - if (dsp_debug & DEBUG_DSP_DTMF) - printk(KERN_DEBUG "DTMF digit: %c\n", - what); - if ((strlen(dsp->dtmf.digits)+1) - < sizeof(dsp->dtmf.digits)) { - dsp->dtmf.digits[strlen( - dsp->dtmf.digits)+1] = '\0'; - dsp->dtmf.digits[strlen( - dsp->dtmf.digits)] = what; - } - } - } - } else - dsp->dtmf.count++; - - dsp->dtmf.lastwhat = what; - - goto again; -} - - diff --git a/trunk/drivers/isdn/mISDN/dsp_ecdis.h b/trunk/drivers/isdn/mISDN/dsp_ecdis.h deleted file mode 100644 index 8a20af43308b..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_ecdis.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * ec_disable_detector.h - A detector which should eventually meet the - * G.164/G.165 requirements for detecting the - * 2100Hz echo cancellor disable tone. - * - * Written by Steve Underwood - * - * Copyright (C) 2001 Steve Underwood - * - * 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; 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "dsp_biquad.h" - -struct ec_disable_detector_state { - struct biquad2_state notch; - int notch_level; - int channel_level; - int tone_present; - int tone_cycle_duration; - int good_cycles; - int hit; -}; - - -#define FALSE 0 -#define TRUE (!FALSE) - -static inline void -echo_can_disable_detector_init(struct ec_disable_detector_state *det) -{ - /* Elliptic notch */ - /* This is actually centred at 2095Hz, but gets the balance we want, due - to the asymmetric walls of the notch */ - biquad2_init(&det->notch, - (int32_t) (-0.7600000*32768.0), - (int32_t) (-0.1183852*32768.0), - (int32_t) (-0.5104039*32768.0), - (int32_t) (0.1567596*32768.0), - (int32_t) (1.0000000*32768.0)); - - det->channel_level = 0; - det->notch_level = 0; - det->tone_present = FALSE; - det->tone_cycle_duration = 0; - det->good_cycles = 0; - det->hit = 0; -} -/*- End of function --------------------------------------------------------*/ - -static inline int -echo_can_disable_detector_update(struct ec_disable_detector_state *det, -int16_t amp) -{ - int16_t notched; - - notched = biquad2(&det->notch, amp); - /* Estimate the overall energy in the channel, and the energy in - the notch (i.e. overall channel energy - tone energy => noise). - Use abs instead of multiply for speed (is it really faster?). - Damp the overall energy a little more for a stable result. - Damp the notch energy a little less, so we don't damp out the - blip every time the phase reverses */ - det->channel_level += ((abs(amp) - det->channel_level) >> 5); - det->notch_level += ((abs(notched) - det->notch_level) >> 4); - if (det->channel_level > 280) { - /* There is adequate energy in the channel. - Is it mostly at 2100Hz? */ - if (det->notch_level*6 < det->channel_level) { - /* The notch says yes, so we have the tone. */ - if (!det->tone_present) { - /* Do we get a kick every 450+-25ms? */ - if (det->tone_cycle_duration >= 425*8 - && det->tone_cycle_duration <= 475*8) { - det->good_cycles++; - if (det->good_cycles > 2) - det->hit = TRUE; - } - det->tone_cycle_duration = 0; - } - det->tone_present = TRUE; - } else - det->tone_present = FALSE; - det->tone_cycle_duration++; - } else { - det->tone_present = FALSE; - det->tone_cycle_duration = 0; - det->good_cycles = 0; - } - return det->hit; -} -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ diff --git a/trunk/drivers/isdn/mISDN/dsp_hwec.c b/trunk/drivers/isdn/mISDN/dsp_hwec.c deleted file mode 100644 index eb892d9dd5c6..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_hwec.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * dsp_hwec.c: - * builtin mISDN dsp pipeline element for enabling the hw echocanceller - * - * Copyright (C) 2007, Nadi Sarrar - * - * Nadi Sarrar - * - * 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. - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - */ - -#include -#include -#include -#include -#include "core.h" -#include "dsp.h" -#include "dsp_hwec.h" - -static struct mISDN_dsp_element_arg args[] = { - { "deftaps", "128", "Set the number of taps of cancellation." }, -}; - -static struct mISDN_dsp_element dsp_hwec_p = { - .name = "hwec", - .new = NULL, - .free = NULL, - .process_tx = NULL, - .process_rx = NULL, - .num_args = sizeof(args) / sizeof(struct mISDN_dsp_element_arg), - .args = args, -}; -struct mISDN_dsp_element *dsp_hwec = &dsp_hwec_p; - -void dsp_hwec_enable(struct dsp *dsp, const char *arg) -{ - int deftaps = 128, - len; - struct mISDN_ctrl_req cq; - - if (!dsp) { - printk(KERN_ERR "%s: failed to enable hwec: dsp is NULL\n", - __func__); - return; - } - - if (!arg) - goto _do; - - len = strlen(arg); - if (!len) - goto _do; - - { - char _dup[len + 1]; - char *dup, *tok, *name, *val; - int tmp; - - strcpy(_dup, arg); - dup = _dup; - - while ((tok = strsep(&dup, ","))) { - if (!strlen(tok)) - continue; - name = strsep(&tok, "="); - val = tok; - - if (!val) - continue; - - if (!strcmp(name, "deftaps")) { - if (sscanf(val, "%d", &tmp) == 1) - deftaps = tmp; - } - } - } - -_do: - printk(KERN_DEBUG "%s: enabling hwec with deftaps=%d\n", - __func__, deftaps); - memset(&cq, 0, sizeof(cq)); - cq.op = MISDN_CTRL_HFC_ECHOCAN_ON; - cq.p1 = deftaps; - if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) { - printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", - __func__); - return; - } -} - -void dsp_hwec_disable(struct dsp *dsp) -{ - struct mISDN_ctrl_req cq; - - if (!dsp) { - printk(KERN_ERR "%s: failed to disable hwec: dsp is NULL\n", - __func__); - return; - } - - printk(KERN_DEBUG "%s: disabling hwec\n", __func__); - memset(&cq, 0, sizeof(cq)); - cq.op = MISDN_CTRL_HFC_ECHOCAN_OFF; - if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) { - printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", - __func__); - return; - } -} - -int dsp_hwec_init(void) -{ - mISDN_dsp_element_register(dsp_hwec); - - return 0; -} - -void dsp_hwec_exit(void) -{ - mISDN_dsp_element_unregister(dsp_hwec); -} - diff --git a/trunk/drivers/isdn/mISDN/dsp_hwec.h b/trunk/drivers/isdn/mISDN/dsp_hwec.h deleted file mode 100644 index eebe80c3f713..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_hwec.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * dsp_hwec.h - */ - -extern struct mISDN_dsp_element *dsp_hwec; -extern void dsp_hwec_enable(struct dsp *dsp, const char *arg); -extern void dsp_hwec_disable(struct dsp *dsp); -extern int dsp_hwec_init(void); -extern void dsp_hwec_exit(void); - diff --git a/trunk/drivers/isdn/mISDN/dsp_pipeline.c b/trunk/drivers/isdn/mISDN/dsp_pipeline.c deleted file mode 100644 index 850260ab57d0..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_pipeline.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * dsp_pipeline.c: pipelined audio processing - * - * Copyright (C) 2007, Nadi Sarrar - * - * Nadi Sarrar - * - * 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. - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - */ - -#include -#include -#include -#include -#include -#include "dsp.h" -#include "dsp_hwec.h" - -/* uncomment for debugging */ -/*#define PIPELINE_DEBUG*/ - -struct dsp_pipeline_entry { - struct mISDN_dsp_element *elem; - void *p; - struct list_head list; -}; -struct dsp_element_entry { - struct mISDN_dsp_element *elem; - struct device dev; - struct list_head list; -}; - -static LIST_HEAD(dsp_elements); - -/* sysfs */ -static struct class *elements_class; - -static ssize_t -attr_show_args(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct mISDN_dsp_element *elem = dev_get_drvdata(dev); - ssize_t len = 0; - int i = 0; - - *buf = 0; - for (; i < elem->num_args; ++i) - len = sprintf(buf, "%sName: %s\n%s%s%sDescription: %s\n" - "\n", buf, - elem->args[i].name, - elem->args[i].def ? "Default: " : "", - elem->args[i].def ? elem->args[i].def : "", - elem->args[i].def ? "\n" : "", - elem->args[i].desc); - - return len; -} - -static struct device_attribute element_attributes[] = { - __ATTR(args, 0444, attr_show_args, NULL), -}; - -int mISDN_dsp_element_register(struct mISDN_dsp_element *elem) -{ - struct dsp_element_entry *entry; - int ret, i; - - if (!elem) - return -EINVAL; - - entry = kzalloc(sizeof(struct dsp_element_entry), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - entry->elem = elem; - - entry->dev.class = elements_class; - dev_set_drvdata(&entry->dev, elem); - snprintf(entry->dev.bus_id, BUS_ID_SIZE, elem->name); - ret = device_register(&entry->dev); - if (ret) { - printk(KERN_ERR "%s: failed to register %s\n", - __func__, elem->name); - goto err1; - } - - for (i = 0; i < (sizeof(element_attributes) - / sizeof(struct device_attribute)); ++i) - ret = device_create_file(&entry->dev, - &element_attributes[i]); - if (ret) { - printk(KERN_ERR "%s: failed to create device file\n", - __func__); - goto err2; - } - - list_add_tail(&entry->list, &dsp_elements); - - printk(KERN_DEBUG "%s: %s registered\n", __func__, elem->name); - - return 0; - -err2: - device_unregister(&entry->dev); -err1: - kfree(entry); - return ret; -} -EXPORT_SYMBOL(mISDN_dsp_element_register); - -void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem) -{ - struct dsp_element_entry *entry, *n; - - if (!elem) - return; - - list_for_each_entry_safe(entry, n, &dsp_elements, list) - if (entry->elem == elem) { - list_del(&entry->list); - device_unregister(&entry->dev); - kfree(entry); - printk(KERN_DEBUG "%s: %s unregistered\n", - __func__, elem->name); - return; - } - printk(KERN_ERR "%s: element %s not in list.\n", __func__, elem->name); -} -EXPORT_SYMBOL(mISDN_dsp_element_unregister); - -int dsp_pipeline_module_init(void) -{ - elements_class = class_create(THIS_MODULE, "dsp_pipeline"); - if (IS_ERR(elements_class)) - return PTR_ERR(elements_class); - -#ifdef PIPELINE_DEBUG - printk(KERN_DEBUG "%s: dsp pipeline module initialized\n", __func__); -#endif - - dsp_hwec_init(); - - return 0; -} - -void dsp_pipeline_module_exit(void) -{ - struct dsp_element_entry *entry, *n; - - dsp_hwec_exit(); - - class_destroy(elements_class); - - list_for_each_entry_safe(entry, n, &dsp_elements, list) { - list_del(&entry->list); - printk(KERN_WARNING "%s: element was still registered: %s\n", - __func__, entry->elem->name); - kfree(entry); - } - - printk(KERN_DEBUG "%s: dsp pipeline module exited\n", __func__); -} - -int dsp_pipeline_init(struct dsp_pipeline *pipeline) -{ - if (!pipeline) - return -EINVAL; - - INIT_LIST_HEAD(&pipeline->list); - -#ifdef PIPELINE_DEBUG - printk(KERN_DEBUG "%s: dsp pipeline ready\n", __func__); -#endif - - return 0; -} - -static inline void _dsp_pipeline_destroy(struct dsp_pipeline *pipeline) -{ - struct dsp_pipeline_entry *entry, *n; - - list_for_each_entry_safe(entry, n, &pipeline->list, list) { - list_del(&entry->list); - if (entry->elem == dsp_hwec) - dsp_hwec_disable(container_of(pipeline, struct dsp, - pipeline)); - else - entry->elem->free(entry->p); - kfree(entry); - } -} - -void dsp_pipeline_destroy(struct dsp_pipeline *pipeline) -{ - - if (!pipeline) - return; - - _dsp_pipeline_destroy(pipeline); - -#ifdef PIPELINE_DEBUG - printk(KERN_DEBUG "%s: dsp pipeline destroyed\n", __func__); -#endif -} - -int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg) -{ - int len, incomplete = 0, found = 0; - char *dup, *tok, *name, *args; - struct dsp_element_entry *entry, *n; - struct dsp_pipeline_entry *pipeline_entry; - struct mISDN_dsp_element *elem; - - if (!pipeline) - return -EINVAL; - - if (!list_empty(&pipeline->list)) - _dsp_pipeline_destroy(pipeline); - - if (!cfg) - return 0; - - len = strlen(cfg); - if (!len) - return 0; - - dup = kmalloc(len + 1, GFP_KERNEL); - if (!dup) - return 0; - strcpy(dup, cfg); - while ((tok = strsep(&dup, "|"))) { - if (!strlen(tok)) - continue; - name = strsep(&tok, "("); - args = strsep(&tok, ")"); - if (args && !*args) - args = 0; - - list_for_each_entry_safe(entry, n, &dsp_elements, list) - if (!strcmp(entry->elem->name, name)) { - elem = entry->elem; - - pipeline_entry = kmalloc(sizeof(struct - dsp_pipeline_entry), GFP_KERNEL); - if (!pipeline_entry) { - printk(KERN_DEBUG "%s: failed to add " - "entry to pipeline: %s (out of " - "memory)\n", __func__, elem->name); - incomplete = 1; - goto _out; - } - pipeline_entry->elem = elem; - - if (elem == dsp_hwec) { - /* This is a hack to make the hwec - available as a pipeline module */ - dsp_hwec_enable(container_of(pipeline, - struct dsp, pipeline), args); - list_add_tail(&pipeline_entry->list, - &pipeline->list); - } else { - pipeline_entry->p = elem->new(args); - if (pipeline_entry->p) { - list_add_tail(&pipeline_entry-> - list, &pipeline->list); -#ifdef PIPELINE_DEBUG - printk(KERN_DEBUG "%s: created " - "instance of %s%s%s\n", - __func__, name, args ? - " with args " : "", args ? - args : ""); -#endif - } else { - printk(KERN_DEBUG "%s: failed " - "to add entry to pipeline: " - "%s (new() returned NULL)\n", - __func__, elem->name); - kfree(pipeline_entry); - incomplete = 1; - } - } - found = 1; - break; - } - - if (found) - found = 0; - else { - printk(KERN_DEBUG "%s: element not found, skipping: " - "%s\n", __func__, name); - incomplete = 1; - } - } - -_out: - if (!list_empty(&pipeline->list)) - pipeline->inuse = 1; - else - pipeline->inuse = 0; - -#ifdef PIPELINE_DEBUG - printk(KERN_DEBUG "%s: dsp pipeline built%s: %s\n", - __func__, incomplete ? " incomplete" : "", cfg); -#endif - kfree(dup); - return 0; -} - -void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len) -{ - struct dsp_pipeline_entry *entry; - - if (!pipeline) - return; - - list_for_each_entry(entry, &pipeline->list, list) - if (entry->elem->process_tx) - entry->elem->process_tx(entry->p, data, len); -} - -void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len) -{ - struct dsp_pipeline_entry *entry; - - if (!pipeline) - return; - - list_for_each_entry_reverse(entry, &pipeline->list, list) - if (entry->elem->process_rx) - entry->elem->process_rx(entry->p, data, len); -} - - diff --git a/trunk/drivers/isdn/mISDN/dsp_tones.c b/trunk/drivers/isdn/mISDN/dsp_tones.c deleted file mode 100644 index 23dd0dd21524..000000000000 --- a/trunk/drivers/isdn/mISDN/dsp_tones.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Audio support data for ISDN4Linux. - * - * Copyright Andreas Eversberg (jolly@eversberg.eu) - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include -#include -#include "core.h" -#include "dsp.h" - - -#define DATA_S sample_silence -#define SIZE_S (&sizeof_silence) -#define DATA_GA sample_german_all -#define SIZE_GA (&sizeof_german_all) -#define DATA_GO sample_german_old -#define SIZE_GO (&sizeof_german_old) -#define DATA_DT sample_american_dialtone -#define SIZE_DT (&sizeof_american_dialtone) -#define DATA_RI sample_american_ringing -#define SIZE_RI (&sizeof_american_ringing) -#define DATA_BU sample_american_busy -#define SIZE_BU (&sizeof_american_busy) -#define DATA_S1 sample_special1 -#define SIZE_S1 (&sizeof_special1) -#define DATA_S2 sample_special2 -#define SIZE_S2 (&sizeof_special2) -#define DATA_S3 sample_special3 -#define SIZE_S3 (&sizeof_special3) - -/***************/ -/* tones loops */ -/***************/ - -/* all tones are alaw encoded */ -/* the last sample+1 is in phase with the first sample. the error is low */ - -static u8 sample_german_all[] = { - 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, - 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, - 0xdc, 0xfc, 0x6c, - 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, - 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, - 0xdc, 0xfc, 0x6c, - 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, - 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, - 0xdc, 0xfc, 0x6c, - 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, - 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, - 0xdc, 0xfc, 0x6c, -}; -static u32 sizeof_german_all = sizeof(sample_german_all); - -static u8 sample_german_old[] = { - 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, - 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, - 0x8c, - 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, - 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, - 0x8c, - 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, - 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, - 0x8c, - 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, - 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, - 0x8c, -}; -static u32 sizeof_german_old = sizeof(sample_german_old); - -static u8 sample_american_dialtone[] = { - 0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c, - 0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d, - 0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0, - 0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67, - 0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67, - 0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef, - 0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8, - 0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61, - 0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e, - 0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30, - 0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d, - 0x6d, 0x91, 0x19, -}; -static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone); - -static u8 sample_american_ringing[] = { - 0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90, - 0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed, - 0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c, - 0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d, - 0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec, - 0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11, - 0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00, - 0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39, - 0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6, - 0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3, - 0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b, - 0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f, - 0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56, - 0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59, - 0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30, - 0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d, - 0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c, - 0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd, - 0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc, - 0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d, - 0x4d, 0xbd, 0x0d, 0xad, 0xe1, -}; -static u32 sizeof_american_ringing = sizeof(sample_american_ringing); - -static u8 sample_american_busy[] = { - 0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66, - 0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96, - 0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57, - 0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f, - 0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40, - 0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d, - 0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c, - 0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d, - 0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40, - 0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7, - 0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a, - 0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7, - 0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40, - 0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d, - 0x4d, 0x4d, 0x6d, 0x01, -}; -static u32 sizeof_american_busy = sizeof(sample_american_busy); - -static u8 sample_special1[] = { - 0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d, - 0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd, - 0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd, - 0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd, - 0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed, - 0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41, - 0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7, - 0x6d, 0xbd, 0x2d, -}; -static u32 sizeof_special1 = sizeof(sample_special1); - -static u8 sample_special2[] = { - 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc, - 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d, - 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6, - 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0, - 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd, - 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc, - 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d, - 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6, - 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0, - 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd, -}; -static u32 sizeof_special2 = sizeof(sample_special2); - -static u8 sample_special3[] = { - 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1, - 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c, - 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc, - 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7, - 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd, - 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1, - 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c, - 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc, - 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7, - 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd, -}; -static u32 sizeof_special3 = sizeof(sample_special3); - -static u8 sample_silence[] = { - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, - 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, -}; -static u32 sizeof_silence = sizeof(sample_silence); - -struct tones_samples { - u32 *len; - u8 *data; -}; -static struct -tones_samples samples[] = { - {&sizeof_german_all, sample_german_all}, - {&sizeof_german_old, sample_german_old}, - {&sizeof_american_dialtone, sample_american_dialtone}, - {&sizeof_american_ringing, sample_american_ringing}, - {&sizeof_american_busy, sample_american_busy}, - {&sizeof_special1, sample_special1}, - {&sizeof_special2, sample_special2}, - {&sizeof_special3, sample_special3}, - {NULL, NULL}, -}; - -/*********************************** - * generate ulaw from alaw samples * - ***********************************/ - -void -dsp_audio_generate_ulaw_samples(void) -{ - int i, j; - - i = 0; - while (samples[i].len) { - j = 0; - while (j < (*samples[i].len)) { - samples[i].data[j] = - dsp_audio_alaw_to_ulaw[samples[i].data[j]]; - j++; - } - i++; - } -} - - -/**************************** - * tone sequence definition * - ****************************/ - -struct pattern { - int tone; - u8 *data[10]; - u32 *siz[10]; - u32 seq[10]; -} pattern[] = { - {TONE_GERMAN_DIALTONE, - {DATA_GA, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GA, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_OLDDIALTONE, - {DATA_GO, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GO, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_AMERICAN_DIALTONE, - {DATA_DT, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_DT, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_DIALPBX, - {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, 0, 0, 0, 0}, - {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, 0, 0, 0, 0}, - {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, - - {TONE_GERMAN_OLDDIALPBX, - {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, 0, 0, 0, 0}, - {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, 0, 0, 0, 0}, - {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, - - {TONE_AMERICAN_DIALPBX, - {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, 0, 0, 0, 0}, - {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, 0, 0, 0, 0}, - {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, - - {TONE_GERMAN_RINGING, - {DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_OLDRINGING, - {DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_AMERICAN_RINGING, - {DATA_RI, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_RI, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_RINGPBX, - {DATA_GA, DATA_S, DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0}, - {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0}, - {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_OLDRINGPBX, - {DATA_GO, DATA_S, DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0}, - {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0}, - {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, - - {TONE_AMERICAN_RINGPBX, - {DATA_RI, DATA_S, DATA_RI, DATA_S, 0, 0, 0, 0, 0, 0}, - {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, 0, 0, 0, 0, 0, 0}, - {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_BUSY, - {DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_OLDBUSY, - {DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_AMERICAN_BUSY, - {DATA_BU, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_BU, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_HANGUP, - {DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_OLDHANGUP, - {DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_AMERICAN_HANGUP, - {DATA_DT, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_DT, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_SPECIAL_INFO, - {DATA_S1, DATA_S2, DATA_S3, DATA_S, 0, 0, 0, 0, 0, 0}, - {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, 0, 0, 0, 0, 0, 0}, - {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_GASSENBESETZT, - {DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0}, - {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} }, - - {TONE_GERMAN_AUFSCHALTTON, - {DATA_GO, DATA_S, DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0}, - {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0}, - {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} }, - - {0, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, -}; - -/****************** - * copy tone data * - ******************/ - -/* an sk_buff is generated from the number of samples needed. - * the count will be changed and may begin from 0 each pattern period. - * the clue is to precalculate the pointers and legths to use only one - * memcpy per function call, or two memcpy if the tone sequence changes. - * - * pattern - the type of the pattern - * count - the sample from the beginning of the pattern (phase) - * len - the number of bytes - * - * return - the sk_buff with the sample - * - * if tones has finished (e.g. knocking tone), dsp->tones is turned off - */ -void dsp_tone_copy(struct dsp *dsp, u8 *data, int len) -{ - int index, count, start, num; - struct pattern *pat; - struct dsp_tone *tone = &dsp->tone; - - /* if we have no tone, we copy silence */ - if (!tone->tone) { - memset(data, dsp_silence, len); - return; - } - - /* process pattern */ - pat = (struct pattern *)tone->pattern; - /* points to the current pattern */ - index = tone->index; /* gives current sequence index */ - count = tone->count; /* gives current sample */ - - /* copy sample */ - while (len) { - /* find sample to start with */ - while (42) { - /* warp arround */ - if (!pat->seq[index]) { - count = 0; - index = 0; - } - /* check if we are currently playing this tone */ - if (count < pat->seq[index]) - break; - if (dsp_debug & DEBUG_DSP_TONE) - printk(KERN_DEBUG "%s: reaching next sequence " - "(index=%d)\n", __func__, index); - count -= pat->seq[index]; - index++; - } - /* calculate start and number of samples */ - start = count % (*(pat->siz[index])); - num = len; - if (num+count > pat->seq[index]) - num = pat->seq[index] - count; - if (num+start > (*(pat->siz[index]))) - num = (*(pat->siz[index])) - start; - /* copy memory */ - memcpy(data, pat->data[index]+start, num); - /* reduce length */ - data += num; - count += num; - len -= num; - } - tone->index = index; - tone->count = count; - - /* return sk_buff */ - return; -} - - -/******************************* - * send HW message to hfc card * - *******************************/ - -static void -dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len) -{ - struct sk_buff *nskb; - - /* unlocking is not required, because we don't expect a response */ - nskb = _alloc_mISDN_skb(PH_CONTROL_REQ, - (len)?HFC_SPL_LOOP_ON:HFC_SPL_LOOP_OFF, len, sample, - GFP_ATOMIC); - if (nskb) { - if (dsp->ch.peer) { - if (dsp->ch.recv(dsp->ch.peer, nskb)) - dev_kfree_skb(nskb); - } else - dev_kfree_skb(nskb); - } -} - - -/***************** - * timer expires * - *****************/ -void -dsp_tone_timeout(void *arg) -{ - struct dsp *dsp = arg; - struct dsp_tone *tone = &dsp->tone; - struct pattern *pat = (struct pattern *)tone->pattern; - int index = tone->index; - - if (!tone->tone) - return; - - index++; - if (!pat->seq[index]) - index = 0; - tone->index = index; - - /* set next tone */ - if (pat->data[index] == DATA_S) - dsp_tone_hw_message(dsp, 0, 0); - else - dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index])); - /* set timer */ - init_timer(&tone->tl); - tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000; - add_timer(&tone->tl); -} - - -/******************** - * set/release tone * - ********************/ - -/* - * tones are relaized by streaming or by special loop commands if supported - * by hardware. when hardware is used, the patterns will be controlled by - * timers. - */ -int -dsp_tone(struct dsp *dsp, int tone) -{ - struct pattern *pat; - int i; - struct dsp_tone *tonet = &dsp->tone; - - tonet->software = 0; - tonet->hardware = 0; - - /* we turn off the tone */ - if (!tone) { - if (dsp->features.hfc_loops) - if (timer_pending(&tonet->tl)) - del_timer(&tonet->tl); - if (dsp->features.hfc_loops) - dsp_tone_hw_message(dsp, NULL, 0); - tonet->tone = 0; - return 0; - } - - pat = NULL; - i = 0; - while (pattern[i].tone) { - if (pattern[i].tone == tone) { - pat = &pattern[i]; - break; - } - i++; - } - if (!pat) { - printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone); - return -EINVAL; - } - if (dsp_debug & DEBUG_DSP_TONE) - printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n", - __func__, tone, 0); - tonet->tone = tone; - tonet->pattern = pat; - tonet->index = 0; - tonet->count = 0; - - if (dsp->features.hfc_loops) { - tonet->hardware = 1; - /* set first tone */ - dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0])); - /* set timer */ - if (timer_pending(&tonet->tl)) - del_timer(&tonet->tl); - init_timer(&tonet->tl); - tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000; - add_timer(&tonet->tl); - } else { - tonet->software = 1; - } - - return 0; -} - - - - - diff --git a/trunk/drivers/isdn/mISDN/fsm.c b/trunk/drivers/isdn/mISDN/fsm.c deleted file mode 100644 index b5d6553f2dc8..000000000000 --- a/trunk/drivers/isdn/mISDN/fsm.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * finite state machine implementation - * - * Author Karsten Keil - * - * Thanks to Jan den Ouden - * Fritz Elfert - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#include -#include -#include -#include -#include "fsm.h" - -#define FSM_TIMER_DEBUG 0 - -void -mISDN_FsmNew(struct Fsm *fsm, - struct FsmNode *fnlist, int fncount) -{ - int i; - - fsm->jumpmatrix = kzalloc(sizeof(FSMFNPTR) * fsm->state_count * - fsm->event_count, GFP_KERNEL); - - for (i = 0; i < fncount; i++) - if ((fnlist[i].state >= fsm->state_count) || - (fnlist[i].event >= fsm->event_count)) { - printk(KERN_ERR - "mISDN_FsmNew Error: %d st(%ld/%ld) ev(%ld/%ld)\n", - i, (long)fnlist[i].state, (long)fsm->state_count, - (long)fnlist[i].event, (long)fsm->event_count); - } else - fsm->jumpmatrix[fsm->state_count * fnlist[i].event + - fnlist[i].state] = (FSMFNPTR) fnlist[i].routine; -} -EXPORT_SYMBOL(mISDN_FsmNew); - -void -mISDN_FsmFree(struct Fsm *fsm) -{ - kfree((void *) fsm->jumpmatrix); -} -EXPORT_SYMBOL(mISDN_FsmFree); - -int -mISDN_FsmEvent(struct FsmInst *fi, int event, void *arg) -{ - FSMFNPTR r; - - if ((fi->state >= fi->fsm->state_count) || - (event >= fi->fsm->event_count)) { - printk(KERN_ERR - "mISDN_FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n", - (long)fi->state, (long)fi->fsm->state_count, event, - (long)fi->fsm->event_count); - return 1; - } - r = fi->fsm->jumpmatrix[fi->fsm->state_count * event + fi->state]; - if (r) { - if (fi->debug) - fi->printdebug(fi, "State %s Event %s", - fi->fsm->strState[fi->state], - fi->fsm->strEvent[event]); - r(fi, event, arg); - return 0; - } else { - if (fi->debug) - fi->printdebug(fi, "State %s Event %s no action", - fi->fsm->strState[fi->state], - fi->fsm->strEvent[event]); - return 1; - } -} -EXPORT_SYMBOL(mISDN_FsmEvent); - -void -mISDN_FsmChangeState(struct FsmInst *fi, int newstate) -{ - fi->state = newstate; - if (fi->debug) - fi->printdebug(fi, "ChangeState %s", - fi->fsm->strState[newstate]); -} -EXPORT_SYMBOL(mISDN_FsmChangeState); - -static void -FsmExpireTimer(struct FsmTimer *ft) -{ -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft); -#endif - mISDN_FsmEvent(ft->fi, ft->event, ft->arg); -} - -void -mISDN_FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft) -{ - ft->fi = fi; - ft->tl.function = (void *) FsmExpireTimer; - ft->tl.data = (long) ft; -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "mISDN_FsmInitTimer %lx", (long) ft); -#endif - init_timer(&ft->tl); -} -EXPORT_SYMBOL(mISDN_FsmInitTimer); - -void -mISDN_FsmDelTimer(struct FsmTimer *ft, int where) -{ -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "mISDN_FsmDelTimer %lx %d", - (long) ft, where); -#endif - del_timer(&ft->tl); -} -EXPORT_SYMBOL(mISDN_FsmDelTimer); - -int -mISDN_FsmAddTimer(struct FsmTimer *ft, - int millisec, int event, void *arg, int where) -{ - -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "mISDN_FsmAddTimer %lx %d %d", - (long) ft, millisec, where); -#endif - - if (timer_pending(&ft->tl)) { - if (ft->fi->debug) { - printk(KERN_WARNING - "mISDN_FsmAddTimer: timer already active!\n"); - ft->fi->printdebug(ft->fi, - "mISDN_FsmAddTimer already active!"); - } - return -1; - } - init_timer(&ft->tl); - ft->event = event; - ft->arg = arg; - ft->tl.expires = jiffies + (millisec * HZ) / 1000; - add_timer(&ft->tl); - return 0; -} -EXPORT_SYMBOL(mISDN_FsmAddTimer); - -void -mISDN_FsmRestartTimer(struct FsmTimer *ft, - int millisec, int event, void *arg, int where) -{ - -#if FSM_TIMER_DEBUG - if (ft->fi->debug) - ft->fi->printdebug(ft->fi, "mISDN_FsmRestartTimer %lx %d %d", - (long) ft, millisec, where); -#endif - - if (timer_pending(&ft->tl)) - del_timer(&ft->tl); - init_timer(&ft->tl); - ft->event = event; - ft->arg = arg; - ft->tl.expires = jiffies + (millisec * HZ) / 1000; - add_timer(&ft->tl); -} -EXPORT_SYMBOL(mISDN_FsmRestartTimer); diff --git a/trunk/drivers/isdn/mISDN/fsm.h b/trunk/drivers/isdn/mISDN/fsm.h deleted file mode 100644 index 928f5be192c1..000000000000 --- a/trunk/drivers/isdn/mISDN/fsm.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Thanks to Jan den Ouden - * Fritz Elfert - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#ifndef _MISDN_FSM_H -#define _MISDN_FSM_H - -#include - -/* Statemachine */ - -struct FsmInst; - -typedef void (*FSMFNPTR)(struct FsmInst *, int, void *); - -struct Fsm { - FSMFNPTR *jumpmatrix; - int state_count, event_count; - char **strEvent, **strState; -}; - -struct FsmInst { - struct Fsm *fsm; - int state; - int debug; - void *userdata; - int userint; - void (*printdebug) (struct FsmInst *, char *, ...); -}; - -struct FsmNode { - int state, event; - void (*routine) (struct FsmInst *, int, void *); -}; - -struct FsmTimer { - struct FsmInst *fi; - struct timer_list tl; - int event; - void *arg; -}; - -extern void mISDN_FsmNew(struct Fsm *, struct FsmNode *, int); -extern void mISDN_FsmFree(struct Fsm *); -extern int mISDN_FsmEvent(struct FsmInst *, int , void *); -extern void mISDN_FsmChangeState(struct FsmInst *, int); -extern void mISDN_FsmInitTimer(struct FsmInst *, struct FsmTimer *); -extern int mISDN_FsmAddTimer(struct FsmTimer *, int, int, void *, int); -extern void mISDN_FsmRestartTimer(struct FsmTimer *, int, int, void *, int); -extern void mISDN_FsmDelTimer(struct FsmTimer *, int); - -#endif diff --git a/trunk/drivers/isdn/mISDN/hwchannel.c b/trunk/drivers/isdn/mISDN/hwchannel.c deleted file mode 100644 index 2596fba4e614..000000000000 --- a/trunk/drivers/isdn/mISDN/hwchannel.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#include -#include - -static void -dchannel_bh(struct work_struct *ws) -{ - struct dchannel *dch = container_of(ws, struct dchannel, workq); - struct sk_buff *skb; - int err; - - if (test_and_clear_bit(FLG_RECVQUEUE, &dch->Flags)) { - while ((skb = skb_dequeue(&dch->rqueue))) { - if (likely(dch->dev.D.peer)) { - err = dch->dev.D.recv(dch->dev.D.peer, skb); - if (err) - dev_kfree_skb(skb); - } else - dev_kfree_skb(skb); - } - } - if (test_and_clear_bit(FLG_PHCHANGE, &dch->Flags)) { - if (dch->phfunc) - dch->phfunc(dch); - } -} - -static void -bchannel_bh(struct work_struct *ws) -{ - struct bchannel *bch = container_of(ws, struct bchannel, workq); - struct sk_buff *skb; - int err; - - if (test_and_clear_bit(FLG_RECVQUEUE, &bch->Flags)) { - while ((skb = skb_dequeue(&bch->rqueue))) { - if (bch->rcount >= 64) - printk(KERN_WARNING "B-channel %p receive " - "queue if full, but empties...\n", bch); - bch->rcount--; - if (likely(bch->ch.peer)) { - err = bch->ch.recv(bch->ch.peer, skb); - if (err) - dev_kfree_skb(skb); - } else - dev_kfree_skb(skb); - } - } -} - -int -mISDN_initdchannel(struct dchannel *ch, int maxlen, void *phf) -{ - test_and_set_bit(FLG_HDLC, &ch->Flags); - ch->maxlen = maxlen; - ch->hw = NULL; - ch->rx_skb = NULL; - ch->tx_skb = NULL; - ch->tx_idx = 0; - ch->phfunc = phf; - skb_queue_head_init(&ch->squeue); - skb_queue_head_init(&ch->rqueue); - INIT_LIST_HEAD(&ch->dev.bchannels); - INIT_WORK(&ch->workq, dchannel_bh); - return 0; -} -EXPORT_SYMBOL(mISDN_initdchannel); - -int -mISDN_initbchannel(struct bchannel *ch, int maxlen) -{ - ch->Flags = 0; - ch->maxlen = maxlen; - ch->hw = NULL; - ch->rx_skb = NULL; - ch->tx_skb = NULL; - ch->tx_idx = 0; - skb_queue_head_init(&ch->rqueue); - ch->rcount = 0; - ch->next_skb = NULL; - INIT_WORK(&ch->workq, bchannel_bh); - return 0; -} -EXPORT_SYMBOL(mISDN_initbchannel); - -int -mISDN_freedchannel(struct dchannel *ch) -{ - if (ch->tx_skb) { - dev_kfree_skb(ch->tx_skb); - ch->tx_skb = NULL; - } - if (ch->rx_skb) { - dev_kfree_skb(ch->rx_skb); - ch->rx_skb = NULL; - } - skb_queue_purge(&ch->squeue); - skb_queue_purge(&ch->rqueue); - flush_scheduled_work(); - return 0; -} -EXPORT_SYMBOL(mISDN_freedchannel); - -int -mISDN_freebchannel(struct bchannel *ch) -{ - if (ch->tx_skb) { - dev_kfree_skb(ch->tx_skb); - ch->tx_skb = NULL; - } - if (ch->rx_skb) { - dev_kfree_skb(ch->rx_skb); - ch->rx_skb = NULL; - } - if (ch->next_skb) { - dev_kfree_skb(ch->next_skb); - ch->next_skb = NULL; - } - skb_queue_purge(&ch->rqueue); - ch->rcount = 0; - flush_scheduled_work(); - return 0; -} -EXPORT_SYMBOL(mISDN_freebchannel); - -static inline u_int -get_sapi_tei(u_char *p) -{ - u_int sapi, tei; - - sapi = *p >> 2; - tei = p[1] >> 1; - return sapi | (tei << 8); -} - -void -recv_Dchannel(struct dchannel *dch) -{ - struct mISDNhead *hh; - - if (dch->rx_skb->len < 2) { /* at least 2 for sapi / tei */ - dev_kfree_skb(dch->rx_skb); - dch->rx_skb = NULL; - return; - } - hh = mISDN_HEAD_P(dch->rx_skb); - hh->prim = PH_DATA_IND; - hh->id = get_sapi_tei(dch->rx_skb->data); - skb_queue_tail(&dch->rqueue, dch->rx_skb); - dch->rx_skb = NULL; - schedule_event(dch, FLG_RECVQUEUE); -} -EXPORT_SYMBOL(recv_Dchannel); - -void -recv_Bchannel(struct bchannel *bch) -{ - struct mISDNhead *hh; - - hh = mISDN_HEAD_P(bch->rx_skb); - hh->prim = PH_DATA_IND; - hh->id = MISDN_ID_ANY; - if (bch->rcount >= 64) { - dev_kfree_skb(bch->rx_skb); - bch->rx_skb = NULL; - return; - } - bch->rcount++; - skb_queue_tail(&bch->rqueue, bch->rx_skb); - bch->rx_skb = NULL; - schedule_event(bch, FLG_RECVQUEUE); -} -EXPORT_SYMBOL(recv_Bchannel); - -void -recv_Dchannel_skb(struct dchannel *dch, struct sk_buff *skb) -{ - skb_queue_tail(&dch->rqueue, skb); - schedule_event(dch, FLG_RECVQUEUE); -} -EXPORT_SYMBOL(recv_Dchannel_skb); - -void -recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb) -{ - if (bch->rcount >= 64) { - dev_kfree_skb(skb); - return; - } - bch->rcount++; - skb_queue_tail(&bch->rqueue, skb); - schedule_event(bch, FLG_RECVQUEUE); -} -EXPORT_SYMBOL(recv_Bchannel_skb); - -static void -confirm_Dsend(struct dchannel *dch) -{ - struct sk_buff *skb; - - skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(dch->tx_skb), - 0, NULL, GFP_ATOMIC); - if (!skb) { - printk(KERN_ERR "%s: no skb id %x\n", __func__, - mISDN_HEAD_ID(dch->tx_skb)); - return; - } - skb_queue_tail(&dch->rqueue, skb); - schedule_event(dch, FLG_RECVQUEUE); -} - -int -get_next_dframe(struct dchannel *dch) -{ - dch->tx_idx = 0; - dch->tx_skb = skb_dequeue(&dch->squeue); - if (dch->tx_skb) { - confirm_Dsend(dch); - return 1; - } - dch->tx_skb = NULL; - test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); - return 0; -} -EXPORT_SYMBOL(get_next_dframe); - -void -confirm_Bsend(struct bchannel *bch) -{ - struct sk_buff *skb; - - if (bch->rcount >= 64) - return; - skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb), - 0, NULL, GFP_ATOMIC); - if (!skb) { - printk(KERN_ERR "%s: no skb id %x\n", __func__, - mISDN_HEAD_ID(bch->tx_skb)); - return; - } - bch->rcount++; - skb_queue_tail(&bch->rqueue, skb); - schedule_event(bch, FLG_RECVQUEUE); -} -EXPORT_SYMBOL(confirm_Bsend); - -int -get_next_bframe(struct bchannel *bch) -{ - bch->tx_idx = 0; - if (test_bit(FLG_TX_NEXT, &bch->Flags)) { - bch->tx_skb = bch->next_skb; - if (bch->tx_skb) { - bch->next_skb = NULL; - test_and_clear_bit(FLG_TX_NEXT, &bch->Flags); - if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) - confirm_Bsend(bch); /* not for transparent */ - return 1; - } else { - test_and_clear_bit(FLG_TX_NEXT, &bch->Flags); - printk(KERN_WARNING "B TX_NEXT without skb\n"); - } - } - bch->tx_skb = NULL; - test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); - return 0; -} -EXPORT_SYMBOL(get_next_bframe); - -void -queue_ch_frame(struct mISDNchannel *ch, u_int pr, int id, struct sk_buff *skb) -{ - struct mISDNhead *hh; - - if (!skb) { - _queue_data(ch, pr, id, 0, NULL, GFP_ATOMIC); - } else { - if (ch->peer) { - hh = mISDN_HEAD_P(skb); - hh->prim = pr; - hh->id = id; - if (!ch->recv(ch->peer, skb)) - return; - } - dev_kfree_skb(skb); - } -} -EXPORT_SYMBOL(queue_ch_frame); - -int -dchannel_senddata(struct dchannel *ch, struct sk_buff *skb) -{ - /* check oversize */ - if (skb->len <= 0) { - printk(KERN_WARNING "%s: skb too small\n", __func__); - return -EINVAL; - } - if (skb->len > ch->maxlen) { - printk(KERN_WARNING "%s: skb too large(%d/%d)\n", - __func__, skb->len, ch->maxlen); - return -EINVAL; - } - /* HW lock must be obtained */ - if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) { - skb_queue_tail(&ch->squeue, skb); - return 0; - } else { - /* write to fifo */ - ch->tx_skb = skb; - ch->tx_idx = 0; - return 1; - } -} -EXPORT_SYMBOL(dchannel_senddata); - -int -bchannel_senddata(struct bchannel *ch, struct sk_buff *skb) -{ - - /* check oversize */ - if (skb->len <= 0) { - printk(KERN_WARNING "%s: skb too small\n", __func__); - return -EINVAL; - } - if (skb->len > ch->maxlen) { - printk(KERN_WARNING "%s: skb too large(%d/%d)\n", - __func__, skb->len, ch->maxlen); - return -EINVAL; - } - /* HW lock must be obtained */ - /* check for pending next_skb */ - if (ch->next_skb) { - printk(KERN_WARNING - "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n", - __func__, skb->len, ch->next_skb->len); - return -EBUSY; - } - if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) { - test_and_set_bit(FLG_TX_NEXT, &ch->Flags); - ch->next_skb = skb; - return 0; - } else { - /* write to fifo */ - ch->tx_skb = skb; - ch->tx_idx = 0; - return 1; - } -} -EXPORT_SYMBOL(bchannel_senddata); diff --git a/trunk/drivers/isdn/mISDN/l1oip.h b/trunk/drivers/isdn/mISDN/l1oip.h deleted file mode 100644 index a23d575449f6..000000000000 --- a/trunk/drivers/isdn/mISDN/l1oip.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * see notice in l1oip.c - */ - -/* debugging */ -#define DEBUG_L1OIP_INIT 0x00010000 -#define DEBUG_L1OIP_SOCKET 0x00020000 -#define DEBUG_L1OIP_MGR 0x00040000 -#define DEBUG_L1OIP_MSG 0x00080000 - -/* enable to disorder received bchannels by sequence 2143658798... */ -/* -#define REORDER_DEBUG -*/ - -/* frames */ -#define L1OIP_MAX_LEN 2048 /* max packet size form l2 */ -#define L1OIP_MAX_PERFRAME 1400 /* max data size in one frame */ - - -/* timers */ -#define L1OIP_KEEPALIVE 15 -#define L1OIP_TIMEOUT 65 - - -/* socket */ -#define L1OIP_DEFAULTPORT 931 - - -/* channel structure */ -struct l1oip_chan { - struct dchannel *dch; - struct bchannel *bch; - u32 tx_counter; /* counts xmit bytes/packets */ - u32 rx_counter; /* counts recv bytes/packets */ - u32 codecstate; /* used by codec to save data */ -#ifdef REORDER_DEBUG - int disorder_flag; - struct sk_buff *disorder_skb; - u32 disorder_cnt; -#endif -}; - - -/* card structure */ -struct l1oip { - struct list_head list; - - /* card */ - int registered; /* if registered with mISDN */ - char name[MISDN_MAX_IDLEN]; - int idx; /* card index */ - int pri; /* 1=pri, 0=bri */ - int d_idx; /* current dchannel number */ - int b_num; /* number of bchannels */ - u32 id; /* id of connection */ - int ondemand; /* if transmis. is on demand */ - int bundle; /* bundle channels in one frm */ - int codec; /* codec to use for transmis. */ - int limit; /* limit number of bchannels */ - - /* timer */ - struct timer_list keep_tl; - struct timer_list timeout_tl; - int timeout_on; - struct work_struct workq; - - /* socket */ - struct socket *socket; /* if set, socket is created */ - struct completion socket_complete;/* completion of sock thread */ - struct task_struct *socket_thread; - spinlock_t socket_lock; /* access sock outside thread */ - u32 remoteip; /* if all set, ip is assigned */ - u16 localport; /* must always be set */ - u16 remoteport; /* must always be set */ - struct sockaddr_in sin_local; /* local socket name */ - struct sockaddr_in sin_remote; /* remote socket name */ - struct msghdr sendmsg; /* ip message to send */ - struct iovec sendiov; /* iov for message */ - - /* frame */ - struct l1oip_chan chan[128]; /* channel instances */ -}; - -extern int l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state); -extern int l1oip_4bit_to_law(u8 *data, int len, u8 *result); -extern int l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result); -extern int l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result); -extern void l1oip_4bit_free(void); -extern int l1oip_4bit_alloc(int ulaw); - diff --git a/trunk/drivers/isdn/mISDN/l1oip_codec.c b/trunk/drivers/isdn/mISDN/l1oip_codec.c deleted file mode 100644 index a2dc4570ef43..000000000000 --- a/trunk/drivers/isdn/mISDN/l1oip_codec.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - - * l1oip_codec.c generic codec using lookup table - * -> conversion from a-Law to u-Law - * -> conversion from u-Law to a-Law - * -> compression by reducing the number of sample resolution to 4 - * - * NOTE: It is not compatible with any standard codec like ADPCM. - * - * Author Andreas Eversberg (jolly@eversberg.eu) - * - * 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. - - */ - -/* - -How the codec works: --------------------- - -The volume is increased to increase the dynamic range of the audio signal. -Each sample is converted to a-LAW with only 16 steps of level resolution. -A pair of two samples are stored in one byte. - -The first byte is stored in the upper bits, the second byte is stored in the -lower bits. - -To speed up compression and decompression, two lookup tables are formed: - -- 16 bits index for two samples (law encoded) with 8 bit compressed result. -- 8 bits index for one compressed data with 16 bits decompressed result. - -NOTE: The bytes are handled as they are law-encoded. - -*/ - -#include -#include -#include "core.h" - -/* definitions of codec. don't use calculations, code may run slower. */ - -static u8 *table_com; -static u16 *table_dec; - - -/* alaw -> ulaw */ -static u8 alaw_to_ulaw[256] = -{ - 0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49, - 0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57, - 0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41, - 0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f, - 0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d, - 0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b, - 0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45, - 0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53, - 0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47, - 0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55, - 0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f, - 0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e, - 0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b, - 0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59, - 0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43, - 0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51, - 0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a, - 0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58, - 0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42, - 0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50, - 0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e, - 0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c, - 0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46, - 0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54, - 0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48, - 0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56, - 0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40, - 0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f, - 0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c, - 0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a, - 0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44, - 0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52 -}; - -/* ulaw -> alaw */ -static u8 ulaw_to_alaw[256] = -{ - 0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35, - 0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25, - 0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d, - 0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d, - 0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31, - 0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21, - 0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9, - 0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9, - 0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47, - 0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf, - 0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f, - 0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33, - 0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23, - 0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b, - 0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b, - 0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b, - 0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34, - 0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24, - 0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c, - 0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c, - 0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30, - 0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20, - 0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8, - 0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8, - 0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46, - 0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde, - 0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e, - 0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32, - 0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22, - 0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a, - 0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a, - 0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a -}; - -/* alaw -> 4bit compression */ -static u8 alaw_to_4bit[256] = { - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02, - 0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04, - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04, - 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03, - 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04, -}; - -/* 4bit -> alaw decompression */ -static u8 _4bit_to_alaw[16] = { - 0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b, - 0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c, -}; - -/* ulaw -> 4bit compression */ -static u8 ulaw_to_4bit[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, - 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, - 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -}; - -/* 4bit -> ulaw decompression */ -static u8 _4bit_to_ulaw[16] = { - 0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71, - 0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f, -}; - - -/* - * Compresses data to the result buffer - * The result size must be at least half of the input buffer. - * The number of samples also must be even! - */ -int -l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state) -{ - int ii, i = 0, o = 0; - - if (!len) - return 0; - - /* send saved byte and first input byte */ - if (*state) { - *result++ = table_com[(((*state)<<8)&0xff00) | (*data++)]; - len--; - o++; - } - - ii = len >> 1; - - while (i < ii) { - *result++ = table_com[(data[0]<<8) | (data[1])]; - data += 2; - i++; - o++; - } - - /* if len has an odd number, we save byte for next call */ - if (len & 1) - *state = 0x100 + *data; - else - *state = 0; - - return o; -} - -/* Decompress data to the result buffer - * The result size must be the number of sample in packet. (2 * input data) - * The number of samples in the result are even! - */ -int -l1oip_4bit_to_law(u8 *data, int len, u8 *result) -{ - int i = 0; - u16 r; - - while (i < len) { - r = table_dec[*data++]; - *result++ = r>>8; - *result++ = r; - i++; - } - - return len << 1; -} - - -/* - * law conversion - */ -int -l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result) -{ - int i = 0; - - while (i < len) { - *result++ = alaw_to_ulaw[*data++]; - i++; - } - - return len; -} - -int -l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result) -{ - int i = 0; - - while (i < len) { - *result++ = ulaw_to_alaw[*data++]; - i++; - } - - return len; -} - - -/* - * generate/free compression and decompression table - */ -void -l1oip_4bit_free(void) -{ - if (table_dec) - vfree(table_dec); - if (table_com) - vfree(table_com); - table_com = NULL; - table_dec = NULL; -} - -int -l1oip_4bit_alloc(int ulaw) -{ - int i1, i2, c, sample; - - /* in case, it is called again */ - if (table_dec) - return 0; - - /* alloc conversion tables */ - table_com = vmalloc(65536); - table_dec = vmalloc(512); - if (!table_com | !table_dec) { - l1oip_4bit_free(); - return -ENOMEM; - } - memset(table_com, 0, 65536); - memset(table_dec, 0, 512); - /* generate compression table */ - i1 = 0; - while (i1 < 256) { - if (ulaw) - c = ulaw_to_4bit[i1]; - else - c = alaw_to_4bit[i1]; - i2 = 0; - while (i2 < 256) { - table_com[(i1<<8) | i2] |= (c<<4); - table_com[(i2<<8) | i1] |= c; - i2++; - } - i1++; - } - - /* generate decompression table */ - i1 = 0; - while (i1 < 16) { - if (ulaw) - sample = _4bit_to_ulaw[i1]; - else - sample = _4bit_to_alaw[i1]; - i2 = 0; - while (i2 < 16) { - table_dec[(i1<<4) | i2] |= (sample<<8); - table_dec[(i2<<4) | i1] |= sample; - i2++; - } - i1++; - } - - return 0; -} - - diff --git a/trunk/drivers/isdn/mISDN/l1oip_core.c b/trunk/drivers/isdn/mISDN/l1oip_core.c deleted file mode 100644 index 155b99780c4f..000000000000 --- a/trunk/drivers/isdn/mISDN/l1oip_core.c +++ /dev/null @@ -1,1518 +0,0 @@ -/* - - * l1oip.c low level driver for tunneling layer 1 over IP - * - * NOTE: It is not compatible with TDMoIP nor "ISDN over IP". - * - * Author Andreas Eversberg (jolly@eversberg.eu) - * - * 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. - * - */ - -/* module parameters: - * type: - Value 1 = BRI - Value 2 = PRI - Value 3 = BRI (multi channel frame, not supported yet) - Value 4 = PRI (multi channel frame, not supported yet) - A multi channel frame reduces overhead to a single frame for all - b-channels, but increases delay. - (NOTE: Multi channel frames are not implemented yet.) - - * codec: - Value 0 = transparent (default) - Value 1 = transfer ALAW - Value 2 = transfer ULAW - Value 3 = transfer generic 4 bit compression. - - * ulaw: - 0 = we use a-Law (default) - 1 = we use u-Law - - * limit: - limitation of B-channels to control bandwidth (1...126) - BRI: 1 or 2 - PRI: 1-30, 31-126 (126, because dchannel ist not counted here) - Also limited ressources are used for stack, resulting in less channels. - It is possible to have more channels than 30 in PRI mode, this must - be supported by the application. - - * ip: - byte representation of remote ip address (127.0.0.1 -> 127,0,0,1) - If not given or four 0, no remote address is set. - For multiple interfaces, concat ip addresses. (127,0,0,1,127,0,0,1) - - * port: - port number (local interface) - If not given or 0, port 931 is used for fist instance, 932 for next... - For multiple interfaces, different ports must be given. - - * remoteport: - port number (remote interface) - If not given or 0, remote port equals local port - For multiple interfaces on equal sites, different ports must be given. - - * ondemand: - 0 = fixed (always transmit packets, even when remote side timed out) - 1 = on demand (only transmit packets, when remote side is detected) - the default is 0 - NOTE: ID must also be set for on demand. - - * id: - optional value to identify frames. This value must be equal on both - peers and should be random. If omitted or 0, no ID is transmitted. - - * debug: - NOTE: only one debug value must be given for all cards - enable debugging (see l1oip.h for debug options) - - -Special mISDN controls: - - op = MISDN_CTRL_SETPEER* - p1 = bytes 0-3 : remote IP address in network order (left element first) - p2 = bytes 1-2 : remote port in network order (high byte first) - optional: - p2 = bytes 3-4 : local port in network order (high byte first) - - op = MISDN_CTRL_UNSETPEER* - - * Use l1oipctrl for comfortable setting or removing ip address. - (Layer 1 Over IP CTRL) - - -L1oIP-Protocol --------------- - -Frame Header: - - 7 6 5 4 3 2 1 0 -+---------------+ -|Ver|T|I|Coding | -+---------------+ -| ID byte 3 * | -+---------------+ -| ID byte 2 * | -+---------------+ -| ID byte 1 * | -+---------------+ -| ID byte 0 * | -+---------------+ -|M| Channel | -+---------------+ -| Length * | -+---------------+ -| Time Base MSB | -+---------------+ -| Time Base LSB | -+---------------+ -| Data.... | - -... - -| | -+---------------+ -|M| Channel | -+---------------+ -| Length * | -+---------------+ -| Time Base MSB | -+---------------+ -| Time Base LSB | -+---------------+ -| Data.... | - -... - - -* Only included in some cases. - -- Ver = Version -If version is missmatch, the frame must be ignored. - -- T = Type of interface -Must be 0 for S0 or 1 for E1. - -- I = Id present -If bit is set, four ID bytes are included in frame. - -- ID = Connection ID -Additional ID to prevent Denial of Service attacs. Also it prevents hijacking -connections with dynamic IP. The ID should be random and must not be 0. - -- Coding = Type of codec -Must be 0 for no transcoding. Also for D-channel and other HDLC frames. - 1 and 2 are reserved for explicitly use of a-LAW or u-LAW codec. - 3 is used for generic table compressor. - -- M = More channels to come. If this flag is 1, the following byte contains -the length of the channel data. After the data block, the next channel will -be defined. The flag for the last channel block (or if only one channel is -transmitted), must be 0 and no length is given. - -- Channel = Channel number -0 reserved -1-3 channel data for S0 (3 is D-channel) -1-31 channel data for E1 (16 is D-channel) -32-127 channel data for extended E1 (16 is D-channel) - -- The length is used if the M-flag is 1. It is used to find the next channel -inside frame. -NOTE: A value of 0 equals 256 bytes of data. - -> For larger data blocks, a single frame must be used. - -> For larger streams, a single frame or multiple blocks with same channel ID - must be used. - -- Time Base = Timestamp of first sample in frame -The "Time Base" is used to rearange packets and to detect packet loss. -The 16 bits are sent in network order (MSB first) and count 1/8000 th of a -second. This causes a wrap arround each 8,192 seconds. There is no requirement -for the initial "Time Base", but 0 should be used for the first packet. -In case of HDLC data, this timestamp counts the packet or byte number. - - -Two Timers: - -After initialisation, a timer of 15 seconds is started. Whenever a packet is -transmitted, the timer is reset to 15 seconds again. If the timer expires, an -empty packet is transmitted. This keep the connection alive. - -When a valid packet is received, a timer 65 seconds is started. The interface -become ACTIVE. If the timer expires, the interface becomes INACTIVE. - - -Dynamic IP handling: - -To allow dynamic IP, the ID must be non 0. In this case, any packet with the -correct port number and ID will be accepted. If the remote side changes its IP -the new IP is used for all transmitted packets until it changes again. - - -On Demand: - -If the ondemand parameter is given, the remote IP is set to 0 on timeout. -This will stop keepalive traffic to remote. If the remote is online again, -traffic will continue to the remote address. This is usefull for road warriors. -This feature only works with ID set, otherwhise it is highly unsecure. - - -Socket and Thread ------------------ - -The complete socket opening and closing is done by a thread. -When the thread opened a socket, the hc->socket descriptor is set. Whenever a -packet shall be sent to the socket, the hc->socket must be checked wheter not -NULL. To prevent change in socket descriptor, the hc->socket_lock must be used. -To change the socket, a recall of l1oip_socket_open() will safely kill the -socket process and create a new one. - -*/ - -#define L1OIP_VERSION 0 /* 0...3 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "core.h" -#include "l1oip.h" - -static const char *l1oip_revision = "2.00"; - -static int l1oip_cnt; -static spinlock_t l1oip_lock; -static struct list_head l1oip_ilist; - -#define MAX_CARDS 16 -static u_int type[MAX_CARDS]; -static u_int codec[MAX_CARDS]; -static u_int ip[MAX_CARDS*4]; -static u_int port[MAX_CARDS]; -static u_int remoteport[MAX_CARDS]; -static u_int ondemand[MAX_CARDS]; -static u_int limit[MAX_CARDS]; -static u_int id[MAX_CARDS]; -static int debug; -static int ulaw; - -MODULE_AUTHOR("Andreas Eversberg"); -MODULE_LICENSE("GPL"); -module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(codec, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(ip, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(remoteport, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(ondemand, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(limit, uint, NULL, S_IRUGO | S_IWUSR); -module_param_array(id, uint, NULL, S_IRUGO | S_IWUSR); -module_param(ulaw, uint, S_IRUGO | S_IWUSR); -module_param(debug, uint, S_IRUGO | S_IWUSR); - -/* - * send a frame via socket, if open and restart timer - */ -static int -l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, - u16 timebase, u8 *buf, int len) -{ - u8 *p; - int multi = 0; - u8 frame[len+32]; - struct socket *socket = NULL; - mm_segment_t oldfs; - - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n", - __func__, len); - - p = frame; - - /* restart timer */ - if ((int)(hc->keep_tl.expires-jiffies) < 5*HZ) { - del_timer(&hc->keep_tl); - hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE*HZ; - add_timer(&hc->keep_tl); - } else - hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE*HZ; - - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: resetting timer\n", __func__); - - /* drop if we have no remote ip or port */ - if (!hc->sin_remote.sin_addr.s_addr || !hc->sin_remote.sin_port) { - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: dropping frame, because remote " - "IP is not set.\n", __func__); - return len; - } - - /* assemble frame */ - *p++ = (L1OIP_VERSION<<6) /* version and coding */ - | (hc->pri?0x20:0x00) /* type */ - | (hc->id?0x10:0x00) /* id */ - | localcodec; - if (hc->id) { - *p++ = hc->id>>24; /* id */ - *p++ = hc->id>>16; - *p++ = hc->id>>8; - *p++ = hc->id; - } - *p++ = (multi == 1)?0x80:0x00 + channel; /* m-flag, channel */ - if (multi == 1) - *p++ = len; /* length */ - *p++ = timebase>>8; /* time base */ - *p++ = timebase; - - if (buf && len) { /* add data to frame */ - if (localcodec == 1 && ulaw) - l1oip_ulaw_to_alaw(buf, len, p); - else if (localcodec == 2 && !ulaw) - l1oip_alaw_to_ulaw(buf, len, p); - else if (localcodec == 3) - len = l1oip_law_to_4bit(buf, len, p, - &hc->chan[channel].codecstate); - else - memcpy(p, buf, len); - } - len += p - frame; - - /* check for socket in safe condition */ - spin_lock(&hc->socket_lock); - if (!hc->socket) { - spin_unlock(&hc->socket_lock); - return 0; - } - /* seize socket */ - socket = hc->socket; - hc->socket = NULL; - spin_unlock(&hc->socket_lock); - /* send packet */ - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: sending packet to socket (len " - "= %d)\n", __func__, len); - hc->sendiov.iov_base = frame; - hc->sendiov.iov_len = len; - oldfs = get_fs(); - set_fs(KERNEL_DS); - len = sock_sendmsg(socket, &hc->sendmsg, len); - set_fs(oldfs); - /* give socket back */ - hc->socket = socket; /* no locking required */ - - return len; -} - - -/* - * receive channel data from socket - */ -static void -l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase, - u8 *buf, int len) -{ - struct sk_buff *nskb; - struct bchannel *bch; - struct dchannel *dch; - u8 *p; - u32 rx_counter; - - if (len == 0) { - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: received empty keepalive data, " - "ignoring\n", __func__); - return; - } - - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: received data, sending to mISDN (%d)\n", - __func__, len); - - if (channel < 1 || channel > 127) { - printk(KERN_WARNING "%s: packet error - channel %d out of " - "range\n", __func__, channel); - return; - } - dch = hc->chan[channel].dch; - bch = hc->chan[channel].bch; - if (!dch && !bch) { - printk(KERN_WARNING "%s: packet error - channel %d not in " - "stack\n", __func__, channel); - return; - } - - /* prepare message */ - nskb = mI_alloc_skb((remotecodec == 3)?(len<<1):len, GFP_ATOMIC); - if (!nskb) { - printk(KERN_ERR "%s: No mem for skb.\n", __func__); - return; - } - p = skb_put(nskb, (remotecodec == 3)?(len<<1):len); - - if (remotecodec == 1 && ulaw) - l1oip_alaw_to_ulaw(buf, len, p); - else if (remotecodec == 2 && !ulaw) - l1oip_ulaw_to_alaw(buf, len, p); - else if (remotecodec == 3) - len = l1oip_4bit_to_law(buf, len, p); - else - memcpy(p, buf, len); - - /* send message up */ - if (dch && len >= 2) { - dch->rx_skb = nskb; - recv_Dchannel(dch); - } - if (bch) { - /* expand 16 bit sequence number to 32 bit sequence number */ - rx_counter = hc->chan[channel].rx_counter; - if (((s16)(timebase - rx_counter)) >= 0) { - /* time has changed forward */ - if (timebase >= (rx_counter & 0xffff)) - rx_counter = - (rx_counter & 0xffff0000) | timebase; - else - rx_counter = ((rx_counter & 0xffff0000)+0x10000) - | timebase; - } else { - /* time has changed backwards */ - if (timebase < (rx_counter & 0xffff)) - rx_counter = - (rx_counter & 0xffff0000) | timebase; - else - rx_counter = ((rx_counter & 0xffff0000)-0x10000) - | timebase; - } - hc->chan[channel].rx_counter = rx_counter; - -#ifdef REORDER_DEBUG - if (hc->chan[channel].disorder_flag) { - struct sk_buff *skb; - int cnt; - skb = hc->chan[channel].disorder_skb; - hc->chan[channel].disorder_skb = nskb; - nskb = skb; - cnt = hc->chan[channel].disorder_cnt; - hc->chan[channel].disorder_cnt = rx_counter; - rx_counter = cnt; - } - hc->chan[channel].disorder_flag ^= 1; - if (nskb) -#endif - queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb); - } -} - - -/* - * parse frame and extract channel data - */ -static void -l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len) -{ - u32 id; - u8 channel; - u8 remotecodec; - u16 timebase; - int m, mlen; - int len_start = len; /* initial frame length */ - struct dchannel *dch = hc->chan[hc->d_idx].dch; - - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n", - __func__, len); - - /* check lenght */ - if (len < 1+1+2) { - printk(KERN_WARNING "%s: packet error - length %d below " - "4 bytes\n", __func__, len); - return; - } - - /* check version */ - if (((*buf)>>6) != L1OIP_VERSION) { - printk(KERN_WARNING "%s: packet error - unknown version %d\n", - __func__, buf[0]>>6); - return; - } - - /* check type */ - if (((*buf)&0x20) && !hc->pri) { - printk(KERN_WARNING "%s: packet error - received E1 packet " - "on S0 interface\n", __func__); - return; - } - if (!((*buf)&0x20) && hc->pri) { - printk(KERN_WARNING "%s: packet error - received S0 packet " - "on E1 interface\n", __func__); - return; - } - - /* get id flag */ - id = (*buf>>4)&1; - - /* check coding */ - remotecodec = (*buf) & 0x0f; - if (remotecodec > 3) { - printk(KERN_WARNING "%s: packet error - remotecodec %d " - "unsupported\n", __func__, remotecodec); - return; - } - buf++; - len--; - - /* check id */ - if (id) { - if (!hc->id) { - printk(KERN_WARNING "%s: packet error - packet has id " - "0x%x, but we have not\n", __func__, id); - return; - } - if (len < 4) { - printk(KERN_WARNING "%s: packet error - packet too " - "short for ID value\n", __func__); - return; - } - id = (*buf++) << 24; - id += (*buf++) << 16; - id += (*buf++) << 8; - id += (*buf++); - len -= 4; - - if (id != hc->id) { - printk(KERN_WARNING "%s: packet error - ID mismatch, " - "got 0x%x, we 0x%x\n", - __func__, id, hc->id); - return; - } - } else { - if (hc->id) { - printk(KERN_WARNING "%s: packet error - packet has no " - "ID, but we have\n", __func__); - return; - } - } - -multiframe: - if (len < 1) { - printk(KERN_WARNING "%s: packet error - packet too short, " - "channel expected at position %d.\n", - __func__, len-len_start+1); - return; - } - - /* get channel and multiframe flag */ - channel = *buf&0x7f; - m = *buf >> 7; - buf++; - len--; - - /* check length on multiframe */ - if (m) { - if (len < 1) { - printk(KERN_WARNING "%s: packet error - packet too " - "short, length expected at position %d.\n", - __func__, len_start-len-1); - return; - } - - mlen = *buf++; - len--; - if (mlen == 0) - mlen = 256; - if (len < mlen+3) { - printk(KERN_WARNING "%s: packet error - length %d at " - "position %d exceeds total length %d.\n", - __func__, mlen, len_start-len-1, len_start); - return; - } - if (len == mlen+3) { - printk(KERN_WARNING "%s: packet error - length %d at " - "position %d will not allow additional " - "packet.\n", - __func__, mlen, len_start-len+1); - return; - } - } else - mlen = len-2; /* single frame, substract timebase */ - - if (len < 2) { - printk(KERN_WARNING "%s: packet error - packet too short, time " - "base expected at position %d.\n", - __func__, len-len_start+1); - return; - } - - /* get time base */ - timebase = (*buf++) << 8; - timebase |= (*buf++); - len -= 2; - - /* if inactive, we send up a PH_ACTIVATE and activate */ - if (!test_bit(FLG_ACTIVE, &dch->Flags)) { - if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET)) - printk(KERN_DEBUG "%s: interface become active due to " - "received packet\n", __func__); - test_and_set_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, - NULL, GFP_ATOMIC); - } - - /* distribute packet */ - l1oip_socket_recv(hc, remotecodec, channel, timebase, buf, mlen); - buf += mlen; - len -= mlen; - - /* multiframe */ - if (m) - goto multiframe; - - /* restart timer */ - if ((int)(hc->timeout_tl.expires-jiffies) < 5*HZ || !hc->timeout_on) { - hc->timeout_on = 1; - del_timer(&hc->timeout_tl); - hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT*HZ; - add_timer(&hc->timeout_tl); - } else /* only adjust timer */ - hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT*HZ; - - /* if ip or source port changes */ - if ((hc->sin_remote.sin_addr.s_addr != sin->sin_addr.s_addr) - || (hc->sin_remote.sin_port != sin->sin_port)) { - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_DEBUG "%s: remote address changes from " - "0x%08x to 0x%08x (port %d to %d)\n", __func__, - ntohl(hc->sin_remote.sin_addr.s_addr), - ntohl(sin->sin_addr.s_addr), - ntohs(hc->sin_remote.sin_port), - ntohs(sin->sin_port)); - hc->sin_remote.sin_addr.s_addr = sin->sin_addr.s_addr; - hc->sin_remote.sin_port = sin->sin_port; - } -} - - -/* - * socket stuff - */ -static int -l1oip_socket_thread(void *data) -{ - struct l1oip *hc = (struct l1oip *)data; - int ret = 0; - struct msghdr msg; - struct iovec iov; - mm_segment_t oldfs; - struct sockaddr_in sin_rx; - unsigned char recvbuf[1500]; - int recvlen; - struct socket *socket = NULL; - DECLARE_COMPLETION(wait); - - /* make daemon */ - allow_signal(SIGTERM); - - /* create socket */ - if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) { - printk(KERN_ERR "%s: Failed to create socket.\n", __func__); - return -EIO; - } - - /* set incoming address */ - hc->sin_local.sin_family = AF_INET; - hc->sin_local.sin_addr.s_addr = INADDR_ANY; - hc->sin_local.sin_port = htons((unsigned short)hc->localport); - - /* set outgoing address */ - hc->sin_remote.sin_family = AF_INET; - hc->sin_remote.sin_addr.s_addr = htonl(hc->remoteip); - hc->sin_remote.sin_port = htons((unsigned short)hc->remoteport); - - /* bind to incomming port */ - if (socket->ops->bind(socket, (struct sockaddr *)&hc->sin_local, - sizeof(hc->sin_local))) { - printk(KERN_ERR "%s: Failed to bind socket to port %d.\n", - __func__, hc->localport); - ret = -EINVAL; - goto fail; - } - - /* check sk */ - if (socket->sk == NULL) { - printk(KERN_ERR "%s: socket->sk == NULL\n", __func__); - ret = -EIO; - goto fail; - } - - /* build receive message */ - msg.msg_name = &sin_rx; - msg.msg_namelen = sizeof(sin_rx); - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - /* build send message */ - hc->sendmsg.msg_name = &hc->sin_remote; - hc->sendmsg.msg_namelen = sizeof(hc->sin_remote); - hc->sendmsg.msg_control = NULL; - hc->sendmsg.msg_controllen = 0; - hc->sendmsg.msg_iov = &hc->sendiov; - hc->sendmsg.msg_iovlen = 1; - - /* give away socket */ - spin_lock(&hc->socket_lock); - hc->socket = socket; - spin_unlock(&hc->socket_lock); - - /* read loop */ - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_DEBUG "%s: socket created and open\n", - __func__); - while (!signal_pending(current)) { - iov.iov_base = recvbuf; - iov.iov_len = sizeof(recvbuf); - oldfs = get_fs(); - set_fs(KERNEL_DS); - recvlen = sock_recvmsg(socket, &msg, sizeof(recvbuf), 0); - set_fs(oldfs); - if (recvlen > 0) { - l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen); - } else { - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_WARNING "%s: broken pipe on socket\n", - __func__); - } - } - - /* get socket back, check first if in use, maybe by send function */ - spin_lock(&hc->socket_lock); - /* if hc->socket is NULL, it is in use until it is given back */ - while (!hc->socket) { - spin_unlock(&hc->socket_lock); - schedule_timeout(HZ/10); - spin_lock(&hc->socket_lock); - } - hc->socket = NULL; - spin_unlock(&hc->socket_lock); - - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_DEBUG "%s: socket thread terminating\n", - __func__); - -fail: - /* close socket */ - if (socket) - sock_release(socket); - - /* if we got killed, signal completion */ - complete(&hc->socket_complete); - hc->socket_thread = NULL; /* show termination of thread */ - - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_DEBUG "%s: socket thread terminated\n", - __func__); - return ret; -} - -static void -l1oip_socket_close(struct l1oip *hc) -{ - /* kill thread */ - if (hc->socket_thread) { - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_DEBUG "%s: socket thread exists, " - "killing...\n", __func__); - send_sig(SIGTERM, hc->socket_thread, 0); - wait_for_completion(&hc->socket_complete); - } -} - -static int -l1oip_socket_open(struct l1oip *hc) -{ - /* in case of reopen, we need to close first */ - l1oip_socket_close(hc); - - init_completion(&hc->socket_complete); - - /* create receive process */ - hc->socket_thread = kthread_run(l1oip_socket_thread, hc, "l1oip_%s", - hc->name); - if (IS_ERR(hc->socket_thread)) { - int err = PTR_ERR(hc->socket_thread); - printk(KERN_ERR "%s: Failed (%d) to create socket process.\n", - __func__, err); - hc->socket_thread = NULL; - sock_release(hc->socket); - return err; - } - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_DEBUG "%s: socket thread created\n", __func__); - - return 0; -} - - -static void -l1oip_send_bh(struct work_struct *work) -{ - struct l1oip *hc = container_of(work, struct l1oip, workq); - - if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET)) - printk(KERN_DEBUG "%s: keepalive timer expired, sending empty " - "frame on dchannel\n", __func__); - - /* send an empty l1oip frame at D-channel */ - l1oip_socket_send(hc, 0, hc->d_idx, 0, 0, NULL, 0); -} - - -/* - * timer stuff - */ -static void -l1oip_keepalive(void *data) -{ - struct l1oip *hc = (struct l1oip *)data; - - schedule_work(&hc->workq); -} - -static void -l1oip_timeout(void *data) -{ - struct l1oip *hc = (struct l1oip *)data; - struct dchannel *dch = hc->chan[hc->d_idx].dch; - - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: timeout timer expired, turn layer one " - "down.\n", __func__); - - hc->timeout_on = 0; /* state that timer must be initialized next time */ - - /* if timeout, we send up a PH_DEACTIVATE and deactivate */ - if (test_bit(FLG_ACTIVE, &dch->Flags)) { - if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET)) - printk(KERN_DEBUG "%s: interface become deactivated " - "due to timeout\n", __func__); - test_and_clear_bit(FLG_ACTIVE, &dch->Flags); - _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, - NULL, GFP_ATOMIC); - } - - /* if we have ondemand set, we remove ip address */ - if (hc->ondemand) { - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: on demand causes ip address to " - "be removed\n", __func__); - hc->sin_remote.sin_addr.s_addr = 0; - } -} - - -/* - * message handling - */ -static int -handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); - struct dchannel *dch = container_of(dev, struct dchannel, dev); - struct l1oip *hc = dch->hw; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - int ret = -EINVAL; - int l, ll; - unsigned char *p; - - switch (hh->prim) { - case PH_DATA_REQ: - if (skb->len < 1) { - printk(KERN_WARNING "%s: skb too small\n", - __func__); - break; - } - if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) { - printk(KERN_WARNING "%s: skb too large\n", - __func__); - break; - } - /* send frame */ - p = skb->data; - l = skb->len; - while (l) { - ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME; - l1oip_socket_send(hc, 0, dch->slot, 0, - hc->chan[dch->slot].tx_counter++, p, ll); - p += ll; - l -= ll; - } - skb_trim(skb, 0); - queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb); - return 0; - case PH_ACTIVATE_REQ: - if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET)) - printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n" - , __func__, dch->slot, hc->b_num+1); - skb_trim(skb, 0); - if (test_bit(FLG_ACTIVE, &dch->Flags)) - queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb); - else - queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb); - return 0; - case PH_DEACTIVATE_REQ: - if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET)) - printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d " - "(1..%d)\n", __func__, dch->slot, - hc->b_num+1); - skb_trim(skb, 0); - if (test_bit(FLG_ACTIVE, &dch->Flags)) - queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb); - else - queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb); - return 0; - } - if (!ret) - dev_kfree_skb(skb); - return ret; -} - -static int -channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) -{ - int ret = 0; - struct l1oip *hc = dch->hw; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER; - break; - case MISDN_CTRL_SETPEER: - hc->remoteip = (u32)cq->p1; - hc->remoteport = cq->p2 & 0xffff; - hc->localport = cq->p2 >> 16; - if (!hc->remoteport) - hc->remoteport = hc->localport; - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_DEBUG "%s: got new ip address from user " - "space.\n", __func__); - l1oip_socket_open(hc); - break; - case MISDN_CTRL_UNSETPEER: - if (debug & DEBUG_L1OIP_SOCKET) - printk(KERN_DEBUG "%s: removing ip address.\n", - __func__); - hc->remoteip = 0; - l1oip_socket_open(hc); - break; - default: - printk(KERN_WARNING "%s: unknown Op %x\n", - __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; -} - -static int -open_dchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq) -{ - if (debug & DEBUG_HW_OPEN) - printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__, - dch->dev.id, __builtin_return_address(0)); - if (rq->protocol == ISDN_P_NONE) - return -EINVAL; - if ((dch->dev.D.protocol != ISDN_P_NONE) && - (dch->dev.D.protocol != rq->protocol)) { - if (debug & DEBUG_HW_OPEN) - printk(KERN_WARNING "%s: change protocol %x to %x\n", - __func__, dch->dev.D.protocol, rq->protocol); - } - if (dch->dev.D.protocol != rq->protocol) - dch->dev.D.protocol = rq->protocol; - - if (test_bit(FLG_ACTIVE, &dch->Flags)) { - _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, - 0, NULL, GFP_KERNEL); - } - rq->ch = &dch->dev.D; - if (!try_module_get(THIS_MODULE)) - printk(KERN_WARNING "%s:cannot get module\n", __func__); - return 0; -} - -static int -open_bchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq) -{ - struct bchannel *bch; - int ch; - - if (!test_bit(rq->adr.channel & 0x1f, - &dch->dev.channelmap[rq->adr.channel >> 5])) - return -EINVAL; - if (rq->protocol == ISDN_P_NONE) - return -EINVAL; - ch = rq->adr.channel; /* BRI: 1=B1 2=B2 PRI: 1..15,17.. */ - bch = hc->chan[ch].bch; - if (!bch) { - printk(KERN_ERR "%s:internal error ch %d has no bch\n", - __func__, ch); - return -EINVAL; - } - if (test_and_set_bit(FLG_OPEN, &bch->Flags)) - return -EBUSY; /* b-channel can be only open once */ - bch->ch.protocol = rq->protocol; - rq->ch = &bch->ch; - if (!try_module_get(THIS_MODULE)) - printk(KERN_WARNING "%s:cannot get module\n", __func__); - return 0; -} - -static int -l1oip_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); - struct dchannel *dch = container_of(dev, struct dchannel, dev); - struct l1oip *hc = dch->hw; - struct channel_req *rq; - int err = 0; - - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: cmd:%x %p\n", - __func__, cmd, arg); - switch (cmd) { - case OPEN_CHANNEL: - rq = arg; - switch (rq->protocol) { - case ISDN_P_TE_S0: - case ISDN_P_NT_S0: - if (hc->pri) { - err = -EINVAL; - break; - } - err = open_dchannel(hc, dch, rq); - break; - case ISDN_P_TE_E1: - case ISDN_P_NT_E1: - if (!hc->pri) { - err = -EINVAL; - break; - } - err = open_dchannel(hc, dch, rq); - break; - default: - err = open_bchannel(hc, dch, rq); - } - break; - case CLOSE_CHANNEL: - if (debug & DEBUG_HW_OPEN) - printk(KERN_DEBUG "%s: dev(%d) close from %p\n", - __func__, dch->dev.id, - __builtin_return_address(0)); - module_put(THIS_MODULE); - break; - case CONTROL_CHANNEL: - err = channel_dctrl(dch, arg); - break; - default: - if (dch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: unknown command %x\n", - __func__, cmd); - err = -EINVAL; - } - return err; -} - -static int -handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct bchannel *bch = container_of(ch, struct bchannel, ch); - struct l1oip *hc = bch->hw; - int ret = -EINVAL; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - int l, ll, i; - unsigned char *p; - - switch (hh->prim) { - case PH_DATA_REQ: - if (skb->len <= 0) { - printk(KERN_WARNING "%s: skb too small\n", - __func__); - break; - } - if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) { - printk(KERN_WARNING "%s: skb too large\n", - __func__); - break; - } - /* check for AIS / ulaw-silence */ - p = skb->data; - l = skb->len; - for (i = 0; i < l; i++) { - if (*p++ != 0xff) - break; - } - if (i == l) { - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: got AIS, not sending, " - "but counting\n", __func__); - hc->chan[bch->slot].tx_counter += l; - skb_trim(skb, 0); - queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb); - return 0; - } - /* check for silence */ - p = skb->data; - l = skb->len; - for (i = 0; i < l; i++) { - if (*p++ != 0x2a) - break; - } - if (i == l) { - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: got silence, not sending" - ", but counting\n", __func__); - hc->chan[bch->slot].tx_counter += l; - skb_trim(skb, 0); - queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb); - return 0; - } - - /* send frame */ - p = skb->data; - l = skb->len; - while (l) { - ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME; - l1oip_socket_send(hc, hc->codec, bch->slot, 0, - hc->chan[bch->slot].tx_counter, p, ll); - hc->chan[bch->slot].tx_counter += ll; - p += ll; - l -= ll; - } - skb_trim(skb, 0); - queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb); - return 0; - case PH_ACTIVATE_REQ: - if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET)) - printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n" - , __func__, bch->slot, hc->b_num+1); - hc->chan[bch->slot].codecstate = 0; - test_and_set_bit(FLG_ACTIVE, &bch->Flags); - skb_trim(skb, 0); - queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb); - return 0; - case PH_DEACTIVATE_REQ: - if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET)) - printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d " - "(1..%d)\n", __func__, bch->slot, - hc->b_num+1); - test_and_clear_bit(FLG_ACTIVE, &bch->Flags); - skb_trim(skb, 0); - queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb); - return 0; - } - if (!ret) - dev_kfree_skb(skb); - return ret; -} - -static int -channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) -{ - int ret = 0; - struct dsp_features *features = - (struct dsp_features *)(*((u_long *)&cq->p1)); - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = MISDN_CTRL_HW_FEATURES_OP; - break; - case MISDN_CTRL_HW_FEATURES: /* fill features structure */ - if (debug & DEBUG_L1OIP_MSG) - printk(KERN_DEBUG "%s: HW_FEATURE request\n", - __func__); - /* create confirm */ - features->unclocked = 1; - features->unordered = 1; - break; - default: - printk(KERN_WARNING "%s: unknown Op %x\n", - __func__, cq->op); - ret = -EINVAL; - break; - } - return ret; -} - -static int -l1oip_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct bchannel *bch = container_of(ch, struct bchannel, ch); - int err = -EINVAL; - - if (bch->debug & DEBUG_HW) - printk(KERN_DEBUG "%s: cmd:%x %p\n", - __func__, cmd, arg); - switch (cmd) { - case CLOSE_CHANNEL: - test_and_clear_bit(FLG_OPEN, &bch->Flags); - test_and_clear_bit(FLG_ACTIVE, &bch->Flags); - ch->protocol = ISDN_P_NONE; - ch->peer = NULL; - module_put(THIS_MODULE); - err = 0; - break; - case CONTROL_CHANNEL: - err = channel_bctrl(bch, arg); - break; - default: - printk(KERN_WARNING "%s: unknown prim(%x)\n", - __func__, cmd); - } - return err; -} - - -/* - * cleanup module and stack - */ -static void -release_card(struct l1oip *hc) -{ - int ch; - - if (timer_pending(&hc->keep_tl)) - del_timer(&hc->keep_tl); - - if (timer_pending(&hc->timeout_tl)) - del_timer(&hc->timeout_tl); - - if (hc->socket_thread) - l1oip_socket_close(hc); - - if (hc->registered && hc->chan[hc->d_idx].dch) - mISDN_unregister_device(&hc->chan[hc->d_idx].dch->dev); - for (ch = 0; ch < 128; ch++) { - if (hc->chan[ch].dch) { - mISDN_freedchannel(hc->chan[ch].dch); - kfree(hc->chan[ch].dch); - } - if (hc->chan[ch].bch) { - mISDN_freebchannel(hc->chan[ch].bch); - kfree(hc->chan[ch].bch); -#ifdef REORDER_DEBUG - if (hc->chan[ch].disorder_skb) - dev_kfree_skb(hc->chan[ch].disorder_skb); -#endif - } - } - - spin_lock(&l1oip_lock); - list_del(&hc->list); - spin_unlock(&l1oip_lock); - - kfree(hc); -} - -static void -l1oip_cleanup(void) -{ - struct l1oip *hc, *next; - - list_for_each_entry_safe(hc, next, &l1oip_ilist, list) - release_card(hc); - - l1oip_4bit_free(); -} - - -/* - * module and stack init - */ -static int -init_card(struct l1oip *hc, int pri, int bundle) -{ - struct dchannel *dch; - struct bchannel *bch; - int ret; - int i, ch; - - spin_lock_init(&hc->socket_lock); - hc->idx = l1oip_cnt; - hc->pri = pri; - hc->d_idx = pri?16:3; - hc->b_num = pri?30:2; - hc->bundle = bundle; - if (hc->pri) - sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1); - else - sprintf(hc->name, "l1oip-s0.%d", l1oip_cnt + 1); - - switch (codec[l1oip_cnt]) { - case 0: /* as is */ - case 1: /* alaw */ - case 2: /* ulaw */ - case 3: /* 4bit */ - break; - default: - printk(KERN_ERR "Codec(%d) not supported.\n", - codec[l1oip_cnt]); - return -EINVAL; - } - hc->codec = codec[l1oip_cnt]; - if (debug & DEBUG_L1OIP_INIT) - printk(KERN_DEBUG "%s: using codec %d\n", - __func__, hc->codec); - - if (id[l1oip_cnt] == 0) { - printk(KERN_WARNING "Warning: No 'id' value given or " - "0, this is highly unsecure. Please use 32 " - "bit randmom number 0x...\n"); - } - hc->id = id[l1oip_cnt]; - if (debug & DEBUG_L1OIP_INIT) - printk(KERN_DEBUG "%s: using id 0x%x\n", __func__, hc->id); - - hc->ondemand = ondemand[l1oip_cnt]; - if (hc->ondemand && !hc->id) { - printk(KERN_ERR "%s: ondemand option only allowed in " - "conjunction with non 0 ID\n", __func__); - return -EINVAL; - } - - if (limit[l1oip_cnt]) - hc->b_num = limit[l1oip_cnt]; - if (!pri && hc->b_num > 2) { - printk(KERN_ERR "Maximum limit for BRI interface is 2 " - "channels.\n"); - return -EINVAL; - } - if (pri && hc->b_num > 126) { - printk(KERN_ERR "Maximum limit for PRI interface is 126 " - "channels.\n"); - return -EINVAL; - } - if (pri && hc->b_num > 30) { - printk(KERN_WARNING "Maximum limit for BRI interface is 30 " - "channels.\n"); - printk(KERN_WARNING "Your selection of %d channels must be " - "supported by application.\n", hc->limit); - } - - hc->remoteip = ip[l1oip_cnt<<2] << 24 - | ip[(l1oip_cnt<<2)+1] << 16 - | ip[(l1oip_cnt<<2)+2] << 8 - | ip[(l1oip_cnt<<2)+3]; - hc->localport = port[l1oip_cnt]?:(L1OIP_DEFAULTPORT+l1oip_cnt); - if (remoteport[l1oip_cnt]) - hc->remoteport = remoteport[l1oip_cnt]; - else - hc->remoteport = hc->localport; - if (debug & DEBUG_L1OIP_INIT) - printk(KERN_DEBUG "%s: using local port %d remote ip " - "%d.%d.%d.%d port %d ondemand %d\n", __func__, - hc->localport, hc->remoteip >> 24, - (hc->remoteip >> 16) & 0xff, - (hc->remoteip >> 8) & 0xff, hc->remoteip & 0xff, - hc->remoteport, hc->ondemand); - - dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); - if (!dch) - return -ENOMEM; - dch->debug = debug; - mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, NULL); - dch->hw = hc; - if (pri) - dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1); - else - dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0); - dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | - (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); - dch->dev.D.send = handle_dmsg; - dch->dev.D.ctrl = l1oip_dctrl; - dch->dev.nrbchan = hc->b_num; - dch->slot = hc->d_idx; - hc->chan[hc->d_idx].dch = dch; - i = 1; - for (ch = 0; ch < dch->dev.nrbchan; ch++) { - if (ch == 15) - i++; - bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); - if (!bch) { - printk(KERN_ERR "%s: no memory for bchannel\n", - __func__); - return -ENOMEM; - } - bch->nr = i + ch; - bch->slot = i + ch; - bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM); - bch->hw = hc; - bch->ch.send = handle_bmsg; - bch->ch.ctrl = l1oip_bctrl; - bch->ch.nr = i + ch; - list_add(&bch->ch.list, &dch->dev.bchannels); - hc->chan[i + ch].bch = bch; - test_and_set_bit(bch->nr & 0x1f, - &dch->dev.channelmap[bch->nr >> 5]); - } - ret = mISDN_register_device(&dch->dev, hc->name); - if (ret) - return ret; - hc->registered = 1; - - if (debug & DEBUG_L1OIP_INIT) - printk(KERN_DEBUG "%s: Setting up network card(%d)\n", - __func__, l1oip_cnt + 1); - ret = l1oip_socket_open(hc); - if (ret) - return ret; - - hc->keep_tl.function = (void *)l1oip_keepalive; - hc->keep_tl.data = (ulong)hc; - init_timer(&hc->keep_tl); - hc->keep_tl.expires = jiffies + 2*HZ; /* two seconds first time */ - add_timer(&hc->keep_tl); - - hc->timeout_tl.function = (void *)l1oip_timeout; - hc->timeout_tl.data = (ulong)hc; - init_timer(&hc->timeout_tl); - hc->timeout_on = 0; /* state that we have timer off */ - - return 0; -} - -static int __init -l1oip_init(void) -{ - int pri, bundle; - struct l1oip *hc; - int ret; - - printk(KERN_INFO "mISDN: Layer-1-over-IP driver Rev. %s\n", - l1oip_revision); - - INIT_LIST_HEAD(&l1oip_ilist); - spin_lock_init(&l1oip_lock); - - if (l1oip_4bit_alloc(ulaw)) - return -ENOMEM; - - l1oip_cnt = 0; - while (type[l1oip_cnt] && l1oip_cnt < MAX_CARDS) { - switch (type[l1oip_cnt] & 0xff) { - case 1: - pri = 0; - bundle = 0; - break; - case 2: - pri = 1; - bundle = 0; - break; - case 3: - pri = 0; - bundle = 1; - break; - case 4: - pri = 1; - bundle = 1; - break; - default: - printk(KERN_ERR "Card type(%d) not supported.\n", - type[l1oip_cnt] & 0xff); - l1oip_cleanup(); - return -EINVAL; - } - - if (debug & DEBUG_L1OIP_INIT) - printk(KERN_DEBUG "%s: interface %d is %s with %s.\n", - __func__, l1oip_cnt, pri?"PRI":"BRI", - bundle?"bundled IP packet for all B-channels" - :"seperate IP packets for every B-channel"); - - hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC); - if (!hc) { - printk(KERN_ERR "No kmem for L1-over-IP driver.\n"); - l1oip_cleanup(); - return -ENOMEM; - } - INIT_WORK(&hc->workq, (void *)l1oip_send_bh); - - spin_lock(&l1oip_lock); - list_add_tail(&hc->list, &l1oip_ilist); - spin_unlock(&l1oip_lock); - - ret = init_card(hc, pri, bundle); - if (ret) { - l1oip_cleanup(); - return ret; - } - - l1oip_cnt++; - } - printk(KERN_INFO "%d virtual devices registered\n", l1oip_cnt); - return 0; -} - -module_init(l1oip_init); -module_exit(l1oip_cleanup); - diff --git a/trunk/drivers/isdn/mISDN/layer1.c b/trunk/drivers/isdn/mISDN/layer1.c deleted file mode 100644 index fced1a2755f8..000000000000 --- a/trunk/drivers/isdn/mISDN/layer1.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - - -#include -#include -#include "layer1.h" -#include "fsm.h" - -static int *debug; - -struct layer1 { - u_long Flags; - struct FsmInst l1m; - struct FsmTimer timer; - int delay; - struct dchannel *dch; - dchannel_l1callback *dcb; -}; - -#define TIMER3_VALUE 7000 - -static -struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; - -enum { - ST_L1_F2, - ST_L1_F3, - ST_L1_F4, - ST_L1_F5, - ST_L1_F6, - ST_L1_F7, - ST_L1_F8, -}; - -#define L1S_STATE_COUNT (ST_L1_F8+1) - -static char *strL1SState[] = -{ - "ST_L1_F2", - "ST_L1_F3", - "ST_L1_F4", - "ST_L1_F5", - "ST_L1_F6", - "ST_L1_F7", - "ST_L1_F8", -}; - -enum { - EV_PH_ACTIVATE, - EV_PH_DEACTIVATE, - EV_RESET_IND, - EV_DEACT_CNF, - EV_DEACT_IND, - EV_POWER_UP, - EV_ANYSIG_IND, - EV_INFO2_IND, - EV_INFO4_IND, - EV_TIMER_DEACT, - EV_TIMER_ACT, - EV_TIMER3, -}; - -#define L1_EVENT_COUNT (EV_TIMER3 + 1) - -static char *strL1Event[] = -{ - "EV_PH_ACTIVATE", - "EV_PH_DEACTIVATE", - "EV_RESET_IND", - "EV_DEACT_CNF", - "EV_DEACT_IND", - "EV_POWER_UP", - "EV_ANYSIG_IND", - "EV_INFO2_IND", - "EV_INFO4_IND", - "EV_TIMER_DEACT", - "EV_TIMER_ACT", - "EV_TIMER3", -}; - -static void -l1m_debug(struct FsmInst *fi, char *fmt, ...) -{ - struct layer1 *l1 = fi->userdata; - va_list va; - - va_start(va, fmt); - printk(KERN_DEBUG "%s: ", l1->dch->dev.name); - vprintk(fmt, va); - printk("\n"); - va_end(va); -} - -static void -l1_reset(struct FsmInst *fi, int event, void *arg) -{ - mISDN_FsmChangeState(fi, ST_L1_F3); -} - -static void -l1_deact_cnf(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - mISDN_FsmChangeState(fi, ST_L1_F3); - if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) - l1->dcb(l1->dch, HW_POWERUP_REQ); -} - -static void -l1_deact_req_s(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - mISDN_FsmChangeState(fi, ST_L1_F3); - mISDN_FsmRestartTimer(&l1->timer, 550, EV_TIMER_DEACT, NULL, 2); - test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); -} - -static void -l1_power_up_s(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) { - mISDN_FsmChangeState(fi, ST_L1_F4); - l1->dcb(l1->dch, INFO3_P8); - } else - mISDN_FsmChangeState(fi, ST_L1_F3); -} - -static void -l1_go_F5(struct FsmInst *fi, int event, void *arg) -{ - mISDN_FsmChangeState(fi, ST_L1_F5); -} - -static void -l1_go_F8(struct FsmInst *fi, int event, void *arg) -{ - mISDN_FsmChangeState(fi, ST_L1_F8); -} - -static void -l1_info2_ind(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - mISDN_FsmChangeState(fi, ST_L1_F6); - l1->dcb(l1->dch, INFO3_P8); -} - -static void -l1_info4_ind(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - mISDN_FsmChangeState(fi, ST_L1_F7); - l1->dcb(l1->dch, INFO3_P8); - if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) - mISDN_FsmDelTimer(&l1->timer, 4); - if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { - if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) - mISDN_FsmDelTimer(&l1->timer, 3); - mISDN_FsmRestartTimer(&l1->timer, 110, EV_TIMER_ACT, NULL, 2); - test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); - } -} - -static void -l1_timer3(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags); - if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) { - if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) - l1->dcb(l1->dch, HW_D_NOBLOCKED); - l1->dcb(l1->dch, PH_DEACTIVATE_IND); - } - if (l1->l1m.state != ST_L1_F6) { - mISDN_FsmChangeState(fi, ST_L1_F3); - l1->dcb(l1->dch, HW_POWERUP_REQ); - } -} - -static void -l1_timer_act(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags); - test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags); - l1->dcb(l1->dch, PH_ACTIVATE_IND); -} - -static void -l1_timer_deact(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags); - test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags); - if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) - l1->dcb(l1->dch, HW_D_NOBLOCKED); - l1->dcb(l1->dch, PH_DEACTIVATE_IND); - l1->dcb(l1->dch, HW_DEACT_REQ); -} - -static void -l1_activate_s(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - mISDN_FsmRestartTimer(&l1->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); - test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); - l1->dcb(l1->dch, HW_RESET_REQ); -} - -static void -l1_activate_no(struct FsmInst *fi, int event, void *arg) -{ - struct layer1 *l1 = fi->userdata; - - if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) && - (!test_bit(FLG_L1_T3RUN, &l1->Flags))) { - test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags); - if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) - l1->dcb(l1->dch, HW_D_NOBLOCKED); - l1->dcb(l1->dch, PH_DEACTIVATE_IND); - } -} - -static struct FsmNode L1SFnList[] = -{ - {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, - {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, - {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, - {ST_L1_F3, EV_RESET_IND, l1_reset}, - {ST_L1_F4, EV_RESET_IND, l1_reset}, - {ST_L1_F5, EV_RESET_IND, l1_reset}, - {ST_L1_F6, EV_RESET_IND, l1_reset}, - {ST_L1_F7, EV_RESET_IND, l1_reset}, - {ST_L1_F8, EV_RESET_IND, l1_reset}, - {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, - {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, - {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, - {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, - {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, - {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5}, - {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8}, - {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8}, - {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, - {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, - {ST_L1_F3, EV_TIMER3, l1_timer3}, - {ST_L1_F4, EV_TIMER3, l1_timer3}, - {ST_L1_F5, EV_TIMER3, l1_timer3}, - {ST_L1_F6, EV_TIMER3, l1_timer3}, - {ST_L1_F8, EV_TIMER3, l1_timer3}, - {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, - {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, - {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, -}; - -static void -release_l1(struct layer1 *l1) { - mISDN_FsmDelTimer(&l1->timer, 0); - if (l1->dch) - l1->dch->l1 = NULL; - module_put(THIS_MODULE); - kfree(l1); -} - -int -l1_event(struct layer1 *l1, u_int event) -{ - int err = 0; - - if (!l1) - return -EINVAL; - switch (event) { - case HW_RESET_IND: - mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); - break; - case HW_DEACT_IND: - mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); - break; - case HW_POWERUP_IND: - mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); - break; - case HW_DEACT_CNF: - mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); - break; - case ANYSIGNAL: - mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); - break; - case LOSTFRAMING: - mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); - break; - case INFO2: - mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); - break; - case INFO4_P8: - mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); - break; - case INFO4_P10: - mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); - break; - case PH_ACTIVATE_REQ: - if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) - l1->dcb(l1->dch, PH_ACTIVATE_IND); - else { - test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); - mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); - } - break; - case CLOSE_CHANNEL: - release_l1(l1); - break; - default: - if (*debug & DEBUG_L1) - printk(KERN_DEBUG "%s %x unhandled\n", - __func__, event); - err = -EINVAL; - } - return err; -} -EXPORT_SYMBOL(l1_event); - -int -create_l1(struct dchannel *dch, dchannel_l1callback *dcb) { - struct layer1 *nl1; - - nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); - if (!nl1) { - printk(KERN_ERR "kmalloc struct layer1 failed\n"); - return -ENOMEM; - } - nl1->l1m.fsm = &l1fsm_s; - nl1->l1m.state = ST_L1_F3; - nl1->Flags = 0; - nl1->l1m.debug = *debug & DEBUG_L1_FSM; - nl1->l1m.userdata = nl1; - nl1->l1m.userint = 0; - nl1->l1m.printdebug = l1m_debug; - nl1->dch = dch; - nl1->dcb = dcb; - mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer); - __module_get(THIS_MODULE); - dch->l1 = nl1; - return 0; -} -EXPORT_SYMBOL(create_l1); - -int -l1_init(u_int *deb) -{ - debug = deb; - l1fsm_s.state_count = L1S_STATE_COUNT; - l1fsm_s.event_count = L1_EVENT_COUNT; - l1fsm_s.strEvent = strL1Event; - l1fsm_s.strState = strL1SState; - mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); - return 0; -} - -void -l1_cleanup(void) -{ - mISDN_FsmFree(&l1fsm_s); -} diff --git a/trunk/drivers/isdn/mISDN/layer1.h b/trunk/drivers/isdn/mISDN/layer1.h deleted file mode 100644 index 9c8125fd89af..000000000000 --- a/trunk/drivers/isdn/mISDN/layer1.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * - * Layer 1 defines - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#define FLG_L1_ACTIVATING 1 -#define FLG_L1_ACTIVATED 2 -#define FLG_L1_DEACTTIMER 3 -#define FLG_L1_ACTTIMER 4 -#define FLG_L1_T3RUN 5 -#define FLG_L1_PULL_REQ 6 -#define FLG_L1_UINT 7 -#define FLG_L1_DBLOCKED 8 - diff --git a/trunk/drivers/isdn/mISDN/layer2.c b/trunk/drivers/isdn/mISDN/layer2.c deleted file mode 100644 index a7915a156c04..000000000000 --- a/trunk/drivers/isdn/mISDN/layer2.c +++ /dev/null @@ -1,2216 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#include "fsm.h" -#include "layer2.h" - -static int *debug; - -static -struct Fsm l2fsm = {NULL, 0, 0, NULL, NULL}; - -static char *strL2State[] = -{ - "ST_L2_1", - "ST_L2_2", - "ST_L2_3", - "ST_L2_4", - "ST_L2_5", - "ST_L2_6", - "ST_L2_7", - "ST_L2_8", -}; - -enum { - EV_L2_UI, - EV_L2_SABME, - EV_L2_DISC, - EV_L2_DM, - EV_L2_UA, - EV_L2_FRMR, - EV_L2_SUPER, - EV_L2_I, - EV_L2_DL_DATA, - EV_L2_ACK_PULL, - EV_L2_DL_UNITDATA, - EV_L2_DL_ESTABLISH_REQ, - EV_L2_DL_RELEASE_REQ, - EV_L2_MDL_ASSIGN, - EV_L2_MDL_REMOVE, - EV_L2_MDL_ERROR, - EV_L1_DEACTIVATE, - EV_L2_T200, - EV_L2_T203, - EV_L2_SET_OWN_BUSY, - EV_L2_CLEAR_OWN_BUSY, - EV_L2_FRAME_ERROR, -}; - -#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR+1) - -static char *strL2Event[] = -{ - "EV_L2_UI", - "EV_L2_SABME", - "EV_L2_DISC", - "EV_L2_DM", - "EV_L2_UA", - "EV_L2_FRMR", - "EV_L2_SUPER", - "EV_L2_I", - "EV_L2_DL_DATA", - "EV_L2_ACK_PULL", - "EV_L2_DL_UNITDATA", - "EV_L2_DL_ESTABLISH_REQ", - "EV_L2_DL_RELEASE_REQ", - "EV_L2_MDL_ASSIGN", - "EV_L2_MDL_REMOVE", - "EV_L2_MDL_ERROR", - "EV_L1_DEACTIVATE", - "EV_L2_T200", - "EV_L2_T203", - "EV_L2_SET_OWN_BUSY", - "EV_L2_CLEAR_OWN_BUSY", - "EV_L2_FRAME_ERROR", -}; - -static void -l2m_debug(struct FsmInst *fi, char *fmt, ...) -{ - struct layer2 *l2 = fi->userdata; - va_list va; - - if (!(*debug & DEBUG_L2_FSM)) - return; - va_start(va, fmt); - printk(KERN_DEBUG "l2 (tei %d): ", l2->tei); - vprintk(fmt, va); - printk("\n"); - va_end(va); -} - -inline u_int -l2headersize(struct layer2 *l2, int ui) -{ - return ((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) + - (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); -} - -inline u_int -l2addrsize(struct layer2 *l2) -{ - return test_bit(FLG_LAPD, &l2->flag) ? 2 : 1; -} - -static u_int -l2_newid(struct layer2 *l2) -{ - u_int id; - - id = l2->next_id++; - if (id == 0x7fff) - l2->next_id = 1; - id <<= 16; - id |= l2->tei << 8; - id |= l2->sapi; - return id; -} - -static void -l2up(struct layer2 *l2, u_int prim, struct sk_buff *skb) -{ - int err; - - if (!l2->up) - return; - mISDN_HEAD_PRIM(skb) = prim; - mISDN_HEAD_ID(skb) = (l2->ch.nr << 16) | l2->ch.addr; - err = l2->up->send(l2->up, skb); - if (err) { - printk(KERN_WARNING "%s: err=%d\n", __func__, err); - dev_kfree_skb(skb); - } -} - -static void -l2up_create(struct layer2 *l2, u_int prim, int len, void *arg) -{ - struct sk_buff *skb; - struct mISDNhead *hh; - int err; - - if (!l2->up) - return; - skb = mI_alloc_skb(len, GFP_ATOMIC); - if (!skb) - return; - hh = mISDN_HEAD_P(skb); - hh->prim = prim; - hh->id = (l2->ch.nr << 16) | l2->ch.addr; - if (len) - memcpy(skb_put(skb, len), arg, len); - err = l2->up->send(l2->up, skb); - if (err) { - printk(KERN_WARNING "%s: err=%d\n", __func__, err); - dev_kfree_skb(skb); - } -} - -static int -l2down_skb(struct layer2 *l2, struct sk_buff *skb) { - int ret; - - ret = l2->ch.recv(l2->ch.peer, skb); - if (ret && (*debug & DEBUG_L2_RECV)) - printk(KERN_DEBUG "l2down_skb: ret(%d)\n", ret); - return ret; -} - -static int -l2down_raw(struct layer2 *l2, struct sk_buff *skb) -{ - struct mISDNhead *hh = mISDN_HEAD_P(skb); - - if (hh->prim == PH_DATA_REQ) { - if (test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) { - skb_queue_tail(&l2->down_queue, skb); - return 0; - } - l2->down_id = mISDN_HEAD_ID(skb); - } - return l2down_skb(l2, skb); -} - -static int -l2down(struct layer2 *l2, u_int prim, u_int id, struct sk_buff *skb) -{ - struct mISDNhead *hh = mISDN_HEAD_P(skb); - - hh->prim = prim; - hh->id = id; - return l2down_raw(l2, skb); -} - -static int -l2down_create(struct layer2 *l2, u_int prim, u_int id, int len, void *arg) -{ - struct sk_buff *skb; - int err; - struct mISDNhead *hh; - - skb = mI_alloc_skb(len, GFP_ATOMIC); - if (!skb) - return -ENOMEM; - hh = mISDN_HEAD_P(skb); - hh->prim = prim; - hh->id = id; - if (len) - memcpy(skb_put(skb, len), arg, len); - err = l2down_raw(l2, skb); - if (err) - dev_kfree_skb(skb); - return err; -} - -static int -ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) { - struct sk_buff *nskb = skb; - int ret = -EAGAIN; - - if (test_bit(FLG_L1_NOTREADY, &l2->flag)) { - if (hh->id == l2->down_id) { - nskb = skb_dequeue(&l2->down_queue); - if (nskb) { - l2->down_id = mISDN_HEAD_ID(nskb); - if (l2down_skb(l2, nskb)) { - dev_kfree_skb(nskb); - l2->down_id = MISDN_ID_NONE; - } - } else - l2->down_id = MISDN_ID_NONE; - if (ret) { - dev_kfree_skb(skb); - ret = 0; - } - if (l2->down_id == MISDN_ID_NONE) { - test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag); - mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL); - } - } - } - if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) { - nskb = skb_dequeue(&l2->down_queue); - if (nskb) { - l2->down_id = mISDN_HEAD_ID(nskb); - if (l2down_skb(l2, nskb)) { - dev_kfree_skb(nskb); - l2->down_id = MISDN_ID_NONE; - test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag); - } - } else - test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag); - } - return ret; -} - -static int -l2mgr(struct layer2 *l2, u_int prim, void *arg) { - long c = (long)arg; - - printk(KERN_WARNING - "l2mgr: addr:%x prim %x %c\n", l2->id, prim, (char)c); - if (test_bit(FLG_LAPD, &l2->flag) && - !test_bit(FLG_FIXED_TEI, &l2->flag)) { - switch (c) { - case 'C': - case 'D': - case 'G': - case 'H': - l2_tei(l2, prim, (u_long)arg); - break; - } - } - return 0; -} - -static void -set_peer_busy(struct layer2 *l2) { - test_and_set_bit(FLG_PEER_BUSY, &l2->flag); - if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue)) - test_and_set_bit(FLG_L2BLOCK, &l2->flag); -} - -static void -clear_peer_busy(struct layer2 *l2) { - if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag)) - test_and_clear_bit(FLG_L2BLOCK, &l2->flag); -} - -static void -InitWin(struct layer2 *l2) -{ - int i; - - for (i = 0; i < MAX_WINDOW; i++) - l2->windowar[i] = NULL; -} - -static int -freewin(struct layer2 *l2) -{ - int i, cnt = 0; - - for (i = 0; i < MAX_WINDOW; i++) { - if (l2->windowar[i]) { - cnt++; - dev_kfree_skb(l2->windowar[i]); - l2->windowar[i] = NULL; - } - } - return cnt; -} - -static void -ReleaseWin(struct layer2 *l2) -{ - int cnt = freewin(l2); - - if (cnt) - printk(KERN_WARNING - "isdnl2 freed %d skbuffs in release\n", cnt); -} - -inline unsigned int -cansend(struct layer2 *l2) -{ - unsigned int p1; - - if (test_bit(FLG_MOD128, &l2->flag)) - p1 = (l2->vs - l2->va) % 128; - else - p1 = (l2->vs - l2->va) % 8; - return (p1 < l2->window) && !test_bit(FLG_PEER_BUSY, &l2->flag); -} - -inline void -clear_exception(struct layer2 *l2) -{ - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); - test_and_clear_bit(FLG_REJEXC, &l2->flag); - test_and_clear_bit(FLG_OWN_BUSY, &l2->flag); - clear_peer_busy(l2); -} - -static int -sethdraddr(struct layer2 *l2, u_char *header, int rsp) -{ - u_char *ptr = header; - int crbit = rsp; - - if (test_bit(FLG_LAPD, &l2->flag)) { - if (test_bit(FLG_LAPD_NET, &l2->flag)) - crbit = !crbit; - *ptr++ = (l2->sapi << 2) | (crbit ? 2 : 0); - *ptr++ = (l2->tei << 1) | 1; - return 2; - } else { - if (test_bit(FLG_ORIG, &l2->flag)) - crbit = !crbit; - if (crbit) - *ptr++ = l2->addr.B; - else - *ptr++ = l2->addr.A; - return 1; - } -} - -static inline void -enqueue_super(struct layer2 *l2, struct sk_buff *skb) -{ - if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb)) - dev_kfree_skb(skb); -} - -static inline void -enqueue_ui(struct layer2 *l2, struct sk_buff *skb) -{ - if (l2->tm) - l2_tei(l2, MDL_STATUS_UI_IND, 0); - if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb)) - dev_kfree_skb(skb); -} - -inline int -IsUI(u_char *data) -{ - return (data[0] & 0xef) == UI; -} - -inline int -IsUA(u_char *data) -{ - return (data[0] & 0xef) == UA; -} - -inline int -IsDM(u_char *data) -{ - return (data[0] & 0xef) == DM; -} - -inline int -IsDISC(u_char *data) -{ - return (data[0] & 0xef) == DISC; -} - -inline int -IsRR(u_char *data, struct layer2 *l2) -{ - if (test_bit(FLG_MOD128, &l2->flag)) - return data[0] == RR; - else - return (data[0] & 0xf) == 1; -} - -inline int -IsSFrame(u_char *data, struct layer2 *l2) -{ - register u_char d = *data; - - if (!test_bit(FLG_MOD128, &l2->flag)) - d &= 0xf; - return ((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c); -} - -inline int -IsSABME(u_char *data, struct layer2 *l2) -{ - u_char d = data[0] & ~0x10; - - return test_bit(FLG_MOD128, &l2->flag) ? d == SABME : d == SABM; -} - -inline int -IsREJ(u_char *data, struct layer2 *l2) -{ - return test_bit(FLG_MOD128, &l2->flag) ? - data[0] == REJ : (data[0] & 0xf) == REJ; -} - -inline int -IsFRMR(u_char *data) -{ - return (data[0] & 0xef) == FRMR; -} - -inline int -IsRNR(u_char *data, struct layer2 *l2) -{ - return test_bit(FLG_MOD128, &l2->flag) ? - data[0] == RNR : (data[0] & 0xf) == RNR; -} - -int -iframe_error(struct layer2 *l2, struct sk_buff *skb) -{ - u_int i; - int rsp = *skb->data & 0x2; - - i = l2addrsize(l2) + (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1); - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; - if (rsp) - return 'L'; - if (skb->len < i) - return 'N'; - if ((skb->len - i) > l2->maxlen) - return 'O'; - return 0; -} - -int -super_error(struct layer2 *l2, struct sk_buff *skb) -{ - if (skb->len != l2addrsize(l2) + - (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1)) - return 'N'; - return 0; -} - -int -unnum_error(struct layer2 *l2, struct sk_buff *skb, int wantrsp) -{ - int rsp = (*skb->data & 0x2) >> 1; - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; - if (rsp != wantrsp) - return 'L'; - if (skb->len != l2addrsize(l2) + 1) - return 'N'; - return 0; -} - -int -UI_error(struct layer2 *l2, struct sk_buff *skb) -{ - int rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; - if (rsp) - return 'L'; - if (skb->len > l2->maxlen + l2addrsize(l2) + 1) - return 'O'; - return 0; -} - -int -FRMR_error(struct layer2 *l2, struct sk_buff *skb) -{ - u_int headers = l2addrsize(l2) + 1; - u_char *datap = skb->data + headers; - int rsp = *skb->data & 0x2; - - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; - if (!rsp) - return 'L'; - if (test_bit(FLG_MOD128, &l2->flag)) { - if (skb->len < headers + 5) - return 'N'; - else if (*debug & DEBUG_L2) - l2m_debug(&l2->l2m, - "FRMR information %2x %2x %2x %2x %2x", - datap[0], datap[1], datap[2], datap[3], datap[4]); - } else { - if (skb->len < headers + 3) - return 'N'; - else if (*debug & DEBUG_L2) - l2m_debug(&l2->l2m, - "FRMR information %2x %2x %2x", - datap[0], datap[1], datap[2]); - } - return 0; -} - -static unsigned int -legalnr(struct layer2 *l2, unsigned int nr) -{ - if (test_bit(FLG_MOD128, &l2->flag)) - return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128); - else - return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8); -} - -static void -setva(struct layer2 *l2, unsigned int nr) -{ - struct sk_buff *skb; - - while (l2->va != nr) { - l2->va++; - if (test_bit(FLG_MOD128, &l2->flag)) - l2->va %= 128; - else - l2->va %= 8; - if (l2->windowar[l2->sow]) { - skb_trim(l2->windowar[l2->sow], 0); - skb_queue_tail(&l2->tmp_queue, l2->windowar[l2->sow]); - l2->windowar[l2->sow] = NULL; - } - l2->sow = (l2->sow + 1) % l2->window; - } - skb = skb_dequeue(&l2->tmp_queue); - while (skb) { - dev_kfree_skb(skb); - skb = skb_dequeue(&l2->tmp_queue); - } -} - -static void -send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr) -{ - u_char tmp[MAX_L2HEADER_LEN]; - int i; - - i = sethdraddr(l2, tmp, cr); - tmp[i++] = cmd; - if (skb) - skb_trim(skb, 0); - else { - skb = mI_alloc_skb(i, GFP_ATOMIC); - if (!skb) { - printk(KERN_WARNING "%s: can't alloc skbuff\n", - __func__); - return; - } - } - memcpy(skb_put(skb, i), tmp, i); - enqueue_super(l2, skb); -} - - -inline u_char -get_PollFlag(struct layer2 *l2, struct sk_buff *skb) -{ - return skb->data[l2addrsize(l2)] & 0x10; -} - -inline u_char -get_PollFlagFree(struct layer2 *l2, struct sk_buff *skb) -{ - u_char PF; - - PF = get_PollFlag(l2, skb); - dev_kfree_skb(skb); - return PF; -} - -inline void -start_t200(struct layer2 *l2, int i) -{ - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i); - test_and_set_bit(FLG_T200_RUN, &l2->flag); -} - -inline void -restart_t200(struct layer2 *l2, int i) -{ - mISDN_FsmRestartTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i); - test_and_set_bit(FLG_T200_RUN, &l2->flag); -} - -inline void -stop_t200(struct layer2 *l2, int i) -{ - if (test_and_clear_bit(FLG_T200_RUN, &l2->flag)) - mISDN_FsmDelTimer(&l2->t200, i); -} - -inline void -st5_dl_release_l2l3(struct layer2 *l2) -{ - int pr; - - if (test_and_clear_bit(FLG_PEND_REL, &l2->flag)) - pr = DL_RELEASE_CNF; - else - pr = DL_RELEASE_IND; - l2up_create(l2, pr, 0, NULL); -} - -inline void -lapb_dl_release_l2l3(struct layer2 *l2, int f) -{ - if (test_bit(FLG_LAPB, &l2->flag)) - l2down_create(l2, PH_DEACTIVATE_REQ, l2_newid(l2), 0, NULL); - l2up_create(l2, f, 0, NULL); -} - -static void -establishlink(struct FsmInst *fi) -{ - struct layer2 *l2 = fi->userdata; - u_char cmd; - - clear_exception(l2); - l2->rc = 0; - cmd = (test_bit(FLG_MOD128, &l2->flag) ? SABME : SABM) | 0x10; - send_uframe(l2, NULL, cmd, CMD); - mISDN_FsmDelTimer(&l2->t203, 1); - restart_t200(l2, 1); - test_and_clear_bit(FLG_PEND_REL, &l2->flag); - freewin(l2); - mISDN_FsmChangeState(fi, ST_L2_5); -} - -static void -l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct layer2 *l2 = fi->userdata; - - if (get_PollFlagFree(l2, skb)) - l2mgr(l2, MDL_ERROR_IND, (void *) 'C'); - else - l2mgr(l2, MDL_ERROR_IND, (void *) 'D'); - -} - -static void -l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct layer2 *l2 = fi->userdata; - - if (get_PollFlagFree(l2, skb)) - l2mgr(l2, MDL_ERROR_IND, (void *) 'B'); - else { - l2mgr(l2, MDL_ERROR_IND, (void *) 'E'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &l2->flag); - } -} - -static void -l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct layer2 *l2 = fi->userdata; - - if (get_PollFlagFree(l2, skb)) - l2mgr(l2, MDL_ERROR_IND, (void *) 'B'); - else - l2mgr(l2, MDL_ERROR_IND, (void *) 'E'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &l2->flag); -} - -static void -l2_go_st3(struct FsmInst *fi, int event, void *arg) -{ - dev_kfree_skb((struct sk_buff *)arg); - mISDN_FsmChangeState(fi, ST_L2_3); -} - -static void -l2_mdl_assign(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - mISDN_FsmChangeState(fi, ST_L2_3); - dev_kfree_skb((struct sk_buff *)arg); - l2_tei(l2, MDL_ASSIGN_IND, 0); -} - -static void -l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_tail(&l2->ui_queue, skb); - mISDN_FsmChangeState(fi, ST_L2_2); - l2_tei(l2, MDL_ASSIGN_IND, 0); -} - -static void -l2_queue_ui(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_tail(&l2->ui_queue, skb); -} - -static void -tx_ui(struct layer2 *l2) -{ - struct sk_buff *skb; - u_char header[MAX_L2HEADER_LEN]; - int i; - - i = sethdraddr(l2, header, CMD); - if (test_bit(FLG_LAPD_NET, &l2->flag)) - header[1] = 0xff; /* tei 127 */ - header[i++] = UI; - while ((skb = skb_dequeue(&l2->ui_queue))) { - memcpy(skb_push(skb, i), header, i); - enqueue_ui(l2, skb); - } -} - -static void -l2_send_ui(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_tail(&l2->ui_queue, skb); - tx_ui(l2); -} - -static void -l2_got_ui(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_pull(skb, l2headersize(l2, 1)); -/* - * in states 1-3 for broadcast - */ - - if (l2->tm) - l2_tei(l2, MDL_STATUS_UI_IND, 0); - l2up(l2, DL_UNITDATA_IND, skb); -} - -static void -l2_establish(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct layer2 *l2 = fi->userdata; - - establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &l2->flag); - dev_kfree_skb(skb); -} - -static void -l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct layer2 *l2 = fi->userdata; - - skb_queue_purge(&l2->i_queue); - test_and_set_bit(FLG_L3_INIT, &l2->flag); - test_and_clear_bit(FLG_PEND_REL, &l2->flag); - dev_kfree_skb(skb); -} - -static void -l2_l3_reestablish(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct layer2 *l2 = fi->userdata; - - skb_queue_purge(&l2->i_queue); - establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &l2->flag); - dev_kfree_skb(skb); -} - -static void -l2_release(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_trim(skb, 0); - l2up(l2, DL_RELEASE_CNF, skb); -} - -static void -l2_pend_rel(struct FsmInst *fi, int event, void *arg) -{ - struct sk_buff *skb = arg; - struct layer2 *l2 = fi->userdata; - - test_and_set_bit(FLG_PEND_REL, &l2->flag); - dev_kfree_skb(skb); -} - -static void -l2_disconnect(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_purge(&l2->i_queue); - freewin(l2); - mISDN_FsmChangeState(fi, ST_L2_6); - l2->rc = 0; - send_uframe(l2, NULL, DISC | 0x10, CMD); - mISDN_FsmDelTimer(&l2->t203, 1); - restart_t200(l2, 2); - if (skb) - dev_kfree_skb(skb); -} - -static void -l2_start_multi(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - l2->vs = 0; - l2->va = 0; - l2->vr = 0; - l2->sow = 0; - clear_exception(l2); - send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP); - mISDN_FsmChangeState(fi, ST_L2_7); - mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3); - skb_trim(skb, 0); - l2up(l2, DL_ESTABLISH_IND, skb); - if (l2->tm) - l2_tei(l2, MDL_STATUS_UP_IND, 0); -} - -static void -l2_send_UA(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP); -} - -static void -l2_send_DM(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - send_uframe(l2, skb, DM | get_PollFlag(l2, skb), RSP); -} - -static void -l2_restart_multi(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - int est = 0; - - send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP); - - l2mgr(l2, MDL_ERROR_IND, (void *) 'F'); - - if (l2->vs != l2->va) { - skb_queue_purge(&l2->i_queue); - est = 1; - } - - clear_exception(l2); - l2->vs = 0; - l2->va = 0; - l2->vr = 0; - l2->sow = 0; - mISDN_FsmChangeState(fi, ST_L2_7); - stop_t200(l2, 3); - mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3); - - if (est) - l2up_create(l2, DL_ESTABLISH_IND, 0, NULL); -/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST, - * MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED, - * 0, NULL, 0); - */ - if (skb_queue_len(&l2->i_queue) && cansend(l2)) - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL); -} - -static void -l2_stop_multi(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - mISDN_FsmChangeState(fi, ST_L2_4); - mISDN_FsmDelTimer(&l2->t203, 3); - stop_t200(l2, 4); - - send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP); - skb_queue_purge(&l2->i_queue); - freewin(l2); - lapb_dl_release_l2l3(l2, DL_RELEASE_IND); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); -} - -static void -l2_connected(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - int pr = -1; - - if (!get_PollFlag(l2, skb)) { - l2_mdl_error_ua(fi, event, arg); - return; - } - dev_kfree_skb(skb); - if (test_and_clear_bit(FLG_PEND_REL, &l2->flag)) - l2_disconnect(fi, event, NULL); - if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) { - pr = DL_ESTABLISH_CNF; - } else if (l2->vs != l2->va) { - skb_queue_purge(&l2->i_queue); - pr = DL_ESTABLISH_IND; - } - stop_t200(l2, 5); - l2->vr = 0; - l2->vs = 0; - l2->va = 0; - l2->sow = 0; - mISDN_FsmChangeState(fi, ST_L2_7); - mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4); - if (pr != -1) - l2up_create(l2, pr, 0, NULL); - - if (skb_queue_len(&l2->i_queue) && cansend(l2)) - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL); - - if (l2->tm) - l2_tei(l2, MDL_STATUS_UP_IND, 0); -} - -static void -l2_released(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - if (!get_PollFlag(l2, skb)) { - l2_mdl_error_ua(fi, event, arg); - return; - } - dev_kfree_skb(skb); - stop_t200(l2, 6); - lapb_dl_release_l2l3(l2, DL_RELEASE_CNF); - mISDN_FsmChangeState(fi, ST_L2_4); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); -} - -static void -l2_reestablish(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - if (!get_PollFlagFree(l2, skb)) { - establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &l2->flag); - } -} - -static void -l2_st5_dm_release(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - if (get_PollFlagFree(l2, skb)) { - stop_t200(l2, 7); - if (!test_bit(FLG_L3_INIT, &l2->flag)) - skb_queue_purge(&l2->i_queue); - if (test_bit(FLG_LAPB, &l2->flag)) - l2down_create(l2, PH_DEACTIVATE_REQ, - l2_newid(l2), 0, NULL); - st5_dl_release_l2l3(l2); - mISDN_FsmChangeState(fi, ST_L2_4); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); - } -} - -static void -l2_st6_dm_release(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - if (get_PollFlagFree(l2, skb)) { - stop_t200(l2, 8); - lapb_dl_release_l2l3(l2, DL_RELEASE_CNF); - mISDN_FsmChangeState(fi, ST_L2_4); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); - } -} - -void -enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf) -{ - struct sk_buff *skb; - u_char tmp[MAX_L2HEADER_LEN]; - int i; - - i = sethdraddr(l2, tmp, cr); - if (test_bit(FLG_MOD128, &l2->flag)) { - tmp[i++] = typ; - tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0); - } else - tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0); - skb = mI_alloc_skb(i, GFP_ATOMIC); - if (!skb) { - printk(KERN_WARNING - "isdnl2 can't alloc sbbuff for enquiry_cr\n"); - return; - } - memcpy(skb_put(skb, i), tmp, i); - enqueue_super(l2, skb); -} - -inline void -enquiry_response(struct layer2 *l2) -{ - if (test_bit(FLG_OWN_BUSY, &l2->flag)) - enquiry_cr(l2, RNR, RSP, 1); - else - enquiry_cr(l2, RR, RSP, 1); - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); -} - -inline void -transmit_enquiry(struct layer2 *l2) -{ - if (test_bit(FLG_OWN_BUSY, &l2->flag)) - enquiry_cr(l2, RNR, CMD, 1); - else - enquiry_cr(l2, RR, CMD, 1); - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); - start_t200(l2, 9); -} - - -static void -nrerrorrecovery(struct FsmInst *fi) -{ - struct layer2 *l2 = fi->userdata; - - l2mgr(l2, MDL_ERROR_IND, (void *) 'J'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &l2->flag); -} - -static void -invoke_retransmission(struct layer2 *l2, unsigned int nr) -{ - u_int p1; - - if (l2->vs != nr) { - while (l2->vs != nr) { - (l2->vs)--; - if (test_bit(FLG_MOD128, &l2->flag)) { - l2->vs %= 128; - p1 = (l2->vs - l2->va) % 128; - } else { - l2->vs %= 8; - p1 = (l2->vs - l2->va) % 8; - } - p1 = (p1 + l2->sow) % l2->window; - if (l2->windowar[p1]) - skb_queue_head(&l2->i_queue, l2->windowar[p1]); - else - printk(KERN_WARNING - "%s: windowar[%d] is NULL\n", - __func__, p1); - l2->windowar[p1] = NULL; - } - mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL); - } -} - -static void -l2_st7_got_super(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - int PollFlag, rsp, typ = RR; - unsigned int nr; - - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; - - skb_pull(skb, l2addrsize(l2)); - if (IsRNR(skb->data, l2)) { - set_peer_busy(l2); - typ = RNR; - } else - clear_peer_busy(l2); - if (IsREJ(skb->data, l2)) - typ = REJ; - - if (test_bit(FLG_MOD128, &l2->flag)) { - PollFlag = (skb->data[1] & 0x1) == 0x1; - nr = skb->data[1] >> 1; - } else { - PollFlag = (skb->data[0] & 0x10); - nr = (skb->data[0] >> 5) & 0x7; - } - dev_kfree_skb(skb); - - if (PollFlag) { - if (rsp) - l2mgr(l2, MDL_ERROR_IND, (void *) 'A'); - else - enquiry_response(l2); - } - if (legalnr(l2, nr)) { - if (typ == REJ) { - setva(l2, nr); - invoke_retransmission(l2, nr); - stop_t200(l2, 10); - if (mISDN_FsmAddTimer(&l2->t203, l2->T203, - EV_L2_T203, NULL, 6)) - l2m_debug(&l2->l2m, "Restart T203 ST7 REJ"); - } else if ((nr == l2->vs) && (typ == RR)) { - setva(l2, nr); - stop_t200(l2, 11); - mISDN_FsmRestartTimer(&l2->t203, l2->T203, - EV_L2_T203, NULL, 7); - } else if ((l2->va != nr) || (typ == RNR)) { - setva(l2, nr); - if (typ != RR) - mISDN_FsmDelTimer(&l2->t203, 9); - restart_t200(l2, 12); - } - if (skb_queue_len(&l2->i_queue) && (typ == RR)) - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL); - } else - nrerrorrecovery(fi); -} - -static void -l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - if (!test_bit(FLG_L3_INIT, &l2->flag)) - skb_queue_tail(&l2->i_queue, skb); - else - dev_kfree_skb(skb); -} - -static void -l2_feed_i_pull(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_tail(&l2->i_queue, skb); - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL); -} - -static void -l2_feed_iqueue(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_tail(&l2->i_queue, skb); -} - -static void -l2_got_iframe(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - int PollFlag, i; - u_int ns, nr; - - i = l2addrsize(l2); - if (test_bit(FLG_MOD128, &l2->flag)) { - PollFlag = ((skb->data[i + 1] & 0x1) == 0x1); - ns = skb->data[i] >> 1; - nr = (skb->data[i + 1] >> 1) & 0x7f; - } else { - PollFlag = (skb->data[i] & 0x10); - ns = (skb->data[i] >> 1) & 0x7; - nr = (skb->data[i] >> 5) & 0x7; - } - if (test_bit(FLG_OWN_BUSY, &l2->flag)) { - dev_kfree_skb(skb); - if (PollFlag) - enquiry_response(l2); - } else { - if (l2->vr == ns) { - l2->vr++; - if (test_bit(FLG_MOD128, &l2->flag)) - l2->vr %= 128; - else - l2->vr %= 8; - test_and_clear_bit(FLG_REJEXC, &l2->flag); - if (PollFlag) - enquiry_response(l2); - else - test_and_set_bit(FLG_ACK_PEND, &l2->flag); - skb_pull(skb, l2headersize(l2, 0)); - l2up(l2, DL_DATA_IND, skb); - } else { - /* n(s)!=v(r) */ - dev_kfree_skb(skb); - if (test_and_set_bit(FLG_REJEXC, &l2->flag)) { - if (PollFlag) - enquiry_response(l2); - } else { - enquiry_cr(l2, REJ, RSP, PollFlag); - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); - } - } - } - if (legalnr(l2, nr)) { - if (!test_bit(FLG_PEER_BUSY, &l2->flag) && - (fi->state == ST_L2_7)) { - if (nr == l2->vs) { - stop_t200(l2, 13); - mISDN_FsmRestartTimer(&l2->t203, l2->T203, - EV_L2_T203, NULL, 7); - } else if (nr != l2->va) - restart_t200(l2, 14); - } - setva(l2, nr); - } else { - nrerrorrecovery(fi); - return; - } - if (skb_queue_len(&l2->i_queue) && (fi->state == ST_L2_7)) - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL); - if (test_and_clear_bit(FLG_ACK_PEND, &l2->flag)) - enquiry_cr(l2, RR, RSP, 0); -} - -static void -l2_got_tei(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - u_int info; - - l2->tei = (signed char)(long)arg; - set_channel_address(&l2->ch, l2->sapi, l2->tei); - info = DL_INFO_L2_CONNECT; - l2up_create(l2, DL_INFORMATION_IND, sizeof(info), &info); - if (fi->state == ST_L2_3) { - establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &l2->flag); - } else - mISDN_FsmChangeState(fi, ST_L2_4); - if (skb_queue_len(&l2->ui_queue)) - tx_ui(l2); -} - -static void -l2_st5_tout_200(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - if (test_bit(FLG_LAPD, &l2->flag) && - test_bit(FLG_DCHAN_BUSY, &l2->flag)) { - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9); - } else if (l2->rc == l2->N200) { - mISDN_FsmChangeState(fi, ST_L2_4); - test_and_clear_bit(FLG_T200_RUN, &l2->flag); - skb_queue_purge(&l2->i_queue); - l2mgr(l2, MDL_ERROR_IND, (void *) 'G'); - if (test_bit(FLG_LAPB, &l2->flag)) - l2down_create(l2, PH_DEACTIVATE_REQ, - l2_newid(l2), 0, NULL); - st5_dl_release_l2l3(l2); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); - } else { - l2->rc++; - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9); - send_uframe(l2, NULL, (test_bit(FLG_MOD128, &l2->flag) ? - SABME : SABM) | 0x10, CMD); - } -} - -static void -l2_st6_tout_200(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - if (test_bit(FLG_LAPD, &l2->flag) && - test_bit(FLG_DCHAN_BUSY, &l2->flag)) { - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9); - } else if (l2->rc == l2->N200) { - mISDN_FsmChangeState(fi, ST_L2_4); - test_and_clear_bit(FLG_T200_RUN, &l2->flag); - l2mgr(l2, MDL_ERROR_IND, (void *) 'H'); - lapb_dl_release_l2l3(l2, DL_RELEASE_CNF); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); - } else { - l2->rc++; - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, - NULL, 9); - send_uframe(l2, NULL, DISC | 0x10, CMD); - } -} - -static void -l2_st7_tout_200(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - if (test_bit(FLG_LAPD, &l2->flag) && - test_bit(FLG_DCHAN_BUSY, &l2->flag)) { - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9); - return; - } - test_and_clear_bit(FLG_T200_RUN, &l2->flag); - l2->rc = 0; - mISDN_FsmChangeState(fi, ST_L2_8); - transmit_enquiry(l2); - l2->rc++; -} - -static void -l2_st8_tout_200(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - if (test_bit(FLG_LAPD, &l2->flag) && - test_bit(FLG_DCHAN_BUSY, &l2->flag)) { - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9); - return; - } - test_and_clear_bit(FLG_T200_RUN, &l2->flag); - if (l2->rc == l2->N200) { - l2mgr(l2, MDL_ERROR_IND, (void *) 'I'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &l2->flag); - } else { - transmit_enquiry(l2); - l2->rc++; - } -} - -static void -l2_st7_tout_203(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - if (test_bit(FLG_LAPD, &l2->flag) && - test_bit(FLG_DCHAN_BUSY, &l2->flag)) { - mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 9); - return; - } - mISDN_FsmChangeState(fi, ST_L2_8); - transmit_enquiry(l2); - l2->rc = 0; -} - -static void -l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb, *nskb, *oskb; - u_char header[MAX_L2HEADER_LEN]; - u_int i, p1; - - if (!cansend(l2)) - return; - - skb = skb_dequeue(&l2->i_queue); - if (!skb) - return; - - if (test_bit(FLG_MOD128, &l2->flag)) - p1 = (l2->vs - l2->va) % 128; - else - p1 = (l2->vs - l2->va) % 8; - p1 = (p1 + l2->sow) % l2->window; - if (l2->windowar[p1]) { - printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n", - p1); - dev_kfree_skb(l2->windowar[p1]); - } - l2->windowar[p1] = skb; - i = sethdraddr(l2, header, CMD); - if (test_bit(FLG_MOD128, &l2->flag)) { - header[i++] = l2->vs << 1; - header[i++] = l2->vr << 1; - l2->vs = (l2->vs + 1) % 128; - } else { - header[i++] = (l2->vr << 5) | (l2->vs << 1); - l2->vs = (l2->vs + 1) % 8; - } - - nskb = skb_clone(skb, GFP_ATOMIC); - p1 = skb_headroom(nskb); - if (p1 >= i) - memcpy(skb_push(nskb, i), header, i); - else { - printk(KERN_WARNING - "isdnl2 pull_iqueue skb header(%d/%d) too short\n", i, p1); - oskb = nskb; - nskb = mI_alloc_skb(oskb->len + i, GFP_ATOMIC); - if (!nskb) { - dev_kfree_skb(oskb); - printk(KERN_WARNING "%s: no skb mem\n", __func__); - return; - } - memcpy(skb_put(nskb, i), header, i); - memcpy(skb_put(nskb, oskb->len), oskb->data, oskb->len); - dev_kfree_skb(oskb); - } - l2down(l2, PH_DATA_REQ, l2_newid(l2), nskb); - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); - if (!test_and_set_bit(FLG_T200_RUN, &l2->flag)) { - mISDN_FsmDelTimer(&l2->t203, 13); - mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 11); - } -} - -static void -l2_st8_got_super(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - int PollFlag, rsp, rnr = 0; - unsigned int nr; - - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; - - skb_pull(skb, l2addrsize(l2)); - - if (IsRNR(skb->data, l2)) { - set_peer_busy(l2); - rnr = 1; - } else - clear_peer_busy(l2); - - if (test_bit(FLG_MOD128, &l2->flag)) { - PollFlag = (skb->data[1] & 0x1) == 0x1; - nr = skb->data[1] >> 1; - } else { - PollFlag = (skb->data[0] & 0x10); - nr = (skb->data[0] >> 5) & 0x7; - } - dev_kfree_skb(skb); - if (rsp && PollFlag) { - if (legalnr(l2, nr)) { - if (rnr) { - restart_t200(l2, 15); - } else { - stop_t200(l2, 16); - mISDN_FsmAddTimer(&l2->t203, l2->T203, - EV_L2_T203, NULL, 5); - setva(l2, nr); - } - invoke_retransmission(l2, nr); - mISDN_FsmChangeState(fi, ST_L2_7); - if (skb_queue_len(&l2->i_queue) && cansend(l2)) - mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL); - } else - nrerrorrecovery(fi); - } else { - if (!rsp && PollFlag) - enquiry_response(l2); - if (legalnr(l2, nr)) - setva(l2, nr); - else - nrerrorrecovery(fi); - } -} - -static void -l2_got_FRMR(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_pull(skb, l2addrsize(l2) + 1); - - if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */ - (IsUA(skb->data) && (fi->state == ST_L2_7))) { - l2mgr(l2, MDL_ERROR_IND, (void *) 'K'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &l2->flag); - } - dev_kfree_skb(skb); -} - -static void -l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - skb_queue_purge(&l2->ui_queue); - l2->tei = GROUP_TEI; - mISDN_FsmChangeState(fi, ST_L2_1); -} - -static void -l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - skb_queue_purge(&l2->ui_queue); - l2->tei = GROUP_TEI; - l2up_create(l2, DL_RELEASE_IND, 0, NULL); - mISDN_FsmChangeState(fi, ST_L2_1); -} - -static void -l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - skb_queue_purge(&l2->i_queue); - skb_queue_purge(&l2->ui_queue); - freewin(l2); - l2->tei = GROUP_TEI; - stop_t200(l2, 17); - st5_dl_release_l2l3(l2); - mISDN_FsmChangeState(fi, ST_L2_1); -} - -static void -l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - skb_queue_purge(&l2->ui_queue); - l2->tei = GROUP_TEI; - stop_t200(l2, 18); - l2up_create(l2, DL_RELEASE_IND, 0, NULL); - mISDN_FsmChangeState(fi, ST_L2_1); -} - -static void -l2_tei_remove(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - skb_queue_purge(&l2->i_queue); - skb_queue_purge(&l2->ui_queue); - freewin(l2); - l2->tei = GROUP_TEI; - stop_t200(l2, 17); - mISDN_FsmDelTimer(&l2->t203, 19); - l2up_create(l2, DL_RELEASE_IND, 0, NULL); -/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST, - * MGR_SHORTSTATUS_IND, SSTATUS_L2_RELEASED, - * 0, NULL, 0); - */ - mISDN_FsmChangeState(fi, ST_L2_1); -} - -static void -l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_purge(&l2->i_queue); - skb_queue_purge(&l2->ui_queue); - if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag)) - l2up(l2, DL_RELEASE_IND, skb); - else - dev_kfree_skb(skb); -} - -static void -l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_purge(&l2->i_queue); - skb_queue_purge(&l2->ui_queue); - freewin(l2); - stop_t200(l2, 19); - st5_dl_release_l2l3(l2); - mISDN_FsmChangeState(fi, ST_L2_4); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); - dev_kfree_skb(skb); -} - -static void -l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_purge(&l2->ui_queue); - stop_t200(l2, 20); - l2up(l2, DL_RELEASE_CNF, skb); - mISDN_FsmChangeState(fi, ST_L2_4); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); -} - -static void -l2_persistant_da(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - skb_queue_purge(&l2->i_queue); - skb_queue_purge(&l2->ui_queue); - freewin(l2); - stop_t200(l2, 19); - mISDN_FsmDelTimer(&l2->t203, 19); - l2up(l2, DL_RELEASE_IND, skb); - mISDN_FsmChangeState(fi, ST_L2_4); - if (l2->tm) - l2_tei(l2, MDL_STATUS_DOWN_IND, 0); -} - -static void -l2_set_own_busy(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - if (!test_and_set_bit(FLG_OWN_BUSY, &l2->flag)) { - enquiry_cr(l2, RNR, RSP, 0); - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); - } - if (skb) - dev_kfree_skb(skb); -} - -static void -l2_clear_own_busy(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - struct sk_buff *skb = arg; - - if (!test_and_clear_bit(FLG_OWN_BUSY, &l2->flag)) { - enquiry_cr(l2, RR, RSP, 0); - test_and_clear_bit(FLG_ACK_PEND, &l2->flag); - } - if (skb) - dev_kfree_skb(skb); -} - -static void -l2_frame_error(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - l2mgr(l2, MDL_ERROR_IND, arg); -} - -static void -l2_frame_error_reest(struct FsmInst *fi, int event, void *arg) -{ - struct layer2 *l2 = fi->userdata; - - l2mgr(l2, MDL_ERROR_IND, arg); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &l2->flag); -} - -static struct FsmNode L2FnList[] = -{ - {ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign}, - {ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3}, - {ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish}, - {ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3}, - {ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, - {ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, - {ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release}, - {ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel}, - {ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect}, - {ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect}, - {ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest}, - {ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull}, - {ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue}, - {ST_L2_1, EV_L2_DL_UNITDATA, l2_queue_ui_assign}, - {ST_L2_2, EV_L2_DL_UNITDATA, l2_queue_ui}, - {ST_L2_3, EV_L2_DL_UNITDATA, l2_queue_ui}, - {ST_L2_4, EV_L2_DL_UNITDATA, l2_send_ui}, - {ST_L2_5, EV_L2_DL_UNITDATA, l2_send_ui}, - {ST_L2_6, EV_L2_DL_UNITDATA, l2_send_ui}, - {ST_L2_7, EV_L2_DL_UNITDATA, l2_send_ui}, - {ST_L2_8, EV_L2_DL_UNITDATA, l2_send_ui}, - {ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei}, - {ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei}, - {ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei}, - {ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove}, - {ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove}, - {ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove}, - {ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove}, - {ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove}, - {ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove}, - {ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove}, - {ST_L2_4, EV_L2_SABME, l2_start_multi}, - {ST_L2_5, EV_L2_SABME, l2_send_UA}, - {ST_L2_6, EV_L2_SABME, l2_send_DM}, - {ST_L2_7, EV_L2_SABME, l2_restart_multi}, - {ST_L2_8, EV_L2_SABME, l2_restart_multi}, - {ST_L2_4, EV_L2_DISC, l2_send_DM}, - {ST_L2_5, EV_L2_DISC, l2_send_DM}, - {ST_L2_6, EV_L2_DISC, l2_send_UA}, - {ST_L2_7, EV_L2_DISC, l2_stop_multi}, - {ST_L2_8, EV_L2_DISC, l2_stop_multi}, - {ST_L2_4, EV_L2_UA, l2_mdl_error_ua}, - {ST_L2_5, EV_L2_UA, l2_connected}, - {ST_L2_6, EV_L2_UA, l2_released}, - {ST_L2_7, EV_L2_UA, l2_mdl_error_ua}, - {ST_L2_8, EV_L2_UA, l2_mdl_error_ua}, - {ST_L2_4, EV_L2_DM, l2_reestablish}, - {ST_L2_5, EV_L2_DM, l2_st5_dm_release}, - {ST_L2_6, EV_L2_DM, l2_st6_dm_release}, - {ST_L2_7, EV_L2_DM, l2_mdl_error_dm}, - {ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm}, - {ST_L2_1, EV_L2_UI, l2_got_ui}, - {ST_L2_2, EV_L2_UI, l2_got_ui}, - {ST_L2_3, EV_L2_UI, l2_got_ui}, - {ST_L2_4, EV_L2_UI, l2_got_ui}, - {ST_L2_5, EV_L2_UI, l2_got_ui}, - {ST_L2_6, EV_L2_UI, l2_got_ui}, - {ST_L2_7, EV_L2_UI, l2_got_ui}, - {ST_L2_8, EV_L2_UI, l2_got_ui}, - {ST_L2_7, EV_L2_FRMR, l2_got_FRMR}, - {ST_L2_8, EV_L2_FRMR, l2_got_FRMR}, - {ST_L2_7, EV_L2_SUPER, l2_st7_got_super}, - {ST_L2_8, EV_L2_SUPER, l2_st8_got_super}, - {ST_L2_7, EV_L2_I, l2_got_iframe}, - {ST_L2_8, EV_L2_I, l2_got_iframe}, - {ST_L2_5, EV_L2_T200, l2_st5_tout_200}, - {ST_L2_6, EV_L2_T200, l2_st6_tout_200}, - {ST_L2_7, EV_L2_T200, l2_st7_tout_200}, - {ST_L2_8, EV_L2_T200, l2_st8_tout_200}, - {ST_L2_7, EV_L2_T203, l2_st7_tout_203}, - {ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue}, - {ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, - {ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, - {ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, - {ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, - {ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error}, - {ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error}, - {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_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_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)) - -static int -ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) -{ - u_char *datap = skb->data; - int ret = -EINVAL; - int psapi, ptei; - u_int l; - int c = 0; - - l = l2addrsize(l2); - if (skb->len <= l) { - mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N'); - return ret; - } - if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */ - psapi = *datap++; - ptei = *datap++; - if ((psapi & 1) || !(ptei & 1)) { - printk(KERN_WARNING - "l2 D-channel frame wrong EA0/EA1\n"); - return ret; - } - psapi >>= 2; - ptei >>= 1; - if (psapi != l2->sapi) { - /* not our bussiness - * printk(KERN_DEBUG "%s: sapi %d/%d sapi mismatch\n", - * __func__, - * psapi, l2->sapi); - */ - dev_kfree_skb(skb); - return 0; - } - if ((ptei != l2->tei) && (ptei != GROUP_TEI)) { - /* not our bussiness - * printk(KERN_DEBUG "%s: tei %d/%d sapi %d mismatch\n", - * __func__, - * ptei, l2->tei, psapi); - */ - dev_kfree_skb(skb); - return 0; - } - } else - datap += l; - if (!(*datap & 1)) { /* I-Frame */ - c = iframe_error(l2, skb); - if (!c) - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_I, skb); - } else if (IsSFrame(datap, l2)) { /* S-Frame */ - c = super_error(l2, skb); - if (!c) - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SUPER, skb); - } else if (IsUI(datap)) { - c = UI_error(l2, skb); - if (!c) - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb); - } else if (IsSABME(datap, l2)) { - c = unnum_error(l2, skb, CMD); - if (!c) - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb); - } else if (IsUA(datap)) { - c = unnum_error(l2, skb, RSP); - if (!c) - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UA, skb); - } else if (IsDISC(datap)) { - c = unnum_error(l2, skb, CMD); - if (!c) - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DISC, skb); - } else if (IsDM(datap)) { - c = unnum_error(l2, skb, RSP); - if (!c) - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DM, skb); - } else if (IsFRMR(datap)) { - c = FRMR_error(l2, skb); - if (!c) - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_FRMR, skb); - } else - c = 'L'; - if (c) { - printk(KERN_WARNING "l2 D-channel frame error %c\n", c); - mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *)(long)c); - } - return ret; -} - -static int -l2_send(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct layer2 *l2 = container_of(ch, struct layer2, ch); - struct mISDNhead *hh = mISDN_HEAD_P(skb); - int ret = -EINVAL; - - if (*debug & DEBUG_L2_RECV) - printk(KERN_DEBUG "%s: prim(%x) id(%x) tei(%d)\n", - __func__, hh->prim, hh->id, l2->tei); - switch (hh->prim) { - case PH_DATA_IND: - ret = ph_data_indication(l2, hh, skb); - break; - case PH_DATA_CNF: - ret = ph_data_confirm(l2, hh, skb); - break; - case PH_ACTIVATE_IND: - test_and_set_bit(FLG_L1_ACTIV, &l2->flag); - l2up_create(l2, MPH_ACTIVATE_IND, 0, NULL); - if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag)) - ret = mISDN_FsmEvent(&l2->l2m, - EV_L2_DL_ESTABLISH_REQ, skb); - break; - case PH_DEACTIVATE_IND: - test_and_clear_bit(FLG_L1_ACTIV, &l2->flag); - l2up_create(l2, MPH_DEACTIVATE_IND, 0, NULL); - ret = mISDN_FsmEvent(&l2->l2m, EV_L1_DEACTIVATE, skb); - break; - case MPH_INFORMATION_IND: - if (!l2->up) - break; - ret = l2->up->send(l2->up, skb); - break; - case DL_DATA_REQ: - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_DATA, skb); - break; - case DL_UNITDATA_REQ: - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_UNITDATA, skb); - break; - case DL_ESTABLISH_REQ: - if (test_bit(FLG_LAPB, &l2->flag)) - test_and_set_bit(FLG_ORIG, &l2->flag); - if (test_bit(FLG_L1_ACTIV, &l2->flag)) { - if (test_bit(FLG_LAPD, &l2->flag) || - test_bit(FLG_ORIG, &l2->flag)) - ret = mISDN_FsmEvent(&l2->l2m, - EV_L2_DL_ESTABLISH_REQ, skb); - } else { - if (test_bit(FLG_LAPD, &l2->flag) || - test_bit(FLG_ORIG, &l2->flag)) { - test_and_set_bit(FLG_ESTAB_PEND, - &l2->flag); - } - ret = l2down(l2, PH_ACTIVATE_REQ, l2_newid(l2), - skb); - } - break; - case DL_RELEASE_REQ: - if (test_bit(FLG_LAPB, &l2->flag)) - l2down_create(l2, PH_DEACTIVATE_REQ, - l2_newid(l2), 0, NULL); - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_RELEASE_REQ, - skb); - break; - default: - if (*debug & DEBUG_L2) - l2m_debug(&l2->l2m, "l2 unknown pr %04x", - hh->prim); - } - if (ret) { - dev_kfree_skb(skb); - ret = 0; - } - return ret; -} - -int -tei_l2(struct layer2 *l2, u_int cmd, u_long arg) -{ - int ret = -EINVAL; - - if (*debug & DEBUG_L2_TEI) - printk(KERN_DEBUG "%s: cmd(%x)\n", __func__, cmd); - switch (cmd) { - case (MDL_ASSIGN_REQ): - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ASSIGN, (void *)arg); - break; - case (MDL_REMOVE_REQ): - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_REMOVE, NULL); - break; - case (MDL_ERROR_IND): - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL); - break; - case (MDL_ERROR_RSP): - /* ETS 300-125 5.3.2.1 Test: TC13010 */ - printk(KERN_NOTICE "MDL_ERROR|REQ (tei_l2)\n"); - ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL); - break; - } - return ret; -} - -static void -release_l2(struct layer2 *l2) -{ - mISDN_FsmDelTimer(&l2->t200, 21); - mISDN_FsmDelTimer(&l2->t203, 16); - skb_queue_purge(&l2->i_queue); - skb_queue_purge(&l2->ui_queue); - skb_queue_purge(&l2->down_queue); - ReleaseWin(l2); - if (test_bit(FLG_LAPD, &l2->flag)) { - TEIrelease(l2); - if (l2->ch.st) - l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, - CLOSE_CHANNEL, NULL); - } - kfree(l2); -} - -static int -l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct layer2 *l2 = container_of(ch, struct layer2, ch); - u_int info; - - if (*debug & DEBUG_L2_CTRL) - printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd); - - switch (cmd) { - case OPEN_CHANNEL: - if (test_bit(FLG_LAPD, &l2->flag)) { - set_channel_address(&l2->ch, l2->sapi, l2->tei); - info = DL_INFO_L2_CONNECT; - l2up_create(l2, DL_INFORMATION_IND, - sizeof(info), &info); - } - break; - case CLOSE_CHANNEL: - if (l2->ch.peer) - l2->ch.peer->ctrl(l2->ch.peer, CLOSE_CHANNEL, NULL); - release_l2(l2); - break; - } - return 0; -} - -struct layer2 * -create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) -{ - struct layer2 *l2; - struct channel_req rq; - - l2 = kzalloc(sizeof(struct layer2), GFP_KERNEL); - if (!l2) { - printk(KERN_ERR "kzalloc layer2 failed\n"); - return NULL; - } - l2->next_id = 1; - l2->down_id = MISDN_ID_NONE; - l2->up = ch; - l2->ch.st = ch->st; - l2->ch.send = l2_send; - l2->ch.ctrl = l2_ctrl; - switch (protocol) { - case ISDN_P_LAPD_NT: - test_and_set_bit(FLG_LAPD, &l2->flag); - test_and_set_bit(FLG_LAPD_NET, &l2->flag); - test_and_set_bit(FLG_MOD128, &l2->flag); - l2->sapi = 0; - l2->maxlen = MAX_DFRAME_LEN; - if (test_bit(OPTION_L2_PMX, &options)) - l2->window = 7; - else - l2->window = 1; - if (test_bit(OPTION_L2_PTP, &options)) - test_and_set_bit(FLG_PTP, &l2->flag); - if (test_bit(OPTION_L2_FIXEDTEI, &options)) - test_and_set_bit(FLG_FIXED_TEI, &l2->flag); - l2->tei = (u_int)arg; - l2->T200 = 1000; - l2->N200 = 3; - l2->T203 = 10000; - if (test_bit(OPTION_L2_PMX, &options)) - rq.protocol = ISDN_P_NT_E1; - else - rq.protocol = ISDN_P_NT_S0; - rq.adr.channel = 0; - l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq); - break; - case ISDN_P_LAPD_TE: - test_and_set_bit(FLG_LAPD, &l2->flag); - test_and_set_bit(FLG_MOD128, &l2->flag); - test_and_set_bit(FLG_ORIG, &l2->flag); - l2->sapi = 0; - l2->maxlen = MAX_DFRAME_LEN; - if (test_bit(OPTION_L2_PMX, &options)) - l2->window = 7; - else - l2->window = 1; - if (test_bit(OPTION_L2_PTP, &options)) - test_and_set_bit(FLG_PTP, &l2->flag); - if (test_bit(OPTION_L2_FIXEDTEI, &options)) - test_and_set_bit(FLG_FIXED_TEI, &l2->flag); - l2->tei = (u_int)arg; - l2->T200 = 1000; - l2->N200 = 3; - l2->T203 = 10000; - if (test_bit(OPTION_L2_PMX, &options)) - rq.protocol = ISDN_P_TE_E1; - else - rq.protocol = ISDN_P_TE_S0; - rq.adr.channel = 0; - l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq); - break; - case ISDN_P_B_X75SLP: - test_and_set_bit(FLG_LAPB, &l2->flag); - l2->window = 7; - l2->maxlen = MAX_DATA_SIZE; - l2->T200 = 1000; - l2->N200 = 4; - l2->T203 = 5000; - l2->addr.A = 3; - l2->addr.B = 1; - break; - default: - printk(KERN_ERR "layer2 create failed prt %x\n", - protocol); - kfree(l2); - return NULL; - } - skb_queue_head_init(&l2->i_queue); - skb_queue_head_init(&l2->ui_queue); - skb_queue_head_init(&l2->down_queue); - skb_queue_head_init(&l2->tmp_queue); - InitWin(l2); - l2->l2m.fsm = &l2fsm; - if (test_bit(FLG_LAPB, &l2->flag) || - test_bit(FLG_PTP, &l2->flag) || - test_bit(FLG_LAPD_NET, &l2->flag)) - l2->l2m.state = ST_L2_4; - else - l2->l2m.state = ST_L2_1; - l2->l2m.debug = *debug; - l2->l2m.userdata = l2; - l2->l2m.userint = 0; - l2->l2m.printdebug = l2m_debug; - - mISDN_FsmInitTimer(&l2->l2m, &l2->t200); - mISDN_FsmInitTimer(&l2->l2m, &l2->t203); - return l2; -} - -static int -x75create(struct channel_req *crq) -{ - struct layer2 *l2; - - if (crq->protocol != ISDN_P_B_X75SLP) - return -EPROTONOSUPPORT; - l2 = create_l2(crq->ch, crq->protocol, 0, 0); - if (!l2) - return -ENOMEM; - crq->ch = &l2->ch; - crq->protocol = ISDN_P_B_HDLC; - return 0; -} - -static struct Bprotocol X75SLP = { - .Bprotocols = (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK)), - .name = "X75SLP", - .create = x75create -}; - -int -Isdnl2_Init(u_int *deb) -{ - debug = deb; - mISDN_register_Bprotocol(&X75SLP); - l2fsm.state_count = L2_STATE_COUNT; - l2fsm.event_count = L2_EVENT_COUNT; - l2fsm.strEvent = strL2Event; - l2fsm.strState = strL2State; - mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList)); - TEIInit(deb); - return 0; -} - -void -Isdnl2_cleanup(void) -{ - mISDN_unregister_Bprotocol(&X75SLP); - TEIFree(); - mISDN_FsmFree(&l2fsm); -} - diff --git a/trunk/drivers/isdn/mISDN/layer2.h b/trunk/drivers/isdn/mISDN/layer2.h deleted file mode 100644 index 6293f80dc2d3..000000000000 --- a/trunk/drivers/isdn/mISDN/layer2.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Layer 2 defines - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#include -#include -#include "fsm.h" - -#define MAX_WINDOW 8 - -struct manager { - struct mISDNchannel ch; - struct mISDNchannel bcast; - u_long options; - struct list_head layer2; - rwlock_t lock; - struct FsmInst deact; - struct FsmTimer datimer; - struct sk_buff_head sendq; - struct mISDNchannel *up; - u_int nextid; - u_int lastid; -}; - -struct teimgr { - int ri; - int rcnt; - struct FsmInst tei_m; - struct FsmTimer timer; - int tval, nval; - struct layer2 *l2; - struct manager *mgr; -}; - -struct laddr { - u_char A; - u_char B; -}; - -struct layer2 { - struct list_head list; - struct mISDNchannel ch; - u_long flag; - int id; - struct mISDNchannel *up; - signed char sapi; - signed char tei; - struct laddr addr; - u_int maxlen; - struct teimgr *tm; - u_int vs, va, vr; - int rc; - u_int window; - u_int sow; - struct FsmInst l2m; - struct FsmTimer t200, t203; - int T200, N200, T203; - u_int next_id; - u_int down_id; - struct sk_buff *windowar[MAX_WINDOW]; - struct sk_buff_head i_queue; - struct sk_buff_head ui_queue; - struct sk_buff_head down_queue; - struct sk_buff_head tmp_queue; -}; - -enum { - ST_L2_1, - ST_L2_2, - ST_L2_3, - ST_L2_4, - ST_L2_5, - ST_L2_6, - ST_L2_7, - ST_L2_8, -}; - -#define L2_STATE_COUNT (ST_L2_8+1) - -extern struct layer2 *create_l2(struct mISDNchannel *, u_int, - u_long, u_long); -extern int tei_l2(struct layer2 *, u_int, u_long arg); - - -/* from tei.c */ -extern int l2_tei(struct layer2 *, u_int, u_long arg); -extern void TEIrelease(struct layer2 *); -extern int TEIInit(u_int *); -extern void TEIFree(void); - -#define MAX_L2HEADER_LEN 4 - -#define RR 0x01 -#define RNR 0x05 -#define REJ 0x09 -#define SABME 0x6f -#define SABM 0x2f -#define DM 0x0f -#define UI 0x03 -#define DISC 0x43 -#define UA 0x63 -#define FRMR 0x87 -#define XID 0xaf - -#define CMD 0 -#define RSP 1 - -#define LC_FLUSH_WAIT 1 - -#define FLG_LAPB 0 -#define FLG_LAPD 1 -#define FLG_ORIG 2 -#define FLG_MOD128 3 -#define FLG_PEND_REL 4 -#define FLG_L3_INIT 5 -#define FLG_T200_RUN 6 -#define FLG_ACK_PEND 7 -#define FLG_REJEXC 8 -#define FLG_OWN_BUSY 9 -#define FLG_PEER_BUSY 10 -#define FLG_DCHAN_BUSY 11 -#define FLG_L1_ACTIV 12 -#define FLG_ESTAB_PEND 13 -#define FLG_PTP 14 -#define FLG_FIXED_TEI 15 -#define FLG_L2BLOCK 16 -#define FLG_L1_NOTREADY 17 -#define FLG_LAPD_NET 18 diff --git a/trunk/drivers/isdn/mISDN/socket.c b/trunk/drivers/isdn/mISDN/socket.c deleted file mode 100644 index 4ba4cc364c9e..000000000000 --- a/trunk/drivers/isdn/mISDN/socket.c +++ /dev/null @@ -1,781 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#include -#include "core.h" - -static int *debug; - -static struct proto mISDN_proto = { - .name = "misdn", - .owner = THIS_MODULE, - .obj_size = sizeof(struct mISDN_sock) -}; - -#define _pms(sk) ((struct mISDN_sock *)sk) - -static struct mISDN_sock_list data_sockets = { - .lock = __RW_LOCK_UNLOCKED(data_sockets.lock) -}; - -static struct mISDN_sock_list base_sockets = { - .lock = __RW_LOCK_UNLOCKED(base_sockets.lock) -}; - -#define L2_HEADER_LEN 4 - -static inline struct sk_buff * -_l2_alloc_skb(unsigned int len, gfp_t gfp_mask) -{ - struct sk_buff *skb; - - skb = alloc_skb(len + L2_HEADER_LEN, gfp_mask); - if (likely(skb)) - skb_reserve(skb, L2_HEADER_LEN); - return skb; -} - -static void -mISDN_sock_link(struct mISDN_sock_list *l, struct sock *sk) -{ - write_lock_bh(&l->lock); - sk_add_node(sk, &l->head); - write_unlock_bh(&l->lock); -} - -static void mISDN_sock_unlink(struct mISDN_sock_list *l, struct sock *sk) -{ - write_lock_bh(&l->lock); - sk_del_node_init(sk); - write_unlock_bh(&l->lock); -} - -static int -mISDN_send(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct mISDN_sock *msk; - int err; - - msk = container_of(ch, struct mISDN_sock, ch); - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s len %d %p\n", __func__, skb->len, skb); - if (msk->sk.sk_state == MISDN_CLOSED) - return -EUNATCH; - __net_timestamp(skb); - err = sock_queue_rcv_skb(&msk->sk, skb); - if (err) - printk(KERN_WARNING "%s: error %d\n", __func__, err); - return err; -} - -static int -mISDN_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct mISDN_sock *msk; - - msk = container_of(ch, struct mISDN_sock, ch); - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s(%p, %x, %p)\n", __func__, ch, cmd, arg); - switch (cmd) { - case CLOSE_CHANNEL: - msk->sk.sk_state = MISDN_CLOSED; - break; - } - return 0; -} - -static inline void -mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) -{ - struct timeval tv; - - if (_pms(sk)->cmask & MISDN_TIME_STAMP) { - skb_get_timestamp(skb, &tv); - put_cmsg(msg, SOL_MISDN, MISDN_TIME_STAMP, sizeof(tv), &tv); - } -} - -static int -mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) -{ - struct sk_buff *skb; - struct sock *sk = sock->sk; - struct sockaddr_mISDN *maddr; - - int copied, err; - - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s: len %d, flags %x ch.nr %d, proto %x\n", - __func__, (int)len, flags, _pms(sk)->ch.nr, - sk->sk_protocol); - if (flags & (MSG_OOB)) - return -EOPNOTSUPP; - - if (sk->sk_state == MISDN_CLOSED) - return 0; - - skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); - if (!skb) - return err; - - if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) { - msg->msg_namelen = sizeof(struct sockaddr_mISDN); - maddr = (struct sockaddr_mISDN *)msg->msg_name; - maddr->family = AF_ISDN; - maddr->dev = _pms(sk)->dev->id; - if ((sk->sk_protocol == ISDN_P_LAPD_TE) || - (sk->sk_protocol == ISDN_P_LAPD_NT)) { - maddr->channel = (mISDN_HEAD_ID(skb) >> 16) & 0xff; - maddr->tei = (mISDN_HEAD_ID(skb) >> 8) & 0xff; - maddr->sapi = mISDN_HEAD_ID(skb) & 0xff; - } else { - maddr->channel = _pms(sk)->ch.nr; - maddr->sapi = _pms(sk)->ch.addr & 0xFF; - maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF; - } - } else { - if (msg->msg_namelen) - printk(KERN_WARNING "%s: too small namelen %d\n", - __func__, msg->msg_namelen); - msg->msg_namelen = 0; - } - - copied = skb->len + MISDN_HEADER_LEN; - if (len < copied) { - if (flags & MSG_PEEK) - atomic_dec(&skb->users); - else - skb_queue_head(&sk->sk_receive_queue, skb); - return -ENOSPC; - } - memcpy(skb_push(skb, MISDN_HEADER_LEN), mISDN_HEAD_P(skb), - MISDN_HEADER_LEN); - - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - - mISDN_sock_cmsg(sk, msg, skb); - - skb_free_datagram(sk, skb); - - return err ? : copied; -} - -static int -mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len) -{ - struct sock *sk = sock->sk; - struct sk_buff *skb; - int err = -ENOMEM; - struct sockaddr_mISDN *maddr; - - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n", - __func__, (int)len, msg->msg_flags, _pms(sk)->ch.nr, - sk->sk_protocol); - - if (msg->msg_flags & MSG_OOB) - return -EOPNOTSUPP; - - if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE)) - return -EINVAL; - - if (len < MISDN_HEADER_LEN) - return -EINVAL; - - if (sk->sk_state != MISDN_BOUND) - return -EBADFD; - - lock_sock(sk); - - skb = _l2_alloc_skb(len, GFP_KERNEL); - if (!skb) - goto done; - - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { - err = -EFAULT; - goto drop; - } - - memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN); - skb_pull(skb, MISDN_HEADER_LEN); - - if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) { - /* if we have a address, we use it */ - maddr = (struct sockaddr_mISDN *)msg->msg_name; - mISDN_HEAD_ID(skb) = maddr->channel; - } else { /* use default for L2 messages */ - if ((sk->sk_protocol == ISDN_P_LAPD_TE) || - (sk->sk_protocol == ISDN_P_LAPD_NT)) - mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr; - } - - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s: ID:%x\n", - __func__, mISDN_HEAD_ID(skb)); - - err = -ENODEV; - if (!_pms(sk)->ch.peer || - (err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb))) - goto drop; - - err = len; - -done: - release_sock(sk); - return err; - -drop: - kfree_skb(skb); - goto done; -} - -static int -data_sock_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk); - if (!sk) - return 0; - switch (sk->sk_protocol) { - case ISDN_P_TE_S0: - case ISDN_P_NT_S0: - case ISDN_P_TE_E1: - case ISDN_P_NT_E1: - if (sk->sk_state == MISDN_BOUND) - delete_channel(&_pms(sk)->ch); - else - mISDN_sock_unlink(&data_sockets, sk); - break; - case ISDN_P_LAPD_TE: - case ISDN_P_LAPD_NT: - case ISDN_P_B_RAW: - case ISDN_P_B_HDLC: - case ISDN_P_B_X75SLP: - case ISDN_P_B_L2DTMF: - case ISDN_P_B_L2DSP: - case ISDN_P_B_L2DSPHDLC: - delete_channel(&_pms(sk)->ch); - mISDN_sock_unlink(&data_sockets, sk); - break; - } - - lock_sock(sk); - - sock_orphan(sk); - skb_queue_purge(&sk->sk_receive_queue); - - release_sock(sk); - sock_put(sk); - - return 0; -} - -static int -data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p) -{ - struct mISDN_ctrl_req cq; - int err = -EINVAL, val; - struct mISDNchannel *bchan, *next; - - lock_sock(sk); - if (!_pms(sk)->dev) { - err = -ENODEV; - goto done; - } - switch (cmd) { - case IMCTRLREQ: - if (copy_from_user(&cq, p, sizeof(cq))) { - err = -EFAULT; - break; - } - if ((sk->sk_protocol & ~ISDN_P_B_MASK) == ISDN_P_B_START) { - list_for_each_entry_safe(bchan, next, - &_pms(sk)->dev->bchannels, list) { - if (bchan->nr == cq.channel) { - err = bchan->ctrl(bchan, - CONTROL_CHANNEL, &cq); - break; - } - } - } else - err = _pms(sk)->dev->D.ctrl(&_pms(sk)->dev->D, - CONTROL_CHANNEL, &cq); - if (err) - break; - if (copy_to_user(p, &cq, sizeof(cq))) - err = -EFAULT; - break; - case IMCLEAR_L2: - if (sk->sk_protocol != ISDN_P_LAPD_NT) { - err = -EINVAL; - break; - } - if (get_user(val, (int __user *)p)) { - err = -EFAULT; - break; - } - err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr, - CONTROL_CHANNEL, &val); - break; - default: - err = -EINVAL; - break; - } -done: - release_sock(sk); - return err; -} - -static int -data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - int err = 0, id; - struct sock *sk = sock->sk; - struct mISDNdevice *dev; - struct mISDNversion ver; - - switch (cmd) { - case IMGETVERSION: - ver.major = MISDN_MAJOR_VERSION; - ver.minor = MISDN_MINOR_VERSION; - ver.release = MISDN_RELEASE; - if (copy_to_user((void __user *)arg, &ver, sizeof(ver))) - err = -EFAULT; - break; - case IMGETCOUNT: - id = get_mdevice_count(); - if (put_user(id, (int __user *)arg)) - err = -EFAULT; - break; - case IMGETDEVINFO: - if (get_user(id, (int __user *)arg)) { - err = -EFAULT; - break; - } - dev = get_mdevice(id); - if (dev) { - struct mISDN_devinfo di; - - di.id = dev->id; - di.Dprotocols = dev->Dprotocols; - di.Bprotocols = dev->Bprotocols | get_all_Bprotocols(); - di.protocol = dev->D.protocol; - memcpy(di.channelmap, dev->channelmap, - MISDN_CHMAP_SIZE * 4); - di.nrbchan = dev->nrbchan; - strcpy(di.name, dev->name); - if (copy_to_user((void __user *)arg, &di, sizeof(di))) - err = -EFAULT; - } else - err = -ENODEV; - break; - default: - if (sk->sk_state == MISDN_BOUND) - err = data_sock_ioctl_bound(sk, cmd, - (void __user *)arg); - else - err = -ENOTCONN; - } - return err; -} - -static int data_sock_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int len) -{ - struct sock *sk = sock->sk; - int err = 0, opt = 0; - - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s(%p, %d, %x, %p, %d)\n", __func__, sock, - level, optname, optval, len); - - lock_sock(sk); - - switch (optname) { - case MISDN_TIME_STAMP: - if (get_user(opt, (int __user *)optval)) { - err = -EFAULT; - break; - } - - if (opt) - _pms(sk)->cmask |= MISDN_TIME_STAMP; - else - _pms(sk)->cmask &= ~MISDN_TIME_STAMP; - break; - default: - err = -ENOPROTOOPT; - break; - } - release_sock(sk); - return err; -} - -static int data_sock_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) -{ - struct sock *sk = sock->sk; - int len, opt; - - if (get_user(len, optlen)) - return -EFAULT; - - switch (optname) { - case MISDN_TIME_STAMP: - if (_pms(sk)->cmask & MISDN_TIME_STAMP) - opt = 1; - else - opt = 0; - - if (put_user(opt, optval)) - return -EFAULT; - break; - default: - return -ENOPROTOOPT; - } - - return 0; -} - -static int -data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) -{ - struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr; - struct sock *sk = sock->sk; - int err = 0; - - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk); - if (addr_len != sizeof(struct sockaddr_mISDN)) - return -EINVAL; - if (!maddr || maddr->family != AF_ISDN) - return -EINVAL; - - lock_sock(sk); - - if (_pms(sk)->dev) { - err = -EALREADY; - goto done; - } - _pms(sk)->dev = get_mdevice(maddr->dev); - if (!_pms(sk)->dev) { - err = -ENODEV; - goto done; - } - _pms(sk)->ch.send = mISDN_send; - _pms(sk)->ch.ctrl = mISDN_ctrl; - - switch (sk->sk_protocol) { - case ISDN_P_TE_S0: - case ISDN_P_NT_S0: - case ISDN_P_TE_E1: - case ISDN_P_NT_E1: - mISDN_sock_unlink(&data_sockets, sk); - err = connect_layer1(_pms(sk)->dev, &_pms(sk)->ch, - sk->sk_protocol, maddr); - if (err) - mISDN_sock_link(&data_sockets, sk); - break; - case ISDN_P_LAPD_TE: - case ISDN_P_LAPD_NT: - err = create_l2entity(_pms(sk)->dev, &_pms(sk)->ch, - sk->sk_protocol, maddr); - break; - case ISDN_P_B_RAW: - case ISDN_P_B_HDLC: - case ISDN_P_B_X75SLP: - case ISDN_P_B_L2DTMF: - case ISDN_P_B_L2DSP: - case ISDN_P_B_L2DSPHDLC: - err = connect_Bstack(_pms(sk)->dev, &_pms(sk)->ch, - sk->sk_protocol, maddr); - break; - default: - err = -EPROTONOSUPPORT; - } - if (err) - goto done; - sk->sk_state = MISDN_BOUND; - _pms(sk)->ch.protocol = sk->sk_protocol; - -done: - release_sock(sk); - return err; -} - -static int -data_sock_getname(struct socket *sock, struct sockaddr *addr, - int *addr_len, int peer) -{ - struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr; - struct sock *sk = sock->sk; - - if (!_pms(sk)->dev) - return -EBADFD; - - lock_sock(sk); - - *addr_len = sizeof(*maddr); - maddr->dev = _pms(sk)->dev->id; - maddr->channel = _pms(sk)->ch.nr; - maddr->sapi = _pms(sk)->ch.addr & 0xff; - maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xff; - release_sock(sk); - return 0; -} - -static const struct proto_ops data_sock_ops = { - .family = PF_ISDN, - .owner = THIS_MODULE, - .release = data_sock_release, - .ioctl = data_sock_ioctl, - .bind = data_sock_bind, - .getname = data_sock_getname, - .sendmsg = mISDN_sock_sendmsg, - .recvmsg = mISDN_sock_recvmsg, - .poll = datagram_poll, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = data_sock_setsockopt, - .getsockopt = data_sock_getsockopt, - .connect = sock_no_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .mmap = sock_no_mmap -}; - -static int -data_sock_create(struct net *net, struct socket *sock, int protocol) -{ - struct sock *sk; - - if (sock->type != SOCK_DGRAM) - return -ESOCKTNOSUPPORT; - - sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto); - if (!sk) - return -ENOMEM; - - sock_init_data(sock, sk); - - sock->ops = &data_sock_ops; - sock->state = SS_UNCONNECTED; - sock_reset_flag(sk, SOCK_ZAPPED); - - sk->sk_protocol = protocol; - sk->sk_state = MISDN_OPEN; - mISDN_sock_link(&data_sockets, sk); - - return 0; -} - -static int -base_sock_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk); - if (!sk) - return 0; - - mISDN_sock_unlink(&base_sockets, sk); - sock_orphan(sk); - sock_put(sk); - - return 0; -} - -static int -base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - int err = 0, id; - struct mISDNdevice *dev; - struct mISDNversion ver; - - switch (cmd) { - case IMGETVERSION: - ver.major = MISDN_MAJOR_VERSION; - ver.minor = MISDN_MINOR_VERSION; - ver.release = MISDN_RELEASE; - if (copy_to_user((void __user *)arg, &ver, sizeof(ver))) - err = -EFAULT; - break; - case IMGETCOUNT: - id = get_mdevice_count(); - if (put_user(id, (int __user *)arg)) - err = -EFAULT; - break; - case IMGETDEVINFO: - if (get_user(id, (int __user *)arg)) { - err = -EFAULT; - break; - } - dev = get_mdevice(id); - if (dev) { - struct mISDN_devinfo di; - - di.id = dev->id; - di.Dprotocols = dev->Dprotocols; - di.Bprotocols = dev->Bprotocols | get_all_Bprotocols(); - di.protocol = dev->D.protocol; - memcpy(di.channelmap, dev->channelmap, - MISDN_CHMAP_SIZE * 4); - di.nrbchan = dev->nrbchan; - strcpy(di.name, dev->name); - if (copy_to_user((void __user *)arg, &di, sizeof(di))) - err = -EFAULT; - } else - err = -ENODEV; - break; - default: - err = -EINVAL; - } - return err; -} - -static int -base_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) -{ - struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr; - struct sock *sk = sock->sk; - int err = 0; - - if (!maddr || maddr->family != AF_ISDN) - return -EINVAL; - - lock_sock(sk); - - if (_pms(sk)->dev) { - err = -EALREADY; - goto done; - } - - _pms(sk)->dev = get_mdevice(maddr->dev); - if (!_pms(sk)->dev) { - err = -ENODEV; - goto done; - } - sk->sk_state = MISDN_BOUND; - -done: - release_sock(sk); - return err; -} - -static const struct proto_ops base_sock_ops = { - .family = PF_ISDN, - .owner = THIS_MODULE, - .release = base_sock_release, - .ioctl = base_sock_ioctl, - .bind = base_sock_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 int -base_sock_create(struct net *net, struct socket *sock, int protocol) -{ - struct sock *sk; - - if (sock->type != SOCK_RAW) - return -ESOCKTNOSUPPORT; - - sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto); - if (!sk) - return -ENOMEM; - - sock_init_data(sock, sk); - sock->ops = &base_sock_ops; - sock->state = SS_UNCONNECTED; - sock_reset_flag(sk, SOCK_ZAPPED); - sk->sk_protocol = protocol; - sk->sk_state = MISDN_OPEN; - mISDN_sock_link(&base_sockets, sk); - - return 0; -} - -static int -mISDN_sock_create(struct net *net, struct socket *sock, int proto) -{ - int err = -EPROTONOSUPPORT; - - switch (proto) { - case ISDN_P_BASE: - err = base_sock_create(net, sock, proto); - break; - case ISDN_P_TE_S0: - case ISDN_P_NT_S0: - case ISDN_P_TE_E1: - case ISDN_P_NT_E1: - case ISDN_P_LAPD_TE: - case ISDN_P_LAPD_NT: - case ISDN_P_B_RAW: - case ISDN_P_B_HDLC: - case ISDN_P_B_X75SLP: - case ISDN_P_B_L2DTMF: - case ISDN_P_B_L2DSP: - case ISDN_P_B_L2DSPHDLC: - err = data_sock_create(net, sock, proto); - break; - default: - return err; - } - - return err; -} - -static struct -net_proto_family mISDN_sock_family_ops = { - .owner = THIS_MODULE, - .family = PF_ISDN, - .create = mISDN_sock_create, -}; - -int -misdn_sock_init(u_int *deb) -{ - int err; - - debug = deb; - err = sock_register(&mISDN_sock_family_ops); - if (err) - printk(KERN_ERR "%s: error(%d)\n", __func__, err); - return err; -} - -void -misdn_sock_cleanup(void) -{ - sock_unregister(PF_ISDN); -} - diff --git a/trunk/drivers/isdn/mISDN/stack.c b/trunk/drivers/isdn/mISDN/stack.c deleted file mode 100644 index 54cfddcc4784..000000000000 --- a/trunk/drivers/isdn/mISDN/stack.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#include -#include -#include "core.h" - -static u_int *debug; - -static inline void -_queue_message(struct mISDNstack *st, struct sk_buff *skb) -{ - struct mISDNhead *hh = mISDN_HEAD_P(skb); - - if (*debug & DEBUG_QUEUE_FUNC) - printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n", - __func__, hh->prim, hh->id, skb); - skb_queue_tail(&st->msgq, skb); - if (likely(!test_bit(mISDN_STACK_STOPPED, &st->status))) { - test_and_set_bit(mISDN_STACK_WORK, &st->status); - wake_up_interruptible(&st->workq); - } -} - -int -mISDN_queue_message(struct mISDNchannel *ch, struct sk_buff *skb) -{ - _queue_message(ch->st, skb); - return 0; -} - -static struct mISDNchannel * -get_channel4id(struct mISDNstack *st, u_int id) -{ - struct mISDNchannel *ch; - - mutex_lock(&st->lmutex); - list_for_each_entry(ch, &st->layer2, list) { - if (id == ch->nr) - goto unlock; - } - ch = NULL; -unlock: - mutex_unlock(&st->lmutex); - return ch; -} - -static void -send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb) -{ - struct hlist_node *node; - struct sock *sk; - struct sk_buff *cskb = NULL; - - read_lock(&sl->lock); - sk_for_each(sk, node, &sl->head) { - if (sk->sk_state != MISDN_BOUND) - continue; - if (!cskb) - cskb = skb_copy(skb, GFP_KERNEL); - if (!cskb) { - printk(KERN_WARNING "%s no skb\n", __func__); - break; - } - if (!sock_queue_rcv_skb(sk, cskb)) - cskb = NULL; - } - read_unlock(&sl->lock); - if (cskb) - dev_kfree_skb(cskb); -} - -static void -send_layer2(struct mISDNstack *st, struct sk_buff *skb) -{ - struct sk_buff *cskb; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - struct mISDNchannel *ch; - int ret; - - if (!st) - return; - mutex_lock(&st->lmutex); - if ((hh->id & MISDN_ID_ADDR_MASK) == MISDN_ID_ANY) { /* L2 for all */ - list_for_each_entry(ch, &st->layer2, list) { - if (list_is_last(&ch->list, &st->layer2)) { - cskb = skb; - skb = NULL; - } else { - cskb = skb_copy(skb, GFP_KERNEL); - } - if (cskb) { - ret = ch->send(ch, cskb); - if (ret) { - if (*debug & DEBUG_SEND_ERR) - printk(KERN_DEBUG - "%s ch%d prim(%x) addr(%x)" - " err %d\n", - __func__, ch->nr, - hh->prim, ch->addr, ret); - dev_kfree_skb(cskb); - } - } else { - printk(KERN_WARNING "%s ch%d addr %x no mem\n", - __func__, ch->nr, ch->addr); - goto out; - } - } - } else { - list_for_each_entry(ch, &st->layer2, list) { - if ((hh->id & MISDN_ID_ADDR_MASK) == ch->addr) { - ret = ch->send(ch, skb); - if (!ret) - skb = NULL; - goto out; - } - } - ret = st->dev->teimgr->ctrl(st->dev->teimgr, CHECK_DATA, skb); - if (!ret) - skb = NULL; - else if (*debug & DEBUG_SEND_ERR) - printk(KERN_DEBUG - "%s ch%d mgr prim(%x) addr(%x) err %d\n", - __func__, ch->nr, hh->prim, ch->addr, ret); - } -out: - mutex_unlock(&st->lmutex); - if (skb) - dev_kfree_skb(skb); -} - -static inline int -send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb) -{ - struct mISDNhead *hh = mISDN_HEAD_P(skb); - struct mISDNchannel *ch; - int lm; - - lm = hh->prim & MISDN_LAYERMASK; - if (*debug & DEBUG_QUEUE_FUNC) - printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n", - __func__, hh->prim, hh->id, skb); - if (lm == 0x1) { - if (!hlist_empty(&st->l1sock.head)) { - __net_timestamp(skb); - send_socklist(&st->l1sock, skb); - } - return st->layer1->send(st->layer1, skb); - } else if (lm == 0x2) { - if (!hlist_empty(&st->l1sock.head)) - send_socklist(&st->l1sock, skb); - send_layer2(st, skb); - return 0; - } else if (lm == 0x4) { - ch = get_channel4id(st, hh->id); - if (ch) - return ch->send(ch, skb); - else - printk(KERN_WARNING - "%s: dev(%s) prim(%x) id(%x) no channel\n", - __func__, st->dev->name, hh->prim, hh->id); - } else if (lm == 0x8) { - WARN_ON(lm == 0x8); - ch = get_channel4id(st, hh->id); - if (ch) - return ch->send(ch, skb); - else - printk(KERN_WARNING - "%s: dev(%s) prim(%x) id(%x) no channel\n", - __func__, st->dev->name, hh->prim, hh->id); - } else { - /* broadcast not handled yet */ - printk(KERN_WARNING "%s: dev(%s) prim %x not delivered\n", - __func__, st->dev->name, hh->prim); - } - return -ESRCH; -} - -static void -do_clear_stack(struct mISDNstack *st) -{ -} - -static int -mISDNStackd(void *data) -{ - struct mISDNstack *st = data; - int err = 0; - -#ifdef CONFIG_SMP - lock_kernel(); -#endif - sigfillset(¤t->blocked); -#ifdef CONFIG_SMP - unlock_kernel(); -#endif - if (*debug & DEBUG_MSG_THREAD) - printk(KERN_DEBUG "mISDNStackd %s started\n", st->dev->name); - - if (st->notify != NULL) { - complete(st->notify); - st->notify = NULL; - } - - for (;;) { - struct sk_buff *skb; - - if (unlikely(test_bit(mISDN_STACK_STOPPED, &st->status))) { - test_and_clear_bit(mISDN_STACK_WORK, &st->status); - test_and_clear_bit(mISDN_STACK_RUNNING, &st->status); - } else - test_and_set_bit(mISDN_STACK_RUNNING, &st->status); - while (test_bit(mISDN_STACK_WORK, &st->status)) { - skb = skb_dequeue(&st->msgq); - if (!skb) { - test_and_clear_bit(mISDN_STACK_WORK, - &st->status); - /* test if a race happens */ - skb = skb_dequeue(&st->msgq); - if (!skb) - continue; - test_and_set_bit(mISDN_STACK_WORK, - &st->status); - } -#ifdef MISDN_MSG_STATS - st->msg_cnt++; -#endif - err = send_msg_to_layer(st, skb); - if (unlikely(err)) { - if (*debug & DEBUG_SEND_ERR) - printk(KERN_DEBUG - "%s: %s prim(%x) id(%x) " - "send call(%d)\n", - __func__, st->dev->name, - mISDN_HEAD_PRIM(skb), - mISDN_HEAD_ID(skb), err); - dev_kfree_skb(skb); - continue; - } - if (unlikely(test_bit(mISDN_STACK_STOPPED, - &st->status))) { - test_and_clear_bit(mISDN_STACK_WORK, - &st->status); - test_and_clear_bit(mISDN_STACK_RUNNING, - &st->status); - break; - } - } - if (test_bit(mISDN_STACK_CLEARING, &st->status)) { - test_and_set_bit(mISDN_STACK_STOPPED, &st->status); - test_and_clear_bit(mISDN_STACK_RUNNING, &st->status); - do_clear_stack(st); - test_and_clear_bit(mISDN_STACK_CLEARING, &st->status); - test_and_set_bit(mISDN_STACK_RESTART, &st->status); - } - if (test_and_clear_bit(mISDN_STACK_RESTART, &st->status)) { - test_and_clear_bit(mISDN_STACK_STOPPED, &st->status); - test_and_set_bit(mISDN_STACK_RUNNING, &st->status); - if (!skb_queue_empty(&st->msgq)) - test_and_set_bit(mISDN_STACK_WORK, - &st->status); - } - if (test_bit(mISDN_STACK_ABORT, &st->status)) - break; - if (st->notify != NULL) { - complete(st->notify); - st->notify = NULL; - } -#ifdef MISDN_MSG_STATS - st->sleep_cnt++; -#endif - test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status); - wait_event_interruptible(st->workq, (st->status & - mISDN_STACK_ACTION_MASK)); - if (*debug & DEBUG_MSG_THREAD) - printk(KERN_DEBUG "%s: %s wake status %08lx\n", - __func__, st->dev->name, st->status); - test_and_set_bit(mISDN_STACK_ACTIVE, &st->status); - - test_and_clear_bit(mISDN_STACK_WAKEUP, &st->status); - - if (test_bit(mISDN_STACK_STOPPED, &st->status)) { - test_and_clear_bit(mISDN_STACK_RUNNING, &st->status); -#ifdef MISDN_MSG_STATS - st->stopped_cnt++; -#endif - } - } -#ifdef MISDN_MSG_STATS - printk(KERN_DEBUG "mISDNStackd daemon for %s proceed %d " - "msg %d sleep %d stopped\n", - st->dev->name, st->msg_cnt, st->sleep_cnt, st->stopped_cnt); - printk(KERN_DEBUG - "mISDNStackd daemon for %s utime(%ld) stime(%ld)\n", - st->dev->name, st->thread->utime, st->thread->stime); - printk(KERN_DEBUG - "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n", - st->dev->name, st->thread->nvcsw, st->thread->nivcsw); - printk(KERN_DEBUG "mISDNStackd daemon for %s killed now\n", - st->dev->name); -#endif - test_and_set_bit(mISDN_STACK_KILLED, &st->status); - test_and_clear_bit(mISDN_STACK_RUNNING, &st->status); - test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status); - test_and_clear_bit(mISDN_STACK_ABORT, &st->status); - skb_queue_purge(&st->msgq); - st->thread = NULL; - if (st->notify != NULL) { - complete(st->notify); - st->notify = NULL; - } - return 0; -} - -static int -l1_receive(struct mISDNchannel *ch, struct sk_buff *skb) -{ - if (!ch->st) - return -ENODEV; - __net_timestamp(skb); - _queue_message(ch->st, skb); - return 0; -} - -void -set_channel_address(struct mISDNchannel *ch, u_int sapi, u_int tei) -{ - ch->addr = sapi | (tei << 8); -} - -void -__add_layer2(struct mISDNchannel *ch, struct mISDNstack *st) -{ - list_add_tail(&ch->list, &st->layer2); -} - -void -add_layer2(struct mISDNchannel *ch, struct mISDNstack *st) -{ - mutex_lock(&st->lmutex); - __add_layer2(ch, st); - mutex_unlock(&st->lmutex); -} - -static int -st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - if (!ch->st || ch->st->layer1) - return -EINVAL; - return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg); -} - -int -create_stack(struct mISDNdevice *dev) -{ - struct mISDNstack *newst; - int err; - DECLARE_COMPLETION_ONSTACK(done); - - newst = kzalloc(sizeof(struct mISDNstack), GFP_KERNEL); - if (!newst) { - printk(KERN_ERR "kmalloc mISDN_stack failed\n"); - return -ENOMEM; - } - newst->dev = dev; - INIT_LIST_HEAD(&newst->layer2); - INIT_HLIST_HEAD(&newst->l1sock.head); - rwlock_init(&newst->l1sock.lock); - init_waitqueue_head(&newst->workq); - skb_queue_head_init(&newst->msgq); - mutex_init(&newst->lmutex); - dev->D.st = newst; - err = create_teimanager(dev); - if (err) { - printk(KERN_ERR "kmalloc teimanager failed\n"); - kfree(newst); - return err; - } - dev->teimgr->peer = &newst->own; - dev->teimgr->recv = mISDN_queue_message; - dev->teimgr->st = newst; - newst->layer1 = &dev->D; - dev->D.recv = l1_receive; - dev->D.peer = &newst->own; - newst->own.st = newst; - newst->own.ctrl = st_own_ctrl; - newst->own.send = mISDN_queue_message; - newst->own.recv = mISDN_queue_message; - if (*debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: st(%s)\n", __func__, newst->dev->name); - newst->notify = &done; - newst->thread = kthread_run(mISDNStackd, (void *)newst, "mISDN_%s", - newst->dev->name); - if (IS_ERR(newst->thread)) { - err = PTR_ERR(newst->thread); - printk(KERN_ERR - "mISDN:cannot create kernel thread for %s (%d)\n", - newst->dev->name, err); - delete_teimanager(dev->teimgr); - kfree(newst); - } else - wait_for_completion(&done); - return err; -} - -int -connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch, - u_int protocol, struct sockaddr_mISDN *adr) -{ - struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch); - struct channel_req rq; - int err; - - - if (*debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n", - __func__, dev->name, protocol, adr->dev, adr->channel, - adr->sapi, adr->tei); - switch (protocol) { - case ISDN_P_NT_S0: - case ISDN_P_NT_E1: - case ISDN_P_TE_S0: - case ISDN_P_TE_E1: -#ifdef PROTOCOL_CHECK - /* this should be enhanced */ - if (!list_empty(&dev->D.st->layer2) - && dev->D.protocol != protocol) - return -EBUSY; - if (!hlist_empty(&dev->D.st->l1sock.head) - && dev->D.protocol != protocol) - return -EBUSY; -#endif - ch->recv = mISDN_queue_message; - ch->peer = &dev->D.st->own; - ch->st = dev->D.st; - rq.protocol = protocol; - rq.adr.channel = 0; - err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq); - printk(KERN_DEBUG "%s: ret 1 %d\n", __func__, err); - if (err) - return err; - write_lock_bh(&dev->D.st->l1sock.lock); - sk_add_node(&msk->sk, &dev->D.st->l1sock.head); - write_unlock_bh(&dev->D.st->l1sock.lock); - break; - default: - return -ENOPROTOOPT; - } - return 0; -} - -int -connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch, - u_int protocol, struct sockaddr_mISDN *adr) -{ - struct channel_req rq, rq2; - int pmask, err; - struct Bprotocol *bp; - - if (*debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n", - __func__, dev->name, protocol, - adr->dev, adr->channel, adr->sapi, - adr->tei); - ch->st = dev->D.st; - pmask = 1 << (protocol & ISDN_P_B_MASK); - if (pmask & dev->Bprotocols) { - rq.protocol = protocol; - rq.adr = *adr; - err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq); - if (err) - return err; - ch->recv = rq.ch->send; - ch->peer = rq.ch; - rq.ch->recv = ch->send; - rq.ch->peer = ch; - rq.ch->st = dev->D.st; - } else { - bp = get_Bprotocol4mask(pmask); - if (!bp) - return -ENOPROTOOPT; - rq2.protocol = protocol; - rq2.adr = *adr; - rq2.ch = ch; - err = bp->create(&rq2); - if (err) - return err; - ch->recv = rq2.ch->send; - ch->peer = rq2.ch; - rq2.ch->st = dev->D.st; - rq.protocol = rq2.protocol; - rq.adr = *adr; - err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq); - if (err) { - rq2.ch->ctrl(rq2.ch, CLOSE_CHANNEL, NULL); - return err; - } - rq2.ch->recv = rq.ch->send; - rq2.ch->peer = rq.ch; - rq.ch->recv = rq2.ch->send; - rq.ch->peer = rq2.ch; - rq.ch->st = dev->D.st; - } - ch->protocol = protocol; - ch->nr = rq.ch->nr; - return 0; -} - -int -create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch, - u_int protocol, struct sockaddr_mISDN *adr) -{ - struct channel_req rq; - int err; - - if (*debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n", - __func__, dev->name, protocol, - adr->dev, adr->channel, adr->sapi, - adr->tei); - rq.protocol = ISDN_P_TE_S0; - if (dev->Dprotocols & (1 << ISDN_P_TE_E1)) - rq.protocol = ISDN_P_TE_E1; - switch (protocol) { - case ISDN_P_LAPD_NT: - rq.protocol = ISDN_P_NT_S0; - if (dev->Dprotocols & (1 << ISDN_P_NT_E1)) - rq.protocol = ISDN_P_NT_E1; - case ISDN_P_LAPD_TE: -#ifdef PROTOCOL_CHECK - /* this should be enhanced */ - if (!list_empty(&dev->D.st->layer2) - && dev->D.protocol != protocol) - return -EBUSY; - if (!hlist_empty(&dev->D.st->l1sock.head) - && dev->D.protocol != protocol) - return -EBUSY; -#endif - ch->recv = mISDN_queue_message; - ch->peer = &dev->D.st->own; - ch->st = dev->D.st; - rq.adr.channel = 0; - err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq); - printk(KERN_DEBUG "%s: ret 1 %d\n", __func__, err); - if (err) - break; - rq.protocol = protocol; - rq.adr = *adr; - rq.ch = ch; - err = dev->teimgr->ctrl(dev->teimgr, OPEN_CHANNEL, &rq); - printk(KERN_DEBUG "%s: ret 2 %d\n", __func__, err); - if (!err) { - if ((protocol == ISDN_P_LAPD_NT) && !rq.ch) - break; - add_layer2(rq.ch, dev->D.st); - rq.ch->recv = mISDN_queue_message; - rq.ch->peer = &dev->D.st->own; - rq.ch->ctrl(rq.ch, OPEN_CHANNEL, NULL); /* can't fail */ - } - break; - default: - err = -EPROTONOSUPPORT; - } - return err; -} - -void -delete_channel(struct mISDNchannel *ch) -{ - struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch); - struct mISDNchannel *pch; - - if (!ch->st) { - printk(KERN_WARNING "%s: no stack\n", __func__); - return; - } - if (*debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: st(%s) protocol(%x)\n", __func__, - ch->st->dev->name, ch->protocol); - if (ch->protocol >= ISDN_P_B_START) { - if (ch->peer) { - ch->peer->ctrl(ch->peer, CLOSE_CHANNEL, NULL); - ch->peer = NULL; - } - return; - } - switch (ch->protocol) { - case ISDN_P_NT_S0: - case ISDN_P_TE_S0: - case ISDN_P_NT_E1: - case ISDN_P_TE_E1: - write_lock_bh(&ch->st->l1sock.lock); - sk_del_node_init(&msk->sk); - write_unlock_bh(&ch->st->l1sock.lock); - ch->st->dev->D.ctrl(&ch->st->dev->D, CLOSE_CHANNEL, NULL); - break; - case ISDN_P_LAPD_TE: - pch = get_channel4id(ch->st, ch->nr); - if (pch) { - mutex_lock(&ch->st->lmutex); - list_del(&pch->list); - mutex_unlock(&ch->st->lmutex); - pch->ctrl(pch, CLOSE_CHANNEL, NULL); - pch = ch->st->dev->teimgr; - pch->ctrl(pch, CLOSE_CHANNEL, NULL); - } else - printk(KERN_WARNING "%s: no l2 channel\n", - __func__); - break; - case ISDN_P_LAPD_NT: - pch = ch->st->dev->teimgr; - if (pch) { - pch->ctrl(pch, CLOSE_CHANNEL, NULL); - } else - printk(KERN_WARNING "%s: no l2 channel\n", - __func__); - break; - default: - break; - } - return; -} - -void -delete_stack(struct mISDNdevice *dev) -{ - struct mISDNstack *st = dev->D.st; - DECLARE_COMPLETION_ONSTACK(done); - - if (*debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: st(%s)\n", __func__, - st->dev->name); - if (dev->teimgr) - delete_teimanager(dev->teimgr); - if (st->thread) { - if (st->notify) { - printk(KERN_WARNING "%s: notifier in use\n", - __func__); - complete(st->notify); - } - st->notify = &done; - test_and_set_bit(mISDN_STACK_ABORT, &st->status); - test_and_set_bit(mISDN_STACK_WAKEUP, &st->status); - wake_up_interruptible(&st->workq); - wait_for_completion(&done); - } - if (!list_empty(&st->layer2)) - printk(KERN_WARNING "%s: layer2 list not empty\n", - __func__); - if (!hlist_empty(&st->l1sock.head)) - printk(KERN_WARNING "%s: layer1 list not empty\n", - __func__); - kfree(st); -} - -void -mISDN_initstack(u_int *dp) -{ - debug = dp; -} diff --git a/trunk/drivers/isdn/mISDN/tei.c b/trunk/drivers/isdn/mISDN/tei.c deleted file mode 100644 index 6fbae42127bf..000000000000 --- a/trunk/drivers/isdn/mISDN/tei.c +++ /dev/null @@ -1,1340 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ -#include "layer2.h" -#include -#include "core.h" - -#define ID_REQUEST 1 -#define ID_ASSIGNED 2 -#define ID_DENIED 3 -#define ID_CHK_REQ 4 -#define ID_CHK_RES 5 -#define ID_REMOVE 6 -#define ID_VERIFY 7 - -#define TEI_ENTITY_ID 0xf - -#define MGR_PH_ACTIVE 16 -#define MGR_PH_NOTREADY 17 - -#define DATIMER_VAL 10000 - -static u_int *debug; - -static struct Fsm deactfsm = {NULL, 0, 0, NULL, NULL}; -static struct Fsm teifsmu = {NULL, 0, 0, NULL, NULL}; -static struct Fsm teifsmn = {NULL, 0, 0, NULL, NULL}; - -enum { - ST_L1_DEACT, - ST_L1_DEACT_PENDING, - ST_L1_ACTIV, -}; -#define DEACT_STATE_COUNT (ST_L1_ACTIV+1) - -static char *strDeactState[] = -{ - "ST_L1_DEACT", - "ST_L1_DEACT_PENDING", - "ST_L1_ACTIV", -}; - -enum { - EV_ACTIVATE, - EV_ACTIVATE_IND, - EV_DEACTIVATE, - EV_DEACTIVATE_IND, - EV_UI, - EV_DATIMER, -}; - -#define DEACT_EVENT_COUNT (EV_DATIMER+1) - -static char *strDeactEvent[] = -{ - "EV_ACTIVATE", - "EV_ACTIVATE_IND", - "EV_DEACTIVATE", - "EV_DEACTIVATE_IND", - "EV_UI", - "EV_DATIMER", -}; - -static void -da_debug(struct FsmInst *fi, char *fmt, ...) -{ - struct manager *mgr = fi->userdata; - va_list va; - - if (!(*debug & DEBUG_L2_TEIFSM)) - return; - va_start(va, fmt); - printk(KERN_DEBUG "mgr(%d): ", mgr->ch.st->dev->id); - vprintk(fmt, va); - printk("\n"); - va_end(va); -} - -static void -da_activate(struct FsmInst *fi, int event, void *arg) -{ - struct manager *mgr = fi->userdata; - - if (fi->state == ST_L1_DEACT_PENDING) - mISDN_FsmDelTimer(&mgr->datimer, 1); - mISDN_FsmChangeState(fi, ST_L1_ACTIV); -} - -static void -da_deactivate_ind(struct FsmInst *fi, int event, void *arg) -{ - mISDN_FsmChangeState(fi, ST_L1_DEACT); -} - -static void -da_deactivate(struct FsmInst *fi, int event, void *arg) -{ - struct manager *mgr = fi->userdata; - struct layer2 *l2; - u_long flags; - - read_lock_irqsave(&mgr->lock, flags); - list_for_each_entry(l2, &mgr->layer2, list) { - if (l2->l2m.state > ST_L2_4) { - /* have still activ TEI */ - read_unlock_irqrestore(&mgr->lock, flags); - return; - } - } - read_unlock_irqrestore(&mgr->lock, flags); - /* All TEI are inactiv */ - mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 1); - mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING); -} - -static void -da_ui(struct FsmInst *fi, int event, void *arg) -{ - struct manager *mgr = fi->userdata; - - /* restart da timer */ - mISDN_FsmDelTimer(&mgr->datimer, 2); - mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 2); - -} - -static void -da_timer(struct FsmInst *fi, int event, void *arg) -{ - struct manager *mgr = fi->userdata; - struct layer2 *l2; - u_long flags; - - /* check again */ - read_lock_irqsave(&mgr->lock, flags); - list_for_each_entry(l2, &mgr->layer2, list) { - if (l2->l2m.state > ST_L2_4) { - /* have still activ TEI */ - read_unlock_irqrestore(&mgr->lock, flags); - mISDN_FsmChangeState(fi, ST_L1_ACTIV); - return; - } - } - read_unlock_irqrestore(&mgr->lock, flags); - /* All TEI are inactiv */ - mISDN_FsmChangeState(fi, ST_L1_DEACT); - _queue_data(&mgr->ch, PH_DEACTIVATE_REQ, MISDN_ID_ANY, 0, NULL, - GFP_ATOMIC); -} - -static struct FsmNode DeactFnList[] = -{ - {ST_L1_DEACT, EV_ACTIVATE_IND, da_activate}, - {ST_L1_ACTIV, EV_DEACTIVATE_IND, da_deactivate_ind}, - {ST_L1_ACTIV, EV_DEACTIVATE, da_deactivate}, - {ST_L1_DEACT_PENDING, EV_ACTIVATE, da_activate}, - {ST_L1_DEACT_PENDING, EV_UI, da_ui}, - {ST_L1_DEACT_PENDING, EV_DATIMER, da_timer}, -}; - -enum { - ST_TEI_NOP, - ST_TEI_IDREQ, - ST_TEI_IDVERIFY, -}; - -#define TEI_STATE_COUNT (ST_TEI_IDVERIFY+1) - -static char *strTeiState[] = -{ - "ST_TEI_NOP", - "ST_TEI_IDREQ", - "ST_TEI_IDVERIFY", -}; - -enum { - EV_IDREQ, - EV_ASSIGN, - EV_ASSIGN_REQ, - EV_DENIED, - EV_CHKREQ, - EV_CHKRESP, - EV_REMOVE, - EV_VERIFY, - EV_TIMER, -}; - -#define TEI_EVENT_COUNT (EV_TIMER+1) - -static char *strTeiEvent[] = -{ - "EV_IDREQ", - "EV_ASSIGN", - "EV_ASSIGN_REQ", - "EV_DENIED", - "EV_CHKREQ", - "EV_CHKRESP", - "EV_REMOVE", - "EV_VERIFY", - "EV_TIMER", -}; - -static void -tei_debug(struct FsmInst *fi, char *fmt, ...) -{ - struct teimgr *tm = fi->userdata; - va_list va; - - if (!(*debug & DEBUG_L2_TEIFSM)) - return; - va_start(va, fmt); - printk(KERN_DEBUG "tei(%d): ", tm->l2->tei); - vprintk(fmt, va); - printk("\n"); - va_end(va); -} - - - -static int -get_free_id(struct manager *mgr) -{ - u64 ids = 0; - int i; - struct layer2 *l2; - - list_for_each_entry(l2, &mgr->layer2, list) { - if (l2->ch.nr > 63) { - printk(KERN_WARNING - "%s: more as 63 layer2 for one device\n", - __func__); - return -EBUSY; - } - test_and_set_bit(l2->ch.nr, (u_long *)&ids); - } - for (i = 1; i < 64; i++) - if (!test_bit(i, (u_long *)&ids)) - return i; - printk(KERN_WARNING "%s: more as 63 layer2 for one device\n", - __func__); - return -EBUSY; -} - -static int -get_free_tei(struct manager *mgr) -{ - u64 ids = 0; - int i; - struct layer2 *l2; - - list_for_each_entry(l2, &mgr->layer2, list) { - if (l2->ch.nr == 0) - continue; - if ((l2->ch.addr & 0xff) != 0) - continue; - i = l2->ch.addr >> 8; - if (i < 64) - continue; - i -= 64; - - test_and_set_bit(i, (u_long *)&ids); - } - for (i = 0; i < 64; i++) - if (!test_bit(i, (u_long *)&ids)) - return i + 64; - printk(KERN_WARNING "%s: more as 63 dynamic tei for one device\n", - __func__); - return -1; -} - -static void -teiup_create(struct manager *mgr, u_int prim, int len, void *arg) -{ - struct sk_buff *skb; - struct mISDNhead *hh; - int err; - - skb = mI_alloc_skb(len, GFP_ATOMIC); - if (!skb) - return; - hh = mISDN_HEAD_P(skb); - hh->prim = prim; - hh->id = (mgr->ch.nr << 16) | mgr->ch.addr; - if (len) - memcpy(skb_put(skb, len), arg, len); - err = mgr->up->send(mgr->up, skb); - if (err) { - printk(KERN_WARNING "%s: err=%d\n", __func__, err); - dev_kfree_skb(skb); - } -} - -static u_int -new_id(struct manager *mgr) -{ - u_int id; - - id = mgr->nextid++; - if (id == 0x7fff) - mgr->nextid = 1; - id <<= 16; - id |= GROUP_TEI << 8; - id |= TEI_SAPI; - return id; -} - -static void -do_send(struct manager *mgr) -{ - if (!test_bit(MGR_PH_ACTIVE, &mgr->options)) - return; - - if (!test_and_set_bit(MGR_PH_NOTREADY, &mgr->options)) { - struct sk_buff *skb = skb_dequeue(&mgr->sendq); - - if (!skb) { - test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options); - return; - } - mgr->lastid = mISDN_HEAD_ID(skb); - mISDN_FsmEvent(&mgr->deact, EV_UI, NULL); - if (mgr->ch.recv(mgr->ch.peer, skb)) { - dev_kfree_skb(skb); - test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options); - mgr->lastid = MISDN_ID_NONE; - } - } -} - -static void -do_ack(struct manager *mgr, u_int id) -{ - if (test_bit(MGR_PH_NOTREADY, &mgr->options)) { - if (id == mgr->lastid) { - if (test_bit(MGR_PH_ACTIVE, &mgr->options)) { - struct sk_buff *skb; - - skb = skb_dequeue(&mgr->sendq); - if (skb) { - mgr->lastid = mISDN_HEAD_ID(skb); - if (!mgr->ch.recv(mgr->ch.peer, skb)) - return; - dev_kfree_skb(skb); - } - } - mgr->lastid = MISDN_ID_NONE; - test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options); - } - } -} - -static void -mgr_send_down(struct manager *mgr, struct sk_buff *skb) -{ - skb_queue_tail(&mgr->sendq, skb); - if (!test_bit(MGR_PH_ACTIVE, &mgr->options)) { - _queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0, - NULL, GFP_KERNEL); - } else { - do_send(mgr); - } -} - -static int -dl_unit_data(struct manager *mgr, struct sk_buff *skb) -{ - if (!test_bit(MGR_OPT_NETWORK, &mgr->options)) /* only net send UI */ - return -EINVAL; - if (!test_bit(MGR_PH_ACTIVE, &mgr->options)) - _queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0, - NULL, GFP_KERNEL); - skb_push(skb, 3); - skb->data[0] = 0x02; /* SAPI 0 C/R = 1 */ - skb->data[1] = 0xff; /* TEI 127 */ - skb->data[2] = UI; /* UI frame */ - mISDN_HEAD_PRIM(skb) = PH_DATA_REQ; - mISDN_HEAD_ID(skb) = new_id(mgr); - skb_queue_tail(&mgr->sendq, skb); - do_send(mgr); - return 0; -} - -unsigned int -random_ri(void) -{ - u16 x; - - get_random_bytes(&x, sizeof(x)); - return x; -} - -static struct layer2 * -findtei(struct manager *mgr, int tei) -{ - struct layer2 *l2; - u_long flags; - - read_lock_irqsave(&mgr->lock, flags); - list_for_each_entry(l2, &mgr->layer2, list) { - if ((l2->sapi == 0) && (l2->tei > 0) && - (l2->tei != GROUP_TEI) && (l2->tei == tei)) - goto done; - } - l2 = NULL; -done: - read_unlock_irqrestore(&mgr->lock, flags); - return l2; -} - -static void -put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei) -{ - struct sk_buff *skb; - u_char bp[8]; - - bp[0] = (TEI_SAPI << 2); - if (test_bit(MGR_OPT_NETWORK, &mgr->options)) - bp[0] |= 2; /* CR:=1 for net command */ - bp[1] = (GROUP_TEI << 1) | 0x1; - bp[2] = UI; - bp[3] = TEI_ENTITY_ID; - bp[4] = ri >> 8; - bp[5] = ri & 0xff; - bp[6] = m_id; - bp[7] = (tei << 1) | 1; - skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), - 8, bp, GFP_ATOMIC); - if (!skb) { - printk(KERN_WARNING "%s: no skb for tei msg\n", __func__); - return; - } - mgr_send_down(mgr, skb); -} - -static void -tei_id_request(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - - if (tm->l2->tei != GROUP_TEI) { - tm->tei_m.printdebug(&tm->tei_m, - "assign request for allready assigned tei %d", - tm->l2->tei); - return; - } - tm->ri = random_ri(); - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(&tm->tei_m, - "assign request ri %d", tm->ri); - put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI); - mISDN_FsmChangeState(fi, ST_TEI_IDREQ); - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 1); - tm->nval = 3; -} - -static void -tei_id_assign(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - struct layer2 *l2; - u_char *dp = arg; - int ri, tei; - - ri = ((unsigned int) *dp++ << 8); - ri += *dp++; - dp++; - tei = *dp >> 1; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "identity assign ri %d tei %d", - ri, tei); - l2 = findtei(tm->mgr, tei); - if (l2) { /* same tei is in use */ - if (ri != l2->tm->ri) { - tm->tei_m.printdebug(fi, - "possible duplicate assignment tei %d", tei); - tei_l2(l2, MDL_ERROR_RSP, 0); - } - } else if (ri == tm->ri) { - mISDN_FsmDelTimer(&tm->timer, 1); - mISDN_FsmChangeState(fi, ST_TEI_NOP); - tei_l2(tm->l2, MDL_ASSIGN_REQ, tei); - } -} - -static void -tei_id_test_dup(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - struct layer2 *l2; - u_char *dp = arg; - int tei, ri; - - ri = ((unsigned int) *dp++ << 8); - ri += *dp++; - dp++; - tei = *dp >> 1; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "foreign identity assign ri %d tei %d", - ri, tei); - l2 = findtei(tm->mgr, tei); - if (l2) { /* same tei is in use */ - if (ri != l2->tm->ri) { /* and it wasn't our request */ - tm->tei_m.printdebug(fi, - "possible duplicate assignment tei %d", tei); - mISDN_FsmEvent(&l2->tm->tei_m, EV_VERIFY, NULL); - } - } -} - -static void -tei_id_denied(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - u_char *dp = arg; - int ri, tei; - - ri = ((unsigned int) *dp++ << 8); - ri += *dp++; - dp++; - tei = *dp >> 1; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "identity denied ri %d tei %d", - ri, tei); -} - -static void -tei_id_chk_req(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - u_char *dp = arg; - int tei; - - tei = *(dp+3) >> 1; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "identity check req tei %d", tei); - if ((tm->l2->tei != GROUP_TEI) && ((tei == GROUP_TEI) || - (tei == tm->l2->tei))) { - mISDN_FsmDelTimer(&tm->timer, 4); - mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP); - put_tei_msg(tm->mgr, ID_CHK_RES, random_ri(), tm->l2->tei); - } -} - -static void -tei_id_remove(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - u_char *dp = arg; - int tei; - - tei = *(dp+3) >> 1; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "identity remove tei %d", tei); - if ((tm->l2->tei != GROUP_TEI) && - ((tei == GROUP_TEI) || (tei == tm->l2->tei))) { - mISDN_FsmDelTimer(&tm->timer, 5); - mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP); - tei_l2(tm->l2, MDL_REMOVE_REQ, 0); - } -} - -static void -tei_id_verify(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "id verify request for tei %d", - tm->l2->tei); - put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei); - mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY); - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2); - tm->nval = 2; -} - -static void -tei_id_req_tout(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - - if (--tm->nval) { - tm->ri = random_ri(); - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "assign req(%d) ri %d", - 4 - tm->nval, tm->ri); - put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI); - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 3); - } else { - tm->tei_m.printdebug(fi, "assign req failed"); - tei_l2(tm->l2, MDL_ERROR_RSP, 0); - mISDN_FsmChangeState(fi, ST_TEI_NOP); - } -} - -static void -tei_id_ver_tout(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - - if (--tm->nval) { - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, - "id verify req(%d) for tei %d", - 3 - tm->nval, tm->l2->tei); - put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei); - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4); - } else { - tm->tei_m.printdebug(fi, "verify req for tei %d failed", - tm->l2->tei); - tei_l2(tm->l2, MDL_REMOVE_REQ, 0); - mISDN_FsmChangeState(fi, ST_TEI_NOP); - } -} - -static struct FsmNode TeiFnListUser[] = -{ - {ST_TEI_NOP, EV_IDREQ, tei_id_request}, - {ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup}, - {ST_TEI_NOP, EV_VERIFY, tei_id_verify}, - {ST_TEI_NOP, EV_REMOVE, tei_id_remove}, - {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req}, - {ST_TEI_IDREQ, EV_TIMER, tei_id_req_tout}, - {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign}, - {ST_TEI_IDREQ, EV_DENIED, tei_id_denied}, - {ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout}, - {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove}, - {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req}, -}; - -static void -tei_l2remove(struct layer2 *l2) -{ - put_tei_msg(l2->tm->mgr, ID_REMOVE, 0, l2->tei); - tei_l2(l2, MDL_REMOVE_REQ, 0); - list_del(&l2->ch.list); - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL); -} - -static void -tei_assign_req(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - u_char *dp = arg; - - if (tm->l2->tei == GROUP_TEI) { - tm->tei_m.printdebug(&tm->tei_m, - "net tei assign request without tei"); - return; - } - tm->ri = ((unsigned int) *dp++ << 8); - tm->ri += *dp++; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(&tm->tei_m, - "net assign request ri %d teim %d", tm->ri, *dp); - put_tei_msg(tm->mgr, ID_ASSIGNED, tm->ri, tm->l2->tei); - mISDN_FsmChangeState(fi, ST_TEI_NOP); -} - -static void -tei_id_chk_req_net(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "id check request for tei %d", - tm->l2->tei); - tm->rcnt = 0; - put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei); - mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY); - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2); - tm->nval = 2; -} - -static void -tei_id_chk_resp(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - u_char *dp = arg; - int tei; - - tei = dp[3] >> 1; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "identity check resp tei %d", tei); - if (tei == tm->l2->tei) - tm->rcnt++; -} - -static void -tei_id_verify_net(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - u_char *dp = arg; - int tei; - - tei = dp[3] >> 1; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, "identity verify req tei %d/%d", - tei, tm->l2->tei); - if (tei == tm->l2->tei) - tei_id_chk_req_net(fi, event, arg); -} - -static void -tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg) -{ - struct teimgr *tm = fi->userdata; - - if (tm->rcnt == 1) { - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, - "check req for tei %d sucessful\n", tm->l2->tei); - mISDN_FsmChangeState(fi, ST_TEI_NOP); - } else if (tm->rcnt > 1) { - /* duplicate assignment; remove */ - tei_l2remove(tm->l2); - } else if (--tm->nval) { - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(fi, - "id check req(%d) for tei %d", - 3 - tm->nval, tm->l2->tei); - put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei); - mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4); - } else { - tm->tei_m.printdebug(fi, "check req for tei %d failed", - tm->l2->tei); - mISDN_FsmChangeState(fi, ST_TEI_NOP); - tei_l2remove(tm->l2); - } -} - -static struct FsmNode TeiFnListNet[] = -{ - {ST_TEI_NOP, EV_ASSIGN_REQ, tei_assign_req}, - {ST_TEI_NOP, EV_VERIFY, tei_id_verify_net}, - {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req_net}, - {ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout_net}, - {ST_TEI_IDVERIFY, EV_CHKRESP, tei_id_chk_resp}, -}; - -static void -tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len) -{ - if (test_bit(FLG_FIXED_TEI, &tm->l2->flag)) - return; - if (*debug & DEBUG_L2_TEI) - tm->tei_m.printdebug(&tm->tei_m, "tei handler mt %x", mt); - if (mt == ID_ASSIGNED) - mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN, dp); - else if (mt == ID_DENIED) - mISDN_FsmEvent(&tm->tei_m, EV_DENIED, dp); - else if (mt == ID_CHK_REQ) - mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, dp); - else if (mt == ID_REMOVE) - mISDN_FsmEvent(&tm->tei_m, EV_REMOVE, dp); - else if (mt == ID_VERIFY) - mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, dp); - else if (mt == ID_CHK_RES) - mISDN_FsmEvent(&tm->tei_m, EV_CHKRESP, dp); -} - -static struct layer2 * -create_new_tei(struct manager *mgr, int tei) -{ - u_long opt = 0; - u_long flags; - int id; - struct layer2 *l2; - - if (!mgr->up) - return NULL; - if (tei < 64) - test_and_set_bit(OPTION_L2_FIXEDTEI, &opt); - if (mgr->ch.st->dev->Dprotocols - & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) - test_and_set_bit(OPTION_L2_PMX, &opt); - l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, (u_int)opt, (u_long)tei); - if (!l2) { - printk(KERN_WARNING "%s:no memory for layer2\n", __func__); - return NULL; - } - l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); - if (!l2->tm) { - kfree(l2); - printk(KERN_WARNING "%s:no memory for teimgr\n", __func__); - return NULL; - } - l2->tm->mgr = mgr; - l2->tm->l2 = l2; - l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM; - l2->tm->tei_m.userdata = l2->tm; - l2->tm->tei_m.printdebug = tei_debug; - l2->tm->tei_m.fsm = &teifsmn; - l2->tm->tei_m.state = ST_TEI_NOP; - l2->tm->tval = 2000; /* T202 2 sec */ - mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer); - write_lock_irqsave(&mgr->lock, flags); - id = get_free_id(mgr); - list_add_tail(&l2->list, &mgr->layer2); - write_unlock_irqrestore(&mgr->lock, flags); - if (id < 0) { - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL); - printk(KERN_WARNING "%s:no free id\n", __func__); - return NULL; - } else { - l2->ch.nr = id; - __add_layer2(&l2->ch, mgr->ch.st); - l2->ch.recv = mgr->ch.recv; - l2->ch.peer = mgr->ch.peer; - l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL); - } - return l2; -} - -static void -new_tei_req(struct manager *mgr, u_char *dp) -{ - int tei, ri; - struct layer2 *l2; - - ri = dp[0] << 8; - ri += dp[1]; - if (!mgr->up) - goto denied; - tei = get_free_tei(mgr); - if (tei < 0) { - printk(KERN_WARNING "%s:No free tei\n", __func__); - goto denied; - } - l2 = create_new_tei(mgr, tei); - if (!l2) - goto denied; - else - mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp); - return; -denied: - put_tei_msg(mgr, ID_DENIED, ri, GROUP_TEI); -} - -static int -ph_data_ind(struct manager *mgr, struct sk_buff *skb) -{ - int ret = -EINVAL; - struct layer2 *l2; - u_long flags; - u_char mt; - - if (skb->len < 8) { - if (*debug & DEBUG_L2_TEI) - printk(KERN_DEBUG "%s: short mgr frame %d/8\n", - __func__, skb->len); - goto done; - } - if (*debug & DEBUG_L2_TEI) - - if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */ - goto done; - if (skb->data[0] & 1) /* EA0 formal error */ - goto done; - if (!(skb->data[1] & 1)) /* EA1 formal error */ - goto done; - if ((skb->data[1] >> 1) != GROUP_TEI) /* not for us */ - goto done; - if ((skb->data[2] & 0xef) != UI) /* not UI */ - goto done; - if (skb->data[3] != TEI_ENTITY_ID) /* not tei entity */ - goto done; - mt = skb->data[6]; - switch (mt) { - case ID_REQUEST: - case ID_CHK_RES: - case ID_VERIFY: - if (!test_bit(MGR_OPT_NETWORK, &mgr->options)) - goto done; - break; - case ID_ASSIGNED: - case ID_DENIED: - case ID_CHK_REQ: - case ID_REMOVE: - if (test_bit(MGR_OPT_NETWORK, &mgr->options)) - goto done; - break; - default: - goto done; - } - ret = 0; - if (mt == ID_REQUEST) { - new_tei_req(mgr, &skb->data[4]); - goto done; - } - read_lock_irqsave(&mgr->lock, flags); - list_for_each_entry(l2, &mgr->layer2, list) { - tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4); - } - read_unlock_irqrestore(&mgr->lock, flags); -done: - return ret; -} - -int -l2_tei(struct layer2 *l2, u_int cmd, u_long arg) -{ - struct teimgr *tm = l2->tm; - - if (test_bit(FLG_FIXED_TEI, &l2->flag)) - return 0; - if (*debug & DEBUG_L2_TEI) - printk(KERN_DEBUG "%s: cmd(%x)\n", __func__, cmd); - switch (cmd) { - case MDL_ASSIGN_IND: - mISDN_FsmEvent(&tm->tei_m, EV_IDREQ, NULL); - break; - case MDL_ERROR_IND: - if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options)) - mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, &l2->tei); - if (test_bit(MGR_OPT_USER, &tm->mgr->options)) - mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, NULL); - break; - case MDL_STATUS_UP_IND: - if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options)) - mISDN_FsmEvent(&tm->mgr->deact, EV_ACTIVATE, NULL); - break; - case MDL_STATUS_DOWN_IND: - if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options)) - mISDN_FsmEvent(&tm->mgr->deact, EV_DEACTIVATE, NULL); - break; - case MDL_STATUS_UI_IND: - if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options)) - mISDN_FsmEvent(&tm->mgr->deact, EV_UI, NULL); - break; - } - return 0; -} - -void -TEIrelease(struct layer2 *l2) -{ - struct teimgr *tm = l2->tm; - u_long flags; - - mISDN_FsmDelTimer(&tm->timer, 1); - write_lock_irqsave(&tm->mgr->lock, flags); - list_del(&l2->list); - write_unlock_irqrestore(&tm->mgr->lock, flags); - l2->tm = NULL; - kfree(tm); -} - -static int -create_teimgr(struct manager *mgr, struct channel_req *crq) -{ - struct layer2 *l2; - u_long opt = 0; - u_long flags; - int id; - - if (*debug & DEBUG_L2_TEI) - printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n", - __func__, mgr->ch.st->dev->name, crq->protocol, - crq->adr.dev, crq->adr.channel, crq->adr.sapi, - crq->adr.tei); - if (crq->adr.sapi != 0) /* not supported yet */ - return -EINVAL; - if (crq->adr.tei > GROUP_TEI) - return -EINVAL; - if (crq->adr.tei < 64) - test_and_set_bit(OPTION_L2_FIXEDTEI, &opt); - if (crq->adr.tei == 0) - test_and_set_bit(OPTION_L2_PTP, &opt); - if (test_bit(MGR_OPT_NETWORK, &mgr->options)) { - if (crq->protocol == ISDN_P_LAPD_TE) - return -EPROTONOSUPPORT; - if ((crq->adr.tei != 0) && (crq->adr.tei != 127)) - return -EINVAL; - if (mgr->up) { - printk(KERN_WARNING - "%s: only one network manager is allowed\n", - __func__); - return -EBUSY; - } - } else if (test_bit(MGR_OPT_USER, &mgr->options)) { - if (crq->protocol == ISDN_P_LAPD_NT) - return -EPROTONOSUPPORT; - if ((crq->adr.tei >= 64) && (crq->adr.tei < GROUP_TEI)) - return -EINVAL; /* dyn tei */ - } else { - if (crq->protocol == ISDN_P_LAPD_NT) - test_and_set_bit(MGR_OPT_NETWORK, &mgr->options); - if (crq->protocol == ISDN_P_LAPD_TE) - test_and_set_bit(MGR_OPT_USER, &mgr->options); - } - if (mgr->ch.st->dev->Dprotocols - & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) - test_and_set_bit(OPTION_L2_PMX, &opt); - if ((crq->protocol == ISDN_P_LAPD_NT) && (crq->adr.tei == 127)) { - mgr->up = crq->ch; - id = DL_INFO_L2_CONNECT; - teiup_create(mgr, DL_INFORMATION_IND, sizeof(id), &id); - crq->ch = NULL; - if (!list_empty(&mgr->layer2)) { - read_lock_irqsave(&mgr->lock, flags); - list_for_each_entry(l2, &mgr->layer2, list) { - l2->up = mgr->up; - l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL); - } - read_unlock_irqrestore(&mgr->lock, flags); - } - return 0; - } - l2 = create_l2(crq->ch, crq->protocol, (u_int)opt, - (u_long)crq->adr.tei); - if (!l2) - return -ENOMEM; - l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); - if (!l2->tm) { - kfree(l2); - printk(KERN_ERR "kmalloc teimgr failed\n"); - return -ENOMEM; - } - l2->tm->mgr = mgr; - l2->tm->l2 = l2; - l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM; - l2->tm->tei_m.userdata = l2->tm; - l2->tm->tei_m.printdebug = tei_debug; - if (crq->protocol == ISDN_P_LAPD_TE) { - l2->tm->tei_m.fsm = &teifsmu; - l2->tm->tei_m.state = ST_TEI_NOP; - l2->tm->tval = 1000; /* T201 1 sec */ - } else { - l2->tm->tei_m.fsm = &teifsmn; - l2->tm->tei_m.state = ST_TEI_NOP; - l2->tm->tval = 2000; /* T202 2 sec */ - } - mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer); - write_lock_irqsave(&mgr->lock, flags); - id = get_free_id(mgr); - list_add_tail(&l2->list, &mgr->layer2); - write_unlock_irqrestore(&mgr->lock, flags); - if (id < 0) { - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL); - } else { - l2->ch.nr = id; - l2->up->nr = id; - crq->ch = &l2->ch; - id = 0; - } - return id; -} - -static int -mgr_send(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct manager *mgr; - struct mISDNhead *hh = mISDN_HEAD_P(skb); - int ret = -EINVAL; - - mgr = container_of(ch, struct manager, ch); - if (*debug & DEBUG_L2_RECV) - printk(KERN_DEBUG "%s: prim(%x) id(%x)\n", - __func__, hh->prim, hh->id); - switch (hh->prim) { - case PH_DATA_IND: - mISDN_FsmEvent(&mgr->deact, EV_UI, NULL); - ret = ph_data_ind(mgr, skb); - break; - case PH_DATA_CNF: - do_ack(mgr, hh->id); - ret = 0; - break; - case PH_ACTIVATE_IND: - test_and_set_bit(MGR_PH_ACTIVE, &mgr->options); - mISDN_FsmEvent(&mgr->deact, EV_ACTIVATE_IND, NULL); - do_send(mgr); - ret = 0; - break; - case PH_DEACTIVATE_IND: - test_and_clear_bit(MGR_PH_ACTIVE, &mgr->options); - mISDN_FsmEvent(&mgr->deact, EV_DEACTIVATE_IND, NULL); - ret = 0; - break; - case DL_UNITDATA_REQ: - return dl_unit_data(mgr, skb); - } - if (!ret) - dev_kfree_skb(skb); - return ret; -} - -static int -free_teimanager(struct manager *mgr) -{ - struct layer2 *l2, *nl2; - - if (test_bit(MGR_OPT_NETWORK, &mgr->options)) { - /* not locked lock is taken in release tei */ - mgr->up = NULL; - if (test_bit(OPTION_L2_CLEANUP, &mgr->options)) { - list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) { - put_tei_msg(mgr, ID_REMOVE, 0, l2->tei); - mutex_lock(&mgr->ch.st->lmutex); - list_del(&l2->ch.list); - mutex_unlock(&mgr->ch.st->lmutex); - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL); - } - test_and_clear_bit(MGR_OPT_NETWORK, &mgr->options); - } else { - list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) { - l2->up = NULL; - } - } - } - if (test_bit(MGR_OPT_USER, &mgr->options)) { - if (list_empty(&mgr->layer2)) - test_and_clear_bit(MGR_OPT_USER, &mgr->options); - } - mgr->ch.st->dev->D.ctrl(&mgr->ch.st->dev->D, CLOSE_CHANNEL, NULL); - return 0; -} - -static int -ctrl_teimanager(struct manager *mgr, void *arg) -{ - /* currently we only have one option */ - int clean = *((int *)arg); - - if (clean) - test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options); - else - test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options); - return 0; -} - -/* This function does create a L2 for fixed TEI in NT Mode */ -static int -check_data(struct manager *mgr, struct sk_buff *skb) -{ - struct mISDNhead *hh = mISDN_HEAD_P(skb); - int ret, tei; - struct layer2 *l2; - - if (*debug & DEBUG_L2_CTRL) - printk(KERN_DEBUG "%s: prim(%x) id(%x)\n", - __func__, hh->prim, hh->id); - if (test_bit(MGR_OPT_USER, &mgr->options)) - return -ENOTCONN; - if (hh->prim != PH_DATA_IND) - return -ENOTCONN; - if (skb->len != 3) - return -ENOTCONN; - if (skb->data[0] != 0) - /* only SAPI 0 command */ - return -ENOTCONN; - if (!(skb->data[1] & 1)) /* invalid EA1 */ - return -EINVAL; - tei = skb->data[1] >> 0; - if (tei > 63) /* not a fixed tei */ - return -ENOTCONN; - if ((skb->data[2] & ~0x10) != SABME) - return -ENOTCONN; - /* We got a SABME for a fixed TEI */ - l2 = create_new_tei(mgr, tei); - if (!l2) - return -ENOMEM; - ret = l2->ch.send(&l2->ch, skb); - return ret; -} - -void -delete_teimanager(struct mISDNchannel *ch) -{ - struct manager *mgr; - struct layer2 *l2, *nl2; - - mgr = container_of(ch, struct manager, ch); - /* not locked lock is taken in release tei */ - list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) { - mutex_lock(&mgr->ch.st->lmutex); - list_del(&l2->ch.list); - mutex_unlock(&mgr->ch.st->lmutex); - l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL); - } - list_del(&mgr->ch.list); - list_del(&mgr->bcast.list); - skb_queue_purge(&mgr->sendq); - kfree(mgr); -} - -static int -mgr_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - struct manager *mgr; - int ret = -EINVAL; - - mgr = container_of(ch, struct manager, ch); - if (*debug & DEBUG_L2_CTRL) - printk(KERN_DEBUG "%s(%x, %p)\n", __func__, cmd, arg); - switch (cmd) { - case OPEN_CHANNEL: - ret = create_teimgr(mgr, arg); - break; - case CLOSE_CHANNEL: - ret = free_teimanager(mgr); - break; - case CONTROL_CHANNEL: - ret = ctrl_teimanager(mgr, arg); - break; - case CHECK_DATA: - ret = check_data(mgr, arg); - break; - } - return ret; -} - -static int -mgr_bcast(struct mISDNchannel *ch, struct sk_buff *skb) -{ - struct manager *mgr = container_of(ch, struct manager, bcast); - struct mISDNhead *hh = mISDN_HEAD_P(skb); - struct sk_buff *cskb = NULL; - struct layer2 *l2; - u_long flags; - int ret; - - read_lock_irqsave(&mgr->lock, flags); - list_for_each_entry(l2, &mgr->layer2, list) { - if ((hh->id & MISDN_ID_SAPI_MASK) == - (l2->ch.addr & MISDN_ID_SAPI_MASK)) { - if (list_is_last(&l2->list, &mgr->layer2)) { - cskb = skb; - skb = NULL; - } else { - if (!cskb) - cskb = skb_copy(skb, GFP_KERNEL); - } - if (cskb) { - ret = l2->ch.send(&l2->ch, cskb); - if (ret) { - if (*debug & DEBUG_SEND_ERR) - printk(KERN_DEBUG - "%s ch%d prim(%x) addr(%x)" - " err %d\n", - __func__, l2->ch.nr, - hh->prim, l2->ch.addr, ret); - } else - cskb = NULL; - } else { - printk(KERN_WARNING "%s ch%d addr %x no mem\n", - __func__, ch->nr, ch->addr); - goto out; - } - } - } -out: - read_unlock_irqrestore(&mgr->lock, flags); - if (cskb) - dev_kfree_skb(cskb); - if (skb) - dev_kfree_skb(skb); - return 0; -} - -static int -mgr_bcast_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) -{ - - return -EINVAL; -} - -int -create_teimanager(struct mISDNdevice *dev) -{ - struct manager *mgr; - - mgr = kzalloc(sizeof(struct manager), GFP_KERNEL); - if (!mgr) - return -ENOMEM; - INIT_LIST_HEAD(&mgr->layer2); - mgr->lock = __RW_LOCK_UNLOCKED(mgr->lock); - skb_queue_head_init(&mgr->sendq); - mgr->nextid = 1; - mgr->lastid = MISDN_ID_NONE; - mgr->ch.send = mgr_send; - mgr->ch.ctrl = mgr_ctrl; - mgr->ch.st = dev->D.st; - set_channel_address(&mgr->ch, TEI_SAPI, GROUP_TEI); - add_layer2(&mgr->ch, dev->D.st); - mgr->bcast.send = mgr_bcast; - mgr->bcast.ctrl = mgr_bcast_ctrl; - mgr->bcast.st = dev->D.st; - set_channel_address(&mgr->bcast, 0, GROUP_TEI); - add_layer2(&mgr->bcast, dev->D.st); - mgr->deact.debug = *debug & DEBUG_MANAGER; - mgr->deact.userdata = mgr; - mgr->deact.printdebug = da_debug; - mgr->deact.fsm = &deactfsm; - mgr->deact.state = ST_L1_DEACT; - mISDN_FsmInitTimer(&mgr->deact, &mgr->datimer); - dev->teimgr = &mgr->ch; - return 0; -} - -int TEIInit(u_int *deb) -{ - debug = deb; - teifsmu.state_count = TEI_STATE_COUNT; - teifsmu.event_count = TEI_EVENT_COUNT; - teifsmu.strEvent = strTeiEvent; - teifsmu.strState = strTeiState; - mISDN_FsmNew(&teifsmu, TeiFnListUser, ARRAY_SIZE(TeiFnListUser)); - teifsmn.state_count = TEI_STATE_COUNT; - teifsmn.event_count = TEI_EVENT_COUNT; - teifsmn.strEvent = strTeiEvent; - teifsmn.strState = strTeiState; - mISDN_FsmNew(&teifsmn, TeiFnListNet, ARRAY_SIZE(TeiFnListNet)); - deactfsm.state_count = DEACT_STATE_COUNT; - deactfsm.event_count = DEACT_EVENT_COUNT; - deactfsm.strEvent = strDeactEvent; - deactfsm.strState = strDeactState; - mISDN_FsmNew(&deactfsm, DeactFnList, ARRAY_SIZE(DeactFnList)); - return 0; -} - -void TEIFree(void) -{ - mISDN_FsmFree(&teifsmu); - mISDN_FsmFree(&teifsmn); - mISDN_FsmFree(&deactfsm); -} diff --git a/trunk/drivers/isdn/mISDN/timerdev.c b/trunk/drivers/isdn/mISDN/timerdev.c deleted file mode 100644 index b5fabc7019d8..000000000000 --- a/trunk/drivers/isdn/mISDN/timerdev.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * - * general timer device for using in ISDN stacks - * - * Author Karsten Keil - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include - -static int *debug; - - -struct mISDNtimerdev { - int next_id; - struct list_head pending; - struct list_head expired; - wait_queue_head_t wait; - u_int work; - spinlock_t lock; /* protect lists */ -}; - -struct mISDNtimer { - struct list_head list; - struct mISDNtimerdev *dev; - struct timer_list tl; - int id; -}; - -static int -mISDN_open(struct inode *ino, struct file *filep) -{ - struct mISDNtimerdev *dev; - - if (*debug & DEBUG_TIMER) - printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep); - dev = kmalloc(sizeof(struct mISDNtimerdev) , GFP_KERNEL); - if (!dev) - return -ENOMEM; - dev->next_id = 1; - INIT_LIST_HEAD(&dev->pending); - INIT_LIST_HEAD(&dev->expired); - spin_lock_init(&dev->lock); - dev->work = 0; - init_waitqueue_head(&dev->wait); - filep->private_data = dev; - __module_get(THIS_MODULE); - return 0; -} - -static int -mISDN_close(struct inode *ino, struct file *filep) -{ - struct mISDNtimerdev *dev = filep->private_data; - struct mISDNtimer *timer, *next; - - if (*debug & DEBUG_TIMER) - printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep); - list_for_each_entry_safe(timer, next, &dev->pending, list) { - del_timer(&timer->tl); - kfree(timer); - } - list_for_each_entry_safe(timer, next, &dev->expired, list) { - kfree(timer); - } - kfree(dev); - module_put(THIS_MODULE); - return 0; -} - -static ssize_t -mISDN_read(struct file *filep, char *buf, size_t count, loff_t *off) -{ - struct mISDNtimerdev *dev = filep->private_data; - struct mISDNtimer *timer; - u_long flags; - int ret = 0; - - if (*debug & DEBUG_TIMER) - printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__, - filep, buf, (int)count, off); - if (*off != filep->f_pos) - return -ESPIPE; - - if (list_empty(&dev->expired) && (dev->work == 0)) { - if (filep->f_flags & O_NONBLOCK) - return -EAGAIN; - wait_event_interruptible(dev->wait, (dev->work || - !list_empty(&dev->expired))); - if (signal_pending(current)) - return -ERESTARTSYS; - } - if (count < sizeof(int)) - return -ENOSPC; - if (dev->work) - dev->work = 0; - if (!list_empty(&dev->expired)) { - spin_lock_irqsave(&dev->lock, flags); - timer = (struct mISDNtimer *)dev->expired.next; - list_del(&timer->list); - spin_unlock_irqrestore(&dev->lock, flags); - if (put_user(timer->id, (int *)buf)) - ret = -EFAULT; - else - ret = sizeof(int); - kfree(timer); - } - return ret; -} - -static loff_t -mISDN_llseek(struct file *filep, loff_t offset, int orig) -{ - return -ESPIPE; -} - -static ssize_t -mISDN_write(struct file *filep, const char *buf, size_t count, loff_t *off) -{ - return -EOPNOTSUPP; -} - -static unsigned int -mISDN_poll(struct file *filep, poll_table *wait) -{ - struct mISDNtimerdev *dev = filep->private_data; - unsigned int mask = POLLERR; - - if (*debug & DEBUG_TIMER) - printk(KERN_DEBUG "%s(%p, %p)\n", __func__, filep, wait); - if (dev) { - poll_wait(filep, &dev->wait, wait); - mask = 0; - if (dev->work || !list_empty(&dev->expired)) - mask |= (POLLIN | POLLRDNORM); - if (*debug & DEBUG_TIMER) - printk(KERN_DEBUG "%s work(%d) empty(%d)\n", __func__, - dev->work, list_empty(&dev->expired)); - } - return mask; -} - -static void -dev_expire_timer(struct mISDNtimer *timer) -{ - u_long flags; - - spin_lock_irqsave(&timer->dev->lock, flags); - list_del(&timer->list); - list_add_tail(&timer->list, &timer->dev->expired); - spin_unlock_irqrestore(&timer->dev->lock, flags); - wake_up_interruptible(&timer->dev->wait); -} - -static int -misdn_add_timer(struct mISDNtimerdev *dev, int timeout) -{ - int id; - u_long flags; - struct mISDNtimer *timer; - - if (!timeout) { - dev->work = 1; - wake_up_interruptible(&dev->wait); - id = 0; - } else { - timer = kzalloc(sizeof(struct mISDNtimer), GFP_KERNEL); - if (!timer) - return -ENOMEM; - spin_lock_irqsave(&dev->lock, flags); - timer->id = dev->next_id++; - if (dev->next_id < 0) - dev->next_id = 1; - list_add_tail(&timer->list, &dev->pending); - spin_unlock_irqrestore(&dev->lock, flags); - timer->dev = dev; - timer->tl.data = (long)timer; - timer->tl.function = (void *) dev_expire_timer; - init_timer(&timer->tl); - timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000); - add_timer(&timer->tl); - id = timer->id; - } - return id; -} - -static int -misdn_del_timer(struct mISDNtimerdev *dev, int id) -{ - u_long flags; - struct mISDNtimer *timer; - int ret = 0; - - spin_lock_irqsave(&dev->lock, flags); - list_for_each_entry(timer, &dev->pending, list) { - if (timer->id == id) { - list_del_init(&timer->list); - del_timer(&timer->tl); - ret = timer->id; - kfree(timer); - goto unlock; - } - } -unlock: - spin_unlock_irqrestore(&dev->lock, flags); - return ret; -} - -static int -mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, - unsigned long arg) -{ - struct mISDNtimerdev *dev = filep->private_data; - int id, tout, ret = 0; - - - if (*debug & DEBUG_TIMER) - printk(KERN_DEBUG "%s(%p, %x, %lx)\n", __func__, - filep, cmd, arg); - switch (cmd) { - case IMADDTIMER: - if (get_user(tout, (int __user *)arg)) { - ret = -EFAULT; - break; - } - id = misdn_add_timer(dev, tout); - if (*debug & DEBUG_TIMER) - printk(KERN_DEBUG "%s add %d id %d\n", __func__, - tout, id); - if (id < 0) { - ret = id; - break; - } - if (put_user(id, (int __user *)arg)) - ret = -EFAULT; - break; - case IMDELTIMER: - if (get_user(id, (int __user *)arg)) { - ret = -EFAULT; - break; - } - if (*debug & DEBUG_TIMER) - printk(KERN_DEBUG "%s del id %d\n", __func__, id); - id = misdn_del_timer(dev, id); - if (put_user(id, (int __user *)arg)) - ret = -EFAULT; - break; - default: - ret = -EINVAL; - } - return ret; -} - -static struct file_operations mISDN_fops = { - .llseek = mISDN_llseek, - .read = mISDN_read, - .write = mISDN_write, - .poll = mISDN_poll, - .ioctl = mISDN_ioctl, - .open = mISDN_open, - .release = mISDN_close, -}; - -static struct miscdevice mISDNtimer = { - .minor = MISC_DYNAMIC_MINOR, - .name = "mISDNtimer", - .fops = &mISDN_fops, -}; - -int -mISDN_inittimer(int *deb) -{ - int err; - - debug = deb; - err = misc_register(&mISDNtimer); - if (err) - printk(KERN_WARNING "mISDN: Could not register timer device\n"); - return err; -} - -void mISDN_timer_cleanup(void) -{ - misc_deregister(&mISDNtimer); -} diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index 71dd65aa31b6..fea966d66f98 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -147,12 +147,9 @@ static struct priority_group *alloc_priority_group(void) static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) { struct pgpath *pgpath, *tmp; - struct multipath *m = ti->private; list_for_each_entry_safe(pgpath, tmp, pgpaths, list) { list_del(&pgpath->list); - if (m->hw_handler_name) - scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev)); dm_put_device(ti, pgpath->path.dev); free_pgpath(pgpath); } @@ -551,7 +548,6 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, { int r; struct pgpath *p; - struct multipath *m = ti->private; /* we need at least a path arg */ if (as->argc < 1) { @@ -570,15 +566,6 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, goto bad; } - if (m->hw_handler_name) { - r = scsi_dh_attach(bdev_get_queue(p->path.dev->bdev), - m->hw_handler_name); - if (r < 0) { - dm_put_device(ti, p->path.dev); - goto bad; - } - } - r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error); if (r) { dm_put_device(ti, p->path.dev); diff --git a/trunk/drivers/media/dvb/pluto2/pluto2.c b/trunk/drivers/media/dvb/pluto2/pluto2.c index a9653c63f4db..1360403b88b6 100644 --- a/trunk/drivers/media/dvb/pluto2/pluto2.c +++ b/trunk/drivers/media/dvb/pluto2/pluto2.c @@ -242,7 +242,7 @@ static int __devinit pluto_dma_map(struct pluto *pluto) pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf, TS_DMA_BYTES, PCI_DMA_FROMDEVICE); - return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr); + return pci_dma_mapping_error(pluto->dma_addr); } static void pluto_dma_unmap(struct pluto *pluto) diff --git a/trunk/drivers/memstick/core/memstick.c b/trunk/drivers/memstick/core/memstick.c index a38005008a20..61b98c333cb0 100644 --- a/trunk/drivers/memstick/core/memstick.c +++ b/trunk/drivers/memstick/core/memstick.c @@ -249,11 +249,8 @@ EXPORT_SYMBOL(memstick_next_req); */ void memstick_new_req(struct memstick_host *host) { - if (host->card) { - host->retries = cmd_retries; - INIT_COMPLETION(host->card->mrq_complete); - host->request(host); - } + host->retries = cmd_retries; + host->request(host); } EXPORT_SYMBOL(memstick_new_req); @@ -418,14 +415,10 @@ static struct memstick_dev *memstick_alloc_card(struct memstick_host *host) return NULL; } -static int memstick_power_on(struct memstick_host *host) +static void memstick_power_on(struct memstick_host *host) { - int rc = host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); - - if (!rc) - rc = host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); - - return rc; + host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); + host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); } static void memstick_check(struct work_struct *work) @@ -436,11 +429,8 @@ static void memstick_check(struct work_struct *work) dev_dbg(&host->dev, "memstick_check started\n"); mutex_lock(&host->lock); - if (!host->card) { - if (memstick_power_on(host)) - goto out_power_off; - } else - host->card->stop(host->card); + if (!host->card) + memstick_power_on(host); card = memstick_alloc_card(host); @@ -458,8 +448,7 @@ static void memstick_check(struct work_struct *work) || !(host->card->check(host->card))) { device_unregister(&host->card->dev); host->card = NULL; - } else - host->card->start(host->card); + } } if (!host->card) { @@ -472,7 +461,6 @@ static void memstick_check(struct work_struct *work) kfree(card); } -out_power_off: if (!host->card) host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); @@ -585,15 +573,11 @@ EXPORT_SYMBOL(memstick_suspend_host); */ void memstick_resume_host(struct memstick_host *host) { - int rc = 0; - mutex_lock(&host->lock); if (host->card) - rc = memstick_power_on(host); + memstick_power_on(host); mutex_unlock(&host->lock); - - if (!rc) - memstick_detect_change(host); + memstick_detect_change(host); } EXPORT_SYMBOL(memstick_resume_host); diff --git a/trunk/drivers/memstick/core/mspro_block.c b/trunk/drivers/memstick/core/mspro_block.c index 44b1817f2f2f..477d0fb6e588 100644 --- a/trunk/drivers/memstick/core/mspro_block.c +++ b/trunk/drivers/memstick/core/mspro_block.c @@ -136,8 +136,9 @@ struct mspro_block_data { unsigned int caps; struct gendisk *disk; struct request_queue *queue; - struct request *block_req; spinlock_t q_lock; + wait_queue_head_t q_wait; + struct task_struct *q_thread; unsigned short page_size; unsigned short cylinders; @@ -146,10 +147,9 @@ struct mspro_block_data { unsigned char system; unsigned char read_only:1, - eject:1, + active:1, has_request:1, - data_dir:1, - active:1; + data_dir:1; unsigned char transfer_cmd; int (*mrq_handler)(struct memstick_dev *card, @@ -160,14 +160,12 @@ struct mspro_block_data { struct scatterlist req_sg[MSPRO_BLOCK_MAX_SEGS]; unsigned int seg_count; unsigned int current_seg; - unsigned int current_page; + unsigned short current_page; }; static DEFINE_IDR(mspro_block_disk_idr); static DEFINE_MUTEX(mspro_block_disk_lock); -static int mspro_block_complete_req(struct memstick_dev *card, int error); - /*** Block device ***/ static int mspro_block_bd_open(struct inode *inode, struct file *filp) @@ -199,10 +197,8 @@ static int mspro_block_disk_release(struct gendisk *disk) mutex_lock(&mspro_block_disk_lock); - if (msb) { - if (msb->usage_count) - msb->usage_count--; - + if (msb->usage_count) { + msb->usage_count--; if (!msb->usage_count) { kfree(msb); disk->private_data = NULL; @@ -527,13 +523,11 @@ static int h_mspro_block_req_init(struct memstick_dev *card, static int h_mspro_block_default(struct memstick_dev *card, struct memstick_request **mrq) { - return mspro_block_complete_req(card, (*mrq)->error); -} - -static int h_mspro_block_default_bad(struct memstick_dev *card, - struct memstick_request **mrq) -{ - return -ENXIO; + complete(&card->mrq_complete); + if (!(*mrq)->error) + return -EAGAIN; + else + return (*mrq)->error; } static int h_mspro_block_get_ro(struct memstick_dev *card, @@ -541,30 +535,44 @@ static int h_mspro_block_get_ro(struct memstick_dev *card, { struct mspro_block_data *msb = memstick_get_drvdata(card); - if (!(*mrq)->error) { - if ((*mrq)->data[offsetof(struct ms_status_register, status0)] - & MEMSTICK_STATUS0_WP) - msb->read_only = 1; - else - msb->read_only = 0; + if ((*mrq)->error) { + complete(&card->mrq_complete); + return (*mrq)->error; } - return mspro_block_complete_req(card, (*mrq)->error); + if ((*mrq)->data[offsetof(struct ms_status_register, status0)] + & MEMSTICK_STATUS0_WP) + msb->read_only = 1; + else + msb->read_only = 0; + + complete(&card->mrq_complete); + return -EAGAIN; } static int h_mspro_block_wait_for_ced(struct memstick_dev *card, struct memstick_request **mrq) { + if ((*mrq)->error) { + complete(&card->mrq_complete); + return (*mrq)->error; + } + dev_dbg(&card->dev, "wait for ced: value %x\n", (*mrq)->data[0]); - if (!(*mrq)->error) { - if ((*mrq)->data[0] & (MEMSTICK_INT_CMDNAK | MEMSTICK_INT_ERR)) - (*mrq)->error = -EFAULT; - else if (!((*mrq)->data[0] & MEMSTICK_INT_CED)) - return 0; + if ((*mrq)->data[0] & (MEMSTICK_INT_CMDNAK | MEMSTICK_INT_ERR)) { + card->current_mrq.error = -EFAULT; + complete(&card->mrq_complete); + return card->current_mrq.error; } - return mspro_block_complete_req(card, (*mrq)->error); + if (!((*mrq)->data[0] & MEMSTICK_INT_CED)) + return 0; + else { + card->current_mrq.error = 0; + complete(&card->mrq_complete); + return -EAGAIN; + } } static int h_mspro_block_transfer_data(struct memstick_dev *card, @@ -575,8 +583,10 @@ static int h_mspro_block_transfer_data(struct memstick_dev *card, struct scatterlist t_sg = { 0 }; size_t t_offset; - if ((*mrq)->error) - return mspro_block_complete_req(card, (*mrq)->error); + if ((*mrq)->error) { + complete(&card->mrq_complete); + return (*mrq)->error; + } switch ((*mrq)->tpc) { case MS_TPC_WRITE_REG: @@ -607,8 +617,8 @@ static int h_mspro_block_transfer_data(struct memstick_dev *card, if (msb->current_seg == msb->seg_count) { if (t_val & MEMSTICK_INT_CED) { - return mspro_block_complete_req(card, - 0); + complete(&card->mrq_complete); + return -EAGAIN; } else { card->next_request = h_mspro_block_wait_for_ced; @@ -656,184 +666,140 @@ static int h_mspro_block_transfer_data(struct memstick_dev *card, /*** Data transfer ***/ -static int mspro_block_issue_req(struct memstick_dev *card, int chunk) +static void mspro_block_process_request(struct memstick_dev *card, + struct request *req) { struct mspro_block_data *msb = memstick_get_drvdata(card); - sector_t t_sec; - unsigned int count; struct mspro_param_register param; + int rc, chunk, cnt; + unsigned short page_count; + sector_t t_sec; + unsigned long flags; -try_again: - while (chunk) { - msb->current_page = 0; + do { + page_count = 0; msb->current_seg = 0; - msb->seg_count = blk_rq_map_sg(msb->block_req->q, - msb->block_req, - msb->req_sg); - - if (!msb->seg_count) { - chunk = __blk_end_request(msb->block_req, -ENOMEM, - blk_rq_cur_bytes(msb->block_req)); - continue; - } + msb->seg_count = blk_rq_map_sg(req->q, req, msb->req_sg); - t_sec = msb->block_req->sector << 9; - sector_div(t_sec, msb->page_size); - - count = msb->block_req->nr_sectors << 9; - count /= msb->page_size; - - param.system = msb->system; - param.data_count = cpu_to_be16(count); - param.data_address = cpu_to_be32((uint32_t)t_sec); - param.tpc_param = 0; - - msb->data_dir = rq_data_dir(msb->block_req); - msb->transfer_cmd = msb->data_dir == READ - ? MSPRO_CMD_READ_DATA - : MSPRO_CMD_WRITE_DATA; - - dev_dbg(&card->dev, "data transfer: cmd %x, " - "lba %x, count %x\n", msb->transfer_cmd, - be32_to_cpu(param.data_address), count); + if (msb->seg_count) { + msb->current_page = 0; + for (rc = 0; rc < msb->seg_count; rc++) + page_count += msb->req_sg[rc].length + / msb->page_size; + + t_sec = req->sector; + sector_div(t_sec, msb->page_size >> 9); + param.system = msb->system; + param.data_count = cpu_to_be16(page_count); + param.data_address = cpu_to_be32((uint32_t)t_sec); + param.tpc_param = 0; + + msb->data_dir = rq_data_dir(req); + msb->transfer_cmd = msb->data_dir == READ + ? MSPRO_CMD_READ_DATA + : MSPRO_CMD_WRITE_DATA; + + dev_dbg(&card->dev, "data transfer: cmd %x, " + "lba %x, count %x\n", msb->transfer_cmd, + be32_to_cpu(param.data_address), + page_count); + + card->next_request = h_mspro_block_req_init; + msb->mrq_handler = h_mspro_block_transfer_data; + memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, + ¶m, sizeof(param)); + memstick_new_req(card->host); + wait_for_completion(&card->mrq_complete); + rc = card->current_mrq.error; - card->next_request = h_mspro_block_req_init; - msb->mrq_handler = h_mspro_block_transfer_data; - memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, - ¶m, sizeof(param)); - memstick_new_req(card->host); - return 0; - } + if (rc || (card->current_mrq.tpc == MSPRO_CMD_STOP)) { + for (cnt = 0; cnt < msb->current_seg; cnt++) + page_count += msb->req_sg[cnt].length + / msb->page_size; + + if (msb->current_page) + page_count += msb->current_page - 1; + + if (page_count && (msb->data_dir == READ)) + rc = msb->page_size * page_count; + else + rc = -EIO; + } else + rc = msb->page_size * page_count; + } else + rc = -EFAULT; - dev_dbg(&card->dev, "elv_next\n"); - msb->block_req = elv_next_request(msb->queue); - if (!msb->block_req) { - dev_dbg(&card->dev, "issue end\n"); - return -EAGAIN; - } + spin_lock_irqsave(&msb->q_lock, flags); + if (rc >= 0) + chunk = __blk_end_request(req, 0, rc); + else + chunk = __blk_end_request(req, rc, 0); - dev_dbg(&card->dev, "trying again\n"); - chunk = 1; - goto try_again; + dev_dbg(&card->dev, "end chunk %d, %d\n", rc, chunk); + spin_unlock_irqrestore(&msb->q_lock, flags); + } while (chunk); } -static int mspro_block_complete_req(struct memstick_dev *card, int error) +static int mspro_block_has_request(struct mspro_block_data *msb) { - struct mspro_block_data *msb = memstick_get_drvdata(card); - int chunk, cnt; - unsigned int t_len = 0; + int rc = 0; unsigned long flags; spin_lock_irqsave(&msb->q_lock, flags); - dev_dbg(&card->dev, "complete %d, %d\n", msb->has_request ? 1 : 0, - error); - - if (msb->has_request) { - /* Nothing to do - not really an error */ - if (error == -EAGAIN) - error = 0; - - if (error || (card->current_mrq.tpc == MSPRO_CMD_STOP)) { - if (msb->data_dir == READ) { - for (cnt = 0; cnt < msb->current_seg; cnt++) - t_len += msb->req_sg[cnt].length - / msb->page_size; - - if (msb->current_page) - t_len += msb->current_page - 1; - - t_len *= msb->page_size; - } - } else - t_len = msb->block_req->nr_sectors << 9; - - dev_dbg(&card->dev, "transferred %x (%d)\n", t_len, error); - - if (error && !t_len) - t_len = blk_rq_cur_bytes(msb->block_req); - - chunk = __blk_end_request(msb->block_req, error, t_len); - - error = mspro_block_issue_req(card, chunk); - - if (!error) - goto out; - else - msb->has_request = 0; - } else { - if (!error) - error = -EAGAIN; - } - - card->next_request = h_mspro_block_default_bad; - complete_all(&card->mrq_complete); -out: + if (kthread_should_stop() || msb->has_request) + rc = 1; spin_unlock_irqrestore(&msb->q_lock, flags); - return error; + return rc; } -static void mspro_block_stop(struct memstick_dev *card) +static int mspro_block_queue_thread(void *data) { + struct memstick_dev *card = data; + struct memstick_host *host = card->host; struct mspro_block_data *msb = memstick_get_drvdata(card); - int rc = 0; + struct request *req; unsigned long flags; while (1) { + wait_event(msb->q_wait, mspro_block_has_request(msb)); + dev_dbg(&card->dev, "thread iter\n"); + spin_lock_irqsave(&msb->q_lock, flags); - if (!msb->has_request) { - blk_stop_queue(msb->queue); - rc = 1; - } + req = elv_next_request(msb->queue); + dev_dbg(&card->dev, "next req %p\n", req); + if (!req) { + msb->has_request = 0; + if (kthread_should_stop()) { + spin_unlock_irqrestore(&msb->q_lock, flags); + break; + } + } else + msb->has_request = 1; spin_unlock_irqrestore(&msb->q_lock, flags); - if (rc) - break; - - wait_for_completion(&card->mrq_complete); - } -} - -static void mspro_block_start(struct memstick_dev *card) -{ - struct mspro_block_data *msb = memstick_get_drvdata(card); - unsigned long flags; - - spin_lock_irqsave(&msb->q_lock, flags); - blk_start_queue(msb->queue); - spin_unlock_irqrestore(&msb->q_lock, flags); -} - -static int mspro_block_prepare_req(struct request_queue *q, struct request *req) -{ - if (!blk_fs_request(req) && !blk_pc_request(req)) { - blk_dump_rq_flags(req, "MSPro unsupported request"); - return BLKPREP_KILL; + if (req) { + mutex_lock(&host->lock); + mspro_block_process_request(card, req); + mutex_unlock(&host->lock); + } } - - req->cmd_flags |= REQ_DONTPREP; - - return BLKPREP_OK; + dev_dbg(&card->dev, "thread finished\n"); + return 0; } -static void mspro_block_submit_req(struct request_queue *q) +static void mspro_block_request(struct request_queue *q) { struct memstick_dev *card = q->queuedata; struct mspro_block_data *msb = memstick_get_drvdata(card); struct request *req = NULL; - if (msb->has_request) - return; - - if (msb->eject) { + if (msb->q_thread) { + msb->has_request = 1; + wake_up_all(&msb->q_wait); + } else { while ((req = elv_next_request(q)) != NULL) end_queued_request(req, -ENODEV); - - return; } - - msb->has_request = 1; - if (mspro_block_issue_req(card, 0)) - msb->has_request = 0; } /*** Initialization ***/ @@ -1203,14 +1169,16 @@ static int mspro_block_init_disk(struct memstick_dev *card) goto out_release_id; } - msb->queue = blk_init_queue(mspro_block_submit_req, &msb->q_lock); + spin_lock_init(&msb->q_lock); + init_waitqueue_head(&msb->q_wait); + + msb->queue = blk_init_queue(mspro_block_request, &msb->q_lock); if (!msb->queue) { rc = -ENOMEM; goto out_put_disk; } msb->queue->queuedata = card; - blk_queue_prep_rq(msb->queue, mspro_block_prepare_req); blk_queue_bounce_limit(msb->queue, limit); blk_queue_max_sectors(msb->queue, MSPRO_BLOCK_MAX_PAGES); @@ -1236,8 +1204,14 @@ static int mspro_block_init_disk(struct memstick_dev *card) capacity *= msb->page_size >> 9; set_capacity(msb->disk, capacity); dev_dbg(&card->dev, "capacity set %ld\n", capacity); + msb->q_thread = kthread_run(mspro_block_queue_thread, card, + DRIVER_NAME"d"); + if (IS_ERR(msb->q_thread)) + goto out_put_disk; + mutex_unlock(&host->lock); add_disk(msb->disk); + mutex_lock(&host->lock); msb->active = 1; return 0; @@ -1285,7 +1259,6 @@ static int mspro_block_probe(struct memstick_dev *card) return -ENOMEM; memstick_set_drvdata(card, msb); msb->card = card; - spin_lock_init(&msb->q_lock); rc = mspro_block_init_card(card); @@ -1299,8 +1272,6 @@ static int mspro_block_probe(struct memstick_dev *card) rc = mspro_block_init_disk(card); if (!rc) { card->check = mspro_block_check_card; - card->stop = mspro_block_stop; - card->start = mspro_block_start; return 0; } @@ -1315,17 +1286,26 @@ static int mspro_block_probe(struct memstick_dev *card) static void mspro_block_remove(struct memstick_dev *card) { struct mspro_block_data *msb = memstick_get_drvdata(card); + struct task_struct *q_thread = NULL; unsigned long flags; del_gendisk(msb->disk); dev_dbg(&card->dev, "mspro block remove\n"); spin_lock_irqsave(&msb->q_lock, flags); - msb->eject = 1; - blk_start_queue(msb->queue); + q_thread = msb->q_thread; + msb->q_thread = NULL; + msb->active = 0; spin_unlock_irqrestore(&msb->q_lock, flags); + if (q_thread) { + mutex_unlock(&card->host->lock); + kthread_stop(q_thread); + mutex_lock(&card->host->lock); + } + + dev_dbg(&card->dev, "queue thread stopped\n"); + blk_cleanup_queue(msb->queue); - msb->queue = NULL; sysfs_remove_group(&card->dev.kobj, &msb->attr_group); @@ -1342,13 +1322,19 @@ static void mspro_block_remove(struct memstick_dev *card) static int mspro_block_suspend(struct memstick_dev *card, pm_message_t state) { struct mspro_block_data *msb = memstick_get_drvdata(card); + struct task_struct *q_thread = NULL; unsigned long flags; spin_lock_irqsave(&msb->q_lock, flags); - blk_stop_queue(msb->queue); + q_thread = msb->q_thread; + msb->q_thread = NULL; msb->active = 0; + blk_stop_queue(msb->queue); spin_unlock_irqrestore(&msb->q_lock, flags); + if (q_thread) + kthread_stop(q_thread); + return 0; } @@ -1387,7 +1373,14 @@ static int mspro_block_resume(struct memstick_dev *card) if (memcmp(s_attr->data, r_attr->data, s_attr->size)) break; - msb->active = 1; + memstick_set_drvdata(card, msb); + msb->q_thread = kthread_run(mspro_block_queue_thread, + card, DRIVER_NAME"d"); + if (IS_ERR(msb->q_thread)) + msb->q_thread = NULL; + else + msb->active = 1; + break; } } diff --git a/trunk/drivers/memstick/host/jmb38x_ms.c b/trunk/drivers/memstick/host/jmb38x_ms.c index 3485c63d20b0..4e3bfbcdf155 100644 --- a/trunk/drivers/memstick/host/jmb38x_ms.c +++ b/trunk/drivers/memstick/host/jmb38x_ms.c @@ -50,7 +50,6 @@ struct jmb38x_ms_host { struct jmb38x_ms *chip; void __iomem *addr; spinlock_t lock; - struct tasklet_struct notify; int id; char host_id[32]; int irq; @@ -591,97 +590,55 @@ static void jmb38x_ms_abort(unsigned long data) spin_unlock_irqrestore(&host->lock, flags); } -static void jmb38x_ms_req_tasklet(unsigned long data) +static void jmb38x_ms_request(struct memstick_host *msh) { - struct memstick_host *msh = (struct memstick_host *)data; struct jmb38x_ms_host *host = memstick_priv(msh); unsigned long flags; int rc; spin_lock_irqsave(&host->lock, flags); - if (!host->req) { - do { - rc = memstick_next_req(msh, &host->req); - dev_dbg(&host->chip->pdev->dev, "tasklet req %d\n", rc); - } while (!rc && jmb38x_ms_issue_cmd(msh)); + if (host->req) { + spin_unlock_irqrestore(&host->lock, flags); + BUG(); + return; } - spin_unlock_irqrestore(&host->lock, flags); -} - -static void jmb38x_ms_dummy_submit(struct memstick_host *msh) -{ - return; -} -static void jmb38x_ms_submit_req(struct memstick_host *msh) -{ - struct jmb38x_ms_host *host = memstick_priv(msh); - - tasklet_schedule(&host->notify); + do { + rc = memstick_next_req(msh, &host->req); + } while (!rc && jmb38x_ms_issue_cmd(msh)); + spin_unlock_irqrestore(&host->lock, flags); } -static int jmb38x_ms_reset(struct jmb38x_ms_host *host) +static void jmb38x_ms_reset(struct jmb38x_ms_host *host) { - int cnt; - - writel(HOST_CONTROL_RESET_REQ | HOST_CONTROL_CLOCK_EN - | readl(host->addr + HOST_CONTROL), - host->addr + HOST_CONTROL); - mmiowb(); - - for (cnt = 0; cnt < 20; ++cnt) { - if (!(HOST_CONTROL_RESET_REQ - & readl(host->addr + HOST_CONTROL))) - goto reset_next; - - ndelay(20); - } - dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); - return -EIO; - -reset_next: - writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN - | readl(host->addr + HOST_CONTROL), - host->addr + HOST_CONTROL); - mmiowb(); + unsigned int host_ctl = readl(host->addr + HOST_CONTROL); - for (cnt = 0; cnt < 20; ++cnt) { - if (!(HOST_CONTROL_RESET - & readl(host->addr + HOST_CONTROL))) - goto reset_ok; + writel(HOST_CONTROL_RESET_REQ, host->addr + HOST_CONTROL); + while (HOST_CONTROL_RESET_REQ + & (host_ctl = readl(host->addr + HOST_CONTROL))) { ndelay(20); + dev_dbg(&host->chip->pdev->dev, "reset %08x\n", host_ctl); } - dev_dbg(&host->chip->pdev->dev, "reset timeout\n"); - return -EIO; -reset_ok: + writel(HOST_CONTROL_RESET, host->addr + HOST_CONTROL); mmiowb(); writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE); writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE); - return 0; } -static int jmb38x_ms_set_param(struct memstick_host *msh, - enum memstick_param param, - int value) +static void jmb38x_ms_set_param(struct memstick_host *msh, + enum memstick_param param, + int value) { struct jmb38x_ms_host *host = memstick_priv(msh); unsigned int host_ctl = readl(host->addr + HOST_CONTROL); unsigned int clock_ctl = CLOCK_CONTROL_40MHZ, clock_delay = 0; - int rc = 0; switch (param) { case MEMSTICK_POWER: if (value == MEMSTICK_POWER_ON) { - rc = jmb38x_ms_reset(host); - if (rc) - return rc; - - host_ctl = 7; - host_ctl |= HOST_CONTROL_POWER_EN - | HOST_CONTROL_CLOCK_EN; - writel(host_ctl, host->addr + HOST_CONTROL); + jmb38x_ms_reset(host); writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 : PAD_PU_PD_ON_MS_SOCK0, @@ -690,7 +647,11 @@ static int jmb38x_ms_set_param(struct memstick_host *msh, writel(PAD_OUTPUT_ENABLE_MS, host->addr + PAD_OUTPUT_ENABLE); - msleep(10); + host_ctl = 7; + host_ctl |= HOST_CONTROL_POWER_EN + | HOST_CONTROL_CLOCK_EN; + writel(host_ctl, host->addr + HOST_CONTROL); + dev_dbg(&host->chip->pdev->dev, "power on\n"); } else if (value == MEMSTICK_POWER_OFF) { host_ctl &= ~(HOST_CONTROL_POWER_EN @@ -699,8 +660,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh, writel(0, host->addr + PAD_OUTPUT_ENABLE); writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD); dev_dbg(&host->chip->pdev->dev, "power off\n"); - } else - return -EINVAL; + } break; case MEMSTICK_INTERFACE: host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); @@ -726,14 +686,12 @@ static int jmb38x_ms_set_param(struct memstick_host *msh, host_ctl &= ~HOST_CONTROL_REI; clock_ctl = CLOCK_CONTROL_60MHZ; clock_delay = 0; - } else - return -EINVAL; + } writel(host_ctl, host->addr + HOST_CONTROL); writel(clock_ctl, host->addr + CLOCK_CONTROL); writel(clock_delay, host->addr + CLOCK_DELAY); break; }; - return 0; } #ifdef CONFIG_PM @@ -827,9 +785,7 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt) host->id); host->irq = jm->pdev->irq; host->timeout_jiffies = msecs_to_jiffies(1000); - - tasklet_init(&host->notify, jmb38x_ms_req_tasklet, (unsigned long)msh); - msh->request = jmb38x_ms_submit_req; + msh->request = jmb38x_ms_request; msh->set_param = jmb38x_ms_set_param; msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8; @@ -941,8 +897,6 @@ static void jmb38x_ms_remove(struct pci_dev *dev) host = memstick_priv(jm->hosts[cnt]); - jm->hosts[cnt]->request = jmb38x_ms_dummy_submit; - tasklet_kill(&host->notify); writel(0, host->addr + INT_SIGNAL_ENABLE); writel(0, host->addr + INT_STATUS_ENABLE); mmiowb(); diff --git a/trunk/drivers/memstick/host/tifm_ms.c b/trunk/drivers/memstick/host/tifm_ms.c index d32d6ad8f3fc..8577de4ebb0e 100644 --- a/trunk/drivers/memstick/host/tifm_ms.c +++ b/trunk/drivers/memstick/host/tifm_ms.c @@ -71,7 +71,6 @@ struct tifm_ms { struct tifm_dev *dev; struct timer_list timer; struct memstick_request *req; - struct tasklet_struct notify; unsigned int mode_mask; unsigned int block_pos; unsigned long timeout_jiffies; @@ -456,51 +455,49 @@ static void tifm_ms_card_event(struct tifm_dev *sock) return; } -static void tifm_ms_req_tasklet(unsigned long data) +static void tifm_ms_request(struct memstick_host *msh) { - struct memstick_host *msh = (struct memstick_host *)data; struct tifm_ms *host = memstick_priv(msh); struct tifm_dev *sock = host->dev; unsigned long flags; int rc; spin_lock_irqsave(&sock->lock, flags); - if (!host->req) { - if (host->eject) { - do { - rc = memstick_next_req(msh, &host->req); - if (!rc) - host->req->error = -ETIME; - } while (!rc); - spin_unlock_irqrestore(&sock->lock, flags); - return; - } + if (host->req) { + printk(KERN_ERR "%s : unfinished request detected\n", + sock->dev.bus_id); + spin_unlock_irqrestore(&sock->lock, flags); + tifm_eject(host->dev); + return; + } + if (host->eject) { do { rc = memstick_next_req(msh, &host->req); - } while (!rc && tifm_ms_issue_cmd(host)); + if (!rc) + host->req->error = -ETIME; + } while (!rc); + spin_unlock_irqrestore(&sock->lock, flags); + return; } - spin_unlock_irqrestore(&sock->lock, flags); -} -static void tifm_ms_dummy_submit(struct memstick_host *msh) -{ - return; -} - -static void tifm_ms_submit_req(struct memstick_host *msh) -{ - struct tifm_ms *host = memstick_priv(msh); + do { + rc = memstick_next_req(msh, &host->req); + } while (!rc && tifm_ms_issue_cmd(host)); - tasklet_schedule(&host->notify); + spin_unlock_irqrestore(&sock->lock, flags); + return; } -static int tifm_ms_set_param(struct memstick_host *msh, - enum memstick_param param, - int value) +static void tifm_ms_set_param(struct memstick_host *msh, + enum memstick_param param, + int value) { struct tifm_ms *host = memstick_priv(msh); struct tifm_dev *sock = host->dev; + unsigned long flags; + + spin_lock_irqsave(&sock->lock, flags); switch (param) { case MEMSTICK_POWER: @@ -515,8 +512,7 @@ static int tifm_ms_set_param(struct memstick_host *msh, writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, sock->addr + SOCK_MS_SYSTEM); writel(0xffffffff, sock->addr + SOCK_MS_STATUS); - } else - return -EINVAL; + } break; case MEMSTICK_INTERFACE: if (value == MEMSTICK_SERIAL) { @@ -529,12 +525,11 @@ static int tifm_ms_set_param(struct memstick_host *msh, writel(TIFM_CTRL_FAST_CLK | readl(sock->addr + SOCK_CONTROL), sock->addr + SOCK_CONTROL); - } else - return -EINVAL; + } break; }; - return 0; + spin_unlock_irqrestore(&sock->lock, flags); } static void tifm_ms_abort(unsigned long data) @@ -575,9 +570,8 @@ static int tifm_ms_probe(struct tifm_dev *sock) host->timeout_jiffies = msecs_to_jiffies(1000); setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); - tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh); - msh->request = tifm_ms_submit_req; + msh->request = tifm_ms_request; msh->set_param = tifm_ms_set_param; sock->card_event = tifm_ms_card_event; sock->data_event = tifm_ms_data_event; @@ -599,8 +593,6 @@ static void tifm_ms_remove(struct tifm_dev *sock) int rc = 0; unsigned long flags; - msh->request = tifm_ms_dummy_submit; - tasklet_kill(&host->notify); spin_lock_irqsave(&sock->lock, flags); host->eject = 1; if (host->req) { diff --git a/trunk/drivers/message/fusion/lsi/mpi_history.txt b/trunk/drivers/message/fusion/lsi/mpi_history.txt index 3f15fcfe4a2e..241592ab13ad 100644 --- a/trunk/drivers/message/fusion/lsi/mpi_history.txt +++ b/trunk/drivers/message/fusion/lsi/mpi_history.txt @@ -127,7 +127,7 @@ mpi_ioc.h * 08-08-01 01.02.01 Original release for v1.2 work. * New format for FWVersion and ProductId in * MSG_IOC_FACTS_REPLY and MPI_FW_HEADER. - * 08-31-01 01.02.02 Added event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and + * 08-31-01 01.02.02 Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and * related structure and defines. * Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED. * Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE. @@ -187,7 +187,7 @@ mpi_ioc.h * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED. * Added MaxInitiators field to PortFacts reply. * Added SAS Device Status Change ReasonCode for - * asynchronous notification. + * asynchronous notificaiton. * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event * data structure. * Added new ImageType values for FWDownload and FWUpload @@ -213,7 +213,7 @@ mpi_cnfg.h * Added _RESPONSE_ID_MASK definition to SCSI_PORT_1 * page and updated the page version. * Added Information field and _INFO_PARAMS_NEGOTIATED - * definition to SCSI_DEVICE_0 page. + * definitionto SCSI_DEVICE_0 page. * 06-22-00 01.00.03 Removed batch controls from LAN_0 page and updated the * page version. * Added BucketsRemaining to LAN_1 page, redefined the diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index d6a0074b9dc3..34402c47027e 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -273,12 +273,12 @@ mpt_fault_reset_work(struct work_struct *work) ioc_raw_state = mpt_GetIocState(ioc, 0); if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", - ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); + ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", - ioc->name, __func__); + ioc->name, __FUNCTION__); rc = mpt_HardResetHandler(ioc, CAN_SLEEP); printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name, - __func__, (rc == 0) ? "success" : "failed"); + __FUNCTION__, (rc == 0) ? "success" : "failed"); ioc_raw_state = mpt_GetIocState(ioc, 0); if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " @@ -356,7 +356,7 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || MptCallbacks[cb_idx] == NULL) { printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", - __func__, ioc->name, cb_idx); + __FUNCTION__, ioc->name, cb_idx); goto out; } @@ -420,7 +420,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || MptCallbacks[cb_idx] == NULL) { printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", - __func__, ioc->name, cb_idx); + __FUNCTION__, ioc->name, cb_idx); freeme = 0; goto out; } @@ -2434,7 +2434,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) if (ioc->cached_fw != NULL) { ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto " - "adapter\n", __func__, ioc->name)); + "adapter\n", __FUNCTION__, ioc->name)); if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) ioc->cached_fw, CAN_SLEEP)) < 0) { printk(MYIOC_s_WARN_FMT @@ -3693,7 +3693,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " - "address=%p\n", ioc->name, __func__, + "address=%p\n", ioc->name, __FUNCTION__, &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); if (sleepFlag == CAN_SLEEP) @@ -4742,12 +4742,12 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) break; } - printk("%s: persist_opcode=%x\n",__func__, persist_opcode); + printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode); /* Get a MF for this command. */ if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { - printk("%s: no msg frames!\n",__func__); + printk("%s: no msg frames!\n",__FUNCTION__); return -1; } @@ -4771,13 +4771,13 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) (SasIoUnitControlReply_t *)ioc->persist_reply_frame; if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", - __func__, + __FUNCTION__, sasIoUnitCntrReply->IOCStatus, sasIoUnitCntrReply->IOCLogInfo); return -1; } - printk("%s: success\n",__func__); + printk("%s: success\n",__FUNCTION__); return 0; } @@ -5784,7 +5784,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", - ioc->name,__func__)); + ioc->name,__FUNCTION__)); return -1; } diff --git a/trunk/drivers/message/fusion/mptctl.c b/trunk/drivers/message/fusion/mptctl.c index f5233f3d9eff..a5920423e2b2 100644 --- a/trunk/drivers/message/fusion/mptctl.c +++ b/trunk/drivers/message/fusion/mptctl.c @@ -505,7 +505,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) event = le32_to_cpu(pEvReply->Event) & 0xFF; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n", - ioc->name, __func__)); + ioc->name, __FUNCTION__)); if(async_queue == NULL) return 1; @@ -2482,7 +2482,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) */ if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", - ioc->name,__func__)); + ioc->name,__FUNCTION__)); goto out; } diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index c3c24fdf9fb6..b36cae9ec6db 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -231,28 +231,28 @@ static int mptfc_abort(struct scsi_cmnd *SCpnt) { return - mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__); + 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, __func__); + 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, __func__); + 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, __func__); + mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__); } static void diff --git a/trunk/drivers/message/fusion/mptlan.c b/trunk/drivers/message/fusion/mptlan.c index a1abf95cf751..d709d92b7b30 100644 --- a/trunk/drivers/message/fusion/mptlan.c +++ b/trunk/drivers/message/fusion/mptlan.c @@ -610,7 +610,7 @@ mpt_lan_send_turbo(struct net_device *dev, u32 tmsg) dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __func__, sent)); + __FUNCTION__, sent)); priv->SendCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, @@ -676,7 +676,7 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep) dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __func__, sent)); + __FUNCTION__, sent)); priv->SendCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, @@ -715,7 +715,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) u16 cur_naa = 0x1000; dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n", - __func__, skb)); + __FUNCTION__, skb)); spin_lock_irqsave(&priv->txfidx_lock, flags); if (priv->mpt_txfidx_tail < 0) { @@ -723,7 +723,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&priv->txfidx_lock, flags); printk (KERN_ERR "%s: no tx context available: %u\n", - __func__, priv->mpt_txfidx_tail); + __FUNCTION__, priv->mpt_txfidx_tail); return 1; } @@ -733,7 +733,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&priv->txfidx_lock, flags); printk (KERN_ERR "%s: Unable to alloc request frame\n", - __func__); + __FUNCTION__); return 1; } @@ -1208,7 +1208,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, Start_buckets = %u, buckets_out = %u\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __func__, buckets, curr)); + __FUNCTION__, buckets, curr)); max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) / (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t)); @@ -1217,9 +1217,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) mf = mpt_get_msg_frame(LanCtx, mpt_dev); if (mf == NULL) { printk (KERN_ERR "%s: Unable to alloc request frame\n", - __func__); + __FUNCTION__); dioprintk((KERN_ERR "%s: %u buckets remaining\n", - __func__, buckets)); + __FUNCTION__, buckets)); goto out; } pRecvReq = (LANReceivePostRequest_t *) mf; @@ -1244,7 +1244,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) spin_lock_irqsave(&priv->rxfidx_lock, flags); if (priv->mpt_rxfidx_tail < 0) { printk (KERN_ERR "%s: Can't alloc context\n", - __func__); + __FUNCTION__); spin_unlock_irqrestore(&priv->rxfidx_lock, flags); break; @@ -1267,7 +1267,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) if (skb == NULL) { printk (KERN_WARNING MYNAM "/%s: Can't alloc skb\n", - __func__); + __FUNCTION__); priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; spin_unlock_irqrestore(&priv->rxfidx_lock, flags); break; @@ -1305,7 +1305,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) if (pSimple == NULL) { /**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n", -/**/ __func__); +/**/ __FUNCTION__); mpt_free_msg_frame(mpt_dev, mf); goto out; } @@ -1329,9 +1329,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) out: dioprintk((KERN_INFO MYNAM "/%s: End_buckets = %u, priv->buckets_out = %u\n", - __func__, buckets, atomic_read(&priv->buckets_out))); + __FUNCTION__, buckets, atomic_read(&priv->buckets_out))); dioprintk((KERN_INFO MYNAM "/%s: Posted %u buckets and received %u back\n", - __func__, priv->total_posted, priv->total_received)); + __FUNCTION__, priv->total_posted, priv->total_received)); clear_bit(0, &priv->post_buckets_active); } diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c index 12b732512e57..b1147aa7afde 100644 --- a/trunk/drivers/message/fusion/mptsas.c +++ b/trunk/drivers/message/fusion/mptsas.c @@ -300,7 +300,7 @@ mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_detai phy_info = port_info->phy_info; dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d " - "bitmask=0x%016llX\n", ioc->name, __func__, port_details, + "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details, port_details->num_phys, (unsigned long long) port_details->phy_bitmask)); @@ -411,7 +411,7 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) */ dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: deleting phy = %d\n", - ioc->name, __func__, port_details, i)); + ioc->name, __FUNCTION__, port_details, i)); port_details->num_phys--; port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); @@ -497,7 +497,7 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) continue; dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: phy_id=%02d num_phys=%02d " - "bitmask=0x%016llX\n", ioc->name, __func__, + "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details, i, port_details->num_phys, (unsigned long long)port_details->phy_bitmask)); dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n", @@ -553,7 +553,7 @@ mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id) if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n", - ioc->name,__func__, __LINE__)); + ioc->name,__FUNCTION__, __LINE__)); return 0; } @@ -606,7 +606,7 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, GFP_ATOMIC); if (!target_reset_list) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", - ioc->name,__func__, __LINE__)); + ioc->name,__FUNCTION__, __LINE__)); return; } @@ -673,7 +673,7 @@ mptsas_dev_reset_complete(MPT_ADAPTER *ioc) ev = kzalloc(sizeof(*ev), GFP_ATOMIC); if (!ev) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", - ioc->name,__func__, __LINE__)); + ioc->name,__FUNCTION__, __LINE__)); return; } @@ -1183,7 +1183,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset) reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply; if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) { printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", - ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo); + ioc->name, __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo); error = -ENXIO; goto out_unlock; } @@ -1270,14 +1270,14 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, if (!rsp) { printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n", - ioc->name, __func__); + ioc->name, __FUNCTION__); return -EINVAL; } /* do we need to support multiple segments? */ if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n", - ioc->name, __func__, req->bio->bi_vcnt, req->data_len, + ioc->name, __FUNCTION__, req->bio->bi_vcnt, req->data_len, rsp->bio->bi_vcnt, rsp->data_len); return -EINVAL; } @@ -1343,7 +1343,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); if (!timeleft) { - printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__); + printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __FUNCTION__); /* On timeout reset the board */ mpt_HardResetHandler(ioc, CAN_SLEEP); ret = -ETIMEDOUT; @@ -1361,7 +1361,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, rsp->data_len -= smprep->ResponseDataLength; } else { printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", - ioc->name, __func__); + ioc->name, __FUNCTION__); ret = -ENXIO; } unmap: @@ -2006,7 +2006,7 @@ static int mptsas_probe_one_phy(struct device *dev, if (error) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); goto out; } mptsas_set_port(ioc, phy_info, port); @@ -2076,7 +2076,7 @@ static int mptsas_probe_one_phy(struct device *dev, if (!rphy) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); goto out; } @@ -2085,7 +2085,7 @@ static int mptsas_probe_one_phy(struct device *dev, if (error) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); sas_rphy_free(rphy); goto out; } @@ -2613,7 +2613,7 @@ mptsas_hotplug_work(struct work_struct *work) (ev->channel << 8) + ev->id)) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } phy_info = mptsas_find_phyinfo_by_sas_address( @@ -2633,20 +2633,20 @@ mptsas_hotplug_work(struct work_struct *work) if (!phy_info){ dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } if (!phy_info->port_details) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } rphy = mptsas_get_rphy(phy_info); if (!rphy) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } @@ -2654,7 +2654,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!port) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } @@ -2665,7 +2665,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!vtarget) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } @@ -2720,7 +2720,7 @@ mptsas_hotplug_work(struct work_struct *work) (ev->channel << 8) + ev->id)) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } @@ -2732,7 +2732,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!phy_info || !phy_info->port_details) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } @@ -2744,7 +2744,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!vtarget) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } /* @@ -2767,7 +2767,7 @@ mptsas_hotplug_work(struct work_struct *work) if (mptsas_get_rphy(phy_info)) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); if (ev->channel) printk("%d\n", __LINE__); break; } @@ -2776,7 +2776,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!port) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; } memcpy(&phy_info->attached, &sas_device, @@ -2801,7 +2801,7 @@ mptsas_hotplug_work(struct work_struct *work) if (!rphy) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); break; /* non-fatal: an rphy can be added later */ } @@ -2809,7 +2809,7 @@ mptsas_hotplug_work(struct work_struct *work) if (sas_rphy_add(rphy)) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, - __func__, __LINE__)); + __FUNCTION__, __LINE__)); sas_rphy_free(rphy); break; } diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c index 9f9354fd3516..d142b6b4b976 100644 --- a/trunk/drivers/message/fusion/mptscsih.c +++ b/trunk/drivers/message/fusion/mptscsih.c @@ -461,7 +461,7 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n", - ioc->name,__func__)); + ioc->name,__FUNCTION__)); return; } @@ -2187,7 +2187,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m (ioc->debug_level & MPT_DEBUG_TM )) printk("%s: ha=%d [%d:%d:0] task_type=0x%02X " "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X " - "term_cmnds=%d\n", __func__, ioc->id, pScsiTmReply->Bus, + "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus, pScsiTmReply->TargetID, pScsiTmReq->TaskType, le16_to_cpu(pScsiTmReply->IOCStatus), le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode, diff --git a/trunk/drivers/mfd/asic3.c b/trunk/drivers/mfd/asic3.c index eabf0bfccab4..3b870e7fb3e1 100644 --- a/trunk/drivers/mfd/asic3.c +++ b/trunk/drivers/mfd/asic3.c @@ -314,12 +314,10 @@ static int __init asic3_irq_probe(struct platform_device *pdev) unsigned long clksel = 0; unsigned int irq, irq_base; int map_size; - int ret; - ret = platform_get_irq(pdev, 0); - if (ret < 0) - return ret; - asic->irq_nr = ret; + asic->irq_nr = platform_get_irq(pdev, 0); + if (asic->irq_nr < 0) + return asic->irq_nr; /* turn on clock to IRQ controller */ clksel |= CLOCK_SEL_CX; diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index f5ade1904aad..321eb9134635 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -360,7 +360,7 @@ config THINKPAD_ACPI_VIDEO If you are not sure, say Y here. config THINKPAD_ACPI_HOTKEY_POLL - bool "Support NVRAM polling for hot keys" + bool "Suport NVRAM polling for hot keys" depends on THINKPAD_ACPI default y ---help--- diff --git a/trunk/drivers/misc/atmel-ssc.c b/trunk/drivers/misc/atmel-ssc.c index bf5e4d065436..e171650766ce 100644 --- a/trunk/drivers/misc/atmel-ssc.c +++ b/trunk/drivers/misc/atmel-ssc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/mmc/core/Makefile b/trunk/drivers/mmc/core/Makefile index 889e5f898f6f..19a1a254a0c5 100644 --- a/trunk/drivers/mmc/core/Makefile +++ b/trunk/drivers/mmc/core/Makefile @@ -12,4 +12,3 @@ mmc_core-y := core.o bus.o host.o \ sdio.o sdio_ops.o sdio_bus.o \ sdio_cis.o sdio_io.o sdio_irq.o -mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o diff --git a/trunk/drivers/mmc/core/bus.c b/trunk/drivers/mmc/core/bus.c index 0d9b2d6f9ebf..fd95b18e988b 100644 --- a/trunk/drivers/mmc/core/bus.c +++ b/trunk/drivers/mmc/core/bus.c @@ -252,10 +252,6 @@ int mmc_add_card(struct mmc_card *card) if (ret) return ret; -#ifdef CONFIG_DEBUG_FS - mmc_add_card_debugfs(card); -#endif - mmc_card_set_present(card); return 0; @@ -267,10 +263,6 @@ int mmc_add_card(struct mmc_card *card) */ void mmc_remove_card(struct mmc_card *card) { -#ifdef CONFIG_DEBUG_FS - mmc_remove_card_debugfs(card); -#endif - if (mmc_card_present(card)) { if (mmc_host_is_spi(card->host)) { printk(KERN_INFO "%s: SPI card removed\n", diff --git a/trunk/drivers/mmc/core/core.h b/trunk/drivers/mmc/core/core.h index c819effa1032..cdb332b7dedc 100644 --- a/trunk/drivers/mmc/core/core.h +++ b/trunk/drivers/mmc/core/core.h @@ -52,12 +52,5 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr); extern int use_spi_crc; -/* Debugfs information for hosts and cards */ -void mmc_add_host_debugfs(struct mmc_host *host); -void mmc_remove_host_debugfs(struct mmc_host *host); - -void mmc_add_card_debugfs(struct mmc_card *card); -void mmc_remove_card_debugfs(struct mmc_card *card); - #endif diff --git a/trunk/drivers/mmc/core/debugfs.c b/trunk/drivers/mmc/core/debugfs.c deleted file mode 100644 index 1237bb4c722b..000000000000 --- a/trunk/drivers/mmc/core/debugfs.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Debugfs support for hosts and cards - * - * Copyright (C) 2008 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. - */ -#include -#include -#include -#include - -#include -#include - -#include "core.h" -#include "mmc_ops.h" - -/* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */ -static int mmc_ios_show(struct seq_file *s, void *data) -{ - static const char *vdd_str[] = { - [8] = "2.0", - [9] = "2.1", - [10] = "2.2", - [11] = "2.3", - [12] = "2.4", - [13] = "2.5", - [14] = "2.6", - [15] = "2.7", - [16] = "2.8", - [17] = "2.9", - [18] = "3.0", - [19] = "3.1", - [20] = "3.2", - [21] = "3.3", - [22] = "3.4", - [23] = "3.5", - [24] = "3.6", - }; - struct mmc_host *host = s->private; - struct mmc_ios *ios = &host->ios; - const char *str; - - seq_printf(s, "clock:\t\t%u Hz\n", ios->clock); - seq_printf(s, "vdd:\t\t%u ", ios->vdd); - if ((1 << ios->vdd) & MMC_VDD_165_195) - seq_printf(s, "(1.65 - 1.95 V)\n"); - else if (ios->vdd < (ARRAY_SIZE(vdd_str) - 1) - && vdd_str[ios->vdd] && vdd_str[ios->vdd + 1]) - seq_printf(s, "(%s ~ %s V)\n", vdd_str[ios->vdd], - vdd_str[ios->vdd + 1]); - else - seq_printf(s, "(invalid)\n"); - - switch (ios->bus_mode) { - case MMC_BUSMODE_OPENDRAIN: - str = "open drain"; - break; - case MMC_BUSMODE_PUSHPULL: - str = "push-pull"; - break; - default: - str = "invalid"; - break; - } - seq_printf(s, "bus mode:\t%u (%s)\n", ios->bus_mode, str); - - switch (ios->chip_select) { - case MMC_CS_DONTCARE: - str = "don't care"; - break; - case MMC_CS_HIGH: - str = "active high"; - break; - case MMC_CS_LOW: - str = "active low"; - break; - default: - str = "invalid"; - break; - } - seq_printf(s, "chip select:\t%u (%s)\n", ios->chip_select, str); - - switch (ios->power_mode) { - case MMC_POWER_OFF: - str = "off"; - break; - case MMC_POWER_UP: - str = "up"; - break; - case MMC_POWER_ON: - str = "on"; - break; - default: - str = "invalid"; - break; - } - seq_printf(s, "power mode:\t%u (%s)\n", ios->power_mode, str); - seq_printf(s, "bus width:\t%u (%u bits)\n", - ios->bus_width, 1 << ios->bus_width); - - switch (ios->timing) { - case MMC_TIMING_LEGACY: - str = "legacy"; - break; - case MMC_TIMING_MMC_HS: - str = "mmc high-speed"; - break; - case MMC_TIMING_SD_HS: - str = "sd high-speed"; - break; - default: - str = "invalid"; - break; - } - seq_printf(s, "timing spec:\t%u (%s)\n", ios->timing, str); - - return 0; -} - -static int mmc_ios_open(struct inode *inode, struct file *file) -{ - return single_open(file, mmc_ios_show, inode->i_private); -} - -static const struct file_operations mmc_ios_fops = { - .open = mmc_ios_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -void mmc_add_host_debugfs(struct mmc_host *host) -{ - struct dentry *root; - - root = debugfs_create_dir(mmc_hostname(host), NULL); - if (IS_ERR(root)) - /* Don't complain -- debugfs just isn't enabled */ - return; - if (!root) - /* Complain -- debugfs is enabled, but it failed to - * create the directory. */ - goto err_root; - - host->debugfs_root = root; - - if (!debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops)) - goto err_ios; - - return; - -err_ios: - debugfs_remove_recursive(root); - host->debugfs_root = NULL; -err_root: - dev_err(&host->class_dev, "failed to initialize debugfs\n"); -} - -void mmc_remove_host_debugfs(struct mmc_host *host) -{ - debugfs_remove_recursive(host->debugfs_root); -} - -static int mmc_dbg_card_status_get(void *data, u64 *val) -{ - struct mmc_card *card = data; - u32 status; - int ret; - - mmc_claim_host(card->host); - - ret = mmc_send_status(data, &status); - if (!ret) - *val = status; - - mmc_release_host(card->host); - - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get, - NULL, "%08llx\n"); - -void mmc_add_card_debugfs(struct mmc_card *card) -{ - struct mmc_host *host = card->host; - struct dentry *root; - - if (!host->debugfs_root) - return; - - root = debugfs_create_dir(mmc_card_id(card), host->debugfs_root); - if (IS_ERR(root)) - /* Don't complain -- debugfs just isn't enabled */ - return; - if (!root) - /* Complain -- debugfs is enabled, but it failed to - * create the directory. */ - goto err; - - card->debugfs_root = root; - - if (!debugfs_create_x32("state", S_IRUSR, root, &card->state)) - goto err; - - if (mmc_card_mmc(card) || mmc_card_sd(card)) - if (!debugfs_create_file("status", S_IRUSR, root, card, - &mmc_dbg_card_status_fops)) - goto err; - - return; - -err: - debugfs_remove_recursive(root); - card->debugfs_root = NULL; - dev_err(&card->dev, "failed to initialize debugfs\n"); -} - -void mmc_remove_card_debugfs(struct mmc_card *card) -{ - debugfs_remove_recursive(card->debugfs_root); -} diff --git a/trunk/drivers/mmc/core/host.c b/trunk/drivers/mmc/core/host.c index 6da80fd4d974..1d795c5379b5 100644 --- a/trunk/drivers/mmc/core/host.c +++ b/trunk/drivers/mmc/core/host.c @@ -127,10 +127,6 @@ int mmc_add_host(struct mmc_host *host) if (err) return err; -#ifdef CONFIG_DEBUG_FS - mmc_add_host_debugfs(host); -#endif - mmc_start_host(host); return 0; @@ -150,10 +146,6 @@ void mmc_remove_host(struct mmc_host *host) { mmc_stop_host(host); -#ifdef CONFIG_DEBUG_FS - mmc_remove_host_debugfs(host); -#endif - device_del(&host->class_dev); led_trigger_unregister_simple(host->led); diff --git a/trunk/drivers/mmc/host/atmel-mci-regs.h b/trunk/drivers/mmc/host/atmel-mci-regs.h index 26bd80e65031..a9a5657706c6 100644 --- a/trunk/drivers/mmc/host/atmel-mci-regs.h +++ b/trunk/drivers/mmc/host/atmel-mci-regs.h @@ -82,8 +82,6 @@ # define MCI_OVRE ( 1 << 30) /* RX Overrun Error */ # define MCI_UNRE ( 1 << 31) /* TX Underrun Error */ -#define MCI_REGS_SIZE 0x100 - /* Register access macros */ #define mci_readl(port,reg) \ __raw_readl((port)->regs + MCI_##reg) diff --git a/trunk/drivers/mmc/host/atmel-mci.c b/trunk/drivers/mmc/host/atmel-mci.c index 992b4beb757c..cce873c5a149 100644 --- a/trunk/drivers/mmc/host/atmel-mci.c +++ b/trunk/drivers/mmc/host/atmel-mci.c @@ -9,18 +9,13 @@ */ #include #include -#include #include -#include -#include #include #include #include #include #include #include -#include -#include #include @@ -29,6 +24,7 @@ #include #include +#include #include "atmel-mci-regs.h" @@ -92,188 +88,6 @@ struct atmel_mci { #define atmci_clear_pending(host, event) \ clear_bit(event, &host->pending_events) -/* - * The debugfs stuff below is mostly optimized away when - * CONFIG_DEBUG_FS is not set. - */ -static int atmci_req_show(struct seq_file *s, void *v) -{ - struct atmel_mci *host = s->private; - struct mmc_request *mrq = host->mrq; - struct mmc_command *cmd; - struct mmc_command *stop; - struct mmc_data *data; - - /* Make sure we get a consistent snapshot */ - spin_lock_irq(&host->mmc->lock); - - if (mrq) { - cmd = mrq->cmd; - data = mrq->data; - stop = mrq->stop; - - if (cmd) - seq_printf(s, - "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", - cmd->opcode, cmd->arg, cmd->flags, - cmd->resp[0], cmd->resp[1], cmd->resp[2], - cmd->resp[2], cmd->error); - if (data) - seq_printf(s, "DATA %u / %u * %u flg %x err %d\n", - data->bytes_xfered, data->blocks, - data->blksz, data->flags, data->error); - if (stop) - seq_printf(s, - "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", - stop->opcode, stop->arg, stop->flags, - stop->resp[0], stop->resp[1], stop->resp[2], - stop->resp[2], stop->error); - } - - spin_unlock_irq(&host->mmc->lock); - - return 0; -} - -static int atmci_req_open(struct inode *inode, struct file *file) -{ - return single_open(file, atmci_req_show, inode->i_private); -} - -static const struct file_operations atmci_req_fops = { - .owner = THIS_MODULE, - .open = atmci_req_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void atmci_show_status_reg(struct seq_file *s, - const char *regname, u32 value) -{ - static const char *sr_bit[] = { - [0] = "CMDRDY", - [1] = "RXRDY", - [2] = "TXRDY", - [3] = "BLKE", - [4] = "DTIP", - [5] = "NOTBUSY", - [8] = "SDIOIRQA", - [9] = "SDIOIRQB", - [16] = "RINDE", - [17] = "RDIRE", - [18] = "RCRCE", - [19] = "RENDE", - [20] = "RTOE", - [21] = "DCRCE", - [22] = "DTOE", - [30] = "OVRE", - [31] = "UNRE", - }; - unsigned int i; - - seq_printf(s, "%s:\t0x%08x", regname, value); - for (i = 0; i < ARRAY_SIZE(sr_bit); i++) { - if (value & (1 << i)) { - if (sr_bit[i]) - seq_printf(s, " %s", sr_bit[i]); - else - seq_puts(s, " UNKNOWN"); - } - } - seq_putc(s, '\n'); -} - -static int atmci_regs_show(struct seq_file *s, void *v) -{ - struct atmel_mci *host = s->private; - u32 *buf; - - buf = kmalloc(MCI_REGS_SIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - /* Grab a more or less consistent snapshot */ - spin_lock_irq(&host->mmc->lock); - memcpy_fromio(buf, host->regs, MCI_REGS_SIZE); - spin_unlock_irq(&host->mmc->lock); - - seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n", - buf[MCI_MR / 4], - buf[MCI_MR / 4] & MCI_MR_RDPROOF ? " RDPROOF" : "", - buf[MCI_MR / 4] & MCI_MR_WRPROOF ? " WRPROOF" : "", - buf[MCI_MR / 4] & 0xff); - seq_printf(s, "DTOR:\t0x%08x\n", buf[MCI_DTOR / 4]); - seq_printf(s, "SDCR:\t0x%08x\n", buf[MCI_SDCR / 4]); - seq_printf(s, "ARGR:\t0x%08x\n", buf[MCI_ARGR / 4]); - seq_printf(s, "BLKR:\t0x%08x BCNT=%u BLKLEN=%u\n", - buf[MCI_BLKR / 4], - buf[MCI_BLKR / 4] & 0xffff, - (buf[MCI_BLKR / 4] >> 16) & 0xffff); - - /* Don't read RSPR and RDR; it will consume the data there */ - - atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); - atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); - - return 0; -} - -static int atmci_regs_open(struct inode *inode, struct file *file) -{ - return single_open(file, atmci_regs_show, inode->i_private); -} - -static const struct file_operations atmci_regs_fops = { - .owner = THIS_MODULE, - .open = atmci_regs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void atmci_init_debugfs(struct atmel_mci *host) -{ - struct mmc_host *mmc; - struct dentry *root; - struct dentry *node; - struct resource *res; - - mmc = host->mmc; - root = mmc->debugfs_root; - if (!root) - return; - - node = debugfs_create_file("regs", S_IRUSR, root, host, - &atmci_regs_fops); - if (IS_ERR(node)) - return; - if (!node) - goto err; - - res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0); - node->d_inode->i_size = res->end - res->start + 1; - - node = debugfs_create_file("req", S_IRUSR, root, host, &atmci_req_fops); - if (!node) - goto err; - - node = debugfs_create_x32("pending_events", S_IRUSR, root, - (u32 *)&host->pending_events); - if (!node) - goto err; - - node = debugfs_create_x32("completed_events", S_IRUSR, root, - (u32 *)&host->completed_events); - if (!node) - goto err; - - return; - -err: - dev_err(&host->pdev->dev, - "failed to initialize debugfs for controller\n"); -} static void atmci_enable(struct atmel_mci *host) { @@ -574,7 +388,7 @@ static int atmci_get_ro(struct mmc_host *mmc) int read_only = 0; struct atmel_mci *host = mmc_priv(mmc); - if (gpio_is_valid(host->wp_pin)) { + if (host->wp_pin >= 0) { read_only = gpio_get_value(host->wp_pin); dev_dbg(&mmc->class_dev, "card is %s\n", read_only ? "read-only" : "read-write"); @@ -636,7 +450,7 @@ static void atmci_detect_change(unsigned long data) * been freed. */ smp_rmb(); - if (!gpio_is_valid(host->detect_pin)) + if (host->detect_pin < 0) return; enable_irq(gpio_to_irq(host->detect_pin)); @@ -1051,7 +865,7 @@ static int __init atmci_probe(struct platform_device *pdev) /* Assume card is present if we don't have a detect pin */ host->present = 1; - if (gpio_is_valid(host->detect_pin)) { + if (host->detect_pin >= 0) { if (gpio_request(host->detect_pin, "mmc_detect")) { dev_dbg(&mmc->class_dev, "no detect pin available\n"); host->detect_pin = -1; @@ -1059,7 +873,7 @@ static int __init atmci_probe(struct platform_device *pdev) host->present = !gpio_get_value(host->detect_pin); } } - if (gpio_is_valid(host->wp_pin)) { + if (host->wp_pin >= 0) { if (gpio_request(host->wp_pin, "mmc_wp")) { dev_dbg(&mmc->class_dev, "no WP pin available\n"); host->wp_pin = -1; @@ -1070,7 +884,7 @@ static int __init atmci_probe(struct platform_device *pdev) mmc_add_host(mmc); - if (gpio_is_valid(host->detect_pin)) { + if (host->detect_pin >= 0) { setup_timer(&host->detect_timer, atmci_detect_change, (unsigned long)host); @@ -1091,8 +905,6 @@ static int __init atmci_probe(struct platform_device *pdev) "Atmel MCI controller at 0x%08lx irq %d\n", host->mapbase, irq); - atmci_init_debugfs(host); - return 0; err_request_irq: @@ -1111,9 +923,7 @@ static int __exit atmci_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); if (host) { - /* Debugfs stuff is cleaned up by mmc core */ - - if (gpio_is_valid(host->detect_pin)) { + if (host->detect_pin >= 0) { int pin = host->detect_pin; /* Make sure the timer doesn't enable the interrupt */ @@ -1133,7 +943,7 @@ static int __exit atmci_remove(struct platform_device *pdev) mci_readl(host, SR); clk_disable(host->mck); - if (gpio_is_valid(host->wp_pin)) + if (host->wp_pin >= 0) gpio_free(host->wp_pin); free_irq(platform_get_irq(pdev, 0), host->mmc); diff --git a/trunk/drivers/mmc/host/imxmmc.c b/trunk/drivers/mmc/host/imxmmc.c index f61406da65d2..5e880c0f1349 100644 --- a/trunk/drivers/mmc/host/imxmmc.c +++ b/trunk/drivers/mmc/host/imxmmc.c @@ -26,6 +26,12 @@ * */ +#ifdef CONFIG_MMC_DEBUG +#define DEBUG +#else +#undef DEBUG +#endif + #include #include #include @@ -901,12 +907,31 @@ static const struct mmc_host_ops imxmci_ops = { .get_ro = imxmci_get_ro, }; +static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) + if (dev->resource[i].flags == mask && nr-- == 0) + return &dev->resource[i]; + return NULL; +} + +static int platform_device_irq(struct platform_device *dev, int nr) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) + if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0) + return dev->resource[i].start; + return NO_IRQ; +} + static void imxmci_check_status(unsigned long data) { struct imxmci_host *host = (struct imxmci_host *)data; - if (host->pdata && host->pdata->card_present && - host->pdata->card_present(mmc_dev(host->mmc)) != host->present) { + if( host->pdata->card_present(mmc_dev(host->mmc)) != host->present ) { host->present ^= 1; dev_info(mmc_dev(host->mmc), "card %s\n", host->present ? "inserted" : "removed"); @@ -937,12 +962,13 @@ static int imxmci_probe(struct platform_device *pdev) printk(KERN_INFO "i.MX mmc driver\n"); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!r || irq < 0) + r = platform_device_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_device_irq(pdev, 0); + if (!r || irq == NO_IRQ) return -ENXIO; - if (!request_mem_region(r->start, 0x100, pdev->name)) + r = request_mem_region(r->start, 0x100, "IMXMCI"); + if (!r) return -EBUSY; mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev); @@ -969,8 +995,6 @@ static int imxmci_probe(struct platform_device *pdev) host->mmc = mmc; host->dma_allocated = 0; host->pdata = pdev->dev.platform_data; - if (!host->pdata) - dev_warn(&pdev->dev, "No platform data provided!\n"); spin_lock_init(&host->lock); host->res = r; @@ -1023,11 +1047,7 @@ static int imxmci_probe(struct platform_device *pdev) if (ret) goto out; - if (host->pdata && host->pdata->card_present) - host->present = host->pdata->card_present(mmc_dev(mmc)); - else /* if there is no way to detect assume that card is present */ - host->present = 1; - + host->present = host->pdata->card_present(mmc_dev(mmc)); init_timer(&host->timer); host->timer.data = (unsigned long)host; host->timer.function = imxmci_check_status; @@ -1053,7 +1073,7 @@ static int imxmci_probe(struct platform_device *pdev) } if (mmc) mmc_free_host(mmc); - release_mem_region(r->start, 0x100); + release_resource(r); return ret; } @@ -1082,7 +1102,7 @@ static int imxmci_remove(struct platform_device *pdev) clk_disable(host->clk); clk_put(host->clk); - release_mem_region(host->res->start, 0x100); + release_resource(host->res); mmc_free_host(mmc); } diff --git a/trunk/drivers/mmc/host/mmc_spi.c b/trunk/drivers/mmc/host/mmc_spi.c index 7503b81374e0..41cc63360e43 100644 --- a/trunk/drivers/mmc/host/mmc_spi.c +++ b/trunk/drivers/mmc/host/mmc_spi.c @@ -1076,7 +1076,6 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) */ if (canpower && ios->power_mode == MMC_POWER_OFF) { int mres; - u8 nullbyte = 0; host->spi->mode &= ~(SPI_CPOL|SPI_CPHA); mres = spi_setup(host->spi); @@ -1084,7 +1083,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) dev_dbg(&host->spi->dev, "switch to SPI mode 0 failed\n"); - if (spi_write(host->spi, &nullbyte, 1) < 0) + if (spi_w8r8(host->spi, 0x00) < 0) dev_dbg(&host->spi->dev, "put spi signals to low failed\n"); diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index 5f95e10229b5..c3a5db72ddd7 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -337,7 +337,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, host->align_addr = dma_map_single(mmc_dev(host->mmc), host->align_buffer, 128 * 4, direction); - if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) + if (dma_mapping_error(host->align_addr)) goto fail; BUG_ON(host->align_addr & 0x3); @@ -439,7 +439,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, host->adma_addr = dma_map_single(mmc_dev(host->mmc), host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); - if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) + if (dma_mapping_error(host->align_addr)) goto unmap_entries; BUG_ON(host->adma_addr & 0x3); diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/host/sdhci.h index e354faee5df0..a06bf8b89343 100644 --- a/trunk/drivers/mmc/host/sdhci.h +++ b/trunk/drivers/mmc/host/sdhci.h @@ -9,8 +9,6 @@ * your option) any later version. */ -#include - /* * Controller registers */ diff --git a/trunk/drivers/mtd/Kconfig b/trunk/drivers/mtd/Kconfig index 14f11f8b9e5f..eed06d068fd1 100644 --- a/trunk/drivers/mtd/Kconfig +++ b/trunk/drivers/mtd/Kconfig @@ -1,3 +1,5 @@ +# $Id: Kconfig,v 1.11 2005/11/07 11:14:19 gleixner Exp $ + menuconfig MTD tristate "Memory Technology Device (MTD) support" depends on HAS_IOMEM diff --git a/trunk/drivers/mtd/afs.c b/trunk/drivers/mtd/afs.c index d072ca5be689..52d51eb91c16 100644 --- a/trunk/drivers/mtd/afs.c +++ b/trunk/drivers/mtd/afs.c @@ -21,6 +21,8 @@ This is access code for flashes using ARM's flash partitioning standards. + $Id: afs.c,v 1.15 2005/11/07 11:14:19 gleixner Exp $ + ======================================================================*/ #include diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c index 5f1b472137a0..fcd1aeccdf93 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c @@ -4,6 +4,8 @@ * * (C) 2000 Red Hat. GPL'd * + * $Id: cfi_cmdset_0001.c,v 1.186 2005/11/23 22:07:52 nico Exp $ + * * * 10/10/2000 Nicolas Pitre * - completely revamped method functions so they are aware and @@ -48,8 +50,6 @@ #define I82802AC 0x00ac #define MANUFACTURER_ST 0x0020 #define M50LPW080 0x002F -#define M50FLW080A 0x0080 -#define M50FLW080B 0x0081 #define AT49BV640D 0x02de static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); @@ -204,7 +204,7 @@ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; - struct cfi_pri_intelext *extp = cfi->cmdset_priv; + struct cfi_pri_amdstd *extp = cfi->cmdset_priv; printk(KERN_WARNING "cfi_cmdset_0001: Suspend " "erase on write disabled.\n"); @@ -301,8 +301,6 @@ static struct cfi_fixup jedec_fixup_table[] = { { MANUFACTURER_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, { MANUFACTURER_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, { MANUFACTURER_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, { 0, 0, NULL, NULL } }; static struct cfi_fixup fixup_table[] = { @@ -1149,7 +1147,7 @@ static int inval_cache_and_wait_for_operation( struct cfi_private *cfi = map->fldrv_priv; map_word status, status_OK = CMD(0x80); int chip_state = chip->state; - unsigned int timeo, sleep_time, reset_timeo; + unsigned int timeo, sleep_time; spin_unlock(chip->mutex); if (inval_len) @@ -1160,7 +1158,6 @@ static int inval_cache_and_wait_for_operation( timeo = chip_op_time * 8; if (!timeo) timeo = 500000; - reset_timeo = timeo; sleep_time = chip_op_time / 2; for (;;) { @@ -1202,12 +1199,6 @@ static int inval_cache_and_wait_for_operation( remove_wait_queue(&chip->wq, &wait); spin_lock(chip->mutex); } - if (chip->erase_suspended || chip->write_suspended) { - /* Suspend has occured while sleep: reset timeout */ - timeo = reset_timeo; - chip->erase_suspended = 0; - chip->write_suspended = 0; - } } /* Done and happy. */ diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c index a972cc6be436..f7fcc6389533 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c @@ -16,6 +16,9 @@ * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com * * This code is GPL + * + * $Id: cfi_cmdset_0002.c,v 1.122 2005/11/07 11:14:22 gleixner Exp $ + * */ #include diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0020.c b/trunk/drivers/mtd/chips/cfi_cmdset_0020.c index d4714dd9f7ab..1b720cc571f3 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0020.c @@ -4,6 +4,8 @@ * * (C) 2000 Red Hat. GPL'd * + * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $ + * * 10/10/2000 Nicolas Pitre * - completely revamped method functions so they are aware and * independent of the flash geometry (buswidth, interleave, etc.) diff --git a/trunk/drivers/mtd/chips/cfi_probe.c b/trunk/drivers/mtd/chips/cfi_probe.c index c418e92e1d92..a4463a91ce31 100644 --- a/trunk/drivers/mtd/chips/cfi_probe.c +++ b/trunk/drivers/mtd/chips/cfi_probe.c @@ -1,6 +1,7 @@ /* Common Flash Interface probe code. (C) 2000 Red Hat. GPL'd. + $Id: cfi_probe.c,v 1.86 2005/11/29 14:48:31 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/chips/cfi_util.c b/trunk/drivers/mtd/chips/cfi_util.c index 0ee457018016..72e0022a47bf 100644 --- a/trunk/drivers/mtd/chips/cfi_util.c +++ b/trunk/drivers/mtd/chips/cfi_util.c @@ -6,6 +6,9 @@ * Copyright (C) 2003 STMicroelectronics Limited * * This code is covered by the GPL. + * + * $Id: cfi_util.c,v 1.10 2005/11/07 11:14:23 gleixner Exp $ + * */ #include diff --git a/trunk/drivers/mtd/chips/chipreg.c b/trunk/drivers/mtd/chips/chipreg.c index c85760968227..2174c97549f0 100644 --- a/trunk/drivers/mtd/chips/chipreg.c +++ b/trunk/drivers/mtd/chips/chipreg.c @@ -1,4 +1,6 @@ /* + * $Id: chipreg.c,v 1.17 2004/11/16 18:29:00 dwmw2 Exp $ + * * Registration for chip drivers * */ diff --git a/trunk/drivers/mtd/chips/gen_probe.c b/trunk/drivers/mtd/chips/gen_probe.c index f061885b2812..d338b8c92780 100644 --- a/trunk/drivers/mtd/chips/gen_probe.c +++ b/trunk/drivers/mtd/chips/gen_probe.c @@ -2,6 +2,7 @@ * Routines common to all CFI-type probes. * (C) 2001-2003 Red Hat, Inc. * GPL'd + * $Id: gen_probe.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $ */ #include @@ -70,8 +71,8 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi interleave and device type, etc. */ if (!genprobe_new_chip(map, cp, &cfi)) { /* The probe didn't like it */ - pr_debug("%s: Found no %s device at location zero\n", - cp->name, map->name); + printk(KERN_DEBUG "%s: Found no %s device at location zero\n", + cp->name, map->name); return NULL; } diff --git a/trunk/drivers/mtd/chips/jedec_probe.c b/trunk/drivers/mtd/chips/jedec_probe.c index dbba5abf0db8..aa07575eb288 100644 --- a/trunk/drivers/mtd/chips/jedec_probe.c +++ b/trunk/drivers/mtd/chips/jedec_probe.c @@ -1,6 +1,7 @@ /* Common Flash Interface probe code. (C) 2000 Red Hat. GPL'd. + $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $ See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) for the standard this probe goes back to. @@ -25,7 +26,6 @@ /* Manufacturers */ #define MANUFACTURER_AMD 0x0001 #define MANUFACTURER_ATMEL 0x001f -#define MANUFACTURER_EON 0x001c #define MANUFACTURER_FUJITSU 0x0004 #define MANUFACTURER_HYUNDAI 0x00AD #define MANUFACTURER_INTEL 0x0089 @@ -37,7 +37,6 @@ #define MANUFACTURER_ST 0x0020 #define MANUFACTURER_TOSHIBA 0x0098 #define MANUFACTURER_WINBOND 0x00da -#define CONTINUATION_CODE 0x007f /* AMD */ @@ -59,8 +58,6 @@ #define AM29LV040B 0x004F #define AM29F032B 0x0041 #define AM29F002T 0x00B0 -#define AM29SL800DB 0x226B -#define AM29SL800DT 0x22EA /* Atmel */ #define AT49BV512 0x0003 @@ -70,10 +67,6 @@ #define AT49BV32X 0x00C8 #define AT49BV32XT 0x00C9 -/* Eon */ -#define EN29SL800BB 0x226B -#define EN29SL800BT 0x22EA - /* Fujitsu */ #define MBM29F040C 0x00A4 #define MBM29F800BA 0x2258 @@ -148,8 +141,6 @@ #define M50FW080 0x002D #define M50FW016 0x002E #define M50LPW080 0x002F -#define M50FLW080A 0x0080 -#define M50FLW080B 0x0081 /* SST */ #define SST29EE020 0x0010 @@ -200,7 +191,6 @@ enum uaddr { MTD_UADDR_0x0555_0x0AAA, MTD_UADDR_0x5555_0x2AAA, MTD_UADDR_0x0AAA_0x0555, - MTD_UADDR_0xAAAA_0x5555, MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */ MTD_UADDR_UNNECESSARY, /* Does not require any address */ }; @@ -248,11 +238,6 @@ static const struct unlock_addr unlock_addrs[] = { .addr2 = 0x0555 }, - [MTD_UADDR_0xAAAA_0x5555] = { - .addr1 = 0xaaaa, - .addr2 = 0x5555 - }, - [MTD_UADDR_DONT_CARE] = { .addr1 = 0x0000, /* Doesn't matter which address */ .addr2 = 0x0000 /* is used - must be last entry */ @@ -536,36 +521,6 @@ static const struct amd_flash_info jedec_table[] = { ERASEINFO(0x02000,2), ERASEINFO(0x04000,1), } - }, { - .mfr_id = MANUFACTURER_AMD, - .dev_id = AM29SL800DT, - .name = "AMD AM29SL800DT", - .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_0x0AAA_0x0555, - .dev_size = SIZE_1MiB, - .cmd_set = P_ID_AMD_STD, - .nr_regions = 4, - .regions = { - ERASEINFO(0x10000,15), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1), - } - }, { - .mfr_id = MANUFACTURER_AMD, - .dev_id = AM29SL800DB, - .name = "AMD AM29SL800DB", - .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_0x0AAA_0x0555, - .dev_size = SIZE_1MiB, - .cmd_set = P_ID_AMD_STD, - .nr_regions = 4, - .regions = { - ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,15), - } }, { .mfr_id = MANUFACTURER_ATMEL, .dev_id = AT49BV512, @@ -643,36 +598,6 @@ static const struct amd_flash_info jedec_table[] = { ERASEINFO(0x10000,63), ERASEINFO(0x02000,8) } - }, { - .mfr_id = MANUFACTURER_EON, - .dev_id = EN29SL800BT, - .name = "Eon EN29SL800BT", - .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_0x0AAA_0x0555, - .dev_size = SIZE_1MiB, - .cmd_set = P_ID_AMD_STD, - .nr_regions = 4, - .regions = { - ERASEINFO(0x10000,15), - ERASEINFO(0x08000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x04000,1), - } - }, { - .mfr_id = MANUFACTURER_EON, - .dev_id = EN29SL800BB, - .name = "Eon EN29SL800BB", - .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_0x0AAA_0x0555, - .dev_size = SIZE_1MiB, - .cmd_set = P_ID_AMD_STD, - .nr_regions = 4, - .regions = { - ERASEINFO(0x04000,1), - ERASEINFO(0x02000,2), - ERASEINFO(0x08000,1), - ERASEINFO(0x10000,15), - } }, { .mfr_id = MANUFACTURER_FUJITSU, .dev_id = MBM29F040C, @@ -1467,8 +1392,8 @@ static const struct amd_flash_info jedec_table[] = { .mfr_id = MANUFACTURER_SST, /* should be CFI */ .dev_id = SST39LF160, .name = "SST 39LF160", - .devtypes = CFI_DEVICETYPE_X16, - .uaddr = MTD_UADDR_0xAAAA_0x5555, + .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, + .uaddr = MTD_UADDR_0x5555_0x2AAA, /* ???? */ .dev_size = SIZE_2MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 2, @@ -1480,8 +1405,8 @@ static const struct amd_flash_info jedec_table[] = { .mfr_id = MANUFACTURER_SST, /* should be CFI */ .dev_id = SST39VF1601, .name = "SST 39VF1601", - .devtypes = CFI_DEVICETYPE_X16, - .uaddr = MTD_UADDR_0xAAAA_0x5555, + .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, + .uaddr = MTD_UADDR_0x5555_0x2AAA, /* ???? */ .dev_size = SIZE_2MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 2, @@ -1665,36 +1590,6 @@ static const struct amd_flash_info jedec_table[] = { .nr_regions = 1, .regions = { ERASEINFO(0x10000,16), - }, - }, { - .mfr_id = MANUFACTURER_ST, - .dev_id = M50FLW080A, - .name = "ST M50FLW080A", - .devtypes = CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_UNNECESSARY, - .dev_size = SIZE_1MiB, - .cmd_set = P_ID_INTEL_EXT, - .nr_regions = 4, - .regions = { - ERASEINFO(0x1000,16), - ERASEINFO(0x10000,13), - ERASEINFO(0x1000,16), - ERASEINFO(0x1000,16), - } - }, { - .mfr_id = MANUFACTURER_ST, - .dev_id = M50FLW080B, - .name = "ST M50FLW080B", - .devtypes = CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_UNNECESSARY, - .dev_size = SIZE_1MiB, - .cmd_set = P_ID_INTEL_EXT, - .nr_regions = 4, - .regions = { - ERASEINFO(0x1000,16), - ERASEINFO(0x1000,16), - ERASEINFO(0x10000,13), - ERASEINFO(0x1000,16), } }, { .mfr_id = MANUFACTURER_TOSHIBA, @@ -1801,21 +1696,9 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base, { map_word result; unsigned long mask; - int bank = 0; - - /* According to JEDEC "Standard Manufacturer's Identification Code" - * (http://www.jedec.org/download/search/jep106W.pdf) - * several first banks can contain 0x7f instead of actual ID - */ - do { - uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), - cfi_interleave(cfi), - cfi->device_type); - mask = (1 << (cfi->device_type * 8)) - 1; - result = map_read(map, base + ofs); - bank++; - } while ((result.x[0] & mask) == CONTINUATION_CODE); - + u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type); + mask = (1 << (cfi->device_type * 8)) -1; + result = map_read(map, base + ofs); return result.x[0] & mask; } diff --git a/trunk/drivers/mtd/chips/map_absent.c b/trunk/drivers/mtd/chips/map_absent.c index 494d30d0631a..fc478c0f93f5 100644 --- a/trunk/drivers/mtd/chips/map_absent.c +++ b/trunk/drivers/mtd/chips/map_absent.c @@ -1,6 +1,7 @@ /* * Common code to handle absent "placeholder" devices * Copyright 2001 Resilience Corporation + * $Id: map_absent.c,v 1.6 2005/11/07 11:14:23 gleixner Exp $ * * This map driver is used to allocate "placeholder" MTD * devices on systems that have socketed/removable media. diff --git a/trunk/drivers/mtd/chips/map_ram.c b/trunk/drivers/mtd/chips/map_ram.c index 072dd8abf33a..5cb6d5263661 100644 --- a/trunk/drivers/mtd/chips/map_ram.c +++ b/trunk/drivers/mtd/chips/map_ram.c @@ -1,6 +1,7 @@ /* * Common code to handle map devices which are simple RAM * (C) 2000 Red Hat. GPL'd. + * $Id: map_ram.c,v 1.22 2005/01/05 18:05:12 dwmw2 Exp $ */ #include diff --git a/trunk/drivers/mtd/chips/map_rom.c b/trunk/drivers/mtd/chips/map_rom.c index 821d0ed6bae3..cb27f855074c 100644 --- a/trunk/drivers/mtd/chips/map_rom.c +++ b/trunk/drivers/mtd/chips/map_rom.c @@ -1,6 +1,7 @@ /* * Common code to handle map devices which are simple ROM * (C) 2000 Red Hat. GPL'd. + * $Id: map_rom.c,v 1.23 2005/01/05 18:05:12 dwmw2 Exp $ */ #include diff --git a/trunk/drivers/mtd/cmdlinepart.c b/trunk/drivers/mtd/cmdlinepart.c index 71bc07f149b7..e472a0e9de9d 100644 --- a/trunk/drivers/mtd/cmdlinepart.c +++ b/trunk/drivers/mtd/cmdlinepart.c @@ -1,4 +1,6 @@ /* + * $Id: cmdlinepart.c,v 1.19 2005/11/07 11:14:19 gleixner Exp $ + * * Read flash partition table from command line * * Copyright 2002 SYSGO Real-Time Solutions GmbH @@ -306,7 +308,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, unsigned long offset; int i; struct cmdline_mtd_partition *part; - const char *mtd_id = master->name; + char *mtd_id = master->name; /* parse command line */ if (!cmdline_parsed) diff --git a/trunk/drivers/mtd/devices/Kconfig b/trunk/drivers/mtd/devices/Kconfig index 9c613f06623c..35ed1103dbb2 100644 --- a/trunk/drivers/mtd/devices/Kconfig +++ b/trunk/drivers/mtd/devices/Kconfig @@ -1,4 +1,5 @@ # drivers/mtd/maps/Kconfig +# $Id: Kconfig,v 1.18 2005/11/07 11:14:24 gleixner Exp $ menu "Self-contained MTD device drivers" depends on MTD!=n diff --git a/trunk/drivers/mtd/devices/Makefile b/trunk/drivers/mtd/devices/Makefile index 0993d5cf3923..0f788d5c4bf8 100644 --- a/trunk/drivers/mtd/devices/Makefile +++ b/trunk/drivers/mtd/devices/Makefile @@ -1,6 +1,7 @@ # # linux/drivers/devices/Makefile # +# $Id: Makefile.common,v 1.7 2004/12/22 17:51:15 joern Exp $ obj-$(CONFIG_MTD_DOC2000) += doc2000.o obj-$(CONFIG_MTD_DOC2001) += doc2001.o diff --git a/trunk/drivers/mtd/devices/block2mtd.c b/trunk/drivers/mtd/devices/block2mtd.c index 91fbba767635..7b72a1b36115 100644 --- a/trunk/drivers/mtd/devices/block2mtd.c +++ b/trunk/drivers/mtd/devices/block2mtd.c @@ -1,4 +1,6 @@ /* + * $Id: block2mtd.c,v 1.30 2005/11/29 14:48:32 gleixner Exp $ + * * block2mtd.c - create an mtd from a block device * * Copyright (C) 2001,2002 Simon Evans @@ -18,6 +20,9 @@ #include #include +#define VERSION "$Revision: 1.30 $" + + #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args) @@ -448,6 +453,7 @@ MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,]\""); static int __init block2mtd_init(void) { int ret = 0; + INFO("version " VERSION); #ifndef MODULE if (strlen(block2mtd_paramline)) diff --git a/trunk/drivers/mtd/devices/doc2000.c b/trunk/drivers/mtd/devices/doc2000.c index 50de839c77a9..846989f292e3 100644 --- a/trunk/drivers/mtd/devices/doc2000.c +++ b/trunk/drivers/mtd/devices/doc2000.c @@ -3,6 +3,8 @@ * Linux driver for Disk-On-Chip 2000 and Millennium * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse + * + * $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/devices/doc2001.c b/trunk/drivers/mtd/devices/doc2001.c index e32c568c1145..6413efc045e0 100644 --- a/trunk/drivers/mtd/devices/doc2001.c +++ b/trunk/drivers/mtd/devices/doc2001.c @@ -3,6 +3,8 @@ * Linux driver for Disk-On-Chip Millennium * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse + * + * $Id: doc2001.c,v 1.49 2005/11/07 11:14:24 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/devices/doc2001plus.c b/trunk/drivers/mtd/devices/doc2001plus.c index d853f891b586..83be3461658f 100644 --- a/trunk/drivers/mtd/devices/doc2001plus.c +++ b/trunk/drivers/mtd/devices/doc2001plus.c @@ -6,6 +6,8 @@ * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse * + * $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $ + * * Released under GPL */ diff --git a/trunk/drivers/mtd/devices/docecc.c b/trunk/drivers/mtd/devices/docecc.c index 874e51b110a2..fd8a8daba3a8 100644 --- a/trunk/drivers/mtd/devices/docecc.c +++ b/trunk/drivers/mtd/devices/docecc.c @@ -7,6 +7,8 @@ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Copyright (C) 2000 Netgem S.A. * + * $Id: docecc.c,v 1.7 2005/11/07 11:14:25 gleixner Exp $ + * * 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 diff --git a/trunk/drivers/mtd/devices/docprobe.c b/trunk/drivers/mtd/devices/docprobe.c index 6e62922942b1..d8cc94ec4e50 100644 --- a/trunk/drivers/mtd/devices/docprobe.c +++ b/trunk/drivers/mtd/devices/docprobe.c @@ -4,6 +4,9 @@ /* (C) 1999 Machine Vision Holdings, Inc. */ /* (C) 1999-2003 David Woodhouse */ +/* $Id: docprobe.c,v 1.46 2005/11/07 11:14:25 gleixner Exp $ */ + + /* DOC_PASSIVE_PROBE: In order to ensure that the BIOS checksum is correct at boot time, and @@ -76,6 +79,8 @@ static unsigned long __initdata doc_locations[] = { 0xe0000, 0xe2000, 0xe4000, 0xe6000, 0xe8000, 0xea000, 0xec000, 0xee000, #endif /* CONFIG_MTD_DOCPROBE_HIGH */ +#elif defined(__PPC__) + 0xe4000000, #else #warning Unknown architecture for DiskOnChip. No default probe locations defined #endif diff --git a/trunk/drivers/mtd/devices/lart.c b/trunk/drivers/mtd/devices/lart.c index f4bda4cee495..1d324e5c412d 100644 --- a/trunk/drivers/mtd/devices/lart.c +++ b/trunk/drivers/mtd/devices/lart.c @@ -2,6 +2,8 @@ /* * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. * + * $Id: lart.c,v 1.9 2005/11/07 11:14:25 gleixner Exp $ + * * Author: Abraham vd Merwe * * Copyright (c) 2001, 2d3D, Inc. diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index b35c3333e210..b402269301f6 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -33,7 +33,6 @@ /* Flash opcodes. */ #define OPCODE_WREN 0x06 /* Write enable */ #define OPCODE_RDSR 0x05 /* Read status register */ -#define OPCODE_WRSR 0x01 /* Write status register 1 byte */ #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ @@ -113,17 +112,6 @@ static int read_sr(struct m25p *flash) return val; } -/* - * Write status register 1 byte - * Returns negative if error occurred. - */ -static int write_sr(struct m25p *flash, u8 val) -{ - flash->command[0] = OPCODE_WRSR; - flash->command[1] = val; - - return spi_write(flash->spi, flash->command, 2); -} /* * Set write enable latch with Write Enable command. @@ -601,16 +589,6 @@ static int __devinit m25p_probe(struct spi_device *spi) mutex_init(&flash->lock); dev_set_drvdata(&spi->dev, flash); - /* - * Atmel serial flash tend to power up - * with the software protection bits set - */ - - if (info->jedec_id >> 16 == 0x1f) { - write_enable(flash); - write_sr(flash, 0); - } - if (data && data->name) flash->mtd.name = data->name; else diff --git a/trunk/drivers/mtd/devices/ms02-nv.c b/trunk/drivers/mtd/devices/ms02-nv.c index 6a9a24a80a6d..9cff119a2024 100644 --- a/trunk/drivers/mtd/devices/ms02-nv.c +++ b/trunk/drivers/mtd/devices/ms02-nv.c @@ -5,6 +5,8 @@ * 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. + * + * $Id: ms02-nv.c,v 1.11 2005/11/14 13:41:47 macro Exp $ */ #include diff --git a/trunk/drivers/mtd/devices/ms02-nv.h b/trunk/drivers/mtd/devices/ms02-nv.h index 04deafd3a771..8a6eef7cfee3 100644 --- a/trunk/drivers/mtd/devices/ms02-nv.h +++ b/trunk/drivers/mtd/devices/ms02-nv.h @@ -9,6 +9,8 @@ * 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. + * + * $Id: ms02-nv.h,v 1.3 2003/08/19 09:25:36 dwmw2 Exp $ */ #include diff --git a/trunk/drivers/mtd/devices/mtd_dataflash.c b/trunk/drivers/mtd/devices/mtd_dataflash.c index 54e36bfc2c3b..b35e4813a3a5 100644 --- a/trunk/drivers/mtd/devices/mtd_dataflash.c +++ b/trunk/drivers/mtd/devices/mtd_dataflash.c @@ -82,7 +82,7 @@ struct dataflash { - uint8_t command[4]; + u8 command[4]; char name[24]; unsigned partitioned:1; @@ -150,7 +150,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) struct spi_transfer x = { .tx_dma = 0, }; struct spi_message msg; unsigned blocksize = priv->page_size << 3; - uint8_t *command; + u8 *command; DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%x len 0x%x\n", spi->dev.bus_id, @@ -182,8 +182,8 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) pageaddr = pageaddr << priv->page_offset; command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE; - command[1] = (uint8_t)(pageaddr >> 16); - command[2] = (uint8_t)(pageaddr >> 8); + command[1] = (u8)(pageaddr >> 16); + command[2] = (u8)(pageaddr >> 8); command[3] = 0; DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n", @@ -234,7 +234,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, struct spi_transfer x[2] = { { .tx_dma = 0, }, }; struct spi_message msg; unsigned int addr; - uint8_t *command; + u8 *command; int status; DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n", @@ -274,9 +274,9 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, * fewer "don't care" bytes. Both buffers stay unchanged. */ command[0] = OP_READ_CONTINUOUS; - command[1] = (uint8_t)(addr >> 16); - command[2] = (uint8_t)(addr >> 8); - command[3] = (uint8_t)(addr >> 0); + command[1] = (u8)(addr >> 16); + command[2] = (u8)(addr >> 8); + command[3] = (u8)(addr >> 0); /* plus 4 "don't care" bytes */ status = spi_sync(priv->spi, &msg); @@ -311,7 +311,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, size_t remaining = len; u_char *writebuf = (u_char *) buf; int status = -EINVAL; - uint8_t *command; + u8 *command; DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n", spi->dev.bus_id, (unsigned)to, (unsigned)(to + len)); @@ -487,9 +487,7 @@ add_dataflash(struct spi_device *spi, char *name, device->write = dataflash_write; device->priv = priv; - dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes, " - "erasesize %d bytes\n", name, device->size/1024, - pagesize, pagesize * 8); /* 8 pages = 1 block */ + dev_info(&spi->dev, "%s (%d KBytes)\n", name, device->size/1024); dev_set_drvdata(&spi->dev, priv); if (mtd_has_partitions()) { @@ -523,7 +521,7 @@ add_dataflash(struct spi_device *spi, char *name, * * Device Density ID code #Pages PageSize Offset * AT45DB011B 1Mbit (128K) xx0011xx (0x0c) 512 264 9 - * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1024 264 9 + * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1025 264 9 * AT45DB041B 4Mbit (512K) xx0111xx (0x1c) 2048 264 9 * AT45DB081B 8Mbit (1M) xx1001xx (0x24) 4096 264 9 * AT45DB0161B 16Mbit (2M) xx1011xx (0x2c) 4096 528 10 @@ -531,114 +529,9 @@ add_dataflash(struct spi_device *spi, char *name, * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 */ - -struct flash_info { - char *name; - - /* JEDEC id zero means "no ID" (most older chips); otherwise it has - * a high byte of zero plus three data bytes: the manufacturer id, - * then a two byte device id. - */ - uint32_t jedec_id; - - /* The size listed here is what works with OPCODE_SE, which isn't - * necessarily called a "sector" by the vendor. - */ - unsigned nr_pages; - uint16_t pagesize; - uint16_t pageoffset; - - uint16_t flags; -#define SUP_POW2PS 0x02 -#define IS_POW2PS 0x01 -}; - -static struct flash_info __devinitdata dataflash_data [] = { - - { "at45db011d", 0x1f2200, 512, 264, 9, SUP_POW2PS}, - { "at45db011d", 0x1f2200, 512, 256, 8, SUP_POW2PS | IS_POW2PS}, - - { "at45db021d", 0x1f2300, 1024, 264, 9, SUP_POW2PS}, - { "at45db021d", 0x1f2300, 1024, 256, 8, SUP_POW2PS | IS_POW2PS}, - - { "at45db041d", 0x1f2400, 2048, 264, 9, SUP_POW2PS}, - { "at45db041d", 0x1f2400, 2048, 256, 8, SUP_POW2PS | IS_POW2PS}, - - { "at45db081d", 0x1f2500, 4096, 264, 9, SUP_POW2PS}, - { "at45db081d", 0x1f2500, 4096, 256, 8, SUP_POW2PS | IS_POW2PS}, - - { "at45db161d", 0x1f2600, 4096, 528, 10, SUP_POW2PS}, - { "at45db161d", 0x1f2600, 4096, 512, 9, SUP_POW2PS | IS_POW2PS}, - - { "at45db321c", 0x1f2700, 8192, 528, 10, }, - - { "at45db321d", 0x1f2701, 8192, 528, 10, SUP_POW2PS}, - { "at45db321d", 0x1f2701, 8192, 512, 9, SUP_POW2PS | IS_POW2PS}, - - { "at45db641d", 0x1f2800, 8192, 1056, 11, SUP_POW2PS}, - { "at45db641d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, -}; - -static struct flash_info *__devinit jedec_probe(struct spi_device *spi) -{ - int tmp; - uint8_t code = OP_READ_ID; - uint8_t id[3]; - uint32_t jedec; - struct flash_info *info; - int status; - - - /* JEDEC also defines an optional "extended device information" - * string for after vendor-specific data, after the three bytes - * we use here. Supporting some chips might require using it. - */ - tmp = spi_write_then_read(spi, &code, 1, id, 3); - if (tmp < 0) { - DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", - spi->dev.bus_id, tmp); - return NULL; - } - jedec = id[0]; - jedec = jedec << 8; - jedec |= id[1]; - jedec = jedec << 8; - jedec |= id[2]; - - for (tmp = 0, info = dataflash_data; - tmp < ARRAY_SIZE(dataflash_data); - tmp++, info++) { - if (info->jedec_id == jedec) { - if (info->flags & SUP_POW2PS) { - status = dataflash_status(spi); - if (status & 0x1) - /* return power of 2 pagesize */ - return ++info; - else - return info; - } - } - } - return NULL; -} - static int __devinit dataflash_probe(struct spi_device *spi) { int status; - struct flash_info *info; - - /* - * Try to detect dataflash by JEDEC ID. - * If it succeeds we know we have either a C or D part. - * D will support power of 2 pagesize option. - */ - - info = jedec_probe(spi); - - if (info != NULL) - return add_dataflash(spi, info->name, info->nr_pages, - info->pagesize, info->pageoffset); - status = dataflash_status(spi); if (status <= 0 || status == 0xff) { @@ -658,16 +551,16 @@ static int __devinit dataflash_probe(struct spi_device *spi) status = add_dataflash(spi, "AT45DB011B", 512, 264, 9); break; case 0x14: /* 0 1 0 1 x x */ - status = add_dataflash(spi, "AT45DB021B", 1024, 264, 9); + status = add_dataflash(spi, "AT45DB021B", 1025, 264, 9); break; case 0x1c: /* 0 1 1 1 x x */ - status = add_dataflash(spi, "AT45DB041B", 2048, 264, 9); + status = add_dataflash(spi, "AT45DB041x", 2048, 264, 9); break; case 0x24: /* 1 0 0 1 x x */ status = add_dataflash(spi, "AT45DB081B", 4096, 264, 9); break; case 0x2c: /* 1 0 1 1 x x */ - status = add_dataflash(spi, "AT45DB161B", 4096, 528, 10); + status = add_dataflash(spi, "AT45DB161x", 4096, 528, 10); break; case 0x34: /* 1 1 0 1 x x */ status = add_dataflash(spi, "AT45DB321x", 8192, 528, 10); diff --git a/trunk/drivers/mtd/devices/mtdram.c b/trunk/drivers/mtd/devices/mtdram.c index 3aaca88847d3..0399be178620 100644 --- a/trunk/drivers/mtd/devices/mtdram.c +++ b/trunk/drivers/mtd/devices/mtdram.c @@ -1,5 +1,6 @@ /* * mtdram - a test mtd device + * $Id: mtdram.c,v 1.37 2005/04/21 03:42:11 joern Exp $ * Author: Alexander Larsson * * Copyright (c) 1999 Alexander Larsson diff --git a/trunk/drivers/mtd/devices/phram.c b/trunk/drivers/mtd/devices/phram.c index 088fbb7595b5..c7987b1c5e01 100644 --- a/trunk/drivers/mtd/devices/phram.c +++ b/trunk/drivers/mtd/devices/phram.c @@ -1,4 +1,6 @@ /** + * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $ + * * Copyright (c) ???? Jochen Schäuble * Copyright (c) 2003-2004 Joern Engel * diff --git a/trunk/drivers/mtd/devices/pmc551.c b/trunk/drivers/mtd/devices/pmc551.c index d38bca64bb15..bc9981749064 100644 --- a/trunk/drivers/mtd/devices/pmc551.c +++ b/trunk/drivers/mtd/devices/pmc551.c @@ -1,4 +1,6 @@ /* + * $Id: pmc551.c,v 1.32 2005/11/07 11:14:25 gleixner Exp $ + * * PMC551 PCI Mezzanine Ram Device * * Author: diff --git a/trunk/drivers/mtd/devices/slram.c b/trunk/drivers/mtd/devices/slram.c index a425d09f35a0..cb86db746f28 100644 --- a/trunk/drivers/mtd/devices/slram.c +++ b/trunk/drivers/mtd/devices/slram.c @@ -1,5 +1,7 @@ /*====================================================================== + $Id: slram.c,v 1.36 2005/11/07 11:14:25 gleixner Exp $ + This driver provides a method to access memory not used by the kernel itself (i.e. if the kernel commandline mem=xxx is used). To actually use slram at least mtdblock or mtdchar is required (for block or diff --git a/trunk/drivers/mtd/ftl.c b/trunk/drivers/mtd/ftl.c index f34f20c78911..5c29872184e6 100644 --- a/trunk/drivers/mtd/ftl.c +++ b/trunk/drivers/mtd/ftl.c @@ -1,4 +1,5 @@ /* This version ported to the Linux-MTD system by dwmw2@infradead.org + * $Id: ftl.c,v 1.59 2005/11/29 14:48:31 gleixner Exp $ * * Fixes: Arnaldo Carvalho de Melo * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups @@ -1077,6 +1078,8 @@ static struct mtd_blktrans_ops ftl_tr = { static int init_ftl(void) { + DEBUG(0, "$Id: ftl.c,v 1.59 2005/11/29 14:48:31 gleixner Exp $\n"); + return register_mtd_blktrans(&ftl_tr); } diff --git a/trunk/drivers/mtd/inftlcore.c b/trunk/drivers/mtd/inftlcore.c index c4f9d3378b24..b0e396504e67 100644 --- a/trunk/drivers/mtd/inftlcore.c +++ b/trunk/drivers/mtd/inftlcore.c @@ -7,6 +7,8 @@ * (c) 1999 Machine Vision Holdings, Inc. * Author: David Woodhouse * + * $Id: inftlcore.c,v 1.19 2005/11/07 11:14:20 gleixner Exp $ + * * 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 @@ -951,6 +953,9 @@ static struct mtd_blktrans_ops inftl_tr = { static int __init init_inftl(void) { + printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, " + "inftlmount.c %s\n", inftlmountrev); + return register_mtd_blktrans(&inftl_tr); } diff --git a/trunk/drivers/mtd/inftlmount.c b/trunk/drivers/mtd/inftlmount.c index 9113628ed1ef..c551d2f0779c 100644 --- a/trunk/drivers/mtd/inftlmount.c +++ b/trunk/drivers/mtd/inftlmount.c @@ -8,6 +8,8 @@ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Copyright (C) 2000 Netgem S.A. * + * $Id: inftlmount.c,v 1.18 2005/11/07 11:14:20 gleixner Exp $ + * * 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 @@ -37,6 +39,8 @@ #include #include +char inftlmountrev[]="$Revision: 1.18 $"; + /* * find_boot_record: Find the INFTL Media Header and its Spare copy which * contains the various device information of the INFTL partition and diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index df8e00bba07b..d2fbc2964523 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -1,4 +1,5 @@ # drivers/mtd/maps/Kconfig +# $Id: Kconfig,v 1.61 2005/11/07 11:14:26 gleixner Exp $ menu "Mapping drivers for chip access" depends on MTD!=n @@ -509,17 +510,6 @@ config MTD_PCMCIA_ANONYMOUS If unsure, say N. -config MTD_BFIN_ASYNC - tristate "Blackfin BF533-STAMP Flash Chip Support" - depends on BFIN533_STAMP && MTD_CFI - select MTD_PARTITIONS - default y - help - Map driver which allows for simultaneous utilization of - ethernet and CFI parallel flash. - - If compiled as a module, it will be called bfin-async-flash. - config MTD_UCLINUX tristate "Generic uClinux RAM/ROM filesystem support" depends on MTD_PARTITIONS && !MMU @@ -549,6 +539,24 @@ config MTD_DMV182 help Map driver for Dy-4 SVME/DMV-182 board. +config MTD_BAST + tristate "Map driver for Simtec BAST (EB2410ITX) or Thorcom VR1000" + depends on ARCH_BAST || MACH_VR1000 + select MTD_PARTITIONS + select MTD_MAP_BANK_WIDTH_16 + select MTD_JEDECPROBE + help + Map driver for NOR flash on the Simtec BAST (EB2410ITX), or the + Thorcom VR1000 + + Note, this driver *cannot* over-ride the WP link on the + board, or currently detect the state of the link. + +config MTD_BAST_MAXSIZE + int "Maximum size for BAST flash area (MiB)" + depends on MTD_BAST + default "4" + config MTD_SHARP_SL tristate "ROM mapped on Sharp SL Series" depends on ARCH_PXA diff --git a/trunk/drivers/mtd/maps/Makefile b/trunk/drivers/mtd/maps/Makefile index 6cda6df973e5..c6ce8673dab2 100644 --- a/trunk/drivers/mtd/maps/Makefile +++ b/trunk/drivers/mtd/maps/Makefile @@ -1,6 +1,7 @@ # # linux/drivers/maps/Makefile # +# $Id: Makefile.common,v 1.34 2005/11/07 11:14:26 gleixner Exp $ ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) obj-$(CONFIG_MTD) += map_funcs.o @@ -9,6 +10,7 @@ endif # Chip mappings obj-$(CONFIG_MTD_CDB89712) += cdb89712.o obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o +obj-$(CONFIG_MTD_BAST) += bast-flash.o obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o obj-$(CONFIG_MTD_DC21285) += dc21285.o obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o @@ -64,4 +66,3 @@ obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o -obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o diff --git a/trunk/drivers/mtd/maps/amd76xrom.c b/trunk/drivers/mtd/maps/amd76xrom.c index 948b86f35ef4..728aed6ad722 100644 --- a/trunk/drivers/mtd/maps/amd76xrom.c +++ b/trunk/drivers/mtd/maps/amd76xrom.c @@ -2,6 +2,7 @@ * amd76xrom.c * * Normal mappings of chips in physical memory + * $Id: amd76xrom.c,v 1.21 2005/11/07 11:14:26 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/maps/autcpu12-nvram.c b/trunk/drivers/mtd/maps/autcpu12-nvram.c index cf32267263df..7ed3424dd959 100644 --- a/trunk/drivers/mtd/maps/autcpu12-nvram.c +++ b/trunk/drivers/mtd/maps/autcpu12-nvram.c @@ -2,6 +2,8 @@ * NV-RAM memory access on autcpu12 * (C) 2002 Thomas Gleixner (gleixner@autronix.de) * + * $Id: autcpu12-nvram.c,v 1.9 2005/11/07 11:14:26 gleixner Exp $ + * * 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 diff --git a/trunk/drivers/mtd/maps/bast-flash.c b/trunk/drivers/mtd/maps/bast-flash.c new file mode 100644 index 000000000000..1f492062f8ca --- /dev/null +++ b/trunk/drivers/mtd/maps/bast-flash.c @@ -0,0 +1,226 @@ +/* linux/drivers/mtd/maps/bast-flash.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks + * + * Simtec Bast (EB2410ITX) NOR MTD Mapping driver + * + * Changelog: + * 20-Sep-2004 BJD Initial version + * 17-Jan-2005 BJD Add whole device if no partitions found + * + * $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $ + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include +#include + +#ifdef CONFIG_MTD_BAST_MAXSIZE +#define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * SZ_1M) +#else +#define AREA_MAXSIZE (32 * SZ_1M) +#endif + +#define PFX "bast-flash: " + +struct bast_flash_info { + struct mtd_info *mtd; + struct map_info map; + struct mtd_partition *partitions; + struct resource *area; +}; + +static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; + +static void bast_flash_setrw(int to) +{ + unsigned int val; + unsigned long flags; + + local_irq_save(flags); + val = __raw_readb(BAST_VA_CTRL3); + + if (to) + val |= BAST_CPLD_CTRL3_ROMWEN; + else + val &= ~BAST_CPLD_CTRL3_ROMWEN; + + pr_debug("new cpld ctrl3=%02x\n", val); + + __raw_writeb(val, BAST_VA_CTRL3); + local_irq_restore(flags); +} + +static int bast_flash_remove(struct platform_device *pdev) +{ + struct bast_flash_info *info = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + if (info == NULL) + return 0; + + if (info->map.virt != NULL) + iounmap(info->map.virt); + + if (info->mtd) { + del_mtd_partitions(info->mtd); + map_destroy(info->mtd); + } + + kfree(info->partitions); + + if (info->area) { + release_resource(info->area); + kfree(info->area); + } + + kfree(info); + + return 0; +} + +static int bast_flash_probe(struct platform_device *pdev) +{ + struct bast_flash_info *info; + struct resource *res; + int err = 0; + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (info == NULL) { + printk(KERN_ERR PFX "no memory for flash info\n"); + err = -ENOMEM; + goto exit_error; + } + + memzero(info, sizeof(*info)); + platform_set_drvdata(pdev, info); + + res = pdev->resource; /* assume that the flash has one resource */ + + info->map.phys = res->start; + info->map.size = res->end - res->start + 1; + info->map.name = pdev->dev.bus_id; + info->map.bankwidth = 2; + + if (info->map.size > AREA_MAXSIZE) + info->map.size = AREA_MAXSIZE; + + pr_debug("%s: area %08lx, size %ld\n", __func__, + info->map.phys, info->map.size); + + info->area = request_mem_region(res->start, info->map.size, + pdev->name); + if (info->area == NULL) { + printk(KERN_ERR PFX "cannot reserve flash memory region\n"); + err = -ENOENT; + goto exit_error; + } + + info->map.virt = ioremap(res->start, info->map.size); + pr_debug("%s: virt at %08x\n", __func__, (int)info->map.virt); + + if (info->map.virt == 0) { + printk(KERN_ERR PFX "failed to ioremap() region\n"); + err = -EIO; + goto exit_error; + } + + simple_map_init(&info->map); + + /* enable the write to the flash area */ + + bast_flash_setrw(1); + + /* probe for the device(s) */ + + info->mtd = do_map_probe("jedec_probe", &info->map); + if (info->mtd == NULL) + info->mtd = do_map_probe("cfi_probe", &info->map); + + if (info->mtd == NULL) { + printk(KERN_ERR PFX "map_probe() failed\n"); + err = -ENXIO; + goto exit_error; + } + + /* mark ourselves as the owner */ + info->mtd->owner = THIS_MODULE; + + err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); + if (err > 0) { + err = add_mtd_partitions(info->mtd, info->partitions, err); + if (err) + printk(KERN_ERR PFX "cannot add/parse partitions\n"); + } else { + err = add_mtd_device(info->mtd); + } + + if (err == 0) + return 0; + + /* fall through to exit error */ + + exit_error: + bast_flash_remove(pdev); + return err; +} + +static struct platform_driver bast_flash_driver = { + .probe = bast_flash_probe, + .remove = bast_flash_remove, + .driver = { + .name = "bast-nor", + .owner = THIS_MODULE, + }, +}; + +static int __init bast_flash_init(void) +{ + printk("BAST NOR-Flash Driver, (c) 2004 Simtec Electronics\n"); + return platform_driver_register(&bast_flash_driver); +} + +static void __exit bast_flash_exit(void) +{ + platform_driver_unregister(&bast_flash_driver); +} + +module_init(bast_flash_init); +module_exit(bast_flash_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Ben Dooks "); +MODULE_DESCRIPTION("BAST MTD Map driver"); +MODULE_ALIAS("platform:bast-nor"); diff --git a/trunk/drivers/mtd/maps/bfin-async-flash.c b/trunk/drivers/mtd/maps/bfin-async-flash.c deleted file mode 100644 index 6fec86aaed7e..000000000000 --- a/trunk/drivers/mtd/maps/bfin-async-flash.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * drivers/mtd/maps/bfin-async-flash.c - * - * Handle the case where flash memory and ethernet mac/phy are - * mapped onto the same async bank. The BF533-STAMP does this - * for example. All board-specific configuration goes in your - * board resources file. - * - * Copyright 2000 Nicolas Pitre - * Copyright 2005-2008 Analog Devices Inc. - * - * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) - -#define DRIVER_NAME "bfin-async-flash" - -struct async_state { - struct mtd_info *mtd; - struct map_info map; - int enet_flash_pin; - uint32_t flash_ambctl0, flash_ambctl1; - uint32_t save_ambctl0, save_ambctl1; - unsigned long irq_flags; -}; - -static void switch_to_flash(struct async_state *state) -{ - local_irq_save(state->irq_flags); - - gpio_set_value(state->enet_flash_pin, 0); - - state->save_ambctl0 = bfin_read_EBIU_AMBCTL0(); - state->save_ambctl1 = bfin_read_EBIU_AMBCTL1(); - bfin_write_EBIU_AMBCTL0(state->flash_ambctl0); - bfin_write_EBIU_AMBCTL1(state->flash_ambctl1); - SSYNC(); -} - -static void switch_back(struct async_state *state) -{ - bfin_write_EBIU_AMBCTL0(state->save_ambctl0); - bfin_write_EBIU_AMBCTL1(state->save_ambctl1); - SSYNC(); - - gpio_set_value(state->enet_flash_pin, 1); - - local_irq_restore(state->irq_flags); -} - -static map_word bfin_read(struct map_info *map, unsigned long ofs) -{ - struct async_state *state = (struct async_state *)map->map_priv_1; - uint16_t word; - map_word test; - - switch_to_flash(state); - - word = readw(map->virt + ofs); - - switch_back(state); - - test.x[0] = word; - return test; -} - -static void bfin_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) -{ - struct async_state *state = (struct async_state *)map->map_priv_1; - - switch_to_flash(state); - - memcpy(to, map->virt + from, len); - - switch_back(state); -} - -static void bfin_write(struct map_info *map, map_word d1, unsigned long ofs) -{ - struct async_state *state = (struct async_state *)map->map_priv_1; - uint16_t d; - - d = d1.x[0]; - - switch_to_flash(state); - - writew(d, map->virt + ofs); - SSYNC(); - - switch_back(state); -} - -static void bfin_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -{ - struct async_state *state = (struct async_state *)map->map_priv_1; - - switch_to_flash(state); - - memcpy(map->virt + to, from, len); - SSYNC(); - - switch_back(state); -} - -#ifdef CONFIG_MTD_PARTITIONS -static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -#endif - -static int __devinit bfin_flash_probe(struct platform_device *pdev) -{ - int ret; - struct physmap_flash_data *pdata = pdev->dev.platform_data; - struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); - struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1); - struct async_state *state; - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - state->map.name = DRIVER_NAME; - state->map.read = bfin_read; - state->map.copy_from = bfin_copy_from; - state->map.write = bfin_write; - state->map.copy_to = bfin_copy_to; - state->map.bankwidth = pdata->width; - state->map.size = memory->end - memory->start + 1; - state->map.virt = (void __iomem *)memory->start; - state->map.phys = memory->start; - state->map.map_priv_1 = (unsigned long)state; - state->enet_flash_pin = platform_get_irq(pdev, 0); - state->flash_ambctl0 = flash_ambctl->start; - state->flash_ambctl1 = flash_ambctl->end; - - if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { - pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); - return -EBUSY; - } - gpio_direction_output(state->enet_flash_pin, 1); - - pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); - state->mtd = do_map_probe(memory->name, &state->map); - if (!state->mtd) - return -ENXIO; - -#ifdef CONFIG_MTD_PARTITIONS - ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); - if (ret > 0) { - pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); - add_mtd_partitions(state->mtd, pdata->parts, ret); - - } else if (pdata->nr_parts) { - pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); - add_mtd_partitions(state->mtd, pdata->parts, pdata->nr_parts); - - } else -#endif - { - pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n"); - add_mtd_device(state->mtd); - } - - platform_set_drvdata(pdev, state); - - return 0; -} - -static int __devexit bfin_flash_remove(struct platform_device *pdev) -{ - struct async_state *state = platform_get_drvdata(pdev); - gpio_free(state->enet_flash_pin); -#ifdef CONFIG_MTD_PARTITIONS - del_mtd_partitions(state->mtd); -#endif - map_destroy(state->mtd); - kfree(state); - return 0; -} - -static struct platform_driver bfin_flash_driver = { - .probe = bfin_flash_probe, - .remove = __devexit_p(bfin_flash_remove), - .driver = { - .name = DRIVER_NAME, - }, -}; - -static int __init bfin_flash_init(void) -{ - return platform_driver_register(&bfin_flash_driver); -} -module_init(bfin_flash_init); - -static void __exit bfin_flash_exit(void) -{ - platform_driver_unregister(&bfin_flash_driver); -} -module_exit(bfin_flash_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MTD map driver for Blackfins with flash/ethernet on same async bank"); diff --git a/trunk/drivers/mtd/maps/cdb89712.c b/trunk/drivers/mtd/maps/cdb89712.c index cb507da0a87d..9f17bb6c5a9d 100644 --- a/trunk/drivers/mtd/maps/cdb89712.c +++ b/trunk/drivers/mtd/maps/cdb89712.c @@ -1,6 +1,7 @@ /* * Flash on Cirrus CDB89712 * + * $Id: cdb89712.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/maps/ceiva.c b/trunk/drivers/mtd/maps/ceiva.c index 6464d487eb1a..629e6e2641a8 100644 --- a/trunk/drivers/mtd/maps/ceiva.c +++ b/trunk/drivers/mtd/maps/ceiva.c @@ -11,6 +11,7 @@ * * (C) 2000 Nicolas Pitre * + * $Id: ceiva.c,v 1.11 2004/09/16 23:27:12 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/maps/cfi_flagadm.c b/trunk/drivers/mtd/maps/cfi_flagadm.c index 0ecc3f6d735b..65e5ee552010 100644 --- a/trunk/drivers/mtd/maps/cfi_flagadm.c +++ b/trunk/drivers/mtd/maps/cfi_flagadm.c @@ -1,6 +1,8 @@ /* * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson * + * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $ + * * 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 diff --git a/trunk/drivers/mtd/maps/dbox2-flash.c b/trunk/drivers/mtd/maps/dbox2-flash.c index e115667bf1d0..92a9c7fac993 100644 --- a/trunk/drivers/mtd/maps/dbox2-flash.c +++ b/trunk/drivers/mtd/maps/dbox2-flash.c @@ -1,4 +1,6 @@ /* + * $Id: dbox2-flash.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $ + * * D-Box 2 flash driver */ diff --git a/trunk/drivers/mtd/maps/dc21285.c b/trunk/drivers/mtd/maps/dc21285.c index 3aa018c092f8..b32bb9347d71 100644 --- a/trunk/drivers/mtd/maps/dc21285.c +++ b/trunk/drivers/mtd/maps/dc21285.c @@ -4,6 +4,8 @@ * (C) 2000 Nicolas Pitre * * This code is GPL + * + * $Id: dc21285.c,v 1.24 2005/11/07 11:14:26 gleixner Exp $ */ #include #include diff --git a/trunk/drivers/mtd/maps/dilnetpc.c b/trunk/drivers/mtd/maps/dilnetpc.c index 0713e3a5a22c..1c3b34ad7325 100644 --- a/trunk/drivers/mtd/maps/dilnetpc.c +++ b/trunk/drivers/mtd/maps/dilnetpc.c @@ -14,6 +14,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * + * $Id: dilnetpc.c,v 1.20 2005/11/07 11:14:26 gleixner Exp $ + * * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems * featuring the AMD Elan SC410 processor. There are two variants of this * board: DNP/1486 and ADNP/1486. The DNP version has 2 megs of flash diff --git a/trunk/drivers/mtd/maps/dmv182.c b/trunk/drivers/mtd/maps/dmv182.c index d171674eb2ed..e0558b0b2fe6 100644 --- a/trunk/drivers/mtd/maps/dmv182.c +++ b/trunk/drivers/mtd/maps/dmv182.c @@ -4,6 +4,8 @@ * * Flash map driver for the Dy4 SVME182 board * + * $Id: dmv182.c,v 1.6 2005/11/07 11:14:26 gleixner Exp $ + * * Copyright 2003-2004, TimeSys Corporation * * Based on the SVME181 flash map, by Tom Nelson, Dot4, Inc. for TimeSys Corp. diff --git a/trunk/drivers/mtd/maps/ebony.c b/trunk/drivers/mtd/maps/ebony.c index d92b7c70d3ed..1488bb92f26f 100644 --- a/trunk/drivers/mtd/maps/ebony.c +++ b/trunk/drivers/mtd/maps/ebony.c @@ -1,4 +1,6 @@ /* + * $Id: ebony.c,v 1.16 2005/11/07 11:14:26 gleixner Exp $ + * * Mapping for Ebony user flash * * Matt Porter diff --git a/trunk/drivers/mtd/maps/edb7312.c b/trunk/drivers/mtd/maps/edb7312.c index 9433738c1664..1c5b97c89685 100644 --- a/trunk/drivers/mtd/maps/edb7312.c +++ b/trunk/drivers/mtd/maps/edb7312.c @@ -1,4 +1,6 @@ /* + * $Id: edb7312.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $ + * * Handle mapping of the NOR flash on Cogent EDB7312 boards * * Copyright 2002 SYSGO Real-Time Solutions GmbH diff --git a/trunk/drivers/mtd/maps/fortunet.c b/trunk/drivers/mtd/maps/fortunet.c index a8e3fde4cbd5..7c50c271651c 100644 --- a/trunk/drivers/mtd/maps/fortunet.c +++ b/trunk/drivers/mtd/maps/fortunet.c @@ -1,5 +1,6 @@ /* fortunet.c memory map * + * $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/maps/h720x-flash.c b/trunk/drivers/mtd/maps/h720x-flash.c index ef8915474462..6dde3182d64a 100644 --- a/trunk/drivers/mtd/maps/h720x-flash.c +++ b/trunk/drivers/mtd/maps/h720x-flash.c @@ -2,6 +2,8 @@ * Flash memory access on Hynix GMS30C7201/HMS30C7202 based * evaluation boards * + * $Id: h720x-flash.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $ + * * (C) 2002 Jungjun Kim * 2003 Thomas Gleixner */ diff --git a/trunk/drivers/mtd/maps/ichxrom.c b/trunk/drivers/mtd/maps/ichxrom.c index aeb6c916e23f..2c884c49e84a 100644 --- a/trunk/drivers/mtd/maps/ichxrom.c +++ b/trunk/drivers/mtd/maps/ichxrom.c @@ -2,6 +2,7 @@ * ichxrom.c * * Normal mappings of chips in physical memory + * $Id: ichxrom.c,v 1.19 2005/11/07 11:14:27 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/maps/impa7.c b/trunk/drivers/mtd/maps/impa7.c index 2682ab51a367..a0b4dc7155dc 100644 --- a/trunk/drivers/mtd/maps/impa7.c +++ b/trunk/drivers/mtd/maps/impa7.c @@ -1,4 +1,6 @@ /* + * $Id: impa7.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $ + * * Handle mapping of the NOR flash on implementa A7 boards * * Copyright 2002 SYSGO Real-Time Solutions GmbH diff --git a/trunk/drivers/mtd/maps/integrator-flash.c b/trunk/drivers/mtd/maps/integrator-flash.c index ee361aaadb1e..325c8880c437 100644 --- a/trunk/drivers/mtd/maps/integrator-flash.c +++ b/trunk/drivers/mtd/maps/integrator-flash.c @@ -22,6 +22,8 @@ This is access code for flashes using ARM's flash partitioning standards. + $Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $ + ======================================================================*/ #include diff --git a/trunk/drivers/mtd/maps/ipaq-flash.c b/trunk/drivers/mtd/maps/ipaq-flash.c index a806119797e0..f27c132794c3 100644 --- a/trunk/drivers/mtd/maps/ipaq-flash.c +++ b/trunk/drivers/mtd/maps/ipaq-flash.c @@ -4,6 +4,8 @@ * (C) 2000 Nicolas Pitre * (C) 2002 Hewlett-Packard Company * (C) 2003 Christian Pellegrin , : concatenation of multiple flashes + * + * $Id: ipaq-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/maps/ixp2000.c b/trunk/drivers/mtd/maps/ixp2000.c index c2264792a20b..c8396b8574c4 100644 --- a/trunk/drivers/mtd/maps/ixp2000.c +++ b/trunk/drivers/mtd/maps/ixp2000.c @@ -1,4 +1,6 @@ /* + * $Id: ixp2000.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $ + * * drivers/mtd/maps/ixp2000.c * * Mapping for the Intel XScale IXP2000 based systems diff --git a/trunk/drivers/mtd/maps/ixp4xx.c b/trunk/drivers/mtd/maps/ixp4xx.c index 9c7a5fbd4e51..01f19a4714b5 100644 --- a/trunk/drivers/mtd/maps/ixp4xx.c +++ b/trunk/drivers/mtd/maps/ixp4xx.c @@ -1,4 +1,6 @@ /* + * $Id: ixp4xx.c,v 1.13 2005/11/16 16:23:21 dvrabel Exp $ + * * drivers/mtd/maps/ixp4xx.c * * MTD Map file for IXP4XX based systems. Please do not make per-board diff --git a/trunk/drivers/mtd/maps/l440gx.c b/trunk/drivers/mtd/maps/l440gx.c index 9e054503c4cf..67620adf4811 100644 --- a/trunk/drivers/mtd/maps/l440gx.c +++ b/trunk/drivers/mtd/maps/l440gx.c @@ -1,4 +1,6 @@ /* + * $Id: l440gx.c,v 1.18 2005/11/07 11:14:27 gleixner Exp $ + * * BIOS Flash chip on Intel 440GX board. * * Bugs this currently does not work under linuxBIOS. diff --git a/trunk/drivers/mtd/maps/map_funcs.c b/trunk/drivers/mtd/maps/map_funcs.c index 3f268370eeca..9105e6ca0aa6 100644 --- a/trunk/drivers/mtd/maps/map_funcs.c +++ b/trunk/drivers/mtd/maps/map_funcs.c @@ -1,4 +1,6 @@ /* + * $Id: map_funcs.c,v 1.10 2005/06/06 23:04:36 tpoynor Exp $ + * * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS * is enabled. */ diff --git a/trunk/drivers/mtd/maps/mbx860.c b/trunk/drivers/mtd/maps/mbx860.c index 706f67394b07..06b118727846 100644 --- a/trunk/drivers/mtd/maps/mbx860.c +++ b/trunk/drivers/mtd/maps/mbx860.c @@ -1,4 +1,6 @@ /* + * $Id: mbx860.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $ + * * Handle mapping of the flash on MBX860 boards * * Author: Anton Todorov diff --git a/trunk/drivers/mtd/maps/netsc520.c b/trunk/drivers/mtd/maps/netsc520.c index c0cb319b2b70..95dcab2146ad 100644 --- a/trunk/drivers/mtd/maps/netsc520.c +++ b/trunk/drivers/mtd/maps/netsc520.c @@ -3,6 +3,8 @@ * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH * + * $Id: netsc520.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $ + * * 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 diff --git a/trunk/drivers/mtd/maps/nettel.c b/trunk/drivers/mtd/maps/nettel.c index 965e6c6d6ab0..0c9b305a72e0 100644 --- a/trunk/drivers/mtd/maps/nettel.c +++ b/trunk/drivers/mtd/maps/nettel.c @@ -5,6 +5,8 @@ * * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) + * + * $Id: nettel.c,v 1.12 2005/11/29 14:30:00 gleixner Exp $ */ /****************************************************************************/ diff --git a/trunk/drivers/mtd/maps/octagon-5066.c b/trunk/drivers/mtd/maps/octagon-5066.c index 43e04c1d22a9..a6642db3d325 100644 --- a/trunk/drivers/mtd/maps/octagon-5066.c +++ b/trunk/drivers/mtd/maps/octagon-5066.c @@ -1,3 +1,4 @@ +// $Id: octagon-5066.c,v 1.28 2005/11/07 11:14:27 gleixner Exp $ /* ###################################################################### Octagon 5066 MTD Driver. diff --git a/trunk/drivers/mtd/maps/omap-toto-flash.c b/trunk/drivers/mtd/maps/omap-toto-flash.c index 0a60ebbc2175..e6e391efbeb6 100644 --- a/trunk/drivers/mtd/maps/omap-toto-flash.c +++ b/trunk/drivers/mtd/maps/omap-toto-flash.c @@ -4,6 +4,8 @@ * jzhang@ti.com (C) 2003 Texas Instruments. * * (C) 2002 MontVista Software, Inc. + * + * $Id: omap-toto-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/maps/pci.c b/trunk/drivers/mtd/maps/pci.c index 5c6a25c90380..d2ab1bae9c34 100644 --- a/trunk/drivers/mtd/maps/pci.c +++ b/trunk/drivers/mtd/maps/pci.c @@ -7,6 +7,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * + * $Id: pci.c,v 1.14 2005/11/17 08:20:27 dwmw2 Exp $ + * * Generic PCI memory map driver. We support the following boards: * - Intel IQ80310 ATU. * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001 diff --git a/trunk/drivers/mtd/maps/pcmciamtd.c b/trunk/drivers/mtd/maps/pcmciamtd.c index 90924fb00481..0cc31675aeb9 100644 --- a/trunk/drivers/mtd/maps/pcmciamtd.c +++ b/trunk/drivers/mtd/maps/pcmciamtd.c @@ -1,4 +1,6 @@ /* + * $Id: pcmciamtd.c,v 1.55 2005/11/07 11:14:28 gleixner Exp $ + * * pcmciamtd.c - MTD driver for PCMCIA flash memory cards * * Author: Simon Evans @@ -46,6 +48,7 @@ static const int debug = 0; #define DRIVER_DESC "PCMCIA Flash memory card driver" +#define DRIVER_VERSION "$Revision: 1.55 $" /* Size of the PCMCIA address space: 26 bits = 64 MB */ #define MAX_PCMCIA_ADDR 0x4000000 @@ -782,7 +785,7 @@ static struct pcmcia_driver pcmciamtd_driver = { static int __init init_pcmciamtd(void) { - info(DRIVER_DESC); + info(DRIVER_DESC " " DRIVER_VERSION); if(bankwidth && bankwidth != 1 && bankwidth != 2) { info("bad bankwidth (%d), using default", bankwidth); diff --git a/trunk/drivers/mtd/maps/physmap.c b/trunk/drivers/mtd/maps/physmap.c index 42d844f8f6bf..183255fcfdcb 100644 --- a/trunk/drivers/mtd/maps/physmap.c +++ b/trunk/drivers/mtd/maps/physmap.c @@ -1,4 +1,6 @@ /* + * $Id: physmap.c,v 1.39 2005/11/29 14:49:36 gleixner Exp $ + * * Normal mappings of chips in physical memory * * Copyright (C) 2003 MontaVista Software Inc. @@ -201,19 +203,7 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state int i; for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) - if (info->mtd[i]->suspend) { - ret = info->mtd[i]->suspend(info->mtd[i]); - if (ret) - goto fail; - } - - return 0; -fail: - for (--i; i >= 0; --i) - if (info->mtd[i]->suspend) { - BUG_ON(!info->mtd[i]->resume); - info->mtd[i]->resume(info->mtd[i]); - } + ret |= info->mtd[i]->suspend(info->mtd[i]); return ret; } @@ -224,8 +214,7 @@ static int physmap_flash_resume(struct platform_device *dev) int i; for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) - if (info->mtd[i]->resume) - info->mtd[i]->resume(info->mtd[i]); + info->mtd[i]->resume(info->mtd[i]); return 0; } @@ -236,9 +225,8 @@ static void physmap_flash_shutdown(struct platform_device *dev) int i; for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) - if (info->mtd[i]->suspend && info->mtd[i]->resume) - if (info->mtd[i]->suspend(info->mtd[i]) == 0) - info->mtd[i]->resume(info->mtd[i]); + if (info->mtd[i]->suspend(info->mtd[i]) == 0) + info->mtd[i]->resume(info->mtd[i]); } #else #define physmap_flash_suspend NULL diff --git a/trunk/drivers/mtd/maps/plat-ram.c b/trunk/drivers/mtd/maps/plat-ram.c index e7dd9c8a965e..3eb2643b2328 100644 --- a/trunk/drivers/mtd/maps/plat-ram.c +++ b/trunk/drivers/mtd/maps/plat-ram.c @@ -6,6 +6,8 @@ * * Generic platfrom device based RAM map * + * $Id: plat-ram.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $ + * * 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 diff --git a/trunk/drivers/mtd/maps/redwood.c b/trunk/drivers/mtd/maps/redwood.c index de002eb1a7fe..4d858b3d5f82 100644 --- a/trunk/drivers/mtd/maps/redwood.c +++ b/trunk/drivers/mtd/maps/redwood.c @@ -1,4 +1,6 @@ /* + * $Id: redwood.c,v 1.11 2005/11/07 11:14:28 gleixner Exp $ + * * drivers/mtd/maps/redwood.c * * FLASH map for the IBM Redwood 4/5/6 boards. diff --git a/trunk/drivers/mtd/maps/rpxlite.c b/trunk/drivers/mtd/maps/rpxlite.c index 14d90edb4430..809a0c8e7aaf 100644 --- a/trunk/drivers/mtd/maps/rpxlite.c +++ b/trunk/drivers/mtd/maps/rpxlite.c @@ -1,4 +1,6 @@ /* + * $Id: rpxlite.c,v 1.22 2004/11/04 13:24:15 gleixner Exp $ + * * Handle mapping of the flash on the RPX Lite and CLLF boards */ diff --git a/trunk/drivers/mtd/maps/sa1100-flash.c b/trunk/drivers/mtd/maps/sa1100-flash.c index e177a43dfff0..c7d5a52a2d55 100644 --- a/trunk/drivers/mtd/maps/sa1100-flash.c +++ b/trunk/drivers/mtd/maps/sa1100-flash.c @@ -2,6 +2,8 @@ * Flash memory access on SA11x0 based devices * * (C) 2000 Nicolas Pitre + * + * $Id: sa1100-flash.c,v 1.51 2005/11/07 11:14:28 gleixner Exp $ */ #include #include diff --git a/trunk/drivers/mtd/maps/sbc8240.c b/trunk/drivers/mtd/maps/sbc8240.c index 6e1e99cd2b59..b8c1331b7a04 100644 --- a/trunk/drivers/mtd/maps/sbc8240.c +++ b/trunk/drivers/mtd/maps/sbc8240.c @@ -4,6 +4,9 @@ * Carolyn Smith, Tektronix, Inc. * * This code is GPLed + * + * $Id: sbc8240.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $ + * */ /* diff --git a/trunk/drivers/mtd/maps/sbc_gxx.c b/trunk/drivers/mtd/maps/sbc_gxx.c index 1b1c0b7e11ef..7cc4041d096d 100644 --- a/trunk/drivers/mtd/maps/sbc_gxx.c +++ b/trunk/drivers/mtd/maps/sbc_gxx.c @@ -17,6 +17,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + $Id: sbc_gxx.c,v 1.35 2005/11/07 11:14:28 gleixner Exp $ + The SBC-MediaGX / SBC-GXx has up to 16 MiB of Intel StrataFlash (28F320/28F640) in x8 mode. diff --git a/trunk/drivers/mtd/maps/sc520cdp.c b/trunk/drivers/mtd/maps/sc520cdp.c index 85c1e56309ec..4045e372b90d 100644 --- a/trunk/drivers/mtd/maps/sc520cdp.c +++ b/trunk/drivers/mtd/maps/sc520cdp.c @@ -16,6 +16,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * + * $Id: sc520cdp.c,v 1.23 2005/11/17 08:20:27 dwmw2 Exp $ + * * * The SC520CDP is an evaluation board for the Elan SC520 processor available * from AMD. It has two banks of 32-bit Flash ROM, each 8 Megabytes in size, diff --git a/trunk/drivers/mtd/maps/scb2_flash.c b/trunk/drivers/mtd/maps/scb2_flash.c index 21169e6d646c..0fc5584324e3 100644 --- a/trunk/drivers/mtd/maps/scb2_flash.c +++ b/trunk/drivers/mtd/maps/scb2_flash.c @@ -1,5 +1,6 @@ /* * MTD map driver for BIOS Flash on Intel SCB2 boards + * $Id: scb2_flash.c,v 1.12 2005/03/18 14:04:35 gleixner Exp $ * Copyright (C) 2002 Sun Microsystems, Inc. * Tim Hockin * diff --git a/trunk/drivers/mtd/maps/scx200_docflash.c b/trunk/drivers/mtd/maps/scx200_docflash.c index b5391ebb736e..5e2bce22f37c 100644 --- a/trunk/drivers/mtd/maps/scx200_docflash.c +++ b/trunk/drivers/mtd/maps/scx200_docflash.c @@ -2,6 +2,8 @@ Copyright (c) 2001,2002 Christer Weinigel + $Id: scx200_docflash.c,v 1.12 2005/11/07 11:14:28 gleixner Exp $ + National Semiconductor SCx200 flash mapped with DOCCS */ diff --git a/trunk/drivers/mtd/maps/sharpsl-flash.c b/trunk/drivers/mtd/maps/sharpsl-flash.c index 026eab028189..917dc778f24e 100644 --- a/trunk/drivers/mtd/maps/sharpsl-flash.c +++ b/trunk/drivers/mtd/maps/sharpsl-flash.c @@ -4,6 +4,8 @@ * Copyright (C) 2001 Lineo Japan, Inc. * Copyright (C) 2002 SHARP * + * $Id: sharpsl-flash.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $ + * * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp * Handle mapping of the flash on the RPX Lite and CLLF boards * diff --git a/trunk/drivers/mtd/maps/solutionengine.c b/trunk/drivers/mtd/maps/solutionengine.c index 0eb41d9c6786..d76ceef453ce 100644 --- a/trunk/drivers/mtd/maps/solutionengine.c +++ b/trunk/drivers/mtd/maps/solutionengine.c @@ -1,4 +1,6 @@ /* + * $Id: solutionengine.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $ + * * Flash and EPROM on Hitachi Solution Engine and similar boards. * * (C) 2001 Red Hat, Inc. diff --git a/trunk/drivers/mtd/maps/sun_uflash.c b/trunk/drivers/mtd/maps/sun_uflash.c index 0d7c88396c88..001af7f7ddda 100644 --- a/trunk/drivers/mtd/maps/sun_uflash.c +++ b/trunk/drivers/mtd/maps/sun_uflash.c @@ -1,4 +1,4 @@ -/* +/* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $ * * sun_uflash - Driver implementation for user-programmable flash * present on many Sun Microsystems SME boardsets. diff --git a/trunk/drivers/mtd/maps/tqm8xxl.c b/trunk/drivers/mtd/maps/tqm8xxl.c index a5d3d8531faa..521734057314 100644 --- a/trunk/drivers/mtd/maps/tqm8xxl.c +++ b/trunk/drivers/mtd/maps/tqm8xxl.c @@ -2,6 +2,8 @@ * Handle mapping of the flash memory access routines * on TQM8xxL based devices. * + * $Id: tqm8xxl.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $ + * * based on rpxlite.c * * Copyright(C) 2001 Kirk Lee diff --git a/trunk/drivers/mtd/maps/ts5500_flash.c b/trunk/drivers/mtd/maps/ts5500_flash.c index e2147bf11c88..b47270e850bc 100644 --- a/trunk/drivers/mtd/maps/ts5500_flash.c +++ b/trunk/drivers/mtd/maps/ts5500_flash.c @@ -22,6 +22,8 @@ * - Drive A and B use the resident flash disk (RFD) flash translation layer. * - If you have created your own jffs file system and the bios overwrites * it during boot, try disabling Drive A: and B: in the boot order. + * + * $Id: ts5500_flash.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/maps/tsunami_flash.c b/trunk/drivers/mtd/maps/tsunami_flash.c index 77a8bfc02577..0f915ac3102e 100644 --- a/trunk/drivers/mtd/maps/tsunami_flash.c +++ b/trunk/drivers/mtd/maps/tsunami_flash.c @@ -2,6 +2,7 @@ * tsunami_flash.c * * flash chip on alpha ds10... + * $Id: tsunami_flash.c,v 1.10 2005/11/07 11:14:29 gleixner Exp $ */ #include #include diff --git a/trunk/drivers/mtd/maps/uclinux.c b/trunk/drivers/mtd/maps/uclinux.c index 0dc645f8152f..3fcf92130aa4 100644 --- a/trunk/drivers/mtd/maps/uclinux.c +++ b/trunk/drivers/mtd/maps/uclinux.c @@ -4,6 +4,8 @@ * uclinux.c -- generic memory mapped MTD driver for uclinux * * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) + * + * $Id: uclinux.c,v 1.12 2005/11/07 11:14:29 gleixner Exp $ */ /****************************************************************************/ diff --git a/trunk/drivers/mtd/maps/vmax301.c b/trunk/drivers/mtd/maps/vmax301.c index 5a0c9a353b0f..b3e487395435 100644 --- a/trunk/drivers/mtd/maps/vmax301.c +++ b/trunk/drivers/mtd/maps/vmax301.c @@ -1,3 +1,4 @@ +// $Id: vmax301.c,v 1.32 2005/11/07 11:14:29 gleixner Exp $ /* ###################################################################### Tempustech VMAX SBC301 MTD Driver. diff --git a/trunk/drivers/mtd/maps/walnut.c b/trunk/drivers/mtd/maps/walnut.c index e243476c8171..ca932122fb64 100644 --- a/trunk/drivers/mtd/maps/walnut.c +++ b/trunk/drivers/mtd/maps/walnut.c @@ -1,4 +1,6 @@ /* + * $Id: walnut.c,v 1.3 2005/11/07 11:14:29 gleixner Exp $ + * * Mapping for Walnut flash * (used ebony.c as a "framework") * diff --git a/trunk/drivers/mtd/maps/wr_sbc82xx_flash.c b/trunk/drivers/mtd/maps/wr_sbc82xx_flash.c index 413b0cf9bbd2..ac5b8105b6ef 100644 --- a/trunk/drivers/mtd/maps/wr_sbc82xx_flash.c +++ b/trunk/drivers/mtd/maps/wr_sbc82xx_flash.c @@ -1,4 +1,6 @@ /* + * $Id: wr_sbc82xx_flash.c,v 1.8 2005/11/07 11:14:29 gleixner Exp $ + * * Map for flash chips on Wind River PowerQUICC II SBC82xx board. * * Copyright (C) 2004 Red Hat, Inc. diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index 9ff007c4962c..839eed8430a2 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -1,4 +1,6 @@ /* + * $Id: mtd_blkdevs.c,v 1.27 2005/11/07 11:14:20 gleixner Exp $ + * * (C) 2003 David Woodhouse * * Interface to Linux 2.5 block layer for MTD 'translation layers'. @@ -210,7 +212,7 @@ static struct block_device_operations mtd_blktrans_ops = { int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) { struct mtd_blktrans_ops *tr = new->tr; - struct mtd_blktrans_dev *d; + struct list_head *this; int last_devnum = -1; struct gendisk *gd; @@ -219,7 +221,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) BUG(); } - list_for_each_entry(d, &tr->devs, list) { + list_for_each(this, &tr->devs) { + struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list); if (new->devnum == -1) { /* Use first free number */ if (d->devnum != last_devnum+1) { @@ -306,24 +309,33 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) static void blktrans_notify_remove(struct mtd_info *mtd) { - struct mtd_blktrans_ops *tr; - struct mtd_blktrans_dev *dev, *next; + struct list_head *this, *this2, *next; + + list_for_each(this, &blktrans_majors) { + struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); + + list_for_each_safe(this2, next, &tr->devs) { + struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list); - list_for_each_entry(tr, &blktrans_majors, list) - list_for_each_entry_safe(dev, next, &tr->devs, list) if (dev->mtd == mtd) tr->remove_dev(dev); + } + } } static void blktrans_notify_add(struct mtd_info *mtd) { - struct mtd_blktrans_ops *tr; + struct list_head *this; if (mtd->type == MTD_ABSENT) return; - list_for_each_entry(tr, &blktrans_majors, list) + list_for_each(this, &blktrans_majors) { + struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); + tr->add_mtd(tr, mtd); + } + } static struct mtd_notifier blktrans_notifier = { @@ -394,7 +406,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) { - struct mtd_blktrans_dev *dev, *next; + struct list_head *this, *next; mutex_lock(&mtd_table_mutex); @@ -404,8 +416,10 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) /* Remove it from the list of active majors */ list_del(&tr->list); - list_for_each_entry_safe(dev, next, &tr->devs, list) + list_for_each_safe(this, next, &tr->devs) { + struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, list); tr->remove_dev(dev); + } blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); diff --git a/trunk/drivers/mtd/mtdblock.c b/trunk/drivers/mtd/mtdblock.c index 208c6faa0358..952da30b1745 100644 --- a/trunk/drivers/mtd/mtdblock.c +++ b/trunk/drivers/mtd/mtdblock.c @@ -1,6 +1,8 @@ /* * Direct MTD block device access * + * $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $ + * * (C) 2000-2003 Nicolas Pitre * (C) 1999-2003 David Woodhouse */ diff --git a/trunk/drivers/mtd/mtdblock_ro.c b/trunk/drivers/mtd/mtdblock_ro.c index 852165f8b1c3..f79dbb49b1a2 100644 --- a/trunk/drivers/mtd/mtdblock_ro.c +++ b/trunk/drivers/mtd/mtdblock_ro.c @@ -1,4 +1,6 @@ /* + * $Id: mtdblock_ro.c,v 1.19 2004/11/16 18:28:59 dwmw2 Exp $ + * * (C) 2003 David Woodhouse * * Simple read-only (writable only for RAM) mtdblock driver diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index d2f331876e4c..aef9f4b687c9 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -1,4 +1,6 @@ /* + * $Id: mtdchar.c,v 1.76 2005/11/07 11:14:20 gleixner Exp $ + * * Character-device access to raw MTD devices. * */ @@ -492,7 +494,6 @@ static int mtd_ioctl(struct inode *inode, struct file *file, { struct mtd_oob_buf buf; struct mtd_oob_ops ops; - struct mtd_oob_buf __user *user_buf = argp; uint32_t retlen; if(!(file->f_mode & 2)) @@ -536,7 +537,8 @@ static int mtd_ioctl(struct inode *inode, struct file *file, if (ops.oobretlen > 0xFFFFFFFFU) ret = -EOVERFLOW; retlen = ops.oobretlen; - if (copy_to_user(&user_buf->length, &retlen, sizeof(buf.length))) + if (copy_to_user(&((struct mtd_oob_buf *)argp)->length, + &retlen, sizeof(buf.length))) ret = -EFAULT; kfree(ops.oobbuf); @@ -590,29 +592,29 @@ static int mtd_ioctl(struct inode *inode, struct file *file, case MEMLOCK: { - struct erase_info_user einfo; + struct erase_info_user info; - if (copy_from_user(&einfo, argp, sizeof(einfo))) + if (copy_from_user(&info, argp, sizeof(info))) return -EFAULT; if (!mtd->lock) ret = -EOPNOTSUPP; else - ret = mtd->lock(mtd, einfo.start, einfo.length); + ret = mtd->lock(mtd, info.start, info.length); break; } case MEMUNLOCK: { - struct erase_info_user einfo; + struct erase_info_user info; - if (copy_from_user(&einfo, argp, sizeof(einfo))) + if (copy_from_user(&info, argp, sizeof(info))) return -EFAULT; if (!mtd->unlock) ret = -EOPNOTSUPP; else - ret = mtd->unlock(mtd, einfo.start, einfo.length); + ret = mtd->unlock(mtd, info.start, info.length); break; } @@ -712,15 +714,15 @@ static int mtd_ioctl(struct inode *inode, struct file *file, case OTPLOCK: { - struct otp_info oinfo; + struct otp_info info; if (mfi->mode != MTD_MODE_OTP_USER) return -EINVAL; - if (copy_from_user(&oinfo, argp, sizeof(oinfo))) + if (copy_from_user(&info, argp, sizeof(info))) return -EFAULT; if (!mtd->lock_user_prot_reg) return -EOPNOTSUPP; - ret = mtd->lock_user_prot_reg(mtd, oinfo.start, oinfo.length); + ret = mtd->lock_user_prot_reg(mtd, info.start, info.length); break; } #endif diff --git a/trunk/drivers/mtd/mtdconcat.c b/trunk/drivers/mtd/mtdconcat.c index 2972a5edb73d..d563dcd4b264 100644 --- a/trunk/drivers/mtd/mtdconcat.c +++ b/trunk/drivers/mtd/mtdconcat.c @@ -6,6 +6,8 @@ * NAND support by Christian Gan * * This code is GPL + * + * $Id: mtdconcat.c,v 1.11 2005/11/07 11:14:20 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/mtdcore.c b/trunk/drivers/mtd/mtdcore.c index a9d246949820..f7e7890e5bc6 100644 --- a/trunk/drivers/mtd/mtdcore.c +++ b/trunk/drivers/mtd/mtdcore.c @@ -1,4 +1,6 @@ /* + * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $ + * * Core registration and callback routines for MTD * drivers and users. * @@ -51,7 +53,7 @@ int add_mtd_device(struct mtd_info *mtd) for (i=0; i < MAX_MTD_DEVICES; i++) if (!mtd_table[i]) { - struct mtd_notifier *not; + struct list_head *this; mtd_table[i] = mtd; mtd->index = i; @@ -70,8 +72,10 @@ int add_mtd_device(struct mtd_info *mtd) DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name); /* No need to get a refcount on the module containing the notifier, since we hold the mtd_table_mutex */ - list_for_each_entry(not, &mtd_notifiers, list) + list_for_each(this, &mtd_notifiers) { + struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); not->add(mtd); + } mutex_unlock(&mtd_table_mutex); /* We _know_ we aren't being removed, because @@ -109,12 +113,14 @@ int del_mtd_device (struct mtd_info *mtd) mtd->index, mtd->name, mtd->usecount); ret = -EBUSY; } else { - struct mtd_notifier *not; + struct list_head *this; /* No need to get a refcount on the module containing the notifier, since we hold the mtd_table_mutex */ - list_for_each_entry(not, &mtd_notifiers, list) + list_for_each(this, &mtd_notifiers) { + struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); not->remove(mtd); + } mtd_table[mtd->index] = NULL; diff --git a/trunk/drivers/mtd/mtdpart.c b/trunk/drivers/mtd/mtdpart.c index edb90b58a9b1..07c701169344 100644 --- a/trunk/drivers/mtd/mtdpart.c +++ b/trunk/drivers/mtd/mtdpart.c @@ -5,6 +5,8 @@ * * This code is GPL * + * $Id: mtdpart.c,v 1.55 2005/11/07 11:14:20 gleixner Exp $ + * * 02-21-2002 Thomas Gleixner * added support for read_oob, write_oob */ @@ -44,8 +46,8 @@ struct mtd_part { * to the _real_ device. */ -static int part_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) +static int part_read (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); int res; @@ -54,7 +56,7 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len, len = 0; else if (from + len > mtd->size) len = mtd->size - from; - res = part->master->read(part->master, from + part->offset, + res = part->master->read (part->master, from + part->offset, len, retlen, buf); if (unlikely(res)) { if (res == -EUCLEAN) @@ -65,8 +67,8 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len, return res; } -static int part_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) +static int part_point (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, void **virt, resource_size_t *phys) { struct mtd_part *part = PART(mtd); if (from >= mtd->size) @@ -85,7 +87,7 @@ static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) } static int part_read_oob(struct mtd_info *mtd, loff_t from, - struct mtd_oob_ops *ops) + struct mtd_oob_ops *ops) { struct mtd_part *part = PART(mtd); int res; @@ -105,38 +107,38 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from, return res; } -static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf) +static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->read_user_prot_reg(part->master, from, + return part->master->read_user_prot_reg (part->master, from, len, retlen, buf); } -static int part_get_user_prot_info(struct mtd_info *mtd, - struct otp_info *buf, size_t len) +static int part_get_user_prot_info (struct mtd_info *mtd, + struct otp_info *buf, size_t len) { struct mtd_part *part = PART(mtd); - return part->master->get_user_prot_info(part->master, buf, len); + return part->master->get_user_prot_info (part->master, buf, len); } -static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf) +static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->read_fact_prot_reg(part->master, from, + return part->master->read_fact_prot_reg (part->master, from, len, retlen, buf); } -static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, - size_t len) +static int part_get_fact_prot_info (struct mtd_info *mtd, + struct otp_info *buf, size_t len) { struct mtd_part *part = PART(mtd); - return part->master->get_fact_prot_info(part->master, buf, len); + return part->master->get_fact_prot_info (part->master, buf, len); } -static int part_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int part_write (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) @@ -145,12 +147,12 @@ static int part_write(struct mtd_info *mtd, loff_t to, size_t len, len = 0; else if (to + len > mtd->size) len = mtd->size - to; - return part->master->write(part->master, to + part->offset, + return part->master->write (part->master, to + part->offset, len, retlen, buf); } -static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) +static int part_panic_write (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) @@ -159,12 +161,12 @@ static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, len = 0; else if (to + len > mtd->size) len = mtd->size - to; - return part->master->panic_write(part->master, to + part->offset, + return part->master->panic_write (part->master, to + part->offset, len, retlen, buf); } static int part_write_oob(struct mtd_info *mtd, loff_t to, - struct mtd_oob_ops *ops) + struct mtd_oob_ops *ops) { struct mtd_part *part = PART(mtd); @@ -178,32 +180,31 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to, return part->master->write_oob(part->master, to + part->offset, ops); } -static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf) +static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->write_user_prot_reg(part->master, from, + return part->master->write_user_prot_reg (part->master, from, len, retlen, buf); } -static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, - size_t len) +static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) { struct mtd_part *part = PART(mtd); - return part->master->lock_user_prot_reg(part->master, from, len); + return part->master->lock_user_prot_reg (part->master, from, len); } -static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, - unsigned long count, loff_t to, size_t *retlen) +static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, + unsigned long count, loff_t to, size_t *retlen) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; - return part->master->writev(part->master, vecs, count, + return part->master->writev (part->master, vecs, count, to + part->offset, retlen); } -static int part_erase(struct mtd_info *mtd, struct erase_info *instr) +static int part_erase (struct mtd_info *mtd, struct erase_info *instr) { struct mtd_part *part = PART(mtd); int ret; @@ -235,7 +236,7 @@ void mtd_erase_callback(struct erase_info *instr) } EXPORT_SYMBOL_GPL(mtd_erase_callback); -static int part_lock(struct mtd_info *mtd, loff_t ofs, size_t len) +static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) { struct mtd_part *part = PART(mtd); if ((len + ofs) > mtd->size) @@ -243,7 +244,7 @@ static int part_lock(struct mtd_info *mtd, loff_t ofs, size_t len) return part->master->lock(part->master, ofs + part->offset, len); } -static int part_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) +static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) { struct mtd_part *part = PART(mtd); if ((len + ofs) > mtd->size) @@ -269,7 +270,7 @@ static void part_resume(struct mtd_info *mtd) part->master->resume(part->master); } -static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) +static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) { struct mtd_part *part = PART(mtd); if (ofs >= mtd->size) @@ -278,7 +279,7 @@ static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) return part->master->block_isbad(part->master, ofs); } -static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) +static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) { struct mtd_part *part = PART(mtd); int res; @@ -301,192 +302,24 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) int del_mtd_partitions(struct mtd_info *master) { - struct mtd_part *slave, *next; + struct list_head *node; + struct mtd_part *slave; - list_for_each_entry_safe(slave, next, &mtd_partitions, list) + for (node = mtd_partitions.next; + node != &mtd_partitions; + node = node->next) { + slave = list_entry(node, struct mtd_part, list); if (slave->master == master) { - list_del(&slave->list); - if (slave->registered) + struct list_head *prev = node->prev; + __list_del(prev, node->next); + if(slave->registered) del_mtd_device(&slave->mtd); kfree(slave); + node = prev; } - - return 0; -} -EXPORT_SYMBOL(del_mtd_partitions); - -static struct mtd_part *add_one_partition(struct mtd_info *master, - const struct mtd_partition *part, int partno, - u_int32_t cur_offset) -{ - struct mtd_part *slave; - - /* allocate the partition structure */ - slave = kzalloc(sizeof(*slave), GFP_KERNEL); - if (!slave) { - printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n", - master->name); - del_mtd_partitions(master); - return NULL; } - list_add(&slave->list, &mtd_partitions); - /* set up the MTD object for this partition */ - slave->mtd.type = master->type; - slave->mtd.flags = master->flags & ~part->mask_flags; - slave->mtd.size = part->size; - slave->mtd.writesize = master->writesize; - slave->mtd.oobsize = master->oobsize; - slave->mtd.oobavail = master->oobavail; - slave->mtd.subpage_sft = master->subpage_sft; - - slave->mtd.name = part->name; - slave->mtd.owner = master->owner; - - slave->mtd.read = part_read; - slave->mtd.write = part_write; - - if (master->panic_write) - slave->mtd.panic_write = part_panic_write; - - if (master->point && master->unpoint) { - slave->mtd.point = part_point; - slave->mtd.unpoint = part_unpoint; - } - - if (master->read_oob) - slave->mtd.read_oob = part_read_oob; - if (master->write_oob) - slave->mtd.write_oob = part_write_oob; - if (master->read_user_prot_reg) - slave->mtd.read_user_prot_reg = part_read_user_prot_reg; - if (master->read_fact_prot_reg) - slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; - if (master->write_user_prot_reg) - slave->mtd.write_user_prot_reg = part_write_user_prot_reg; - if (master->lock_user_prot_reg) - slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; - if (master->get_user_prot_info) - slave->mtd.get_user_prot_info = part_get_user_prot_info; - if (master->get_fact_prot_info) - slave->mtd.get_fact_prot_info = part_get_fact_prot_info; - if (master->sync) - slave->mtd.sync = part_sync; - if (!partno && master->suspend && master->resume) { - slave->mtd.suspend = part_suspend; - slave->mtd.resume = part_resume; - } - if (master->writev) - slave->mtd.writev = part_writev; - if (master->lock) - slave->mtd.lock = part_lock; - if (master->unlock) - slave->mtd.unlock = part_unlock; - if (master->block_isbad) - slave->mtd.block_isbad = part_block_isbad; - if (master->block_markbad) - slave->mtd.block_markbad = part_block_markbad; - slave->mtd.erase = part_erase; - slave->master = master; - slave->offset = part->offset; - slave->index = partno; - - if (slave->offset == MTDPART_OFS_APPEND) - slave->offset = cur_offset; - if (slave->offset == MTDPART_OFS_NXTBLK) { - slave->offset = cur_offset; - if ((cur_offset % master->erasesize) != 0) { - /* Round up to next erasesize */ - slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; - printk(KERN_NOTICE "Moving partition %d: " - "0x%08x -> 0x%08x\n", partno, - cur_offset, slave->offset); - } - } - if (slave->mtd.size == MTDPART_SIZ_FULL) - slave->mtd.size = master->size - slave->offset; - - printk(KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, - slave->offset + slave->mtd.size, slave->mtd.name); - - /* let's do some sanity checks */ - if (slave->offset >= master->size) { - /* let's register it anyway to preserve ordering */ - slave->offset = 0; - slave->mtd.size = 0; - printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n", - part->name); - goto out_register; - } - if (slave->offset + slave->mtd.size > master->size) { - slave->mtd.size = master->size - slave->offset; - printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", - part->name, master->name, slave->mtd.size); - } - if (master->numeraseregions > 1) { - /* Deal with variable erase size stuff */ - int i, max = master->numeraseregions; - u32 end = slave->offset + slave->mtd.size; - struct mtd_erase_region_info *regions = master->eraseregions; - - /* Find the first erase regions which is part of this - * partition. */ - for (i = 0; i < max && regions[i].offset <= slave->offset; i++) - ; - /* The loop searched for the region _behind_ the first one */ - i--; - - /* Pick biggest erasesize */ - for (; i < max && regions[i].offset < end; i++) { - if (slave->mtd.erasesize < regions[i].erasesize) { - slave->mtd.erasesize = regions[i].erasesize; - } - } - BUG_ON(slave->mtd.erasesize == 0); - } else { - /* Single erase size */ - slave->mtd.erasesize = master->erasesize; - } - - if ((slave->mtd.flags & MTD_WRITEABLE) && - (slave->offset % slave->mtd.erasesize)) { - /* Doesn't start on a boundary of major erase size */ - /* FIXME: Let it be writable if it is on a boundary of - * _minor_ erase size though */ - slave->mtd.flags &= ~MTD_WRITEABLE; - printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", - part->name); - } - if ((slave->mtd.flags & MTD_WRITEABLE) && - (slave->mtd.size % slave->mtd.erasesize)) { - slave->mtd.flags &= ~MTD_WRITEABLE; - printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", - part->name); - } - - slave->mtd.ecclayout = master->ecclayout; - if (master->block_isbad) { - uint32_t offs = 0; - - while (offs < slave->mtd.size) { - if (master->block_isbad(master, - offs + slave->offset)) - slave->mtd.ecc_stats.badblocks++; - offs += slave->mtd.erasesize; - } - } - -out_register: - if (part->mtdp) { - /* store the object pointer (caller may or may not register it*/ - *part->mtdp = &slave->mtd; - slave->registered = 0; - } else { - /* register our partition */ - add_mtd_device(&slave->mtd); - slave->registered = 1; - } - return slave; + return 0; } /* @@ -504,34 +337,194 @@ int add_mtd_partitions(struct mtd_info *master, u_int32_t cur_offset = 0; int i; - printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); + printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); for (i = 0; i < nbparts; i++) { - slave = add_one_partition(master, parts + i, i, cur_offset); - if (!slave) + + /* allocate the partition structure */ + slave = kzalloc (sizeof(*slave), GFP_KERNEL); + if (!slave) { + printk ("memory allocation error while creating partitions for \"%s\"\n", + master->name); + del_mtd_partitions(master); return -ENOMEM; + } + list_add(&slave->list, &mtd_partitions); + + /* set up the MTD object for this partition */ + slave->mtd.type = master->type; + slave->mtd.flags = master->flags & ~parts[i].mask_flags; + slave->mtd.size = parts[i].size; + slave->mtd.writesize = master->writesize; + slave->mtd.oobsize = master->oobsize; + slave->mtd.oobavail = master->oobavail; + slave->mtd.subpage_sft = master->subpage_sft; + + slave->mtd.name = parts[i].name; + slave->mtd.owner = master->owner; + + slave->mtd.read = part_read; + slave->mtd.write = part_write; + + if (master->panic_write) + slave->mtd.panic_write = part_panic_write; + + if(master->point && master->unpoint){ + slave->mtd.point = part_point; + slave->mtd.unpoint = part_unpoint; + } + + if (master->read_oob) + slave->mtd.read_oob = part_read_oob; + if (master->write_oob) + slave->mtd.write_oob = part_write_oob; + if(master->read_user_prot_reg) + slave->mtd.read_user_prot_reg = part_read_user_prot_reg; + if(master->read_fact_prot_reg) + slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; + if(master->write_user_prot_reg) + slave->mtd.write_user_prot_reg = part_write_user_prot_reg; + if(master->lock_user_prot_reg) + slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; + if(master->get_user_prot_info) + slave->mtd.get_user_prot_info = part_get_user_prot_info; + if(master->get_fact_prot_info) + slave->mtd.get_fact_prot_info = part_get_fact_prot_info; + if (master->sync) + slave->mtd.sync = part_sync; + if (!i && master->suspend && master->resume) { + slave->mtd.suspend = part_suspend; + slave->mtd.resume = part_resume; + } + if (master->writev) + slave->mtd.writev = part_writev; + if (master->lock) + slave->mtd.lock = part_lock; + if (master->unlock) + slave->mtd.unlock = part_unlock; + if (master->block_isbad) + slave->mtd.block_isbad = part_block_isbad; + if (master->block_markbad) + slave->mtd.block_markbad = part_block_markbad; + slave->mtd.erase = part_erase; + slave->master = master; + slave->offset = parts[i].offset; + slave->index = i; + + if (slave->offset == MTDPART_OFS_APPEND) + slave->offset = cur_offset; + if (slave->offset == MTDPART_OFS_NXTBLK) { + slave->offset = cur_offset; + if ((cur_offset % master->erasesize) != 0) { + /* Round up to next erasesize */ + slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; + printk(KERN_NOTICE "Moving partition %d: " + "0x%08x -> 0x%08x\n", i, + cur_offset, slave->offset); + } + } + if (slave->mtd.size == MTDPART_SIZ_FULL) + slave->mtd.size = master->size - slave->offset; cur_offset = slave->offset + slave->mtd.size; + + printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, + slave->offset + slave->mtd.size, slave->mtd.name); + + /* let's do some sanity checks */ + if (slave->offset >= master->size) { + /* let's register it anyway to preserve ordering */ + slave->offset = 0; + slave->mtd.size = 0; + printk ("mtd: partition \"%s\" is out of reach -- disabled\n", + parts[i].name); + } + if (slave->offset + slave->mtd.size > master->size) { + slave->mtd.size = master->size - slave->offset; + printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", + parts[i].name, master->name, slave->mtd.size); + } + if (master->numeraseregions>1) { + /* Deal with variable erase size stuff */ + int i; + struct mtd_erase_region_info *regions = master->eraseregions; + + /* Find the first erase regions which is part of this partition. */ + for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) + ; + + for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) { + if (slave->mtd.erasesize < regions[i].erasesize) { + slave->mtd.erasesize = regions[i].erasesize; + } + } + } else { + /* Single erase size */ + slave->mtd.erasesize = master->erasesize; + } + + if ((slave->mtd.flags & MTD_WRITEABLE) && + (slave->offset % slave->mtd.erasesize)) { + /* Doesn't start on a boundary of major erase size */ + /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ + slave->mtd.flags &= ~MTD_WRITEABLE; + printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", + parts[i].name); + } + if ((slave->mtd.flags & MTD_WRITEABLE) && + (slave->mtd.size % slave->mtd.erasesize)) { + slave->mtd.flags &= ~MTD_WRITEABLE; + printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", + parts[i].name); + } + + slave->mtd.ecclayout = master->ecclayout; + if (master->block_isbad) { + uint32_t offs = 0; + + while(offs < slave->mtd.size) { + if (master->block_isbad(master, + offs + slave->offset)) + slave->mtd.ecc_stats.badblocks++; + offs += slave->mtd.erasesize; + } + } + + if(parts[i].mtdp) + { /* store the object pointer (caller may or may not register it */ + *parts[i].mtdp = &slave->mtd; + slave->registered = 0; + } + else + { + /* register our partition */ + add_mtd_device(&slave->mtd); + slave->registered = 1; + } } return 0; } + EXPORT_SYMBOL(add_mtd_partitions); +EXPORT_SYMBOL(del_mtd_partitions); static DEFINE_SPINLOCK(part_parser_lock); static LIST_HEAD(part_parsers); static struct mtd_part_parser *get_partition_parser(const char *name) { - struct mtd_part_parser *p, *ret = NULL; - + struct list_head *this; + void *ret = NULL; spin_lock(&part_parser_lock); - list_for_each_entry(p, &part_parsers, list) + list_for_each(this, &part_parsers) { + struct mtd_part_parser *p = list_entry(this, struct mtd_part_parser, list); + if (!strcmp(p->name, name) && try_module_get(p->owner)) { ret = p; break; } - + } spin_unlock(&part_parser_lock); return ret; @@ -545,7 +538,6 @@ int register_mtd_parser(struct mtd_part_parser *p) return 0; } -EXPORT_SYMBOL_GPL(register_mtd_parser); int deregister_mtd_parser(struct mtd_part_parser *p) { @@ -554,7 +546,6 @@ int deregister_mtd_parser(struct mtd_part_parser *p) spin_unlock(&part_parser_lock); return 0; } -EXPORT_SYMBOL_GPL(deregister_mtd_parser); int parse_mtd_partitions(struct mtd_info *master, const char **types, struct mtd_partition **pparts, unsigned long origin) @@ -582,4 +573,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, } return ret; } + EXPORT_SYMBOL_GPL(parse_mtd_partitions); +EXPORT_SYMBOL_GPL(register_mtd_parser); +EXPORT_SYMBOL_GPL(deregister_mtd_parser); diff --git a/trunk/drivers/mtd/nand/Kconfig b/trunk/drivers/mtd/nand/Kconfig index 71406e517857..5076faf9ca66 100644 --- a/trunk/drivers/mtd/nand/Kconfig +++ b/trunk/drivers/mtd/nand/Kconfig @@ -1,4 +1,5 @@ # drivers/mtd/nand/Kconfig +# $Id: Kconfig,v 1.35 2005/11/07 11:14:30 gleixner Exp $ menuconfig MTD_NAND tristate "NAND Device Support" @@ -271,23 +272,22 @@ config MTD_NAND_CS553X If you say "m", the module will be called "cs553x_nand.ko". -config MTD_NAND_ATMEL - tristate "Support for NAND Flash / SmartMedia on AT91 and AVR32" - depends on ARCH_AT91 || AVR32 +config MTD_NAND_AT91 + bool "Support for NAND Flash / SmartMedia on AT91" + depends on ARCH_AT91 help Enables support for NAND Flash / Smart Media Card interface - on Atmel AT91 and AVR32 processors. + on Atmel AT91 processors. choice - prompt "ECC management for NAND Flash / SmartMedia on AT91 / AVR32" - depends on MTD_NAND_ATMEL + prompt "ECC management for NAND Flash / SmartMedia on AT91" + depends on MTD_NAND_AT91 -config MTD_NAND_ATMEL_ECC_HW +config MTD_NAND_AT91_ECC_HW bool "Hardware ECC" - depends on ARCH_AT91SAM9263 || ARCH_AT91SAM9260 || AVR32 + depends on ARCH_AT91SAM9263 || ARCH_AT91SAM9260 help - Use hardware ECC instead of software ECC when the chip - supports it. - + Uses hardware ECC provided by the at91sam9260/at91sam9263 chip + instead of software ECC. The hardware ECC controller is capable of single bit error correction and 2-bit random detection per page. @@ -297,16 +297,16 @@ config MTD_NAND_ATMEL_ECC_HW If unsure, say Y -config MTD_NAND_ATMEL_ECC_SOFT +config MTD_NAND_AT91_ECC_SOFT bool "Software ECC" help - Use software ECC. + Uses software ECC. NB : hardware and software ECC schemes are incompatible. If you switch from one to another, you'll have to erase your mtd partition. -config MTD_NAND_ATMEL_ECC_NONE +config MTD_NAND_AT91_ECC_NONE bool "No ECC (testing only, DANGEROUS)" depends on DEBUG_KERNEL help diff --git a/trunk/drivers/mtd/nand/Makefile b/trunk/drivers/mtd/nand/Makefile index d772581de573..a6e74a46992a 100644 --- a/trunk/drivers/mtd/nand/Makefile +++ b/trunk/drivers/mtd/nand/Makefile @@ -1,6 +1,7 @@ # # linux/drivers/nand/Makefile # +# $Id: Makefile.common,v 1.15 2004/11/26 12:28:22 dedekind Exp $ obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o @@ -23,7 +24,7 @@ obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o -obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o +obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/at91_nand.c similarity index 62% rename from trunk/drivers/mtd/nand/atmel_nand.c rename to trunk/drivers/mtd/nand/at91_nand.c index 99aec46e2145..0adb287027a2 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/at91_nand.c @@ -1,4 +1,6 @@ /* + * drivers/mtd/nand/at91_nand.c + * * Copyright (C) 2003 Rick Bronson * * Derived from drivers/mtd/nand/autcpu12.c @@ -29,19 +31,20 @@ #include #include -#include -#include +#include +#include +#include #include -#include +#include -#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW +#ifdef CONFIG_MTD_NAND_AT91_ECC_HW #define hard_ecc 1 #else #define hard_ecc 0 #endif -#ifdef CONFIG_MTD_NAND_ATMEL_ECC_NONE +#ifdef CONFIG_MTD_NAND_AT91_ECC_NONE #define no_ecc 1 #else #define no_ecc 0 @@ -49,18 +52,18 @@ /* Register access macros */ #define ecc_readl(add, reg) \ - __raw_readl(add + ATMEL_ECC_##reg) + __raw_readl(add + AT91_ECC_##reg) #define ecc_writel(add, reg, value) \ - __raw_writel((value), add + ATMEL_ECC_##reg) + __raw_writel((value), add + AT91_ECC_##reg) -#include "atmel_nand_ecc.h" /* Hardware ECC registers */ +#include /* AT91SAM9260/3 ECC registers */ /* oob layout for large page size * bad block info is on bytes 0 and 1 * the bytes have to be consecutives to avoid * several NAND_CMD_RNDOUT during read */ -static struct nand_ecclayout atmel_oobinfo_large = { +static struct nand_ecclayout at91_oobinfo_large = { .eccbytes = 4, .eccpos = {60, 61, 62, 63}, .oobfree = { @@ -73,7 +76,7 @@ static struct nand_ecclayout atmel_oobinfo_large = { * the bytes have to be consecutives to avoid * several NAND_CMD_RNDOUT during read */ -static struct nand_ecclayout atmel_oobinfo_small = { +static struct nand_ecclayout at91_oobinfo_small = { .eccbytes = 4, .eccpos = {0, 1, 2, 3}, .oobfree = { @@ -81,11 +84,11 @@ static struct nand_ecclayout atmel_oobinfo_small = { }, }; -struct atmel_nand_host { +struct at91_nand_host { struct nand_chip nand_chip; struct mtd_info mtd; void __iomem *io_base; - struct atmel_nand_data *board; + struct at91_nand_data *board; struct device *dev; void __iomem *ecc; }; @@ -93,34 +96,34 @@ struct atmel_nand_host { /* * Enable NAND. */ -static void atmel_nand_enable(struct atmel_nand_host *host) +static void at91_nand_enable(struct at91_nand_host *host) { if (host->board->enable_pin) - gpio_set_value(host->board->enable_pin, 0); + at91_set_gpio_value(host->board->enable_pin, 0); } /* * Disable NAND. */ -static void atmel_nand_disable(struct atmel_nand_host *host) +static void at91_nand_disable(struct at91_nand_host *host) { if (host->board->enable_pin) - gpio_set_value(host->board->enable_pin, 1); + at91_set_gpio_value(host->board->enable_pin, 1); } /* * Hardware specific access to control-lines */ -static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *nand_chip = mtd->priv; - struct atmel_nand_host *host = nand_chip->priv; + struct at91_nand_host *host = nand_chip->priv; if (ctrl & NAND_CTRL_CHANGE) { if (ctrl & NAND_NCE) - atmel_nand_enable(host); + at91_nand_enable(host); else - atmel_nand_disable(host); + at91_nand_disable(host); } if (cmd == NAND_CMD_NONE) return; @@ -134,49 +137,18 @@ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl /* * Read the Device Ready pin. */ -static int atmel_nand_device_ready(struct mtd_info *mtd) +static int at91_nand_device_ready(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd->priv; - struct atmel_nand_host *host = nand_chip->priv; + struct at91_nand_host *host = nand_chip->priv; - return gpio_get_value(host->board->rdy_pin); -} - -/* - * Minimal-overhead PIO for data access. - */ -static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) -{ - struct nand_chip *nand_chip = mtd->priv; - - __raw_readsb(nand_chip->IO_ADDR_R, buf, len); -} - -static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) -{ - struct nand_chip *nand_chip = mtd->priv; - - __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); -} - -static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) -{ - struct nand_chip *nand_chip = mtd->priv; - - __raw_writesb(nand_chip->IO_ADDR_W, buf, len); -} - -static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) -{ - struct nand_chip *nand_chip = mtd->priv; - - __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); + return at91_get_gpio_value(host->board->rdy_pin); } /* * write oob for small pages */ -static int atmel_nand_write_oob_512(struct mtd_info *mtd, +static int at91_nand_write_oob_512(struct mtd_info *mtd, struct nand_chip *chip, int page) { int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; @@ -204,7 +176,7 @@ static int atmel_nand_write_oob_512(struct mtd_info *mtd, /* * read oob for small pages */ -static int atmel_nand_read_oob_512(struct mtd_info *mtd, +static int at91_nand_read_oob_512(struct mtd_info *mtd, struct nand_chip *chip, int page, int sndcmd) { if (sndcmd) { @@ -224,11 +196,11 @@ static int atmel_nand_read_oob_512(struct mtd_info *mtd, * dat: raw data (unused) * ecc_code: buffer for ECC */ -static int atmel_nand_calculate(struct mtd_info *mtd, +static int at91_nand_calculate(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) { struct nand_chip *nand_chip = mtd->priv; - struct atmel_nand_host *host = nand_chip->priv; + struct at91_nand_host *host = nand_chip->priv; uint32_t *eccpos = nand_chip->ecc.layout->eccpos; unsigned int ecc_value; @@ -239,7 +211,7 @@ static int atmel_nand_calculate(struct mtd_info *mtd, ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; /* get the last 2 ECC bytes */ - ecc_value = ecc_readl(host->ecc, NPR) & ATMEL_ECC_NPARITY; + ecc_value = ecc_readl(host->ecc, NPR) & AT91_ECC_NPARITY; ecc_code[eccpos[2]] = ecc_value & 0xFF; ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; @@ -254,7 +226,7 @@ static int atmel_nand_calculate(struct mtd_info *mtd, * chip: nand chip info structure * buf: buffer to store read data */ -static int atmel_nand_read_page(struct mtd_info *mtd, +static int at91_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf) { int eccsize = chip->ecc.size; @@ -265,19 +237,6 @@ static int atmel_nand_read_page(struct mtd_info *mtd, uint8_t *ecc_pos; int stat; - /* - * Errata: ALE is incorrectly wired up to the ECC controller - * on the AP7000, so it will include the address cycles in the - * ECC calculation. - * - * Workaround: Reset the parity registers before reading the - * actual data. - */ - if (cpu_is_at32ap7000()) { - struct atmel_nand_host *host = chip->priv; - ecc_writel(host->ecc, CR, ATMEL_ECC_RST); - } - /* read the page */ chip->read_buf(mtd, p, eccsize); @@ -326,11 +285,11 @@ static int atmel_nand_read_page(struct mtd_info *mtd, * * Detect and correct a 1 bit error for a page */ -static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, +static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *isnull) { struct nand_chip *nand_chip = mtd->priv; - struct atmel_nand_host *host = nand_chip->priv; + struct at91_nand_host *host = nand_chip->priv; unsigned int ecc_status; unsigned int ecc_word, ecc_bit; @@ -338,43 +297,43 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, ecc_status = ecc_readl(host->ecc, SR); /* if there's no error */ - if (likely(!(ecc_status & ATMEL_ECC_RECERR))) + if (likely(!(ecc_status & AT91_ECC_RECERR))) return 0; /* get error bit offset (4 bits) */ - ecc_bit = ecc_readl(host->ecc, PR) & ATMEL_ECC_BITADDR; + ecc_bit = ecc_readl(host->ecc, PR) & AT91_ECC_BITADDR; /* get word address (12 bits) */ - ecc_word = ecc_readl(host->ecc, PR) & ATMEL_ECC_WORDADDR; + ecc_word = ecc_readl(host->ecc, PR) & AT91_ECC_WORDADDR; ecc_word >>= 4; /* if there are multiple errors */ - if (ecc_status & ATMEL_ECC_MULERR) { + if (ecc_status & AT91_ECC_MULERR) { /* check if it is a freshly erased block * (filled with 0xff) */ - if ((ecc_bit == ATMEL_ECC_BITADDR) - && (ecc_word == (ATMEL_ECC_WORDADDR >> 4))) { + if ((ecc_bit == AT91_ECC_BITADDR) + && (ecc_word == (AT91_ECC_WORDADDR >> 4))) { /* the block has just been erased, return OK */ return 0; } /* it doesn't seems to be a freshly * erased block. * We can't correct so many errors */ - dev_dbg(host->dev, "atmel_nand : multiple errors detected." + dev_dbg(host->dev, "at91_nand : multiple errors detected." " Unable to correct.\n"); return -EIO; } /* if there's a single bit error : we can correct it */ - if (ecc_status & ATMEL_ECC_ECCERR) { + if (ecc_status & AT91_ECC_ECCERR) { /* there's nothing much to do here. * the bit error is on the ECC itself. */ - dev_dbg(host->dev, "atmel_nand : one bit error on ECC code." + dev_dbg(host->dev, "at91_nand : one bit error on ECC code." " Nothing to correct\n"); return 0; } - dev_dbg(host->dev, "atmel_nand : one bit error on data." + dev_dbg(host->dev, "at91_nand : one bit error on data." " (word offset in the page :" " 0x%x bit offset : 0x%x)\n", ecc_word, ecc_bit); @@ -386,21 +345,14 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, /* 8 bits words */ dat[ecc_word] ^= (1 << ecc_bit); } - dev_dbg(host->dev, "atmel_nand : error corrected\n"); + dev_dbg(host->dev, "at91_nand : error corrected\n"); return 1; } /* - * Enable HW ECC : unused on most chips + * Enable HW ECC : unsused */ -static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) -{ - if (cpu_is_at32ap7000()) { - struct nand_chip *nand_chip = mtd->priv; - struct atmel_nand_host *host = nand_chip->priv; - ecc_writel(host->ecc, CR, ATMEL_ECC_RST); - } -} +static void at91_nand_hwctl(struct mtd_info *mtd, int mode) { ; } #ifdef CONFIG_MTD_PARTITIONS static const char *part_probes[] = { "cmdlinepart", NULL }; @@ -409,9 +361,9 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; /* * Probe for the NAND device. */ -static int __init atmel_nand_probe(struct platform_device *pdev) +static int __init at91_nand_probe(struct platform_device *pdev) { - struct atmel_nand_host *host; + struct at91_nand_host *host; struct mtd_info *mtd; struct nand_chip *nand_chip; struct resource *regs; @@ -423,24 +375,24 @@ static int __init atmel_nand_probe(struct platform_device *pdev) int num_partitions = 0; #endif - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n"); - return -ENXIO; - } - /* Allocate memory for the device structure (and zero it) */ - host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL); + host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL); if (!host) { - printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n"); + printk(KERN_ERR "at91_nand: failed to allocate device structure.\n"); return -ENOMEM; } + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + printk(KERN_ERR "at91_nand: can't get I/O resource mem\n"); + return -ENXIO; + } + host->io_base = ioremap(mem->start, mem->end - mem->start + 1); if (host->io_base == NULL) { - printk(KERN_ERR "atmel_nand: ioremap failed\n"); - res = -EIO; - goto err_nand_ioremap; + printk(KERN_ERR "at91_nand: ioremap failed\n"); + kfree(host); + return -EIO; } mtd = &host->mtd; @@ -455,14 +407,14 @@ static int __init atmel_nand_probe(struct platform_device *pdev) /* Set address of NAND IO lines */ nand_chip->IO_ADDR_R = host->io_base; nand_chip->IO_ADDR_W = host->io_base; - nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; + nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; if (host->board->rdy_pin) - nand_chip->dev_ready = atmel_nand_device_ready; + nand_chip->dev_ready = at91_nand_device_ready; regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!regs && hard_ecc) { - printk(KERN_ERR "atmel_nand: can't get I/O resource " + printk(KERN_ERR "at91_nand: can't get I/O resource " "regs\nFalling back on software ECC\n"); } @@ -472,15 +424,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev) if (hard_ecc && regs) { host->ecc = ioremap(regs->start, regs->end - regs->start + 1); if (host->ecc == NULL) { - printk(KERN_ERR "atmel_nand: ioremap failed\n"); + printk(KERN_ERR "at91_nand: ioremap failed\n"); res = -EIO; goto err_ecc_ioremap; } nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; - nand_chip->ecc.calculate = atmel_nand_calculate; - nand_chip->ecc.correct = atmel_nand_correct; - nand_chip->ecc.hwctl = atmel_nand_hwctl; - nand_chip->ecc.read_page = atmel_nand_read_page; + nand_chip->ecc.calculate = at91_nand_calculate; + nand_chip->ecc.correct = at91_nand_correct; + nand_chip->ecc.hwctl = at91_nand_hwctl; + nand_chip->ecc.read_page = at91_nand_read_page; nand_chip->ecc.bytes = 4; nand_chip->ecc.prepad = 0; nand_chip->ecc.postpad = 0; @@ -488,30 +440,24 @@ static int __init atmel_nand_probe(struct platform_device *pdev) nand_chip->chip_delay = 20; /* 20us command delay time */ - if (host->board->bus_width_16) { /* 16-bit bus width */ + if (host->board->bus_width_16) /* 16-bit bus width */ nand_chip->options |= NAND_BUSWIDTH_16; - nand_chip->read_buf = atmel_read_buf16; - nand_chip->write_buf = atmel_write_buf16; - } else { - nand_chip->read_buf = atmel_read_buf; - nand_chip->write_buf = atmel_write_buf; - } platform_set_drvdata(pdev, host); - atmel_nand_enable(host); + at91_nand_enable(host); if (host->board->det_pin) { - if (gpio_get_value(host->board->det_pin)) { - printk("No SmartMedia card inserted.\n"); + if (at91_get_gpio_value(host->board->det_pin)) { + printk ("No SmartMedia card inserted.\n"); res = ENXIO; - goto err_no_card; + goto out; } } /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, 1)) { res = -ENXIO; - goto err_scan_ident; + goto out; } if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { @@ -521,22 +467,22 @@ static int __init atmel_nand_probe(struct platform_device *pdev) /* set ECC page size and oob layout */ switch (mtd->writesize) { case 512: - nand_chip->ecc.layout = &atmel_oobinfo_small; - nand_chip->ecc.read_oob = atmel_nand_read_oob_512; - nand_chip->ecc.write_oob = atmel_nand_write_oob_512; - ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528); + nand_chip->ecc.layout = &at91_oobinfo_small; + nand_chip->ecc.read_oob = at91_nand_read_oob_512; + nand_chip->ecc.write_oob = at91_nand_write_oob_512; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_528); break; case 1024: - nand_chip->ecc.layout = &atmel_oobinfo_large; - ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056); + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_1056); break; case 2048: - nand_chip->ecc.layout = &atmel_oobinfo_large; - ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112); + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_2112); break; case 4096: - nand_chip->ecc.layout = &atmel_oobinfo_large; - ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224); + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_4224); break; default: /* page size not handled by HW ECC */ @@ -556,12 +502,12 @@ static int __init atmel_nand_probe(struct platform_device *pdev) /* second phase scan */ if (nand_scan_tail(mtd)) { res = -ENXIO; - goto err_scan_tail; + goto out; } #ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_CMDLINE_PARTS - mtd->name = "atmel_nand"; + mtd->name = "at91_nand"; num_partitions = parse_mtd_partitions(mtd, part_probes, &partitions, 0); #endif @@ -570,9 +516,9 @@ static int __init atmel_nand_probe(struct platform_device *pdev) &num_partitions); if ((!partitions) || (num_partitions == 0)) { - printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n"); + printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); res = ENXIO; - goto err_no_partitions; + goto release; } res = add_mtd_partitions(mtd, partitions, num_partitions); @@ -584,19 +530,17 @@ static int __init atmel_nand_probe(struct platform_device *pdev) return res; #ifdef CONFIG_MTD_PARTITIONS -err_no_partitions: +release: #endif nand_release(mtd); -err_scan_tail: -err_scan_ident: -err_no_card: - atmel_nand_disable(host); - platform_set_drvdata(pdev, NULL); - if (host->ecc) - iounmap(host->ecc); + +out: + iounmap(host->ecc); + err_ecc_ioremap: + at91_nand_disable(host); + platform_set_drvdata(pdev, NULL); iounmap(host->io_base); -err_nand_ioremap: kfree(host); return res; } @@ -604,47 +548,47 @@ static int __init atmel_nand_probe(struct platform_device *pdev) /* * Remove a NAND device. */ -static int __exit atmel_nand_remove(struct platform_device *pdev) +static int __devexit at91_nand_remove(struct platform_device *pdev) { - struct atmel_nand_host *host = platform_get_drvdata(pdev); + struct at91_nand_host *host = platform_get_drvdata(pdev); struct mtd_info *mtd = &host->mtd; nand_release(mtd); - atmel_nand_disable(host); + at91_nand_disable(host); - if (host->ecc) - iounmap(host->ecc); iounmap(host->io_base); + iounmap(host->ecc); kfree(host); return 0; } -static struct platform_driver atmel_nand_driver = { - .remove = __exit_p(atmel_nand_remove), +static struct platform_driver at91_nand_driver = { + .probe = at91_nand_probe, + .remove = at91_nand_remove, .driver = { - .name = "atmel_nand", + .name = "at91_nand", .owner = THIS_MODULE, }, }; -static int __init atmel_nand_init(void) +static int __init at91_nand_init(void) { - return platform_driver_probe(&atmel_nand_driver, atmel_nand_probe); + return platform_driver_register(&at91_nand_driver); } -static void __exit atmel_nand_exit(void) +static void __exit at91_nand_exit(void) { - platform_driver_unregister(&atmel_nand_driver); + platform_driver_unregister(&at91_nand_driver); } -module_init(atmel_nand_init); -module_exit(atmel_nand_exit); +module_init(at91_nand_init); +module_exit(at91_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Rick Bronson"); -MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91 / AVR32"); -MODULE_ALIAS("platform:atmel_nand"); +MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200 / AT91SAM9"); +MODULE_ALIAS("platform:at91_nand"); diff --git a/trunk/drivers/mtd/nand/atmel_nand_ecc.h b/trunk/drivers/mtd/nand/atmel_nand_ecc.h deleted file mode 100644 index 1ee7f993db1c..000000000000 --- a/trunk/drivers/mtd/nand/atmel_nand_ecc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Error Corrected Code Controller (ECC) - System peripherals regsters. - * Based on AT91SAM9260 datasheet revision B. - * - * 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 ATMEL_NAND_ECC_H -#define ATMEL_NAND_ECC_H - -#define ATMEL_ECC_CR 0x00 /* Control register */ -#define ATMEL_ECC_RST (1 << 0) /* Reset parity */ - -#define ATMEL_ECC_MR 0x04 /* Mode register */ -#define ATMEL_ECC_PAGESIZE (3 << 0) /* Page Size */ -#define ATMEL_ECC_PAGESIZE_528 (0) -#define ATMEL_ECC_PAGESIZE_1056 (1) -#define ATMEL_ECC_PAGESIZE_2112 (2) -#define ATMEL_ECC_PAGESIZE_4224 (3) - -#define ATMEL_ECC_SR 0x08 /* Status register */ -#define ATMEL_ECC_RECERR (1 << 0) /* Recoverable Error */ -#define ATMEL_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ -#define ATMEL_ECC_MULERR (1 << 2) /* Multiple Errors */ - -#define ATMEL_ECC_PR 0x0c /* Parity register */ -#define ATMEL_ECC_BITADDR (0xf << 0) /* Bit Error Address */ -#define ATMEL_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ - -#define ATMEL_ECC_NPR 0x10 /* NParity register */ -#define ATMEL_ECC_NPARITY (0xffff << 0) /* NParity */ - -#endif diff --git a/trunk/drivers/mtd/nand/au1550nd.c b/trunk/drivers/mtd/nand/au1550nd.c index 761946ea45b1..09e421a96893 100644 --- a/trunk/drivers/mtd/nand/au1550nd.c +++ b/trunk/drivers/mtd/nand/au1550nd.c @@ -3,6 +3,8 @@ * * Copyright (C) 2004 Embedded Edge, LLC * + * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $ + * * 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. @@ -602,6 +604,8 @@ module_init(au1xxx_nand_init); */ static void __exit au1550_cleanup(void) { + struct nand_chip *this = (struct nand_chip *)&au1550_mtd[1]; + /* Release resources, unregister device */ nand_release(au1550_mtd); diff --git a/trunk/drivers/mtd/nand/autcpu12.c b/trunk/drivers/mtd/nand/autcpu12.c index 553dd7e9b41c..dd38011ee0b7 100644 --- a/trunk/drivers/mtd/nand/autcpu12.c +++ b/trunk/drivers/mtd/nand/autcpu12.c @@ -6,6 +6,8 @@ * Derived from drivers/mtd/spia.c * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * + * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nand/cafe_nand.c b/trunk/drivers/mtd/nand/cafe_nand.c index 95345d051579..da6ceaa80ba1 100644 --- a/trunk/drivers/mtd/nand/cafe_nand.c +++ b/trunk/drivers/mtd/nand/cafe_nand.c @@ -626,12 +626,10 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, { struct mtd_info *mtd; struct cafe_priv *cafe; - uint32_t ctrl; - int err = 0; -#ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *parts; + uint32_t ctrl; int nr_parts; -#endif + int err = 0; /* Very old versions shared the same PCI ident for all three functions on the chip. Verify the class too... */ diff --git a/trunk/drivers/mtd/nand/diskonchip.c b/trunk/drivers/mtd/nand/diskonchip.c index 765d4f0f7c86..0e72153b3297 100644 --- a/trunk/drivers/mtd/nand/diskonchip.c +++ b/trunk/drivers/mtd/nand/diskonchip.c @@ -15,6 +15,8 @@ * converted to the generic Reed-Solomon library by Thomas Gleixner * * Interface to generic NAND code for M-Systems DiskOnChip devices + * + * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $ */ #include @@ -52,6 +54,8 @@ static unsigned long __initdata doc_locations[] = { 0xe0000, 0xe2000, 0xe4000, 0xe6000, 0xe8000, 0xea000, 0xec000, 0xee000, #endif /* CONFIG_MTD_DOCPROBE_HIGH */ +#elif defined(__PPC__) + 0xe4000000, #else #warning Unknown architecture for DiskOnChip. No default probe locations defined #endif diff --git a/trunk/drivers/mtd/nand/edb7312.c b/trunk/drivers/mtd/nand/edb7312.c index 387e4352903e..ba67bbec20d3 100644 --- a/trunk/drivers/mtd/nand/edb7312.c +++ b/trunk/drivers/mtd/nand/edb7312.c @@ -6,6 +6,8 @@ * Derived from drivers/mtd/nand/autcpu12.c * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) * + * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nand/excite_nandflash.c b/trunk/drivers/mtd/nand/excite_nandflash.c index ced14b5294d5..bed87290decc 100644 --- a/trunk/drivers/mtd/nand/excite_nandflash.c +++ b/trunk/drivers/mtd/nand/excite_nandflash.c @@ -209,7 +209,7 @@ static int __init excite_nand_probe(struct device *dev) if (likely(!scan_res)) { DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id); add_mtd_partitions(&drvdata->board_mtd, partition_info, - ARRAY_SIZE(partition_info)); + sizeof partition_info / sizeof partition_info[0]); } else { iounmap(drvdata->regs); kfree(drvdata); diff --git a/trunk/drivers/mtd/nand/fsl_elbc_nand.c b/trunk/drivers/mtd/nand/fsl_elbc_nand.c index 9dff51351f4f..4b69aacdf5ca 100644 --- a/trunk/drivers/mtd/nand/fsl_elbc_nand.c +++ b/trunk/drivers/mtd/nand/fsl_elbc_nand.c @@ -89,6 +89,7 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = { .eccbytes = 3, .eccpos = {6, 7, 8}, .oobfree = { {0, 5}, {9, 7} }, + .oobavail = 12, }; /* Small Page FLASH with FMR[ECCM] = 1 */ @@ -96,6 +97,7 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = { .eccbytes = 3, .eccpos = {8, 9, 10}, .oobfree = { {0, 5}, {6, 2}, {11, 5} }, + .oobavail = 12, }; /* Large Page FLASH with FMR[ECCM] = 0 */ @@ -103,6 +105,7 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = { .eccbytes = 12, .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56}, .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }, + .oobavail = 48, }; /* Large Page FLASH with FMR[ECCM] = 1 */ @@ -110,48 +113,7 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = { .eccbytes = 12, .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, -}; - -/* - * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset - * 1, so we have to adjust bad block pattern. This pattern should be used for - * x8 chips only. So far hardware does not support x16 chips anyway. - */ -static u8 scan_ff_pattern[] = { 0xff, }; - -static struct nand_bbt_descr largepage_memorybased = { - .options = 0, - .offs = 0, - .len = 1, - .pattern = scan_ff_pattern, -}; - -/* - * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, - * interfere with ECC positions, that's why we implement our own descriptors. - * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. - */ -static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; -static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; - -static struct nand_bbt_descr bbt_main_descr = { - .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | - NAND_BBT_2BIT | NAND_BBT_VERSION, - .offs = 11, - .len = 4, - .veroffs = 15, - .maxblocks = 4, - .pattern = bbt_pattern, -}; - -static struct nand_bbt_descr bbt_mirror_descr = { - .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | - NAND_BBT_2BIT | NAND_BBT_VERSION, - .offs = 11, - .len = 4, - .veroffs = 15, - .maxblocks = 4, - .pattern = mirror_pattern, + .oobavail = 48, }; /*=================================*/ @@ -725,7 +687,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) chip->ecc.layout = (priv->fmr & FMR_ECCM) ? &fsl_elbc_oob_lp_eccm1 : &fsl_elbc_oob_lp_eccm0; - chip->badblock_pattern = &largepage_memorybased; + mtd->ecclayout = chip->ecc.layout; + mtd->oobavail = chip->ecc.layout->oobavail; } } else { dev_err(ctrl->dev, @@ -789,12 +752,8 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) chip->cmdfunc = fsl_elbc_cmdfunc; chip->waitfunc = fsl_elbc_wait; - chip->bbt_td = &bbt_main_descr; - chip->bbt_md = &bbt_mirror_descr; - /* set up nand options */ - chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR | - NAND_USE_FLASH_BBT; + chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR; chip->controller = &ctrl->controller; chip->priv = priv; @@ -836,8 +795,8 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) return 0; } -static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, - struct device_node *node) +static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, + struct device_node *node) { struct fsl_lbc_regs __iomem *lbc = ctrl->regs; struct fsl_elbc_mtd *priv; @@ -958,7 +917,7 @@ static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl) return 0; } -static int fsl_elbc_ctrl_remove(struct of_device *ofdev) +static int __devexit fsl_elbc_ctrl_remove(struct of_device *ofdev) { struct fsl_elbc_ctrl *ctrl = dev_get_drvdata(&ofdev->dev); int i; @@ -1082,7 +1041,7 @@ static struct of_platform_driver fsl_elbc_ctrl_driver = { }, .match_table = fsl_elbc_match, .probe = fsl_elbc_ctrl_probe, - .remove = fsl_elbc_ctrl_remove, + .remove = __devexit_p(fsl_elbc_ctrl_remove), }; static int __init fsl_elbc_init(void) diff --git a/trunk/drivers/mtd/nand/h1910.c b/trunk/drivers/mtd/nand/h1910.c index 9e59de501c2e..2d585d2d090c 100644 --- a/trunk/drivers/mtd/nand/h1910.c +++ b/trunk/drivers/mtd/nand/h1910.c @@ -7,6 +7,8 @@ * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) * + * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index d1129bae6c27..ba1bdf787323 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -797,87 +797,6 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, return 0; } -/** - * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function - * @mtd: mtd info structure - * @chip: nand chip info structure - * @dataofs offset of requested data within the page - * @readlen data length - * @buf: buffer to store read data - */ -static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) -{ - int start_step, end_step, num_steps; - uint32_t *eccpos = chip->ecc.layout->eccpos; - uint8_t *p; - int data_col_addr, i, gaps = 0; - int datafrag_len, eccfrag_len, aligned_len, aligned_pos; - int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; - - /* Column address wihin the page aligned to ECC size (256bytes). */ - start_step = data_offs / chip->ecc.size; - end_step = (data_offs + readlen - 1) / chip->ecc.size; - num_steps = end_step - start_step + 1; - - /* Data size aligned to ECC ecc.size*/ - datafrag_len = num_steps * chip->ecc.size; - eccfrag_len = num_steps * chip->ecc.bytes; - - data_col_addr = start_step * chip->ecc.size; - /* If we read not a page aligned data */ - if (data_col_addr != 0) - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1); - - p = bufpoi + data_col_addr; - chip->read_buf(mtd, p, datafrag_len); - - /* Calculate ECC */ - for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) - chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]); - - /* The performance is faster if to position offsets - according to ecc.pos. Let make sure here that - there are no gaps in ecc positions */ - for (i = 0; i < eccfrag_len - 1; i++) { - if (eccpos[i + start_step * chip->ecc.bytes] + 1 != - eccpos[i + start_step * chip->ecc.bytes + 1]) { - gaps = 1; - break; - } - } - if (gaps) { - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - } else { - /* send the command to read the particular ecc bytes */ - /* take care about buswidth alignment in read_buf */ - aligned_pos = eccpos[start_step * chip->ecc.bytes] & ~(busw - 1); - aligned_len = eccfrag_len; - if (eccpos[start_step * chip->ecc.bytes] & (busw - 1)) - aligned_len++; - if (eccpos[(start_step + num_steps) * chip->ecc.bytes] & (busw - 1)) - aligned_len++; - - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize + aligned_pos, -1); - chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len); - } - - for (i = 0; i < eccfrag_len; i++) - chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + start_step * chip->ecc.bytes]]; - - p = bufpoi + data_col_addr; - for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { - int stat; - - stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); - if (stat == -1) - mtd->ecc_stats.failed++; - else - mtd->ecc_stats.corrected += stat; - } - return 0; -} - /** * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function * @mtd: mtd info structure @@ -1075,8 +994,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, /* Now read the page into the buffer */ if (unlikely(ops->mode == MTD_OOB_RAW)) ret = chip->ecc.read_page_raw(mtd, chip, bufpoi); - else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) - ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi); else ret = chip->ecc.read_page(mtd, chip, bufpoi); if (ret < 0) @@ -1084,8 +1001,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, /* Transfer not aligned data */ if (!aligned) { - if (!NAND_SUBPAGE_READ(chip) && !oob) - chip->pagebuf = realpage; + chip->pagebuf = realpage; memcpy(buf, chip->buffers->databuf + col, bytes); } @@ -2605,7 +2521,6 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.calculate = nand_calculate_ecc; chip->ecc.correct = nand_correct_data; chip->ecc.read_page = nand_read_page_swecc; - chip->ecc.read_subpage = nand_read_subpage; chip->ecc.write_page = nand_write_page_swecc; chip->ecc.read_oob = nand_read_oob_std; chip->ecc.write_oob = nand_write_oob_std; diff --git a/trunk/drivers/mtd/nand/nand_bbt.c b/trunk/drivers/mtd/nand/nand_bbt.c index 0b1c48595f12..5e121ceaa598 100644 --- a/trunk/drivers/mtd/nand/nand_bbt.c +++ b/trunk/drivers/mtd/nand/nand_bbt.c @@ -6,6 +6,8 @@ * * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) * + * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nand/nand_ecc.c b/trunk/drivers/mtd/nand/nand_ecc.c index 918a806a8471..9003a135e050 100644 --- a/trunk/drivers/mtd/nand/nand_ecc.c +++ b/trunk/drivers/mtd/nand/nand_ecc.c @@ -9,6 +9,8 @@ * * Copyright (C) 2006 Thomas Gleixner * + * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $ + * * This file 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 diff --git a/trunk/drivers/mtd/nand/nand_ids.c b/trunk/drivers/mtd/nand/nand_ids.c index 69ee2c90eb0b..a3e3ab0185d5 100644 --- a/trunk/drivers/mtd/nand/nand_ids.c +++ b/trunk/drivers/mtd/nand/nand_ids.c @@ -3,6 +3,8 @@ * * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) * + * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nand/nandsim.c b/trunk/drivers/mtd/nand/nandsim.c index ecd70e2504f6..bb885d1fcab5 100644 --- a/trunk/drivers/mtd/nand/nandsim.c +++ b/trunk/drivers/mtd/nand/nandsim.c @@ -21,6 +21,8 @@ * 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 + * + * $Id: nandsim.c,v 1.8 2005/03/19 15:33:56 dedekind Exp $ */ #include @@ -37,7 +39,6 @@ #include #include #include -#include /* Default simulator parameters values */ #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ @@ -297,11 +298,11 @@ struct nandsim { /* NAND flash "geometry" */ struct nandsin_geometry { - uint64_t totsz; /* total flash size, bytes */ + uint32_t totsz; /* total flash size, bytes */ uint32_t secsz; /* flash sector (erase block) size, bytes */ uint pgsz; /* NAND flash page size, bytes */ uint oobsz; /* page OOB area size, bytes */ - uint64_t totszoob; /* total flash size including OOB, bytes */ + uint32_t totszoob; /* total flash size including OOB, bytes */ uint pgszoob; /* page size including OOB , bytes*/ uint secszoob; /* sector size including OOB, bytes */ uint pgnum; /* total number of pages */ @@ -458,12 +459,6 @@ static char *get_partition_name(int i) return kstrdup(buf, GFP_KERNEL); } -static u_int64_t divide(u_int64_t n, u_int32_t d) -{ - do_div(n, d); - return n; -} - /* * Initialize the nandsim structure. * @@ -474,8 +469,8 @@ static int init_nandsim(struct mtd_info *mtd) struct nand_chip *chip = (struct nand_chip *)mtd->priv; struct nandsim *ns = (struct nandsim *)(chip->priv); int i, ret = 0; - u_int64_t remains; - u_int64_t next_offset; + u_int32_t remains; + u_int32_t next_offset; if (NS_IS_INITIALIZED(ns)) { NS_ERR("init_nandsim: nandsim is already initialized\n"); @@ -492,8 +487,8 @@ static int init_nandsim(struct mtd_info *mtd) ns->geom.oobsz = mtd->oobsize; ns->geom.secsz = mtd->erasesize; ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; - ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz); - ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; + ns->geom.pgnum = ns->geom.totsz / ns->geom.pgsz; + ns->geom.totszoob = ns->geom.totsz + ns->geom.pgnum * ns->geom.oobsz; ns->geom.secshift = ffs(ns->geom.secsz) - 1; ns->geom.pgshift = chip->page_shift; ns->geom.oobshift = ffs(ns->geom.oobsz) - 1; @@ -516,7 +511,7 @@ static int init_nandsim(struct mtd_info *mtd) } if (ns->options & OPT_SMALLPAGE) { - if (ns->geom.totsz <= (32 << 20)) { + if (ns->geom.totsz < (32 << 20)) { ns->geom.pgaddrbytes = 3; ns->geom.secaddrbytes = 2; } else { @@ -542,16 +537,15 @@ static int init_nandsim(struct mtd_info *mtd) remains = ns->geom.totsz; next_offset = 0; for (i = 0; i < parts_num; ++i) { - u_int64_t part_sz = (u_int64_t)parts[i] * ns->geom.secsz; - - if (!part_sz || part_sz > remains) { + unsigned long part = parts[i]; + if (!part || part > remains / ns->geom.secsz) { NS_ERR("bad partition size.\n"); ret = -EINVAL; goto error; } ns->partitions[i].name = get_partition_name(i); ns->partitions[i].offset = next_offset; - ns->partitions[i].size = part_sz; + ns->partitions[i].size = part * ns->geom.secsz; next_offset += ns->partitions[i].size; remains -= ns->partitions[i].size; } @@ -579,7 +573,7 @@ static int init_nandsim(struct mtd_info *mtd) if (ns->busw == 16) NS_WARN("16-bit flashes support wasn't tested\n"); - printk("flash size: %llu MiB\n", ns->geom.totsz >> 20); + printk("flash size: %u MiB\n", ns->geom.totsz >> 20); printk("page size: %u bytes\n", ns->geom.pgsz); printk("OOB area size: %u bytes\n", ns->geom.oobsz); printk("sector size: %u KiB\n", ns->geom.secsz >> 10); @@ -589,7 +583,7 @@ static int init_nandsim(struct mtd_info *mtd) printk("bits in sector size: %u\n", ns->geom.secshift); printk("bits in page size: %u\n", ns->geom.pgshift); printk("bits in OOB size: %u\n", ns->geom.oobshift); - printk("flash size with OOB: %llu KiB\n", ns->geom.totszoob >> 10); + printk("flash size with OOB: %u KiB\n", ns->geom.totszoob >> 10); printk("page address bytes: %u\n", ns->geom.pgaddrbytes); printk("sector address bytes: %u\n", ns->geom.secaddrbytes); printk("options: %#x\n", ns->options); @@ -831,7 +825,7 @@ static int setup_wear_reporting(struct mtd_info *mtd) if (!rptwear) return 0; - wear_eb_count = divide(mtd->size, mtd->erasesize); + wear_eb_count = mtd->size / mtd->erasesize; mem = wear_eb_count * sizeof(unsigned long); if (mem / sizeof(unsigned long) != wear_eb_count) { NS_ERR("Too many erase blocks for wear reporting\n"); @@ -2019,7 +2013,7 @@ static int __init ns_init_module(void) } if (overridesize) { - u_int64_t new_size = (u_int64_t)nsmtd->erasesize << overridesize; + u_int32_t new_size = nsmtd->erasesize << overridesize; if (new_size >> overridesize != nsmtd->erasesize) { NS_ERR("overridesize is too big\n"); goto err_exit; @@ -2027,8 +2021,7 @@ static int __init ns_init_module(void) /* N.B. This relies on nand_scan not doing anything with the size before we change it */ nsmtd->size = new_size; chip->chipsize = new_size; - chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1; - chip->pagemask = (chip->chipsize >> chip->page_shift) - 1; + chip->chip_shift = ffs(new_size) - 1; } if ((retval = setup_wear_reporting(nsmtd)) != 0) diff --git a/trunk/drivers/mtd/nand/ppchameleonevb.c b/trunk/drivers/mtd/nand/ppchameleonevb.c index cc8658431851..082073acf20f 100644 --- a/trunk/drivers/mtd/nand/ppchameleonevb.c +++ b/trunk/drivers/mtd/nand/ppchameleonevb.c @@ -6,6 +6,8 @@ * Derived from drivers/mtd/nand/edb7312.c * * + * $Id: ppchameleonevb.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nand/rtc_from4.c b/trunk/drivers/mtd/nand/rtc_from4.c index a033c4cd8e16..26f88215bc47 100644 --- a/trunk/drivers/mtd/nand/rtc_from4.c +++ b/trunk/drivers/mtd/nand/rtc_from4.c @@ -6,6 +6,8 @@ * Derived from drivers/mtd/nand/spia.c * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * + * $Id: rtc_from4.c,v 1.10 2005/11/07 11:14:31 gleixner Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nand/s3c2410.c b/trunk/drivers/mtd/nand/s3c2410.c index 556139ed1fdf..b34a460ab679 100644 --- a/trunk/drivers/mtd/nand/s3c2410.c +++ b/trunk/drivers/mtd/nand/s3c2410.c @@ -1,10 +1,26 @@ /* linux/drivers/mtd/nand/s3c2410.c * - * Copyright © 2004-2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ + * Copyright (c) 2004,2005 Simtec Electronics + * http://www.simtec.co.uk/products/SWLINUX/ * Ben Dooks * - * Samsung S3C2410/S3C2440/S3C2412 NAND driver + * Samsung S3C2410/S3C240 NAND driver + * + * Changelog: + * 21-Sep-2004 BJD Initial version + * 23-Sep-2004 BJD Multiple device support + * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode + * 12-Oct-2004 BJD Fixed errors in use of platform data + * 18-Feb-2005 BJD Fix sparse errors + * 14-Mar-2005 BJD Applied tglx's code reduction patch + * 02-May-2005 BJD Fixed s3c2440 support + * 02-May-2005 BJD Reduced hwcontrol decode + * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug + * 08-Jul-2005 BJD Fix OOPS when no platform data supplied + * 20-Oct-2005 BJD Fix timing calculation bug + * 14-Jan-2006 BJD Allow clock to be stopped when idle + * + * $Id: s3c2410.c,v 1.23 2006/04/01 18:06:29 bjd Exp $ * * 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 @@ -36,7 +52,6 @@ #include #include #include -#include #include #include @@ -105,13 +120,8 @@ struct s3c2410_nand_info { int sel_bit; int mtd_count; unsigned long save_sel; - unsigned long clk_rate; enum s3c_cpu_type cpu_type; - -#ifdef CONFIG_CPU_FREQ - struct notifier_block freq_transition; -#endif }; /* conversion functions */ @@ -169,18 +179,17 @@ static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max) /* controller setup */ -static int s3c2410_nand_setrate(struct s3c2410_nand_info *info) +static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, + struct platform_device *pdev) { - struct s3c2410_platform_nand *plat = info->platform; + struct s3c2410_platform_nand *plat = to_nand_plat(pdev); + unsigned long clkrate = clk_get_rate(info->clk); int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; int tacls, twrph0, twrph1; - unsigned long clkrate = clk_get_rate(info->clk); - unsigned long set, cfg, mask; - unsigned long flags; + unsigned long cfg = 0; /* calculate the timing information for the controller */ - info->clk_rate = clkrate; clkrate /= 1000; /* turn clock into kHz for ease of use */ if (plat != NULL) { @@ -202,69 +211,28 @@ static int s3c2410_nand_setrate(struct s3c2410_nand_info *info) dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate)); - switch (info->cpu_type) { - case TYPE_S3C2410: - mask = (S3C2410_NFCONF_TACLS(3) | - S3C2410_NFCONF_TWRPH0(7) | - S3C2410_NFCONF_TWRPH1(7)); - set = S3C2410_NFCONF_EN; - set |= S3C2410_NFCONF_TACLS(tacls - 1); - set |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); - set |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); - break; - - case TYPE_S3C2440: - case TYPE_S3C2412: - mask = (S3C2410_NFCONF_TACLS(tacls_max - 1) | - S3C2410_NFCONF_TWRPH0(7) | - S3C2410_NFCONF_TWRPH1(7)); - - set = S3C2440_NFCONF_TACLS(tacls - 1); - set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); - set |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); - break; - - default: - /* keep compiler happy */ - mask = 0; - set = 0; - BUG(); - } - - dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); - - local_irq_save(flags); - - cfg = readl(info->regs + S3C2410_NFCONF); - cfg &= ~mask; - cfg |= set; - writel(cfg, info->regs + S3C2410_NFCONF); - - local_irq_restore(flags); - - return 0; -} - -static int s3c2410_nand_inithw(struct s3c2410_nand_info *info) -{ - int ret; - - ret = s3c2410_nand_setrate(info); - if (ret < 0) - return ret; - switch (info->cpu_type) { case TYPE_S3C2410: - default: + cfg = S3C2410_NFCONF_EN; + cfg |= S3C2410_NFCONF_TACLS(tacls - 1); + cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); + cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); break; case TYPE_S3C2440: case TYPE_S3C2412: + cfg = S3C2440_NFCONF_TACLS(tacls - 1); + cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); + cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); + /* enable the controller and de-assert nFCE */ writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT); } + dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); + + writel(cfg, info->regs + S3C2410_NFCONF); return 0; } @@ -545,52 +513,6 @@ static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int writesl(info->regs + S3C2440_NFDATA, buf, len / 4); } -/* cpufreq driver support */ - -#ifdef CONFIG_CPU_FREQ - -static int s3c2410_nand_cpufreq_transition(struct notifier_block *nb, - unsigned long val, void *data) -{ - struct s3c2410_nand_info *info; - unsigned long newclk; - - info = container_of(nb, struct s3c2410_nand_info, freq_transition); - newclk = clk_get_rate(info->clk); - - if ((val == CPUFREQ_POSTCHANGE && newclk < info->clk_rate) || - (val == CPUFREQ_PRECHANGE && newclk > info->clk_rate)) { - s3c2410_nand_setrate(info); - } - - return 0; -} - -static inline int s3c2410_nand_cpufreq_register(struct s3c2410_nand_info *info) -{ - info->freq_transition.notifier_call = s3c2410_nand_cpufreq_transition; - - return cpufreq_register_notifier(&info->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -} - -static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info) -{ - cpufreq_unregister_notifier(&info->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -} - -#else -static inline int s3c2410_nand_cpufreq_register(struct s3c2410_nand_info *info) -{ - return 0; -} - -static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info) -{ -} -#endif - /* device management functions */ static int s3c2410_nand_remove(struct platform_device *pdev) @@ -602,10 +524,9 @@ static int s3c2410_nand_remove(struct platform_device *pdev) if (info == NULL) return 0; - s3c2410_nand_cpufreq_deregister(info); - - /* Release all our mtds and their partitions, then go through - * freeing the resources used + /* first thing we need to do is release all our mtds + * and their partitions, then go through freeing the + * resources used */ if (info->mtds != NULL) { @@ -770,8 +691,7 @@ static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, { struct nand_chip *chip = &nmtd->chip; - dev_dbg(info->device, "chip %p => page shift %d\n", - chip, chip->page_shift); + printk("%s: chip %p: %d\n", __func__, chip, chip->page_shift); if (hardware_ecc) { /* change the behaviour depending on wether we are using @@ -864,7 +784,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, /* initialise the hardware */ - err = s3c2410_nand_inithw(info); + err = s3c2410_nand_inithw(info, pdev); if (err != 0) goto exit_error; @@ -907,12 +827,6 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, sets++; } - err = s3c2410_nand_cpufreq_register(info); - if (err < 0) { - dev_err(&pdev->dev, "failed to init cpufreq support\n"); - goto exit_error; - } - if (allow_clk_stop(info)) { dev_info(&pdev->dev, "clock idle support enabled\n"); clk_disable(info->clk); @@ -960,7 +874,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) if (info) { clk_enable(info->clk); - s3c2410_nand_inithw(info); + s3c2410_nand_inithw(info, dev); /* Restore the state of the nFCE line. */ diff --git a/trunk/drivers/mtd/nand/sharpsl.c b/trunk/drivers/mtd/nand/sharpsl.c index 6dba2fb66ae5..033f8800b1e6 100644 --- a/trunk/drivers/mtd/nand/sharpsl.c +++ b/trunk/drivers/mtd/nand/sharpsl.c @@ -3,6 +3,8 @@ * * Copyright (C) 2004 Richard Purdie * + * $Id: sharpsl.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $ + * * Based on Sharp's NAND driver sharp_sl.c * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/drivers/mtd/nand/spia.c b/trunk/drivers/mtd/nand/spia.c index 0cc6d0acb8fe..1f6d429b1583 100644 --- a/trunk/drivers/mtd/nand/spia.c +++ b/trunk/drivers/mtd/nand/spia.c @@ -8,6 +8,8 @@ * to controllines (due to change in nand.c) * page_cache added * + * $Id: spia.c,v 1.25 2005/11/07 11:14:31 gleixner Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nand/toto.c b/trunk/drivers/mtd/nand/toto.c index bbf492e6830d..f9e2d4a0ab8c 100644 --- a/trunk/drivers/mtd/nand/toto.c +++ b/trunk/drivers/mtd/nand/toto.c @@ -14,6 +14,8 @@ * Overview: * This is a device driver for the NAND flash device found on the * TI fido board. It supports 32MiB and 64MiB cards + * + * $Id: toto.c,v 1.5 2005/11/07 11:14:31 gleixner Exp $ */ #include diff --git a/trunk/drivers/mtd/nand/ts7250.c b/trunk/drivers/mtd/nand/ts7250.c index 807a72752eeb..f40081069ab2 100644 --- a/trunk/drivers/mtd/nand/ts7250.c +++ b/trunk/drivers/mtd/nand/ts7250.c @@ -9,6 +9,8 @@ * Derived from drivers/mtd/nand/autcpu12.c * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) * + * $Id: ts7250.c,v 1.4 2004/12/30 22:02:07 joff Exp $ + * * 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. diff --git a/trunk/drivers/mtd/nftlcore.c b/trunk/drivers/mtd/nftlcore.c index 320b929abe79..0c9ce19ea27a 100644 --- a/trunk/drivers/mtd/nftlcore.c +++ b/trunk/drivers/mtd/nftlcore.c @@ -1,6 +1,7 @@ /* Linux driver for NAND Flash Translation Layer */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse */ +/* $Id: nftlcore.c,v 1.98 2005/11/07 11:14:21 gleixner Exp $ */ /* The contents of this file are distributed under the GNU General @@ -802,8 +803,12 @@ static struct mtd_blktrans_ops nftl_tr = { .owner = THIS_MODULE, }; +extern char nftlmountrev[]; + static int __init init_nftl(void) { + printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.98 $, nftlmount.c %s\n", nftlmountrev); + return register_mtd_blktrans(&nftl_tr); } diff --git a/trunk/drivers/mtd/nftlmount.c b/trunk/drivers/mtd/nftlmount.c index ccc4f209fbb5..345e6eff89ce 100644 --- a/trunk/drivers/mtd/nftlmount.c +++ b/trunk/drivers/mtd/nftlmount.c @@ -4,6 +4,8 @@ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Copyright (C) 2000 Netgem S.A. * + * $Id: nftlmount.c,v 1.41 2005/11/07 11:14:21 gleixner Exp $ + * * 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 @@ -29,6 +31,8 @@ #define SECTORSIZE 512 +char nftlmountrev[]="$Revision: 1.41 $"; + /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the * various device information of the NFTL partition and Bad Unit Table. Update * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[] diff --git a/trunk/drivers/mtd/onenand/onenand_base.c b/trunk/drivers/mtd/onenand/onenand_base.c index 926cf3a4135d..5d7965f7e9ce 100644 --- a/trunk/drivers/mtd/onenand/onenand_base.c +++ b/trunk/drivers/mtd/onenand/onenand_base.c @@ -325,11 +325,28 @@ static int onenand_wait(struct mtd_info *mtd, int state) ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); - /* - * In the Spec. it checks the controller status first - * However if you get the correct information in case of - * power off recovery (POR) test, it should read ECC status first - */ + if (ctrl & ONENAND_CTRL_ERROR) { + printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl); + if (ctrl & ONENAND_CTRL_LOCK) + printk(KERN_ERR "onenand_wait: it's locked error.\n"); + if (state == FL_READING) { + /* + * A power loss while writing can result in a page + * becoming unreadable. When the device is mounted + * again, reading that page gives controller errors. + * Upper level software like JFFS2 treat -EIO as fatal, + * refusing to mount at all. That means it is necessary + * to treat the error as an ECC error to allow recovery. + * Note that typically in this case, the eraseblock can + * still be erased and rewritten i.e. it has not become + * a bad block. + */ + mtd->ecc_stats.failed++; + return -EBADMSG; + } + return -EIO; + } + if (interrupt & ONENAND_INT_READ) { int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); if (ecc) { @@ -347,15 +364,6 @@ static int onenand_wait(struct mtd_info *mtd, int state) return -EIO; } - /* If there's controller error, it's a real error */ - if (ctrl & ONENAND_CTRL_ERROR) { - printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", - ctrl); - if (ctrl & ONENAND_CTRL_LOCK) - printk(KERN_ERR "onenand_wait: it's locked error.\n"); - return -EIO; - } - return 0; } @@ -1127,26 +1135,22 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state) interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); + /* Initial bad block case: 0x2400 or 0x0400 */ + if (ctrl & ONENAND_CTRL_ERROR) { + printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl); + return ONENAND_BBT_READ_ERROR; + } + if (interrupt & ONENAND_INT_READ) { int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); - if (ecc & ONENAND_ECC_2BIT_ALL) { - printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x" - ", controller error 0x%04x\n", ecc, ctrl); + if (ecc & ONENAND_ECC_2BIT_ALL) return ONENAND_BBT_READ_ERROR; - } } else { printk(KERN_ERR "onenand_bbt_wait: read timeout!" "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); return ONENAND_BBT_READ_FATAL_ERROR; } - /* Initial bad block case: 0x2400 or 0x0400 */ - if (ctrl & ONENAND_CTRL_ERROR) { - printk(KERN_DEBUG "onenand_bbt_wait: " - "controller error = 0x%04x\n", ctrl); - return ONENAND_BBT_READ_ERROR; - } - return 0; } diff --git a/trunk/drivers/mtd/redboot.c b/trunk/drivers/mtd/redboot.c index 2d600a1bf2aa..c5030f94f04e 100644 --- a/trunk/drivers/mtd/redboot.c +++ b/trunk/drivers/mtd/redboot.c @@ -1,4 +1,6 @@ /* + * $Id: redboot.c,v 1.21 2006/03/30 18:34:37 bjd Exp $ + * * Parse RedBoot-style Flash Image System (FIS) tables and * produce a Linux partition array to match. */ diff --git a/trunk/drivers/mtd/rfd_ftl.c b/trunk/drivers/mtd/rfd_ftl.c index e538c0a72abb..c84e45465499 100644 --- a/trunk/drivers/mtd/rfd_ftl.c +++ b/trunk/drivers/mtd/rfd_ftl.c @@ -3,6 +3,8 @@ * * Copyright (C) 2005 Sean Young * + * $Id: rfd_ftl.c,v 1.8 2006/01/15 12:51:44 sean Exp $ + * * This type of flash translation layer (FTL) is used by the Embedded BIOS * by General Software. It is known as the Resident Flash Disk (RFD), see: * diff --git a/trunk/drivers/net/arm/ep93xx_eth.c b/trunk/drivers/net/arm/ep93xx_eth.c index 18d3eeb7eab2..7a14980f3472 100644 --- a/trunk/drivers/net/arm/ep93xx_eth.c +++ b/trunk/drivers/net/arm/ep93xx_eth.c @@ -482,7 +482,7 @@ static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) goto err; d = dma_map_single(NULL, page, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(NULL, d)) { + if (dma_mapping_error(d)) { free_page((unsigned long)page); goto err; } @@ -505,7 +505,7 @@ static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) goto err; d = dma_map_single(NULL, page, PAGE_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(NULL, d)) { + if (dma_mapping_error(d)) { free_page((unsigned long)page); goto err; } diff --git a/trunk/drivers/net/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c index af251a5df844..0263bef9cc6d 100644 --- a/trunk/drivers/net/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -814,7 +814,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, } /* release skb */ - WARN_ON(!skb); + BUG_TRAP(skb); dev_kfree_skb(skb); tx_buf->first_bd = 0; tx_buf->skb = NULL; @@ -837,9 +837,9 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; #ifdef BNX2X_STOP_ON_ERROR - WARN_ON(used < 0); - WARN_ON(used > fp->bp->tx_ring_size); - WARN_ON((fp->bp->tx_ring_size - used) > MAX_TX_AVAIL); + BUG_TRAP(used >= 0); + BUG_TRAP(used <= fp->bp->tx_ring_size); + BUG_TRAP((fp->bp->tx_ring_size - used) <= MAX_TX_AVAIL); #endif return (s16)(fp->bp->tx_ring_size) - used; @@ -1020,7 +1020,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, mapping = pci_map_page(bp->pdev, page, 0, BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { + if (unlikely(dma_mapping_error(mapping))) { __free_pages(page, PAGES_PER_SGE_SHIFT); return -ENOMEM; } @@ -1048,7 +1048,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { + if (unlikely(dma_mapping_error(mapping))) { dev_kfree_skb(skb); return -ENOMEM; } @@ -4374,7 +4374,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp) } ring_prod = NEXT_RX_IDX(ring_prod); cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); - WARN_ON(ring_prod <= i); + BUG_TRAP(ring_prod > i); } fp->rx_bd_prod = ring_prod; diff --git a/trunk/drivers/net/cassini.c b/trunk/drivers/net/cassini.c index f1936d51b458..83768df27806 100644 --- a/trunk/drivers/net/cassini.c +++ b/trunk/drivers/net/cassini.c @@ -576,18 +576,6 @@ static void cas_spare_recover(struct cas *cp, const gfp_t flags) list_for_each_safe(elem, tmp, &list) { cas_page_t *page = list_entry(elem, cas_page_t, list); - /* - * With the lockless pagecache, cassini buffering scheme gets - * slightly less accurate: we might find that a page has an - * elevated reference count here, due to a speculative ref, - * and skip it as in-use. Ideally we would be able to reclaim - * it. However this would be such a rare case, it doesn't - * matter too much as we should pick it up the next time round. - * - * Importantly, if we find that the page has a refcount of 1 - * here (our refcount), then we know it is definitely not inuse - * so we can reuse it. - */ if (page_count(page->buffer) > 1) continue; diff --git a/trunk/drivers/net/cxgb3/sge.c b/trunk/drivers/net/cxgb3/sge.c index 1b0861d73ab7..a96331c875e6 100644 --- a/trunk/drivers/net/cxgb3/sge.c +++ b/trunk/drivers/net/cxgb3/sge.c @@ -386,7 +386,7 @@ static inline int add_one_rx_buf(void *va, unsigned int len, dma_addr_t mapping; mapping = pci_map_single(pdev, va, len, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(pdev, mapping))) + if (unlikely(pci_dma_mapping_error(mapping))) return -ENOMEM; pci_unmap_addr_set(sd, dma_addr, mapping); diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 19d32a227be1..1037b1332312 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -1790,7 +1790,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(nic->pdev, rx->dma_addr)) { + if (pci_dma_mapping_error(rx->dma_addr)) { dev_kfree_skb_any(rx->skb); rx->skb = NULL; rx->dma_addr = 0; diff --git a/trunk/drivers/net/e1000e/ethtool.c b/trunk/drivers/net/e1000e/ethtool.c index 9350564065e7..a14561f40db0 100644 --- a/trunk/drivers/net/e1000e/ethtool.c +++ b/trunk/drivers/net/e1000e/ethtool.c @@ -1090,7 +1090,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) tx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(pdev, tx_ring->buffer_info[i].dma)) { + if (pci_dma_mapping_error(tx_ring->buffer_info[i].dma)) { ret_val = 4; goto err_nomem; } @@ -1153,7 +1153,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, 2048, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(pdev, rx_ring->buffer_info[i].dma)) { + if (pci_dma_mapping_error(rx_ring->buffer_info[i].dma)) { ret_val = 8; goto err_nomem; } diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index d13677899767..9c0f56b3c518 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -195,7 +195,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(pdev, buffer_info->dma)) { + if (pci_dma_mapping_error(buffer_info->dma)) { dev_err(&pdev->dev, "RX DMA map failed\n"); adapter->rx_dma_failed++; break; @@ -265,7 +265,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, ps_page->page, 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(pdev, ps_page->dma)) { + if (pci_dma_mapping_error(ps_page->dma)) { dev_err(&adapter->pdev->dev, "RX DMA page map failed\n"); adapter->rx_dma_failed++; @@ -300,7 +300,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_ps_bsize0, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(pdev, buffer_info->dma)) { + if (pci_dma_mapping_error(buffer_info->dma)) { dev_err(&pdev->dev, "RX DMA map failed\n"); adapter->rx_dma_failed++; /* cleanup skb */ @@ -3344,7 +3344,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, skb->data + offset, size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) { + if (pci_dma_mapping_error(buffer_info->dma)) { dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); adapter->tx_dma_failed++; return -1; @@ -3382,8 +3382,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, offset, size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(adapter->pdev, - buffer_info->dma)) { + if (pci_dma_mapping_error(buffer_info->dma)) { dev_err(&adapter->pdev->dev, "TX DMA page map failed\n"); adapter->tx_dma_failed++; diff --git a/trunk/drivers/net/ibmveth.c b/trunk/drivers/net/ibmveth.c index 91ec9fdc7184..e5a6e2e84540 100644 --- a/trunk/drivers/net/ibmveth.c +++ b/trunk/drivers/net/ibmveth.c @@ -260,7 +260,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, pool->buff_size, DMA_FROM_DEVICE); - if (dma_mapping_error((&adapter->vdev->dev, dma_addr)) + if (dma_mapping_error(dma_addr)) goto failure; pool->free_map[free_index] = IBM_VETH_INVALID_MAP; @@ -294,7 +294,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc pool->consumer_index = pool->size - 1; else pool->consumer_index--; - if (!dma_mapping_error((&adapter->vdev->dev, dma_addr)) + if (!dma_mapping_error(dma_addr)) dma_unmap_single(&adapter->vdev->dev, pool->dma_addr[index], pool->buff_size, DMA_FROM_DEVICE); @@ -448,11 +448,11 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) static void ibmveth_cleanup(struct ibmveth_adapter *adapter) { int i; - struct device *dev = &adapter->vdev->dev; if(adapter->buffer_list_addr != NULL) { - if (!dma_mapping_error(dev, adapter->buffer_list_dma)) { - dma_unmap_single(dev, adapter->buffer_list_dma, 4096, + if(!dma_mapping_error(adapter->buffer_list_dma)) { + dma_unmap_single(&adapter->vdev->dev, + adapter->buffer_list_dma, 4096, DMA_BIDIRECTIONAL); adapter->buffer_list_dma = DMA_ERROR_CODE; } @@ -461,8 +461,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) } if(adapter->filter_list_addr != NULL) { - if (!dma_mapping_error(dev, adapter->filter_list_dma)) { - dma_unmap_single(dev, adapter->filter_list_dma, 4096, + if(!dma_mapping_error(adapter->filter_list_dma)) { + dma_unmap_single(&adapter->vdev->dev, + adapter->filter_list_dma, 4096, DMA_BIDIRECTIONAL); adapter->filter_list_dma = DMA_ERROR_CODE; } @@ -471,8 +472,8 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) } if(adapter->rx_queue.queue_addr != NULL) { - if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { - dma_unmap_single(dev, + if(!dma_mapping_error(adapter->rx_queue.queue_dma)) { + dma_unmap_single(&adapter->vdev->dev, adapter->rx_queue.queue_dma, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); @@ -534,7 +535,6 @@ static int ibmveth_open(struct net_device *netdev) int rc; union ibmveth_buf_desc rxq_desc; int i; - struct device *dev; ibmveth_debug_printk("open starting\n"); @@ -563,19 +563,17 @@ static int ibmveth_open(struct net_device *netdev) return -ENOMEM; } - dev = &adapter->vdev->dev; - - adapter->buffer_list_dma = dma_map_single(dev, + adapter->buffer_list_dma = dma_map_single(&adapter->vdev->dev, adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); - adapter->filter_list_dma = dma_map_single(dev, + adapter->filter_list_dma = dma_map_single(&adapter->vdev->dev, adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); - adapter->rx_queue.queue_dma = dma_map_single(dev, + adapter->rx_queue.queue_dma = dma_map_single(&adapter->vdev->dev, adapter->rx_queue.queue_addr, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); - if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || - (dma_mapping_error(dev, adapter->filter_list_dma)) || - (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { + if((dma_mapping_error(adapter->buffer_list_dma) ) || + (dma_mapping_error(adapter->filter_list_dma)) || + (dma_mapping_error(adapter->rx_queue.queue_dma))) { ibmveth_error_printk("unable to map filter or buffer list pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -647,7 +645,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->bounce_buffer_dma = dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); - if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { + if (dma_mapping_error(adapter->bounce_buffer_dma)) { ibmveth_error_printk("unable to map bounce buffer\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -924,7 +922,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) buf[1] = 0; } - if (dma_mapping_error((&adapter->vdev->dev, data_dma_addr)) { + if (dma_mapping_error(data_dma_addr)) { if (!firmware_has_feature(FW_FEATURE_CMO)) ibmveth_error_printk("tx: unable to map xmit buffer\n"); skb_copy_from_linear_data(skb, adapter->bounce_buffer, diff --git a/trunk/drivers/net/iseries_veth.c b/trunk/drivers/net/iseries_veth.c index c46864d626b2..b8d0639c1cdf 100644 --- a/trunk/drivers/net/iseries_veth.c +++ b/trunk/drivers/net/iseries_veth.c @@ -1128,7 +1128,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, msg->data.addr[0] = dma_map_single(port->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(port->dev, msg->data.addr[0])) + if (dma_mapping_error(msg->data.addr[0])) goto recycle_and_drop; msg->dev = port->dev; @@ -1226,7 +1226,7 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx, dma_address = msg->data.addr[0]; dma_length = msg->data.len[0]; - if (!dma_mapping_error(msg->dev, dma_address)) + if (!dma_mapping_error(dma_address)) dma_unmap_single(msg->dev, dma_address, dma_length, DMA_TO_DEVICE); diff --git a/trunk/drivers/net/mlx4/alloc.c b/trunk/drivers/net/mlx4/alloc.c index 096bca54bcf7..f9d6b4dca180 100644 --- a/trunk/drivers/net/mlx4/alloc.c +++ b/trunk/drivers/net/mlx4/alloc.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/mlx4/catas.c b/trunk/drivers/net/mlx4/catas.c index f094ee00c416..aa9528779044 100644 --- a/trunk/drivers/net/mlx4/catas.c +++ b/trunk/drivers/net/mlx4/catas.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/mlx4/cmd.c b/trunk/drivers/net/mlx4/cmd.c index 2845a0560b84..04d5bc69a6f8 100644 --- a/trunk/drivers/net/mlx4/cmd.c +++ b/trunk/drivers/net/mlx4/cmd.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/cq.c b/trunk/drivers/net/mlx4/cq.c index 9bb50e3f8974..95e87a2f8896 100644 --- a/trunk/drivers/net/mlx4/cq.c +++ b/trunk/drivers/net/mlx4/cq.c @@ -2,7 +2,7 @@ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2004 Voltaire, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/eq.c b/trunk/drivers/net/mlx4/eq.c index 8a8b56135a58..ea3a09aaa844 100644 --- a/trunk/drivers/net/mlx4/eq.c +++ b/trunk/drivers/net/mlx4/eq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two @@ -526,7 +526,7 @@ int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt) return -ENOMEM; priv->eq_table.icm_dma = pci_map_page(dev->pdev, priv->eq_table.icm_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, priv->eq_table.icm_dma)) { + if (pci_dma_mapping_error(priv->eq_table.icm_dma)) { __free_page(priv->eq_table.icm_page); return -ENOMEM; } diff --git a/trunk/drivers/net/mlx4/fw.c b/trunk/drivers/net/mlx4/fw.c index 7e32955da982..57278224ba1e 100644 --- a/trunk/drivers/net/mlx4/fw.c +++ b/trunk/drivers/net/mlx4/fw.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/fw.h b/trunk/drivers/net/mlx4/fw.h index decbb5c2ad41..fbf0e22be122 100644 --- a/trunk/drivers/net/mlx4/fw.h +++ b/trunk/drivers/net/mlx4/fw.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2006, 2007 Cisco Systems. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/icm.c b/trunk/drivers/net/mlx4/icm.c index baf4bf66062c..2a5bef6388fe 100644 --- a/trunk/drivers/net/mlx4/icm.c +++ b/trunk/drivers/net/mlx4/icm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/icm.h b/trunk/drivers/net/mlx4/icm.h index ab56a2f89b65..6c44edf35847 100644 --- a/trunk/drivers/net/mlx4/icm.h +++ b/trunk/drivers/net/mlx4/icm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/intf.c b/trunk/drivers/net/mlx4/intf.c index 0e7eb1038f9f..4a6c4d526f1b 100644 --- a/trunk/drivers/net/mlx4/intf.c +++ b/trunk/drivers/net/mlx4/intf.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/mlx4/main.c b/trunk/drivers/net/mlx4/main.c index 1252a919de2e..8e1d24cda1b0 100644 --- a/trunk/drivers/net/mlx4/main.c +++ b/trunk/drivers/net/mlx4/main.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/mcg.c b/trunk/drivers/net/mlx4/mcg.c index c83f88ce0736..b4b57870ddfd 100644 --- a/trunk/drivers/net/mlx4/mcg.c +++ b/trunk/drivers/net/mlx4/mcg.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/mlx4/mlx4.h b/trunk/drivers/net/mlx4/mlx4.h index 5337e3ac3e78..78038499cff5 100644 --- a/trunk/drivers/net/mlx4/mlx4.h +++ b/trunk/drivers/net/mlx4/mlx4.h @@ -2,7 +2,7 @@ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2005, 2006, 2007 Cisco Systems. All rights reserved. - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2004 Voltaire, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/mr.c b/trunk/drivers/net/mlx4/mr.c index 62071d9c4a55..a3c04c5f12c2 100644 --- a/trunk/drivers/net/mlx4/mr.c +++ b/trunk/drivers/net/mlx4/mr.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2004 Topspin Communications. All rights reserved. - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/qp.c b/trunk/drivers/net/mlx4/qp.c index c49a86044bf7..ee5484c44a18 100644 --- a/trunk/drivers/net/mlx4/qp.c +++ b/trunk/drivers/net/mlx4/qp.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2004 Topspin Communications. All rights reserved. * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. * Copyright (c) 2004 Voltaire, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/net/mlx4/reset.c b/trunk/drivers/net/mlx4/reset.c index 3951b884c0fb..e199715fabd0 100644 --- a/trunk/drivers/net/mlx4/reset.c +++ b/trunk/drivers/net/mlx4/reset.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/mlx4/srq.c b/trunk/drivers/net/mlx4/srq.c index 533eb6db24b3..d23f46d692ef 100644 --- a/trunk/drivers/net/mlx4/srq.c +++ b/trunk/drivers/net/mlx4/srq.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/pasemi_mac.c b/trunk/drivers/net/pasemi_mac.c index edc0fd588985..993d87c9296f 100644 --- a/trunk/drivers/net/pasemi_mac.c +++ b/trunk/drivers/net/pasemi_mac.c @@ -650,7 +650,7 @@ static void pasemi_mac_replenish_rx_ring(const struct net_device *dev, mac->bufsz - LOCAL_SKB_ALIGN, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(mac->dma_pdev, dma))) { + if (unlikely(dma_mapping_error(dma))) { dev_kfree_skb_irq(info->skb); break; } @@ -1519,7 +1519,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) map[0] = pci_map_single(mac->dma_pdev, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE); map_size[0] = skb_headlen(skb); - if (pci_dma_mapping_error(mac->dma_pdev, map[0])) + if (dma_mapping_error(map[0])) goto out_err_nolock; for (i = 0; i < nfrags; i++) { @@ -1529,7 +1529,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) frag->page_offset, frag->size, PCI_DMA_TODEVICE); map_size[i+1] = frag->size; - if (pci_dma_mapping_error(mac->dma_pdev, map[i+1])) { + if (dma_mapping_error(map[i+1])) { nfrags = i; goto out_err_nolock; } diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index ddccc074a76a..739b3ab7bccc 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -581,12 +581,12 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (file == ppp->owner) ppp_shutdown_interface(ppp); } - if (atomic_long_read(&file->f_count) <= 2) { + if (atomic_read(&file->f_count) <= 2) { ppp_release(NULL, file); err = 0; } else - printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%ld\n", - atomic_long_read(&file->f_count)); + printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%d\n", + atomic_read(&file->f_count)); unlock_kernel(); return err; } diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c index e82b37bbd6c3..e7d48a352beb 100644 --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -328,7 +328,7 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, qdev->lrg_buffer_len - QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = pci_dma_mapping_error(map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -1919,7 +1919,7 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = pci_dma_mapping_error(map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -2454,7 +2454,7 @@ static int ql_send_map(struct ql3_adapter *qdev, */ map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = pci_dma_mapping_error(map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -2487,7 +2487,7 @@ static int ql_send_map(struct ql3_adapter *qdev, sizeof(struct oal), PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = pci_dma_mapping_error(map); if(err) { printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n", @@ -2514,7 +2514,7 @@ static int ql_send_map(struct ql3_adapter *qdev, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = pci_dma_mapping_error(map); if(err) { printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n", qdev->ndev->name, err); @@ -2916,7 +2916,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = pci_dma_mapping_error(map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 86d77d05190a..9dae40ccf048 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -2512,8 +2512,8 @@ static void stop_nic(struct s2io_nic *nic) * Return Value: * SUCCESS on success or an appropriate -ve value on failure. */ -static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, - int from_card_up) + +static int fill_rx_buffers(struct ring_info *ring, int from_card_up) { struct sk_buff *skb; struct RxD_t *rxdp; @@ -2602,8 +2602,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, rxdp1->Buffer0_ptr = pci_map_single (ring->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(nic->pdev, - rxdp1->Buffer0_ptr)) + if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) goto pci_map_failed; rxdp->Control_2 = @@ -2637,8 +2636,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, rxdp3->Buffer0_ptr = pci_map_single(ring->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(nic->pdev, - rxdp3->Buffer0_ptr)) + if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) goto pci_map_failed; } else pci_dma_sync_single_for_device(ring->pdev, @@ -2657,8 +2655,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, (ring->pdev, skb->data, ring->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(nic->pdev, - rxdp3->Buffer2_ptr)) + if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) goto pci_map_failed; if (from_card_up) { @@ -2667,8 +2664,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(nic->pdev, - rxdp3->Buffer1_ptr)) { + if (pci_dma_mapping_error + (rxdp3->Buffer1_ptr)) { pci_unmap_single (ring->pdev, (dma_addr_t)(unsigned long) @@ -2809,9 +2806,9 @@ static void free_rx_buffers(struct s2io_nic *sp) } } -static int s2io_chk_rx_buffers(struct s2io_nic *nic, struct ring_info *ring) +static int s2io_chk_rx_buffers(struct ring_info *ring) { - if (fill_rx_buffers(nic, ring, 0) == -ENOMEM) { + if (fill_rx_buffers(ring, 0) == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); } @@ -2851,7 +2848,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) return 0; pkts_processed = rx_intr_handler(ring, budget); - s2io_chk_rx_buffers(nic, ring); + s2io_chk_rx_buffers(ring); if (pkts_processed < budget_org) { netif_rx_complete(dev, napi); @@ -2885,7 +2882,7 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget) for (i = 0; i < config->rx_ring_num; i++) { ring = &mac_control->rings[i]; ring_pkts_processed = rx_intr_handler(ring, budget); - s2io_chk_rx_buffers(nic, ring); + s2io_chk_rx_buffers(ring); pkts_processed += ring_pkts_processed; budget -= ring_pkts_processed; if (budget <= 0) @@ -2942,8 +2939,7 @@ static void s2io_netpoll(struct net_device *dev) rx_intr_handler(&mac_control->rings[i], 0); for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(nic, &mac_control->rings[i], 0) == - -ENOMEM) { + if (fill_rx_buffers(&mac_control->rings[i], 0) == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n"); break; @@ -4239,14 +4235,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = pci_map_single(sp->pdev, fifo->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer)) + if (pci_dma_mapping_error(txdp->Buffer_Pointer)) goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer)) + if (pci_dma_mapping_error(txdp->Buffer_Pointer)) goto pci_map_failed; txdp->Host_Control = (unsigned long) skb; @@ -4349,7 +4345,7 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) netif_rx_schedule(dev, &ring->napi); } else { rx_intr_handler(ring, 0); - s2io_chk_rx_buffers(sp, ring); + s2io_chk_rx_buffers(ring); } return IRQ_HANDLED; @@ -4830,7 +4826,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) */ if (!config->napi) { for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, &mac_control->rings[i]); + s2io_chk_rx_buffers(&mac_control->rings[i]); } writeq(sp->general_int_mask, &bar0->general_int_mask); readl(&bar0->general_int_status); @@ -6863,7 +6859,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(sp->pdev, rxdp1->Buffer0_ptr)) + if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) goto memalloc_failed; rxdp->Host_Control = (unsigned long) (*skb); } @@ -6890,13 +6886,12 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(sp->pdev, rxdp3->Buffer2_ptr)) + if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) goto memalloc_failed; rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(sp->pdev, - rxdp3->Buffer0_ptr)) { + if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); @@ -6908,8 +6903,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(sp->pdev, - rxdp3->Buffer1_ptr)) { + if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); @@ -7193,7 +7187,7 @@ static int s2io_card_up(struct s2io_nic * sp) for (i = 0; i < config->rx_ring_num; i++) { mac_control->rings[i].mtu = dev->mtu; - ret = fill_rx_buffers(sp, &mac_control->rings[i], 1); + ret = fill_rx_buffers(&mac_control->rings[i], 1); if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", dev->name); diff --git a/trunk/drivers/net/sfc/rx.c b/trunk/drivers/net/sfc/rx.c index 0d27dd39bc09..601b001437c0 100644 --- a/trunk/drivers/net/sfc/rx.c +++ b/trunk/drivers/net/sfc/rx.c @@ -233,7 +233,7 @@ static inline int efx_init_rx_buffer_skb(struct efx_rx_queue *rx_queue, rx_buf->data, rx_buf->len, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(efx->pci_dev, rx_buf->dma_addr))) { + if (unlikely(pci_dma_mapping_error(rx_buf->dma_addr))) { dev_kfree_skb_any(rx_buf->skb); rx_buf->skb = NULL; return -EIO; @@ -275,7 +275,7 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, 0, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(efx->pci_dev, dma_addr))) { + if (unlikely(pci_dma_mapping_error(dma_addr))) { __free_pages(rx_buf->page, efx->rx_buffer_order); rx_buf->page = NULL; return -EIO; diff --git a/trunk/drivers/net/sfc/tx.c b/trunk/drivers/net/sfc/tx.c index 5e8374ab28ee..5cdd082ab8f6 100644 --- a/trunk/drivers/net/sfc/tx.c +++ b/trunk/drivers/net/sfc/tx.c @@ -172,7 +172,7 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue, /* Process all fragments */ while (1) { - if (unlikely(pci_dma_mapping_error(pci_dev, dma_addr))) + if (unlikely(pci_dma_mapping_error(dma_addr))) goto pci_err; /* Store fields for marking in the per-fragment final @@ -661,8 +661,7 @@ efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len) tsoh->dma_addr = pci_map_single(tx_queue->efx->pci_dev, TSOH_BUFFER(tsoh), header_len, PCI_DMA_TODEVICE); - if (unlikely(pci_dma_mapping_error(tx_queue->efx->pci_dev, - tsoh->dma_addr))) { + if (unlikely(pci_dma_mapping_error(tsoh->dma_addr))) { kfree(tsoh); return NULL; } @@ -864,7 +863,7 @@ static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off, len, PCI_DMA_TODEVICE); - if (likely(!pci_dma_mapping_error(efx->pci_dev, st->ifc.unmap_addr))) { + if (likely(!pci_dma_mapping_error(st->ifc.unmap_addr))) { st->ifc.unmap_len = len; st->ifc.len = len; st->ifc.dma_addr = st->ifc.unmap_addr; diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index b6435d0d71f9..00aa0b108cb9 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -452,7 +452,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, /* iommu-map the skb */ buf = pci_map_single(card->pdev, descr->skb->data, SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(card->pdev, buf)) { + if (pci_dma_mapping_error(buf)) { dev_kfree_skb_any(descr->skb); descr->skb = NULL; if (netif_msg_rx_err(card) && net_ratelimit()) @@ -691,7 +691,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, unsigned long flags; buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(card->pdev, buf)) { + if (pci_dma_mapping_error(buf)) { if (netif_msg_tx_err(card) && net_ratelimit()) dev_err(&card->netdev->dev, "could not iommu-map packet (%p, %i). " "Dropping packet\n", skb->data, skb->len); diff --git a/trunk/drivers/net/tc35815.c b/trunk/drivers/net/tc35815.c index 8487ace9d2e3..a645e5028c14 100644 --- a/trunk/drivers/net/tc35815.c +++ b/trunk/drivers/net/tc35815.c @@ -506,7 +506,7 @@ static void *alloc_rxbuf_page(struct pci_dev *hwdev, dma_addr_t *dma_handle) return NULL; *dma_handle = pci_map_single(hwdev, buf, PAGE_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(hwdev, *dma_handle)) { + if (pci_dma_mapping_error(*dma_handle)) { free_page((unsigned long)buf); return NULL; } @@ -536,7 +536,7 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev, return NULL; *dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(hwdev, *dma_handle)) { + if (pci_dma_mapping_error(*dma_handle)) { dev_kfree_skb_any(skb); return NULL; } diff --git a/trunk/drivers/net/wireless/ath5k/base.c b/trunk/drivers/net/wireless/ath5k/base.c index d9769c527346..217d506527a9 100644 --- a/trunk/drivers/net/wireless/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath5k/base.c @@ -1166,7 +1166,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) bf->skb = skb; bf->skbaddr = pci_map_single(sc->pdev, skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) { + if (unlikely(pci_dma_mapping_error(bf->skbaddr))) { ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); dev_kfree_skb(skb); bf->skb = NULL; @@ -1918,7 +1918,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " "skbaddr %llx\n", skb, skb->data, skb->len, (unsigned long long)bf->skbaddr); - if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) { + if (pci_dma_mapping_error(bf->skbaddr)) { ATH5K_ERR(sc, "beacon DMA mapping failed\n"); return -EIO; } diff --git a/trunk/drivers/parport/ieee1284.c b/trunk/drivers/parport/ieee1284.c index e97059415ab4..0338b0912674 100644 --- a/trunk/drivers/parport/ieee1284.c +++ b/trunk/drivers/parport/ieee1284.c @@ -199,6 +199,8 @@ int parport_wait_peripheral(struct parport *port, /* 40ms of slow polling. */ deadline = jiffies + msecs_to_jiffies(40); while (time_before (jiffies, deadline)) { + int ret; + if (signal_pending (current)) return -EINTR; diff --git a/trunk/drivers/parport/parport_cs.c b/trunk/drivers/parport/parport_cs.c index 00e1d9620f7c..802a81d47367 100644 --- a/trunk/drivers/parport/parport_cs.c +++ b/trunk/drivers/parport/parport_cs.c @@ -235,7 +235,7 @@ static int parport_config(struct pcmcia_device *link) ======================================================================*/ -static void parport_cs_release(struct pcmcia_device *link) +void parport_cs_release(struct pcmcia_device *link) { parport_info_t *info = link->priv; diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index 8a846adf1dcf..e0c2a4584ec6 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -2867,7 +2867,7 @@ static struct parport_pc_pci { * and 840 locks up if you write 1 to bit 2! */ /* oxsemi_952 */ { 1, { { 0, 1 }, } }, /* oxsemi_954 */ { 1, { { 0, -1 }, } }, - /* oxsemi_840 */ { 1, { { 0, 1 }, } }, + /* oxsemi_840 */ { 1, { { 0, -1 }, } }, /* aks_0100 */ { 1, { { 0, -1 }, } }, /* mobility_pp */ { 1, { { 0, 1 }, } }, /* netmos_9705 */ { 1, { { 0, -1 }, } }, /* untested */ diff --git a/trunk/drivers/parport/procfs.c b/trunk/drivers/parport/procfs.c index 554e11f9e1ce..d950fc34320a 100644 --- a/trunk/drivers/parport/procfs.c +++ b/trunk/drivers/parport/procfs.c @@ -429,6 +429,9 @@ struct parport_default_sysctl_table ctl_table dev_dir[2]; }; +extern unsigned long parport_default_timeslice; +extern int parport_default_spintime; + static struct parport_default_sysctl_table parport_default_sysctl_table = { .sysctl_header = NULL, diff --git a/trunk/drivers/pnp/base.h b/trunk/drivers/pnp/base.h index 9fd7bb9b7dce..e3fa9a2d9a3d 100644 --- a/trunk/drivers/pnp/base.h +++ b/trunk/drivers/pnp/base.h @@ -19,6 +19,7 @@ struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id); int pnp_interface_attach_device(struct pnp_dev *dev); int pnp_add_card(struct pnp_card *card); +struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id); void pnp_remove_card(struct pnp_card *card); int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); void pnp_remove_card_device(struct pnp_dev *dev); diff --git a/trunk/drivers/pnp/card.c b/trunk/drivers/pnp/card.c index e75b060daa95..a762a4176736 100644 --- a/trunk/drivers/pnp/card.c +++ b/trunk/drivers/pnp/card.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "base.h" LIST_HEAD(pnp_cards); @@ -102,7 +101,7 @@ static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv) * @id: pointer to a pnp_id structure * @card: pointer to the desired card */ -static struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id) +struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id) { struct pnp_id *dev_id, *ptr; @@ -168,9 +167,6 @@ struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnp sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number, card->number); - card->dev.coherent_dma_mask = DMA_24BIT_MASK; - card->dev.dma_mask = &card->dev.coherent_dma_mask; - dev_id = pnp_add_card_id(card, pnpid); if (!dev_id) { kfree(card); diff --git a/trunk/drivers/pnp/quirks.c b/trunk/drivers/pnp/quirks.c index 0bdf9b8a5e58..55f55ed72dc7 100644 --- a/trunk/drivers/pnp/quirks.c +++ b/trunk/drivers/pnp/quirks.c @@ -245,17 +245,15 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) */ for_each_pci_dev(pdev) { for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - unsigned int type; - - type = pci_resource_flags(pdev, i) & - (IORESOURCE_IO | IORESOURCE_MEM); - if (!type || pci_resource_len(pdev, i) == 0) + if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM) || + pci_resource_len(pdev, i) == 0) continue; pci_start = pci_resource_start(pdev, i); pci_end = pci_resource_end(pdev, i); for (j = 0; - (res = pnp_get_resource(dev, type, j)); j++) { + (res = pnp_get_resource(dev, IORESOURCE_MEM, j)); + j++) { if (res->start == 0 && res->end == 0) continue; @@ -285,10 +283,9 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) * the PCI region, and that might prevent a PCI * driver from requesting its resources. */ - dev_warn(&dev->dev, "%s resource " + dev_warn(&dev->dev, "mem resource " "(0x%llx-0x%llx) overlaps %s BAR %d " "(0x%llx-0x%llx), disabling\n", - pnp_resource_type_name(res), (unsigned long long) pnp_start, (unsigned long long) pnp_end, pci_name(pdev), i, diff --git a/trunk/drivers/s390/kvm/Makefile b/trunk/drivers/s390/kvm/Makefile index 0815690ac1e0..4a5ec39f9ca6 100644 --- a/trunk/drivers/s390/kvm/Makefile +++ b/trunk/drivers/s390/kvm/Makefile @@ -6,4 +6,4 @@ # it under the terms of the GNU General Public License (version 2 only) # as published by the Free Software Foundation. -obj-$(CONFIG_S390_GUEST) += kvm_virtio.o +obj-$(CONFIG_VIRTIO) += kvm_virtio.o diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index cebb25e36e82..c3ad89e302bd 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -3321,7 +3321,7 @@ int qeth_change_mtu(struct net_device *dev, int new_mtu) struct qeth_card *card; char dbf_text[15]; - card = dev->ml_priv; + card = netdev_priv(dev); QETH_DBF_TEXT(TRACE, 4, "chgmtu"); sprintf(dbf_text, "%8x", new_mtu); @@ -3343,7 +3343,7 @@ struct net_device_stats *qeth_get_stats(struct net_device *dev) { struct qeth_card *card; - card = dev->ml_priv; + card = netdev_priv(dev); QETH_DBF_TEXT(TRACE, 5, "getstat"); @@ -3395,7 +3395,7 @@ void qeth_tx_timeout(struct net_device *dev) { struct qeth_card *card; - card = dev->ml_priv; + card = netdev_priv(dev); card->stats.tx_errors++; qeth_schedule_recovery(card); } @@ -3403,7 +3403,7 @@ EXPORT_SYMBOL_GPL(qeth_tx_timeout); int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); int rc = 0; switch (regnum) { @@ -4253,7 +4253,7 @@ EXPORT_SYMBOL_GPL(qeth_core_get_stats_count); void qeth_core_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); data[0] = card->stats.rx_packets - card->perf_stats.initial_rx_packets; data[1] = card->perf_stats.bufs_rec; @@ -4313,7 +4313,7 @@ EXPORT_SYMBOL_GPL(qeth_core_get_strings); void qeth_core_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); if (card->options.layer2) strcpy(info->driver, "qeth_l2"); else @@ -4331,7 +4331,7 @@ EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo); int qeth_core_ethtool_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { - struct qeth_card *card = netdev->ml_priv; + struct qeth_card *card = netdev_priv(netdev); enum qeth_link_types link_type; if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan)) diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index a8b069cd9a4c..3fbc3bdec0c5 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -35,7 +35,7 @@ static int qeth_l2_recover(void *); static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); struct mii_ioctl_data *mii_data; int rc = 0; @@ -317,7 +317,7 @@ static void qeth_l2_process_vlans(struct qeth_card *card, int clear) static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); struct qeth_vlan_vid *id; QETH_DBF_TEXT_(TRACE, 4, "aid:%d", vid); @@ -334,7 +334,7 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) static void qeth_l2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) { struct qeth_vlan_vid *id, *tmpid = NULL; - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid); spin_lock_bh(&card->vlanlock); @@ -566,7 +566,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) static int qeth_l2_set_mac_address(struct net_device *dev, void *p) { struct sockaddr *addr = p; - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); int rc = 0; QETH_DBF_TEXT(TRACE, 3, "setmac"); @@ -590,7 +590,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) static void qeth_l2_set_multicast_list(struct net_device *dev) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); struct dev_mc_list *dm; if (card->info.type == QETH_CARD_TYPE_OSN) @@ -612,7 +612,7 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) int rc; struct qeth_hdr *hdr = NULL; int elements = 0; - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); struct sk_buff *new_skb = skb; int ipv = qeth_get_ip_version(skb); int cast_type = qeth_get_cast_type(card, skb); @@ -767,7 +767,7 @@ static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev, static int qeth_l2_open(struct net_device *dev) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); QETH_DBF_TEXT(TRACE, 4, "qethopen"); if (card->state != CARD_STATE_SOFTSETUP) @@ -791,7 +791,7 @@ static int qeth_l2_open(struct net_device *dev) static int qeth_l2_stop(struct net_device *dev) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); QETH_DBF_TEXT(TRACE, 4, "qethstop"); netif_tx_disable(dev); @@ -838,7 +838,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) static int qeth_l2_ethtool_set_tso(struct net_device *dev, u32 data) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); if (data) { if (card->options.large_send == QETH_LARGE_SEND_NO) { @@ -894,7 +894,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) if (!card->dev) return -ENODEV; - card->dev->ml_priv = card; + card->dev->priv = card; card->dev->tx_timeout = &qeth_tx_timeout; card->dev->watchdog_timeo = QETH_TX_TIMEOUT; card->dev->open = qeth_l2_open; @@ -1178,7 +1178,7 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len) QETH_DBF_TEXT(TRACE, 2, "osnsdmc"); if (!dev) return -ENODEV; - card = dev->ml_priv; + card = netdev_priv(dev); if (!card) return -ENODEV; if ((card->state != CARD_STATE_UP) && @@ -1201,7 +1201,7 @@ int qeth_osn_register(unsigned char *read_dev_no, struct net_device **dev, *dev = qeth_l2_netdev_by_devno(read_dev_no); if (*dev == NULL) return -ENODEV; - card = (*dev)->ml_priv; + card = netdev_priv(*dev); if (!card) return -ENODEV; if ((assist_cb == NULL) || (data_cb == NULL)) @@ -1219,7 +1219,7 @@ void qeth_osn_deregister(struct net_device *dev) QETH_DBF_TEXT(TRACE, 2, "osndereg"); if (!dev) return; - card = dev->ml_priv; + card = netdev_priv(dev); if (!card) return; card->osn_info.assist_cb = NULL; diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index 3e1d13857350..38de31b55708 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -1813,7 +1813,7 @@ static void qeth_l3_free_vlan_addresses(struct qeth_card *card, static void qeth_l3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); unsigned long flags; QETH_DBF_TEXT(TRACE, 4, "vlanreg"); @@ -1825,7 +1825,7 @@ static void qeth_l3_vlan_rx_register(struct net_device *dev, static void qeth_l3_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct net_device *vlandev; - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = (struct qeth_card *) dev->priv; struct in_device *in_dev; if (card->info.type == QETH_CARD_TYPE_IQD) @@ -1851,7 +1851,7 @@ static void qeth_l3_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); unsigned long flags; QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid); @@ -2013,7 +2013,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev, } } - if (rc && !(vlan_dev_real_dev(dev)->ml_priv == (void *)card)) + if (rc && !(netdev_priv(vlan_dev_real_dev(dev)) == (void *)card)) return 0; return rc; @@ -2047,9 +2047,9 @@ static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev) rc = qeth_l3_verify_dev(dev); if (rc == QETH_REAL_CARD) - card = dev->ml_priv; + card = netdev_priv(dev); else if (rc == QETH_VLAN_CARD) - card = vlan_dev_real_dev(dev)->ml_priv; + card = netdev_priv(vlan_dev_real_dev(dev)); if (card && card->options.layer2) card = NULL; QETH_DBF_TEXT_(TRACE, 4, "%d", rc); @@ -2110,7 +2110,7 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) static void qeth_l3_set_multicast_list(struct net_device *dev) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); QETH_DBF_TEXT(TRACE, 3, "setmulti"); qeth_l3_delete_mc_addresses(card); @@ -2438,7 +2438,7 @@ static int qeth_l3_arp_flush_cache(struct qeth_card *card) static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); struct qeth_arp_cache_entry arp_entry; struct mii_ioctl_data *mii_data; int rc = 0; @@ -2595,7 +2595,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) u16 *tag; struct qeth_hdr *hdr = NULL; int elements_needed = 0; - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); struct sk_buff *new_skb = NULL; int ipv = qeth_get_ip_version(skb); int cast_type = qeth_get_cast_type(card, skb); @@ -2763,7 +2763,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) static int qeth_l3_open(struct net_device *dev) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); QETH_DBF_TEXT(TRACE, 4, "qethopen"); if (card->state != CARD_STATE_SOFTSETUP) @@ -2780,7 +2780,7 @@ static int qeth_l3_open(struct net_device *dev) static int qeth_l3_stop(struct net_device *dev) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); QETH_DBF_TEXT(TRACE, 4, "qethstop"); netif_tx_disable(dev); @@ -2792,14 +2792,14 @@ static int qeth_l3_stop(struct net_device *dev) static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); return (card->options.checksum_type == HW_CHECKSUMMING); } static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); enum qeth_card_states old_state; enum qeth_checksum_types csum_type; @@ -2825,7 +2825,7 @@ static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data) static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data) { - struct qeth_card *card = dev->ml_priv; + struct qeth_card *card = netdev_priv(dev); if (data) { if (card->options.large_send == QETH_LARGE_SEND_NO) { @@ -2915,7 +2915,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) return -ENODEV; card->dev->hard_start_xmit = qeth_l3_hard_start_xmit; - card->dev->ml_priv = card; + card->dev->priv = card; card->dev->tx_timeout = &qeth_tx_timeout; card->dev->watchdog_timeo = QETH_TX_TIMEOUT; card->dev->open = qeth_l3_open; diff --git a/trunk/drivers/scsi/3w-9xxx.c b/trunk/drivers/scsi/3w-9xxx.c index b92c19bb6876..7045511f9ad2 100644 --- a/trunk/drivers/scsi/3w-9xxx.c +++ b/trunk/drivers/scsi/3w-9xxx.c @@ -4,7 +4,7 @@ Written By: Adam Radford Modifications By: Tom Couch - Copyright (C) 2004-2008 Applied Micro Circuits Corporation. + Copyright (C) 2004-2007 Applied Micro Circuits Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -71,10 +71,6 @@ Add support for 9650SE controllers. 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails. 2.26.02.010 - Add support for 9690SA controllers. - 2.26.02.011 - Increase max AENs drained to 256. - Add MSI support and "use_msi" module parameter. - Fix bug in twa_get_param() on 4GB+. - Use pci_resource_len() for ioremap(). */ #include @@ -99,7 +95,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.011" +#define TW_DRIVER_VERSION "2.26.02.010" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -111,10 +107,6 @@ MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(TW_DRIVER_VERSION); -static int use_msi = 0; -module_param(use_msi, int, S_IRUGO); -MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0"); - /* Function prototypes */ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header); static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id); @@ -1046,6 +1038,7 @@ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl TW_Command_Full *full_command_packet; TW_Command *command_packet; TW_Param_Apache *param; + unsigned long param_value; void *retval = NULL; /* Setup the command packet */ @@ -1064,8 +1057,9 @@ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl param->table_id = cpu_to_le16(table_id | 0x8000); param->parameter_id = cpu_to_le16(parameter_id); param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes); + param_value = tw_dev->generic_buffer_phys[request_id]; - command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); + command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(param_value); command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); /* Post the command packet to the board */ @@ -2006,7 +2000,7 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id { struct Scsi_Host *host = NULL; TW_Device_Extension *tw_dev; - unsigned long mem_addr, mem_len; + u32 mem_addr; int retval = -ENODEV; retval = pci_enable_device(pdev); @@ -2051,16 +2045,13 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id goto out_free_device_extension; } - if (pdev->device == PCI_DEVICE_ID_3WARE_9000) { + if (pdev->device == PCI_DEVICE_ID_3WARE_9000) mem_addr = pci_resource_start(pdev, 1); - mem_len = pci_resource_len(pdev, 1); - } else { + else mem_addr = pci_resource_start(pdev, 2); - mem_len = pci_resource_len(pdev, 2); - } /* Save base address */ - tw_dev->base_addr = ioremap(mem_addr, mem_len); + tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE); if (!tw_dev->base_addr) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap"); goto out_release_mem_region; @@ -2095,7 +2086,7 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id pci_set_drvdata(pdev, host); - printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%lx, IRQ: %d.\n", + printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%x, IRQ: %d.\n", host->host_no, mem_addr, pdev->irq); printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n", host->host_no, @@ -2106,11 +2097,6 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id le32_to_cpu(*(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE, TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH))); - /* Try to enable MSI */ - if (use_msi && (pdev->device != PCI_DEVICE_ID_3WARE_9000) && - !pci_enable_msi(pdev)) - set_bit(TW_USING_MSI, &tw_dev->flags); - /* Now setup the interrupt handler */ retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev); if (retval) { @@ -2134,8 +2120,6 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id return 0; out_remove_host: - if (test_bit(TW_USING_MSI, &tw_dev->flags)) - pci_disable_msi(pdev); scsi_remove_host(host); out_iounmap: iounmap(tw_dev->base_addr); @@ -2167,10 +2151,6 @@ static void twa_remove(struct pci_dev *pdev) /* Shutdown the card */ __twa_shutdown(tw_dev); - /* Disable MSI if enabled */ - if (test_bit(TW_USING_MSI, &tw_dev->flags)) - pci_disable_msi(pdev); - /* Free IO remapping */ iounmap(tw_dev->base_addr); diff --git a/trunk/drivers/scsi/3w-9xxx.h b/trunk/drivers/scsi/3w-9xxx.h index 1729a8785fea..d14a9479e389 100644 --- a/trunk/drivers/scsi/3w-9xxx.h +++ b/trunk/drivers/scsi/3w-9xxx.h @@ -4,7 +4,7 @@ Written By: Adam Radford Modifications By: Tom Couch - Copyright (C) 2004-2008 Applied Micro Circuits Corporation. + Copyright (C) 2004-2007 Applied Micro Circuits Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -319,8 +319,8 @@ static twa_message_type twa_error_table[] = { /* Compatibility defines */ #define TW_9000_ARCH_ID 0x5 -#define TW_CURRENT_DRIVER_SRL 35 -#define TW_CURRENT_DRIVER_BUILD 0 +#define TW_CURRENT_DRIVER_SRL 30 +#define TW_CURRENT_DRIVER_BUILD 80 #define TW_CURRENT_DRIVER_BRANCH 0 /* Phase defines */ @@ -352,9 +352,8 @@ static twa_message_type twa_error_table[] = { #define TW_MAX_RESET_TRIES 2 #define TW_MAX_CMDS_PER_LUN 254 #define TW_MAX_RESPONSE_DRAIN 256 -#define TW_MAX_AEN_DRAIN 255 +#define TW_MAX_AEN_DRAIN 40 #define TW_IN_RESET 2 -#define TW_USING_MSI 3 #define TW_IN_ATTENTION_LOOP 4 #define TW_MAX_SECTORS 256 #define TW_AEN_WAIT_TIME 1000 diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index c7f06298bd3c..26be540d1dd3 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -63,7 +63,6 @@ comment "SCSI support type (disk, tape, CD-ROM)" config BLK_DEV_SD tristate "SCSI disk support" depends on SCSI - select CRC_T10DIF ---help--- If you want to use SCSI hard disks, Fibre Channel disks, Serial ATA (SATA) or Parallel ATA (PATA) hard disks, diff --git a/trunk/drivers/scsi/Makefile b/trunk/drivers/scsi/Makefile index 72fd5043cfa1..a8149677de23 100644 --- a/trunk/drivers/scsi/Makefile +++ b/trunk/drivers/scsi/Makefile @@ -151,8 +151,6 @@ scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o sd_mod-objs := sd.o -sd_mod-$(CONFIG_BLK_DEV_INTEGRITY) += sd_dif.o - sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ := -DCONFIG_NCR53C8XX_PREFETCH -DSCSI_NCR_BIG_ENDIAN \ diff --git a/trunk/drivers/scsi/advansys.c b/trunk/drivers/scsi/advansys.c index 218777bfc143..8591585e5cc5 100644 --- a/trunk/drivers/scsi/advansys.c +++ b/trunk/drivers/scsi/advansys.c @@ -2278,7 +2278,7 @@ do { \ #define ASC_DBG(lvl, format, arg...) { \ if (asc_dbglvl >= (lvl)) \ printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \ - __func__ , ## arg); \ + __FUNCTION__ , ## arg); \ } #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \ diff --git a/trunk/drivers/scsi/aha152x.c b/trunk/drivers/scsi/aha152x.c index b5a868d85eb4..0899cb61e3dd 100644 --- a/trunk/drivers/scsi/aha152x.c +++ b/trunk/drivers/scsi/aha152x.c @@ -288,20 +288,20 @@ static LIST_HEAD(aha152x_host_list); #define DO_LOCK(flags) \ do { \ if(spin_is_locked(&QLOCK)) { \ - DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __func__, __LINE__, QLOCKER, QLOCKERL); \ + DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ } \ - DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \ + DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ spin_lock_irqsave(&QLOCK,flags); \ - DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \ - QLOCKER=__func__; \ + DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ + QLOCKER=__FUNCTION__; \ QLOCKERL=__LINE__; \ } while(0) #define DO_UNLOCK(flags) \ do { \ - DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __func__, __LINE__, QLOCKER, QLOCKERL); \ + DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ spin_unlock_irqrestore(&QLOCK,flags); \ - DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __func__, __LINE__); \ + DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ QLOCKER="(not locked)"; \ QLOCKERL=0; \ } while(0) diff --git a/trunk/drivers/scsi/aic94xx/aic94xx.h b/trunk/drivers/scsi/aic94xx/aic94xx.h index 2863a9d22851..2ef459e9cda1 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx.h +++ b/trunk/drivers/scsi/aic94xx/aic94xx.h @@ -39,9 +39,9 @@ #ifdef ASD_ENTER_EXIT #define ENTER printk(KERN_NOTICE "%s: ENTER %s\n", ASD_DRIVER_NAME, \ - __func__) + __FUNCTION__) #define EXIT printk(KERN_NOTICE "%s: --EXIT %s\n", ASD_DRIVER_NAME, \ - __func__) + __FUNCTION__) #else #define ENTER #define EXIT diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c index eb9dc3195fdf..83a78222896d 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -1359,7 +1359,7 @@ int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask) struct asd_ascb *ascb_list; if (!phy_mask) { - asd_printk("%s called with phy_mask of 0!?\n", __func__); + asd_printk("%s called with phy_mask of 0!?\n", __FUNCTION__); return 0; } diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_scb.c b/trunk/drivers/scsi/aic94xx/aic94xx_scb.c index ca55013b6ae5..46643319c520 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_scb.c @@ -211,7 +211,7 @@ static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) phy->asd_port = port; } ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n", - __func__, phy->asd_port->phy_mask, sas_phy->id); + __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); } @@ -294,7 +294,7 @@ static void asd_link_reset_err_tasklet(struct asd_ascb *ascb, struct asd_ascb *cp = asd_ascb_alloc_list(ascb->ha, &num, GFP_ATOMIC); if (!cp) { - asd_printk("%s: out of memory\n", __func__); + asd_printk("%s: out of memory\n", __FUNCTION__); goto out; } ASD_DPRINTK("phy%d: retries:0 performing link reset seq\n", @@ -446,7 +446,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, struct domain_device *failed_dev = NULL; ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n", - __func__, dl->status_block[3]); + __FUNCTION__, dl->status_block[3]); /* * Find the task that caused the abort and abort it first. @@ -474,7 +474,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, if (!failed_dev) { ASD_DPRINTK("%s: Can't find task (tc=%d) to abort!\n", - __func__, tc_abort); + __FUNCTION__, tc_abort); goto out; } @@ -502,7 +502,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, conn_handle = *((u16*)(&dl->status_block[1])); conn_handle = le16_to_cpu(conn_handle); - ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __func__, + ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__, dl->status_block[3]); /* Find the last pending task for the device... */ @@ -522,7 +522,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, if (!last_dev_task) { ASD_DPRINTK("%s: Device reset for idle device %d?\n", - __func__, conn_handle); + __FUNCTION__, conn_handle); goto out; } @@ -549,10 +549,10 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, goto out; } case SIGNAL_NCQ_ERROR: - ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __func__); + ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __FUNCTION__); goto out; case CLEAR_NCQ_ERROR: - ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __func__); + ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __FUNCTION__); goto out; } @@ -560,26 +560,26 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, switch (sb_opcode) { case BYTES_DMAED: - ASD_DPRINTK("%s: phy%d: BYTES_DMAED\n", __func__, phy_id); + ASD_DPRINTK("%s: phy%d: BYTES_DMAED\n", __FUNCTION__, phy_id); asd_bytes_dmaed_tasklet(ascb, dl, edb, phy_id); break; case PRIMITIVE_RECVD: - ASD_DPRINTK("%s: phy%d: PRIMITIVE_RECVD\n", __func__, + ASD_DPRINTK("%s: phy%d: PRIMITIVE_RECVD\n", __FUNCTION__, phy_id); asd_primitive_rcvd_tasklet(ascb, dl, phy_id); break; case PHY_EVENT: - ASD_DPRINTK("%s: phy%d: PHY_EVENT\n", __func__, phy_id); + ASD_DPRINTK("%s: phy%d: PHY_EVENT\n", __FUNCTION__, phy_id); asd_phy_event_tasklet(ascb, dl); break; case LINK_RESET_ERROR: - ASD_DPRINTK("%s: phy%d: LINK_RESET_ERROR\n", __func__, + ASD_DPRINTK("%s: phy%d: LINK_RESET_ERROR\n", __FUNCTION__, phy_id); asd_link_reset_err_tasklet(ascb, dl, phy_id); break; case TIMER_EVENT: ASD_DPRINTK("%s: phy%d: TIMER_EVENT, lost dw sync\n", - __func__, phy_id); + __FUNCTION__, phy_id); asd_turn_led(asd_ha, phy_id, 0); /* the device is gone */ sas_phy_disconnected(sas_phy); @@ -587,7 +587,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); break; default: - ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __func__, + ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__, phy_id, sb_opcode); ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n", edb, dl->opcode); @@ -654,7 +654,7 @@ static void control_phy_tasklet_complete(struct asd_ascb *ascb, if (status != 0) { ASD_DPRINTK("%s: phy%d status block opcode:0x%x\n", - __func__, phy_id, status); + __FUNCTION__, phy_id, status); goto out; } @@ -663,7 +663,7 @@ static void control_phy_tasklet_complete(struct asd_ascb *ascb, asd_ha->hw_prof.enabled_phys &= ~(1 << phy_id); asd_turn_led(asd_ha, phy_id, 0); asd_control_led(asd_ha, phy_id, 0); - ASD_DPRINTK("%s: disable phy%d\n", __func__, phy_id); + ASD_DPRINTK("%s: disable phy%d\n", __FUNCTION__, phy_id); break; case ENABLE_PHY: @@ -673,40 +673,40 @@ static void control_phy_tasklet_complete(struct asd_ascb *ascb, get_lrate_mode(phy, oob_mode); asd_turn_led(asd_ha, phy_id, 1); ASD_DPRINTK("%s: phy%d, lrate:0x%x, proto:0x%x\n", - __func__, phy_id,phy->sas_phy.linkrate, + __FUNCTION__, phy_id,phy->sas_phy.linkrate, phy->sas_phy.iproto); } else if (oob_status & CURRENT_SPINUP_HOLD) { asd_ha->hw_prof.enabled_phys |= (1 << phy_id); asd_turn_led(asd_ha, phy_id, 1); - ASD_DPRINTK("%s: phy%d, spinup hold\n", __func__, + ASD_DPRINTK("%s: phy%d, spinup hold\n", __FUNCTION__, phy_id); } else if (oob_status & CURRENT_ERR_MASK) { asd_turn_led(asd_ha, phy_id, 0); ASD_DPRINTK("%s: phy%d: error: oob status:0x%02x\n", - __func__, phy_id, oob_status); + __FUNCTION__, phy_id, oob_status); } else if (oob_status & (CURRENT_HOT_PLUG_CNCT | CURRENT_DEVICE_PRESENT)) { asd_ha->hw_prof.enabled_phys |= (1 << phy_id); asd_turn_led(asd_ha, phy_id, 1); ASD_DPRINTK("%s: phy%d: hot plug or device present\n", - __func__, phy_id); + __FUNCTION__, phy_id); } else { asd_ha->hw_prof.enabled_phys |= (1 << phy_id); asd_turn_led(asd_ha, phy_id, 0); ASD_DPRINTK("%s: phy%d: no device present: " "oob_status:0x%x\n", - __func__, phy_id, oob_status); + __FUNCTION__, phy_id, oob_status); } break; case RELEASE_SPINUP_HOLD: case PHY_NO_OP: case EXECUTE_HARD_RESET: - ASD_DPRINTK("%s: phy%d: sub_func:0x%x\n", __func__, + ASD_DPRINTK("%s: phy%d: sub_func:0x%x\n", __FUNCTION__, phy_id, control_phy->sub_func); /* XXX finish */ break; default: - ASD_DPRINTK("%s: phy%d: sub_func:0x%x?\n", __func__, + ASD_DPRINTK("%s: phy%d: sub_func:0x%x?\n", __FUNCTION__, phy_id, control_phy->sub_func); break; } diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_task.c b/trunk/drivers/scsi/aic94xx/aic94xx_task.c index 75d20f72501f..326765c9caf8 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_task.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_task.c @@ -320,7 +320,7 @@ static void asd_task_tasklet_complete(struct asd_ascb *ascb, case TC_RESUME: case TC_PARTIAL_SG_LIST: default: - ASD_DPRINTK("%s: dl opcode: 0x%x?\n", __func__, opcode); + ASD_DPRINTK("%s: dl opcode: 0x%x?\n", __FUNCTION__, opcode); break; } diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_tmf.c b/trunk/drivers/scsi/aic94xx/aic94xx_tmf.c index d4640ef6d44f..633ff40c736a 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_tmf.c @@ -75,12 +75,12 @@ static void asd_clear_nexus_tasklet_complete(struct asd_ascb *ascb, struct done_list_struct *dl) { struct tasklet_completion_status *tcs = ascb->uldd_task; - ASD_DPRINTK("%s: here\n", __func__); + ASD_DPRINTK("%s: here\n", __FUNCTION__); if (!del_timer(&ascb->timer)) { - ASD_DPRINTK("%s: couldn't delete timer\n", __func__); + ASD_DPRINTK("%s: couldn't delete timer\n", __FUNCTION__); return; } - ASD_DPRINTK("%s: opcode: 0x%x\n", __func__, dl->opcode); + ASD_DPRINTK("%s: opcode: 0x%x\n", __FUNCTION__, dl->opcode); tcs->dl_opcode = dl->opcode; complete(ascb->completion); asd_ascb_free(ascb); @@ -91,7 +91,7 @@ static void asd_clear_nexus_timedout(unsigned long data) struct asd_ascb *ascb = (void *)data; struct tasklet_completion_status *tcs = ascb->uldd_task; - ASD_DPRINTK("%s: here\n", __func__); + ASD_DPRINTK("%s: here\n", __FUNCTION__); tcs->dl_opcode = TMF_RESP_FUNC_FAILED; complete(ascb->completion); } @@ -103,7 +103,7 @@ static void asd_clear_nexus_timedout(unsigned long data) DECLARE_COMPLETION_ONSTACK(completion); \ DECLARE_TCS(tcs); \ \ - ASD_DPRINTK("%s: PRE\n", __func__); \ + ASD_DPRINTK("%s: PRE\n", __FUNCTION__); \ res = 1; \ ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); \ if (!ascb) \ @@ -115,12 +115,12 @@ static void asd_clear_nexus_timedout(unsigned long data) scb->header.opcode = CLEAR_NEXUS #define CLEAR_NEXUS_POST \ - ASD_DPRINTK("%s: POST\n", __func__); \ + ASD_DPRINTK("%s: POST\n", __FUNCTION__); \ res = asd_enqueue_internal(ascb, asd_clear_nexus_tasklet_complete, \ asd_clear_nexus_timedout); \ if (res) \ goto out_err; \ - ASD_DPRINTK("%s: clear nexus posted, waiting...\n", __func__); \ + ASD_DPRINTK("%s: clear nexus posted, waiting...\n", __FUNCTION__); \ wait_for_completion(&completion); \ res = tcs.dl_opcode; \ if (res == TC_NO_ERROR) \ @@ -417,7 +417,7 @@ int asd_abort_task(struct sas_task *task) if (task->task_state_flags & SAS_TASK_STATE_DONE) { spin_unlock_irqrestore(&task->task_state_lock, flags); res = TMF_RESP_FUNC_COMPLETE; - ASD_DPRINTK("%s: task 0x%p done\n", __func__, task); + ASD_DPRINTK("%s: task 0x%p done\n", __FUNCTION__, task); goto out_done; } spin_unlock_irqrestore(&task->task_state_lock, flags); @@ -481,7 +481,7 @@ int asd_abort_task(struct sas_task *task) if (task->task_state_flags & SAS_TASK_STATE_DONE) { spin_unlock_irqrestore(&task->task_state_lock, flags); res = TMF_RESP_FUNC_COMPLETE; - ASD_DPRINTK("%s: task 0x%p done\n", __func__, task); + ASD_DPRINTK("%s: task 0x%p done\n", __FUNCTION__, task); goto out_done; } spin_unlock_irqrestore(&task->task_state_lock, flags); diff --git a/trunk/drivers/scsi/arm/fas216.c b/trunk/drivers/scsi/arm/fas216.c index 477542602284..a715632e19d4 100644 --- a/trunk/drivers/scsi/arm/fas216.c +++ b/trunk/drivers/scsi/arm/fas216.c @@ -240,7 +240,7 @@ static void __fas216_checkmagic(FAS216_Info *info, const char *func) panic("scsi memory space corrupted in %s", func); } } -#define fas216_checkmagic(info) __fas216_checkmagic((info), __func__) +#define fas216_checkmagic(info) __fas216_checkmagic((info), __FUNCTION__) #else #define fas216_checkmagic(info) #endif @@ -2658,7 +2658,7 @@ int fas216_eh_host_reset(struct scsi_cmnd *SCpnt) fas216_checkmagic(info); printk("scsi%d.%c: %s: resetting host\n", - info->host->host_no, '0' + SCpnt->device->id, __func__); + info->host->host_no, '0' + SCpnt->device->id, __FUNCTION__); /* * Reset the SCSI chip. diff --git a/trunk/drivers/scsi/ch.c b/trunk/drivers/scsi/ch.c index 3c257fe0893e..aa2011b64683 100644 --- a/trunk/drivers/scsi/ch.c +++ b/trunk/drivers/scsi/ch.c @@ -930,7 +930,6 @@ static int ch_probe(struct device *dev) if (init) ch_init_elem(ch); - dev_set_drvdata(dev, ch); sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name); return 0; diff --git a/trunk/drivers/scsi/device_handler/Kconfig b/trunk/drivers/scsi/device_handler/Kconfig index 67070257919f..2adc0f666b68 100644 --- a/trunk/drivers/scsi/device_handler/Kconfig +++ b/trunk/drivers/scsi/device_handler/Kconfig @@ -30,11 +30,3 @@ config SCSI_DH_EMC depends on SCSI_DH help If you have a EMC CLARiiON select y. Otherwise, say N. - -config SCSI_DH_ALUA - tristate "SPC-3 ALUA Device Handler (EXPERIMENTAL)" - depends on SCSI_DH && EXPERIMENTAL - help - SCSI Device handler for generic SPC-3 Asymmetric Logical Unit - Access (ALUA). - diff --git a/trunk/drivers/scsi/device_handler/Makefile b/trunk/drivers/scsi/device_handler/Makefile index e1d2ea083e15..35272e93b1c8 100644 --- a/trunk/drivers/scsi/device_handler/Makefile +++ b/trunk/drivers/scsi/device_handler/Makefile @@ -5,4 +5,3 @@ obj-$(CONFIG_SCSI_DH) += scsi_dh.o obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o -obj-$(CONFIG_SCSI_DH_ALUA) += scsi_dh_alua.o diff --git a/trunk/drivers/scsi/device_handler/scsi_dh.c b/trunk/drivers/scsi/device_handler/scsi_dh.c index a518f2eff19a..ab6c21cd9689 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh.c @@ -24,16 +24,8 @@ #include #include "../scsi_priv.h" -struct scsi_dh_devinfo_list { - struct list_head node; - char vendor[9]; - char model[17]; - struct scsi_device_handler *handler; -}; - static DEFINE_SPINLOCK(list_lock); static LIST_HEAD(scsi_dh_list); -static LIST_HEAD(scsi_dh_dev_list); static struct scsi_device_handler *get_device_handler(const char *name) { @@ -41,7 +33,7 @@ static struct scsi_device_handler *get_device_handler(const char *name) spin_lock(&list_lock); list_for_each_entry(tmp, &scsi_dh_list, list) { - if (!strncmp(tmp->name, name, strlen(tmp->name))) { + if (!strcmp(tmp->name, name)) { found = tmp; break; } @@ -50,307 +42,11 @@ static struct scsi_device_handler *get_device_handler(const char *name) return found; } - -static struct scsi_device_handler * -scsi_dh_cache_lookup(struct scsi_device *sdev) -{ - struct scsi_dh_devinfo_list *tmp; - struct scsi_device_handler *found_dh = NULL; - - spin_lock(&list_lock); - list_for_each_entry(tmp, &scsi_dh_dev_list, node) { - if (!strncmp(sdev->vendor, tmp->vendor, strlen(tmp->vendor)) && - !strncmp(sdev->model, tmp->model, strlen(tmp->model))) { - found_dh = tmp->handler; - break; - } - } - spin_unlock(&list_lock); - - return found_dh; -} - -static int scsi_dh_handler_lookup(struct scsi_device_handler *scsi_dh, - struct scsi_device *sdev) -{ - int i, found = 0; - - for(i = 0; scsi_dh->devlist[i].vendor; i++) { - if (!strncmp(sdev->vendor, scsi_dh->devlist[i].vendor, - strlen(scsi_dh->devlist[i].vendor)) && - !strncmp(sdev->model, scsi_dh->devlist[i].model, - strlen(scsi_dh->devlist[i].model))) { - found = 1; - break; - } - } - return found; -} - -/* - * device_handler_match - Attach a device handler to a device - * @scsi_dh - The device handler to match against or NULL - * @sdev - SCSI device to be tested against @scsi_dh - * - * Tests @sdev against the device handler @scsi_dh or against - * all registered device_handler if @scsi_dh == NULL. - * Returns the found device handler or NULL if not found. - */ -static struct scsi_device_handler * -device_handler_match(struct scsi_device_handler *scsi_dh, - struct scsi_device *sdev) -{ - struct scsi_device_handler *found_dh = NULL; - struct scsi_dh_devinfo_list *tmp; - - found_dh = scsi_dh_cache_lookup(sdev); - if (found_dh) - return found_dh; - - if (scsi_dh) { - if (scsi_dh_handler_lookup(scsi_dh, sdev)) - found_dh = scsi_dh; - } else { - struct scsi_device_handler *tmp_dh; - - spin_lock(&list_lock); - list_for_each_entry(tmp_dh, &scsi_dh_list, list) { - if (scsi_dh_handler_lookup(tmp_dh, sdev)) - found_dh = tmp_dh; - } - spin_unlock(&list_lock); - } - - if (found_dh) { /* If device is found, add it to the cache */ - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); - if (tmp) { - strncpy(tmp->vendor, sdev->vendor, 8); - strncpy(tmp->model, sdev->model, 16); - tmp->vendor[8] = '\0'; - tmp->model[16] = '\0'; - tmp->handler = found_dh; - spin_lock(&list_lock); - list_add(&tmp->node, &scsi_dh_dev_list); - spin_unlock(&list_lock); - } else { - found_dh = NULL; - } - } - - return found_dh; -} - -/* - * scsi_dh_handler_attach - Attach a device handler to a device - * @sdev - SCSI device the device handler should attach to - * @scsi_dh - The device handler to attach - */ -static int scsi_dh_handler_attach(struct scsi_device *sdev, - struct scsi_device_handler *scsi_dh) -{ - int err = 0; - - if (sdev->scsi_dh_data) { - if (sdev->scsi_dh_data->scsi_dh != scsi_dh) - err = -EBUSY; - } else if (scsi_dh->attach) - err = scsi_dh->attach(sdev); - - return err; -} - -/* - * scsi_dh_handler_detach - Detach a device handler from a device - * @sdev - SCSI device the device handler should be detached from - * @scsi_dh - Device handler to be detached - * - * Detach from a device handler. If a device handler is specified, - * only detach if the currently attached handler matches @scsi_dh. - */ -static void scsi_dh_handler_detach(struct scsi_device *sdev, - struct scsi_device_handler *scsi_dh) -{ - if (!sdev->scsi_dh_data) - return; - - if (scsi_dh && scsi_dh != sdev->scsi_dh_data->scsi_dh) - return; - - if (!scsi_dh) - scsi_dh = sdev->scsi_dh_data->scsi_dh; - - if (scsi_dh && scsi_dh->detach) - scsi_dh->detach(sdev); -} - -/* - * Functions for sysfs attribute 'dh_state' - */ -static ssize_t -store_dh_state(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct scsi_device *sdev = to_scsi_device(dev); - struct scsi_device_handler *scsi_dh; - int err = -EINVAL; - - if (!sdev->scsi_dh_data) { - /* - * Attach to a device handler - */ - if (!(scsi_dh = get_device_handler(buf))) - return err; - err = scsi_dh_handler_attach(sdev, scsi_dh); - } else { - scsi_dh = sdev->scsi_dh_data->scsi_dh; - if (!strncmp(buf, "detach", 6)) { - /* - * Detach from a device handler - */ - scsi_dh_handler_detach(sdev, scsi_dh); - err = 0; - } else if (!strncmp(buf, "activate", 8)) { - /* - * Activate a device handler - */ - if (scsi_dh->activate) - err = scsi_dh->activate(sdev); - else - err = 0; - } - } - - return err<0?err:count; -} - -static ssize_t -show_dh_state(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct scsi_device *sdev = to_scsi_device(dev); - - if (!sdev->scsi_dh_data) - return snprintf(buf, 20, "detached\n"); - - return snprintf(buf, 20, "%s\n", sdev->scsi_dh_data->scsi_dh->name); -} - -static struct device_attribute scsi_dh_state_attr = - __ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state, - store_dh_state); - -/* - * scsi_dh_sysfs_attr_add - Callback for scsi_init_dh - */ -static int scsi_dh_sysfs_attr_add(struct device *dev, void *data) -{ - struct scsi_device *sdev; - int err; - - if (!scsi_is_sdev_device(dev)) - return 0; - - sdev = to_scsi_device(dev); - - err = device_create_file(&sdev->sdev_gendev, - &scsi_dh_state_attr); - - return 0; -} - -/* - * scsi_dh_sysfs_attr_remove - Callback for scsi_exit_dh - */ -static int scsi_dh_sysfs_attr_remove(struct device *dev, void *data) -{ - struct scsi_device *sdev; - - if (!scsi_is_sdev_device(dev)) - return 0; - - sdev = to_scsi_device(dev); - - device_remove_file(&sdev->sdev_gendev, - &scsi_dh_state_attr); - - return 0; -} - -/* - * scsi_dh_notifier - notifier chain callback - */ -static int scsi_dh_notifier(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct device *dev = data; - struct scsi_device *sdev; - int err = 0; - struct scsi_device_handler *devinfo = NULL; - - if (!scsi_is_sdev_device(dev)) - return 0; - - sdev = to_scsi_device(dev); - - if (action == BUS_NOTIFY_ADD_DEVICE) { - devinfo = device_handler_match(NULL, sdev); - if (!devinfo) - goto out; - - err = scsi_dh_handler_attach(sdev, devinfo); - if (!err) - err = device_create_file(dev, &scsi_dh_state_attr); - } else if (action == BUS_NOTIFY_DEL_DEVICE) { - device_remove_file(dev, &scsi_dh_state_attr); - scsi_dh_handler_detach(sdev, NULL); - } -out: - return err; -} - -/* - * scsi_dh_notifier_add - Callback for scsi_register_device_handler - */ static int scsi_dh_notifier_add(struct device *dev, void *data) { struct scsi_device_handler *scsi_dh = data; - struct scsi_device *sdev; - - if (!scsi_is_sdev_device(dev)) - return 0; - - if (!get_device(dev)) - return 0; - - sdev = to_scsi_device(dev); - - if (device_handler_match(scsi_dh, sdev)) - scsi_dh_handler_attach(sdev, scsi_dh); - - put_device(dev); - - return 0; -} - -/* - * scsi_dh_notifier_remove - Callback for scsi_unregister_device_handler - */ -static int scsi_dh_notifier_remove(struct device *dev, void *data) -{ - struct scsi_device_handler *scsi_dh = data; - struct scsi_device *sdev; - - if (!scsi_is_sdev_device(dev)) - return 0; - - if (!get_device(dev)) - return 0; - - sdev = to_scsi_device(dev); - - scsi_dh_handler_detach(sdev, scsi_dh); - - put_device(dev); + scsi_dh->nb.notifier_call(&scsi_dh->nb, BUS_NOTIFY_ADD_DEVICE, dev); return 0; } @@ -363,19 +59,33 @@ static int scsi_dh_notifier_remove(struct device *dev, void *data) */ int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) { - if (get_device_handler(scsi_dh->name)) - return -EBUSY; + int ret = -EBUSY; + struct scsi_device_handler *tmp; + tmp = get_device_handler(scsi_dh->name); + if (tmp) + goto done; + + ret = bus_register_notifier(&scsi_bus_type, &scsi_dh->nb); + + bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add); spin_lock(&list_lock); list_add(&scsi_dh->list, &scsi_dh_list); spin_unlock(&list_lock); - bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add); - printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name); - return SCSI_DH_OK; +done: + return ret; } EXPORT_SYMBOL_GPL(scsi_register_device_handler); +static int scsi_dh_notifier_remove(struct device *dev, void *data) +{ + struct scsi_device_handler *scsi_dh = data; + + scsi_dh->nb.notifier_call(&scsi_dh->nb, BUS_NOTIFY_DEL_DEVICE, dev); + return 0; +} + /* * scsi_unregister_device_handler - register a device handler personality * module. @@ -385,26 +95,23 @@ EXPORT_SYMBOL_GPL(scsi_register_device_handler); */ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) { - struct scsi_dh_devinfo_list *tmp, *pos; + int ret = -ENODEV; + struct scsi_device_handler *tmp; - if (!get_device_handler(scsi_dh->name)) - return -ENODEV; + tmp = get_device_handler(scsi_dh->name); + if (!tmp) + goto done; - bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, - scsi_dh_notifier_remove); + ret = bus_unregister_notifier(&scsi_bus_type, &scsi_dh->nb); + bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, + scsi_dh_notifier_remove); spin_lock(&list_lock); list_del(&scsi_dh->list); - list_for_each_entry_safe(pos, tmp, &scsi_dh_dev_list, node) { - if (pos->handler == scsi_dh) { - list_del(&pos->node); - kfree(pos); - } - } spin_unlock(&list_lock); - printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name); - return SCSI_DH_OK; +done: + return ret; } EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); @@ -450,97 +157,6 @@ int scsi_dh_handler_exist(const char *name) } EXPORT_SYMBOL_GPL(scsi_dh_handler_exist); -/* - * scsi_dh_handler_attach - Attach device handler - * @sdev - sdev the handler should be attached to - * @name - name of the handler to attach - */ -int scsi_dh_attach(struct request_queue *q, const char *name) -{ - unsigned long flags; - struct scsi_device *sdev; - struct scsi_device_handler *scsi_dh; - int err = 0; - - scsi_dh = get_device_handler(name); - if (!scsi_dh) - return -EINVAL; - - spin_lock_irqsave(q->queue_lock, flags); - sdev = q->queuedata; - if (!sdev || !get_device(&sdev->sdev_gendev)) - err = -ENODEV; - spin_unlock_irqrestore(q->queue_lock, flags); - - if (!err) { - err = scsi_dh_handler_attach(sdev, scsi_dh); - - put_device(&sdev->sdev_gendev); - } - return err; -} -EXPORT_SYMBOL_GPL(scsi_dh_attach); - -/* - * scsi_dh_handler_detach - Detach device handler - * @sdev - sdev the handler should be detached from - * - * This function will detach the device handler only - * if the sdev is not part of the internal list, ie - * if it has been attached manually. - */ -void scsi_dh_detach(struct request_queue *q) -{ - unsigned long flags; - struct scsi_device *sdev; - struct scsi_device_handler *scsi_dh = NULL; - - spin_lock_irqsave(q->queue_lock, flags); - sdev = q->queuedata; - if (!sdev || !get_device(&sdev->sdev_gendev)) - sdev = NULL; - spin_unlock_irqrestore(q->queue_lock, flags); - - if (!sdev) - return; - - if (sdev->scsi_dh_data) { - /* if sdev is not on internal list, detach */ - scsi_dh = sdev->scsi_dh_data->scsi_dh; - if (!device_handler_match(scsi_dh, sdev)) - scsi_dh_handler_detach(sdev, scsi_dh); - } - put_device(&sdev->sdev_gendev); -} -EXPORT_SYMBOL_GPL(scsi_dh_detach); - -static struct notifier_block scsi_dh_nb = { - .notifier_call = scsi_dh_notifier -}; - -static int __init scsi_dh_init(void) -{ - int r; - - r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb); - - if (!r) - bus_for_each_dev(&scsi_bus_type, NULL, NULL, - scsi_dh_sysfs_attr_add); - - return r; -} - -static void __exit scsi_dh_exit(void) -{ - bus_for_each_dev(&scsi_bus_type, NULL, NULL, - scsi_dh_sysfs_attr_remove); - bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb); -} - -module_init(scsi_dh_init); -module_exit(scsi_dh_exit); - MODULE_DESCRIPTION("SCSI device handler"); MODULE_AUTHOR("Chandra Seetharaman "); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/scsi/device_handler/scsi_dh_alua.c b/trunk/drivers/scsi/device_handler/scsi_dh_alua.c deleted file mode 100644 index fcdd73f25625..000000000000 --- a/trunk/drivers/scsi/device_handler/scsi_dh_alua.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Generic SCSI-3 ALUA SCSI Device Handler - * - * Copyright (C) 2007, 2008 Hannes Reinecke, SUSE Linux Products GmbH. - * 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; 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 - -#define ALUA_DH_NAME "alua" -#define ALUA_DH_VER "1.2" - -#define TPGS_STATE_OPTIMIZED 0x0 -#define TPGS_STATE_NONOPTIMIZED 0x1 -#define TPGS_STATE_STANDBY 0x2 -#define TPGS_STATE_UNAVAILABLE 0x3 -#define TPGS_STATE_OFFLINE 0xe -#define TPGS_STATE_TRANSITIONING 0xf - -#define TPGS_SUPPORT_NONE 0x00 -#define TPGS_SUPPORT_OPTIMIZED 0x01 -#define TPGS_SUPPORT_NONOPTIMIZED 0x02 -#define TPGS_SUPPORT_STANDBY 0x04 -#define TPGS_SUPPORT_UNAVAILABLE 0x08 -#define TPGS_SUPPORT_OFFLINE 0x40 -#define TPGS_SUPPORT_TRANSITION 0x80 - -#define TPGS_MODE_UNINITIALIZED -1 -#define TPGS_MODE_NONE 0x0 -#define TPGS_MODE_IMPLICIT 0x1 -#define TPGS_MODE_EXPLICIT 0x2 - -#define ALUA_INQUIRY_SIZE 36 -#define ALUA_FAILOVER_TIMEOUT (60 * HZ) -#define ALUA_FAILOVER_RETRIES 5 - -struct alua_dh_data { - int group_id; - int rel_port; - int tpgs; - int state; - unsigned char inq[ALUA_INQUIRY_SIZE]; - unsigned char *buff; - int bufflen; - unsigned char sense[SCSI_SENSE_BUFFERSIZE]; - int senselen; -}; - -#define ALUA_POLICY_SWITCH_CURRENT 0 -#define ALUA_POLICY_SWITCH_ALL 1 - -static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev) -{ - struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data; - BUG_ON(scsi_dh_data == NULL); - return ((struct alua_dh_data *) scsi_dh_data->buf); -} - -static int realloc_buffer(struct alua_dh_data *h, unsigned len) -{ - if (h->buff && h->buff != h->inq) - kfree(h->buff); - - h->buff = kmalloc(len, GFP_NOIO); - if (!h->buff) { - h->buff = h->inq; - h->bufflen = ALUA_INQUIRY_SIZE; - return 1; - } - h->bufflen = len; - return 0; -} - -static struct request *get_alua_req(struct scsi_device *sdev, - void *buffer, unsigned buflen, int rw) -{ - struct request *rq; - struct request_queue *q = sdev->request_queue; - - rq = blk_get_request(q, rw, GFP_NOIO); - - if (!rq) { - sdev_printk(KERN_INFO, sdev, - "%s: blk_get_request failed\n", __func__); - return NULL; - } - - if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) { - blk_put_request(rq); - sdev_printk(KERN_INFO, sdev, - "%s: blk_rq_map_kern failed\n", __func__); - return NULL; - } - - rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; - rq->retries = ALUA_FAILOVER_RETRIES; - rq->timeout = ALUA_FAILOVER_TIMEOUT; - - return rq; -} - -/* - * submit_std_inquiry - Issue a standard INQUIRY command - * @sdev: sdev the command should be send to - */ -static int submit_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) -{ - struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; - - rq = get_alua_req(sdev, h->inq, ALUA_INQUIRY_SIZE, READ); - if (!rq) - goto done; - - /* Prepare the command. */ - rq->cmd[0] = INQUIRY; - rq->cmd[1] = 0; - rq->cmd[2] = 0; - rq->cmd[4] = ALUA_INQUIRY_SIZE; - rq->cmd_len = COMMAND_SIZE(INQUIRY); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; - - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: std inquiry failed with %x\n", - ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; - err = SCSI_DH_IO; - } - blk_put_request(rq); -done: - return err; -} - -/* - * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command - * @sdev: sdev the command should be sent to - */ -static int submit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) -{ - struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; - - rq = get_alua_req(sdev, h->buff, h->bufflen, READ); - if (!rq) - goto done; - - /* Prepare the command. */ - rq->cmd[0] = INQUIRY; - rq->cmd[1] = 1; - rq->cmd[2] = 0x83; - rq->cmd[4] = h->bufflen; - rq->cmd_len = COMMAND_SIZE(INQUIRY); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; - - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: evpd inquiry failed with %x\n", - ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; - err = SCSI_DH_IO; - } - blk_put_request(rq); -done: - return err; -} - -/* - * submit_rtpg - Issue a REPORT TARGET GROUP STATES command - * @sdev: sdev the command should be sent to - */ -static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) -{ - struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; - - rq = get_alua_req(sdev, h->buff, h->bufflen, READ); - if (!rq) - goto done; - - /* Prepare the command. */ - rq->cmd[0] = MAINTENANCE_IN; - rq->cmd[1] = MI_REPORT_TARGET_PGS; - rq->cmd[6] = (h->bufflen >> 24) & 0xff; - rq->cmd[7] = (h->bufflen >> 16) & 0xff; - rq->cmd[8] = (h->bufflen >> 8) & 0xff; - rq->cmd[9] = h->bufflen & 0xff; - rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; - - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: rtpg failed with %x\n", - ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; - err = SCSI_DH_IO; - } - blk_put_request(rq); -done: - return err; -} - -/* - * submit_stpg - Issue a SET TARGET GROUP STATES command - * @sdev: sdev the command should be sent to - * - * Currently we're only setting the current target port group state - * to 'active/optimized' and let the array firmware figure out - * the states of the remaining groups. - */ -static unsigned submit_stpg(struct scsi_device *sdev, struct alua_dh_data *h) -{ - struct request *rq; - int err = SCSI_DH_RES_TEMP_UNAVAIL; - int stpg_len = 8; - - /* Prepare the data buffer */ - memset(h->buff, 0, stpg_len); - h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f; - h->buff[6] = (h->group_id >> 8) & 0x0f; - h->buff[7] = h->group_id & 0x0f; - - rq = get_alua_req(sdev, h->buff, stpg_len, WRITE); - if (!rq) - goto done; - - /* Prepare the command. */ - rq->cmd[0] = MAINTENANCE_OUT; - rq->cmd[1] = MO_SET_TARGET_PGS; - rq->cmd[6] = (stpg_len >> 24) & 0xff; - rq->cmd[7] = (stpg_len >> 16) & 0xff; - rq->cmd[8] = (stpg_len >> 8) & 0xff; - rq->cmd[9] = stpg_len & 0xff; - rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = h->senselen = 0; - - err = blk_execute_rq(rq->q, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: stpg failed with %x\n", - ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; - err = SCSI_DH_IO; - } - blk_put_request(rq); -done: - return err; -} - -/* - * alua_std_inquiry - Evaluate standard INQUIRY command - * @sdev: device to be checked - * - * Just extract the TPGS setting to find out if ALUA - * is supported. - */ -static int alua_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) -{ - int err; - - err = submit_std_inquiry(sdev, h); - - if (err != SCSI_DH_OK) - return err; - - /* Check TPGS setting */ - h->tpgs = (h->inq[5] >> 4) & 0x3; - switch (h->tpgs) { - case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT: - sdev_printk(KERN_INFO, sdev, - "%s: supports implicit and explicit TPGS\n", - ALUA_DH_NAME); - break; - case TPGS_MODE_EXPLICIT: - sdev_printk(KERN_INFO, sdev, "%s: supports explicit TPGS\n", - ALUA_DH_NAME); - break; - case TPGS_MODE_IMPLICIT: - sdev_printk(KERN_INFO, sdev, "%s: supports implicit TPGS\n", - ALUA_DH_NAME); - break; - default: - h->tpgs = TPGS_MODE_NONE; - sdev_printk(KERN_INFO, sdev, "%s: not supported\n", - ALUA_DH_NAME); - err = SCSI_DH_DEV_UNSUPP; - break; - } - - return err; -} - -/* - * alua_vpd_inquiry - Evaluate INQUIRY vpd page 0x83 - * @sdev: device to be checked - * - * Extract the relative target port and the target port group - * descriptor from the list of identificators. - */ -static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) -{ - int len; - unsigned err; - unsigned char *d; - - retry: - err = submit_vpd_inquiry(sdev, h); - - if (err != SCSI_DH_OK) - return err; - - /* Check if vpd page exceeds initial buffer */ - len = (h->buff[2] << 8) + h->buff[3] + 4; - if (len > h->bufflen) { - /* Resubmit with the correct length */ - if (realloc_buffer(h, len)) { - sdev_printk(KERN_WARNING, sdev, - "%s: kmalloc buffer failed\n", - ALUA_DH_NAME); - /* Temporary failure, bypass */ - return SCSI_DH_DEV_TEMP_BUSY; - } - goto retry; - } - - /* - * Now look for the correct descriptor. - */ - d = h->buff + 4; - while (d < h->buff + len) { - switch (d[1] & 0xf) { - case 0x4: - /* Relative target port */ - h->rel_port = (d[6] << 8) + d[7]; - break; - case 0x5: - /* Target port group */ - h->group_id = (d[6] << 8) + d[7]; - break; - default: - break; - } - d += d[3] + 4; - } - - if (h->group_id == -1) { - /* - * Internal error; TPGS supported but required - * VPD identification descriptors not present. - * Disable ALUA support - */ - sdev_printk(KERN_INFO, sdev, - "%s: No target port descriptors found\n", - ALUA_DH_NAME); - h->state = TPGS_STATE_OPTIMIZED; - h->tpgs = TPGS_MODE_NONE; - err = SCSI_DH_DEV_UNSUPP; - } else { - sdev_printk(KERN_INFO, sdev, - "%s: port group %02x rel port %02x\n", - ALUA_DH_NAME, h->group_id, h->rel_port); - } - - return err; -} - -static char print_alua_state(int state) -{ - switch (state) { - case TPGS_STATE_OPTIMIZED: - return 'A'; - case TPGS_STATE_NONOPTIMIZED: - return 'N'; - case TPGS_STATE_STANDBY: - return 'S'; - case TPGS_STATE_UNAVAILABLE: - return 'U'; - case TPGS_STATE_OFFLINE: - return 'O'; - case TPGS_STATE_TRANSITIONING: - return 'T'; - default: - return 'X'; - } -} - -static int alua_check_sense(struct scsi_device *sdev, - struct scsi_sense_hdr *sense_hdr) -{ - switch (sense_hdr->sense_key) { - case NOT_READY: - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) - /* - * LUN Not Accessible - ALUA state transition - */ - return NEEDS_RETRY; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b) - /* - * LUN Not Accessible -- Target port in standby state - */ - return SUCCESS; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0c) - /* - * LUN Not Accessible -- Target port in unavailable state - */ - return SUCCESS; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x12) - /* - * LUN Not Ready -- Offline - */ - return SUCCESS; - break; - case UNIT_ATTENTION: - if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) - /* - * Power On, Reset, or Bus Device Reset, just retry. - */ - return NEEDS_RETRY; - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) { - /* - * ALUA state changed - */ - return NEEDS_RETRY; - } - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) { - /* - * Implicit ALUA state transition failed - */ - return NEEDS_RETRY; - } - break; - } - - return SCSI_RETURN_NOT_HANDLED; -} - -/* - * alua_stpg - Evaluate SET TARGET GROUP STATES - * @sdev: the device to be evaluated - * @state: the new target group state - * - * Send a SET TARGET GROUP STATES command to the device. - * We only have to test here if we should resubmit the command; - * any other error is assumed as a failure. - */ -static int alua_stpg(struct scsi_device *sdev, int state, - struct alua_dh_data *h) -{ - struct scsi_sense_hdr sense_hdr; - unsigned err; - int retry = ALUA_FAILOVER_RETRIES; - - retry: - err = submit_stpg(sdev, h); - if (err == SCSI_DH_IO && h->senselen > 0) { - err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, - &sense_hdr); - if (!err) - return SCSI_DH_IO; - err = alua_check_sense(sdev, &sense_hdr); - if (retry > 0 && err == NEEDS_RETRY) { - retry--; - goto retry; - } - sdev_printk(KERN_INFO, sdev, - "%s: stpg sense code: %02x/%02x/%02x\n", - ALUA_DH_NAME, sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); - err = SCSI_DH_IO; - } - if (err == SCSI_DH_OK) { - h->state = state; - sdev_printk(KERN_INFO, sdev, - "%s: port group %02x switched to state %c\n", - ALUA_DH_NAME, h->group_id, - print_alua_state(h->state) ); - } - return err; -} - -/* - * alua_rtpg - Evaluate REPORT TARGET GROUP STATES - * @sdev: the device to be evaluated. - * - * Evaluate the Target Port Group State. - * Returns SCSI_DH_DEV_OFFLINED if the path is - * found to be unuseable. - */ -static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) -{ - struct scsi_sense_hdr sense_hdr; - int len, k, off, valid_states = 0; - char *ucp; - unsigned err; - - retry: - err = submit_rtpg(sdev, h); - - if (err == SCSI_DH_IO && h->senselen > 0) { - err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, - &sense_hdr); - if (!err) - return SCSI_DH_IO; - - err = alua_check_sense(sdev, &sense_hdr); - if (err == NEEDS_RETRY) - goto retry; - sdev_printk(KERN_INFO, sdev, - "%s: rtpg sense code %02x/%02x/%02x\n", - ALUA_DH_NAME, sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); - err = SCSI_DH_IO; - } - if (err != SCSI_DH_OK) - return err; - - len = (h->buff[0] << 24) + (h->buff[1] << 16) + - (h->buff[2] << 8) + h->buff[3] + 4; - - if (len > h->bufflen) { - /* Resubmit with the correct length */ - if (realloc_buffer(h, len)) { - sdev_printk(KERN_WARNING, sdev, - "%s: kmalloc buffer failed\n",__func__); - /* Temporary failure, bypass */ - return SCSI_DH_DEV_TEMP_BUSY; - } - goto retry; - } - - for (k = 4, ucp = h->buff + 4; k < len; k += off, ucp += off) { - if (h->group_id == (ucp[2] << 8) + ucp[3]) { - h->state = ucp[0] & 0x0f; - valid_states = ucp[1]; - } - off = 8 + (ucp[7] * 4); - } - - sdev_printk(KERN_INFO, sdev, - "%s: port group %02x state %c supports %c%c%c%c%c%c\n", - ALUA_DH_NAME, h->group_id, print_alua_state(h->state), - valid_states&TPGS_SUPPORT_TRANSITION?'T':'t', - valid_states&TPGS_SUPPORT_OFFLINE?'O':'o', - valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u', - valid_states&TPGS_SUPPORT_STANDBY?'S':'s', - valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n', - valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a'); - - if (h->tpgs & TPGS_MODE_EXPLICIT) { - switch (h->state) { - case TPGS_STATE_TRANSITIONING: - /* State transition, retry */ - goto retry; - break; - case TPGS_STATE_OFFLINE: - /* Path is offline, fail */ - err = SCSI_DH_DEV_OFFLINED; - break; - default: - break; - } - } else { - /* Only Implicit ALUA support */ - if (h->state == TPGS_STATE_OPTIMIZED || - h->state == TPGS_STATE_NONOPTIMIZED || - h->state == TPGS_STATE_STANDBY) - /* Useable path if active */ - err = SCSI_DH_OK; - else - /* Path unuseable for unavailable/offline */ - err = SCSI_DH_DEV_OFFLINED; - } - return err; -} - -/* - * alua_initialize - Initialize ALUA state - * @sdev: the device to be initialized - * - * For the prep_fn to work correctly we have - * to initialize the ALUA state for the device. - */ -static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) -{ - int err; - - err = alua_std_inquiry(sdev, h); - if (err != SCSI_DH_OK) - goto out; - - err = alua_vpd_inquiry(sdev, h); - if (err != SCSI_DH_OK) - goto out; - - err = alua_rtpg(sdev, h); - if (err != SCSI_DH_OK) - goto out; - -out: - return err; -} - -/* - * alua_activate - activate a path - * @sdev: device on the path to be activated - * - * We're currently switching the port group to be activated only and - * let the array figure out the rest. - * There may be other arrays which require us to switch all port groups - * based on a certain policy. But until we actually encounter them it - * should be okay. - */ -static int alua_activate(struct scsi_device *sdev) -{ - struct alua_dh_data *h = get_alua_data(sdev); - int err = SCSI_DH_OK; - - if (h->group_id != -1) { - err = alua_rtpg(sdev, h); - if (err != SCSI_DH_OK) - goto out; - } - - if (h->tpgs == TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED) - err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h); - -out: - return err; -} - -/* - * alua_prep_fn - request callback - * - * Fail I/O to all paths not in state - * active/optimized or active/non-optimized. - */ -static int alua_prep_fn(struct scsi_device *sdev, struct request *req) -{ - struct alua_dh_data *h = get_alua_data(sdev); - int ret = BLKPREP_OK; - - if (h->state != TPGS_STATE_OPTIMIZED && - h->state != TPGS_STATE_NONOPTIMIZED) { - ret = BLKPREP_KILL; - req->cmd_flags |= REQ_QUIET; - } - return ret; - -} - -const struct scsi_dh_devlist alua_dev_list[] = { - {"HP", "MSA VOLUME" }, - {"HP", "HSV101" }, - {"HP", "HSV111" }, - {"HP", "HSV200" }, - {"HP", "HSV210" }, - {"HP", "HSV300" }, - {"IBM", "2107900" }, - {"IBM", "2145" }, - {"Pillar", "Axiom" }, - {NULL, NULL} -}; - -static int alua_bus_attach(struct scsi_device *sdev); -static void alua_bus_detach(struct scsi_device *sdev); - -static struct scsi_device_handler alua_dh = { - .name = ALUA_DH_NAME, - .module = THIS_MODULE, - .devlist = alua_dev_list, - .attach = alua_bus_attach, - .detach = alua_bus_detach, - .prep_fn = alua_prep_fn, - .check_sense = alua_check_sense, - .activate = alua_activate, -}; - -/* - * alua_bus_attach - Attach device handler - * @sdev: device to be attached to - */ -static int alua_bus_attach(struct scsi_device *sdev) -{ - struct scsi_dh_data *scsi_dh_data; - struct alua_dh_data *h; - unsigned long flags; - int err = SCSI_DH_OK; - - scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) - + sizeof(*h) , GFP_KERNEL); - if (!scsi_dh_data) { - sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", - ALUA_DH_NAME); - return -ENOMEM; - } - - scsi_dh_data->scsi_dh = &alua_dh; - h = (struct alua_dh_data *) scsi_dh_data->buf; - h->tpgs = TPGS_MODE_UNINITIALIZED; - h->state = TPGS_STATE_OPTIMIZED; - h->group_id = -1; - h->rel_port = -1; - h->buff = h->inq; - h->bufflen = ALUA_INQUIRY_SIZE; - - err = alua_initialize(sdev, h); - if (err != SCSI_DH_OK) - goto failed; - - if (!try_module_get(THIS_MODULE)) - goto failed; - - spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - sdev->scsi_dh_data = scsi_dh_data; - spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); - - return 0; - -failed: - kfree(scsi_dh_data); - sdev_printk(KERN_ERR, sdev, "%s: not attached\n", ALUA_DH_NAME); - return -EINVAL; -} - -/* - * alua_bus_detach - Detach device handler - * @sdev: device to be detached from - */ -static void alua_bus_detach(struct scsi_device *sdev) -{ - struct scsi_dh_data *scsi_dh_data; - struct alua_dh_data *h; - unsigned long flags; - - spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - scsi_dh_data = sdev->scsi_dh_data; - sdev->scsi_dh_data = NULL; - spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); - - h = (struct alua_dh_data *) scsi_dh_data->buf; - if (h->buff && h->inq != h->buff) - kfree(h->buff); - kfree(scsi_dh_data); - module_put(THIS_MODULE); - sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", ALUA_DH_NAME); -} - -static int __init alua_init(void) -{ - int r; - - r = scsi_register_device_handler(&alua_dh); - if (r != 0) - printk(KERN_ERR "%s: Failed to register scsi device handler", - ALUA_DH_NAME); - return r; -} - -static void __exit alua_exit(void) -{ - scsi_unregister_device_handler(&alua_dh); -} - -module_init(alua_init); -module_exit(alua_exit); - -MODULE_DESCRIPTION("DM Multipath ALUA support"); -MODULE_AUTHOR("Hannes Reinecke "); -MODULE_LICENSE("GPL"); -MODULE_VERSION(ALUA_DH_VER); diff --git a/trunk/drivers/scsi/device_handler/scsi_dh_emc.c b/trunk/drivers/scsi/device_handler/scsi_dh_emc.c index aa46b131b20e..f2467e936e55 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh_emc.c @@ -25,31 +25,28 @@ #include #include -#define CLARIION_NAME "emc" +#define CLARIION_NAME "emc_clariion" #define CLARIION_TRESPASS_PAGE 0x22 -#define CLARIION_BUFFER_SIZE 0xFC +#define CLARIION_BUFFER_SIZE 0x80 #define CLARIION_TIMEOUT (60 * HZ) #define CLARIION_RETRIES 3 #define CLARIION_UNBOUND_LU -1 -#define CLARIION_SP_A 0 -#define CLARIION_SP_B 1 - -/* Flags */ -#define CLARIION_SHORT_TRESPASS 1 -#define CLARIION_HONOR_RESERVATIONS 2 - -/* LUN states */ -#define CLARIION_LUN_UNINITIALIZED -1 -#define CLARIION_LUN_UNBOUND 0 -#define CLARIION_LUN_BOUND 1 -#define CLARIION_LUN_OWNED 2 static unsigned char long_trespass[] = { - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, CLARIION_TRESPASS_PAGE, /* Page code */ 0x09, /* Page length - 2 */ - 0x01, /* Trespass code */ + 0x81, /* Trespass code + Honor reservation bit */ + 0xff, 0xff, /* Trespass target */ + 0, 0, 0, 0, 0, 0 /* Reserved bytes / unknown */ +}; + +static unsigned char long_trespass_hr[] = { + 0, 0, 0, 0, + CLARIION_TRESPASS_PAGE, /* Page code */ + 0x09, /* Page length - 2 */ + 0x01, /* Trespass code + Honor reservation bit */ 0xff, 0xff, /* Trespass target */ 0, 0, 0, 0, 0, 0 /* Reserved bytes / unknown */ }; @@ -58,56 +55,39 @@ static unsigned char short_trespass[] = { 0, 0, 0, 0, CLARIION_TRESPASS_PAGE, /* Page code */ 0x02, /* Page length - 2 */ - 0x01, /* Trespass code */ + 0x81, /* Trespass code + Honor reservation bit */ 0xff, /* Trespass target */ }; -static const char * lun_state[] = -{ - "not bound", - "bound", - "owned", +static unsigned char short_trespass_hr[] = { + 0, 0, 0, 0, + CLARIION_TRESPASS_PAGE, /* Page code */ + 0x02, /* Page length - 2 */ + 0x01, /* Trespass code + Honor reservation bit */ + 0xff, /* Trespass target */ }; struct clariion_dh_data { /* - * Flags: - * CLARIION_SHORT_TRESPASS * Use short trespass command (FC-series) or the long version * (default for AX/CX CLARiiON arrays). - * - * CLARIION_HONOR_RESERVATIONS - * Whether or not (default) to honor SCSI reservations when - * initiating a switch-over. */ - unsigned flags; + unsigned short_trespass; /* - * I/O buffer for both MODE_SELECT and INQUIRY commands. + * Whether or not (default) to honor SCSI reservations when + * initiating a switch-over. */ + unsigned hr; + /* I/O buffer for both MODE_SELECT and INQUIRY commands. */ char buffer[CLARIION_BUFFER_SIZE]; /* * SCSI sense buffer for commands -- assumes serial issuance * and completion sequence of all commands for same multipath. */ unsigned char sense[SCSI_SENSE_BUFFERSIZE]; - unsigned int senselen; - /* - * LUN state - */ - int lun_state; - /* - * SP Port number - */ - int port; - /* - * which SP (A=0,B=1,UNBOUND=-1) is the default SP for this - * path's mapped LUN - */ + /* which SP (A=0,B=1,UNBOUND=-1) is dflt SP for path's mapped dev */ int default_sp; - /* - * which SP (A=0,B=1,UNBOUND=-1) is the active SP for this - * path's mapped LUN - */ + /* which SP (A=0,B=1,UNBOUND=-1) is active for path's mapped dev */ int current_sp; }; @@ -122,16 +102,19 @@ static inline struct clariion_dh_data /* * Parse MODE_SELECT cmd reply. */ -static int trespass_endio(struct scsi_device *sdev, char *sense) +static int trespass_endio(struct scsi_device *sdev, int result) { - int err = SCSI_DH_IO; + int err = SCSI_DH_OK; struct scsi_sense_hdr sshdr; + struct clariion_dh_data *csdev = get_clariion_data(sdev); + char *sense = csdev->sense; - if (!scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) { - sdev_printk(KERN_ERR, sdev, "%s: Found valid sense data 0x%2x, " + if (status_byte(result) == CHECK_CONDITION && + scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) { + sdev_printk(KERN_ERR, sdev, "Found valid sense data 0x%2x, " "0x%2x, 0x%2x while sending CLARiiON trespass " - "command.\n", CLARIION_NAME, sshdr.sense_key, - sshdr.asc, sshdr.ascq); + "command.\n", sshdr.sense_key, sshdr.asc, + sshdr.ascq); if ((sshdr.sense_key == 0x05) && (sshdr.asc == 0x04) && (sshdr.ascq == 0x00)) { @@ -139,9 +122,9 @@ static int trespass_endio(struct scsi_device *sdev, char *sense) * Array based copy in progress -- do not send * mode_select or copy will be aborted mid-stream. */ - sdev_printk(KERN_INFO, sdev, "%s: Array Based Copy in " + sdev_printk(KERN_INFO, sdev, "Array Based Copy in " "progress while sending CLARiiON trespass " - "command.\n", CLARIION_NAME); + "command.\n"); err = SCSI_DH_DEV_TEMP_BUSY; } else if ((sshdr.sense_key == 0x02) && (sshdr.asc == 0x04) && (sshdr.ascq == 0x03)) { @@ -149,153 +132,160 @@ static int trespass_endio(struct scsi_device *sdev, char *sense) * LUN Not Ready - Manual Intervention Required * indicates in-progress ucode upgrade (NDU). */ - sdev_printk(KERN_INFO, sdev, "%s: Detected in-progress " + sdev_printk(KERN_INFO, sdev, "Detected in-progress " "ucode upgrade NDU operation while sending " - "CLARiiON trespass command.\n", CLARIION_NAME); + "CLARiiON trespass command.\n"); err = SCSI_DH_DEV_TEMP_BUSY; } else err = SCSI_DH_DEV_FAILED; - } else { - sdev_printk(KERN_INFO, sdev, - "%s: failed to send MODE SELECT, no sense available\n", - CLARIION_NAME); + } else if (result) { + sdev_printk(KERN_ERR, sdev, "Error 0x%x while sending " + "CLARiiON trespass command.\n", result); + err = SCSI_DH_IO; } + return err; } -static int parse_sp_info_reply(struct scsi_device *sdev, - struct clariion_dh_data *csdev) +static int parse_sp_info_reply(struct scsi_device *sdev, int result, + int *default_sp, int *current_sp, int *new_current_sp) { int err = SCSI_DH_OK; + struct clariion_dh_data *csdev = get_clariion_data(sdev); - /* check for in-progress ucode upgrade (NDU) */ - if (csdev->buffer[48] != 0) { - sdev_printk(KERN_NOTICE, sdev, "%s: Detected in-progress " - "ucode upgrade NDU operation while finding " - "current active SP.", CLARIION_NAME); - err = SCSI_DH_DEV_TEMP_BUSY; - goto out; - } - if (csdev->buffer[4] < 0 || csdev->buffer[4] > 2) { - /* Invalid buffer format */ - sdev_printk(KERN_NOTICE, sdev, - "%s: invalid VPD page 0xC0 format\n", - CLARIION_NAME); - err = SCSI_DH_NOSYS; - goto out; - } - switch (csdev->buffer[28] & 0x0f) { - case 6: - sdev_printk(KERN_NOTICE, sdev, - "%s: ALUA failover mode detected\n", - CLARIION_NAME); - break; - case 4: - /* Linux failover */ - break; - default: - sdev_printk(KERN_WARNING, sdev, - "%s: Invalid failover mode %d\n", - CLARIION_NAME, csdev->buffer[28] & 0x0f); - err = SCSI_DH_NOSYS; - goto out; - } + if (result == 0) { + /* check for in-progress ucode upgrade (NDU) */ + if (csdev->buffer[48] != 0) { + sdev_printk(KERN_NOTICE, sdev, "Detected in-progress " + "ucode upgrade NDU operation while finding " + "current active SP."); + err = SCSI_DH_DEV_TEMP_BUSY; + } else { + *default_sp = csdev->buffer[5]; + + if (csdev->buffer[4] == 2) + /* SP for path is current */ + *current_sp = csdev->buffer[8]; + else { + if (csdev->buffer[4] == 1) + /* SP for this path is NOT current */ + if (csdev->buffer[8] == 0) + *current_sp = 1; + else + *current_sp = 0; + else + /* unbound LU or LUNZ */ + *current_sp = CLARIION_UNBOUND_LU; + } + *new_current_sp = csdev->buffer[8]; + } + } else { + struct scsi_sense_hdr sshdr; - csdev->default_sp = csdev->buffer[5]; - csdev->lun_state = csdev->buffer[4]; - csdev->current_sp = csdev->buffer[8]; - csdev->port = csdev->buffer[7]; + err = SCSI_DH_IO; + + if (scsi_normalize_sense(csdev->sense, SCSI_SENSE_BUFFERSIZE, + &sshdr)) + sdev_printk(KERN_ERR, sdev, "Found valid sense data " + "0x%2x, 0x%2x, 0x%2x while finding current " + "active SP.", sshdr.sense_key, sshdr.asc, + sshdr.ascq); + else + sdev_printk(KERN_ERR, sdev, "Error 0x%x finding " + "current active SP.", result); + } -out: return err; } -#define emc_default_str "FC (Legacy)" - -static char * parse_sp_model(struct scsi_device *sdev, unsigned char *buffer) +static int sp_info_endio(struct scsi_device *sdev, int result, + int mode_select_sent, int *done) { - unsigned char len = buffer[4] + 5; - char *sp_model = NULL; - unsigned char sp_len, serial_len; - - if (len < 160) { - sdev_printk(KERN_WARNING, sdev, - "%s: Invalid information section length %d\n", - CLARIION_NAME, len); - /* Check for old FC arrays */ - if (!strncmp(buffer + 8, "DGC", 3)) { - /* Old FC array, not supporting extended information */ - sp_model = emc_default_str; - } - goto out; - } + struct clariion_dh_data *csdev = get_clariion_data(sdev); + int err_flags, default_sp, current_sp, new_current_sp; - /* - * Parse extended information for SP model number - */ - serial_len = buffer[160]; - if (serial_len == 0 || serial_len + 161 > len) { - sdev_printk(KERN_WARNING, sdev, - "%s: Invalid array serial number length %d\n", - CLARIION_NAME, serial_len); - goto out; - } - sp_len = buffer[99]; - if (sp_len == 0 || serial_len + sp_len + 161 > len) { - sdev_printk(KERN_WARNING, sdev, - "%s: Invalid model number length %d\n", - CLARIION_NAME, sp_len); - goto out; - } - sp_model = &buffer[serial_len + 161]; - /* Strip whitespace at the end */ - while (sp_len > 1 && sp_model[sp_len - 1] == ' ') - sp_len--; + err_flags = parse_sp_info_reply(sdev, result, &default_sp, + ¤t_sp, &new_current_sp); - sp_model[sp_len] = '\0'; + if (err_flags != SCSI_DH_OK) + goto done; -out: - return sp_model; + if (mode_select_sent) { + csdev->default_sp = default_sp; + csdev->current_sp = current_sp; + } else { + /* + * Issue the actual module_selec request IFF either + * (1) we do not know the identity of the current SP OR + * (2) what we think we know is actually correct. + */ + if ((current_sp != CLARIION_UNBOUND_LU) && + (new_current_sp != current_sp)) { + + csdev->default_sp = default_sp; + csdev->current_sp = current_sp; + + sdev_printk(KERN_INFO, sdev, "Ignoring path group " + "switch-over command for CLARiiON SP%s since " + " mapped device is already initialized.", + current_sp ? "B" : "A"); + if (done) + *done = 1; /* as good as doing it */ + } + } +done: + return err_flags; } /* - * Get block request for REQ_BLOCK_PC command issued to path. Currently - * limited to MODE_SELECT (trespass) and INQUIRY (VPD page 0xC0) commands. - * - * Uses data and sense buffers in hardware handler context structure and - * assumes serial servicing of commands, both issuance and completion. - */ -static struct request *get_req(struct scsi_device *sdev, int cmd, - unsigned char *buffer) +* Get block request for REQ_BLOCK_PC command issued to path. Currently +* limited to MODE_SELECT (trespass) and INQUIRY (VPD page 0xC0) commands. +* +* Uses data and sense buffers in hardware handler context structure and +* assumes serial servicing of commands, both issuance and completion. +*/ +static struct request *get_req(struct scsi_device *sdev, int cmd) { + struct clariion_dh_data *csdev = get_clariion_data(sdev); struct request *rq; + unsigned char *page22; int len = 0; rq = blk_get_request(sdev->request_queue, - (cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO); + (cmd == MODE_SELECT) ? WRITE : READ, GFP_ATOMIC); if (!rq) { sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); return NULL; } - memset(rq->cmd, 0, BLK_MAX_CDB); - rq->cmd_len = COMMAND_SIZE(cmd); + memset(&rq->cmd, 0, BLK_MAX_CDB); rq->cmd[0] = cmd; + rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); switch (cmd) { case MODE_SELECT: - len = sizeof(short_trespass); - rq->cmd_flags |= REQ_RW; - rq->cmd[1] = 0x10; - break; - case MODE_SELECT_10: - len = sizeof(long_trespass); + if (csdev->short_trespass) { + page22 = csdev->hr ? short_trespass_hr : short_trespass; + len = sizeof(short_trespass); + } else { + page22 = csdev->hr ? long_trespass_hr : long_trespass; + len = sizeof(long_trespass); + } + /* + * Can't DMA from kernel BSS -- must copy selected trespass + * command mode page contents to context buffer which is + * allocated by kmalloc. + */ + BUG_ON((len > CLARIION_BUFFER_SIZE)); + memcpy(csdev->buffer, page22, len); rq->cmd_flags |= REQ_RW; rq->cmd[1] = 0x10; break; case INQUIRY: + rq->cmd[1] = 0x1; + rq->cmd[2] = 0xC0; len = CLARIION_BUFFER_SIZE; - memset(buffer, 0, len); + memset(csdev->buffer, 0, CLARIION_BUFFER_SIZE); break; default: BUG_ON(1); @@ -308,94 +298,47 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, rq->timeout = CLARIION_TIMEOUT; rq->retries = CLARIION_RETRIES; - if (blk_rq_map_kern(rq->q, rq, buffer, len, GFP_NOIO)) { - blk_put_request(rq); + rq->sense = csdev->sense; + memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); + rq->sense_len = 0; + + if (blk_rq_map_kern(sdev->request_queue, rq, csdev->buffer, + len, GFP_ATOMIC)) { + __blk_put_request(rq->q, rq); return NULL; } return rq; } -static int send_inquiry_cmd(struct scsi_device *sdev, int page, - struct clariion_dh_data *csdev) +static int send_cmd(struct scsi_device *sdev, int cmd) { - struct request *rq = get_req(sdev, INQUIRY, csdev->buffer); - int err; + struct request *rq = get_req(sdev, cmd); if (!rq) return SCSI_DH_RES_TEMP_UNAVAIL; - rq->sense = csdev->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = csdev->senselen = 0; - - rq->cmd[0] = INQUIRY; - if (page != 0) { - rq->cmd[1] = 1; - rq->cmd[2] = page; - } - err = blk_execute_rq(sdev->request_queue, NULL, rq, 1); - if (err == -EIO) { - sdev_printk(KERN_INFO, sdev, - "%s: failed to send %s INQUIRY: %x\n", - CLARIION_NAME, page?"EVPD":"standard", - rq->errors); - csdev->senselen = rq->sense_len; - err = SCSI_DH_IO; - } - - blk_put_request(rq); - - return err; + return blk_execute_rq(sdev->request_queue, NULL, rq, 1); } -static int send_trespass_cmd(struct scsi_device *sdev, - struct clariion_dh_data *csdev) +static int clariion_activate(struct scsi_device *sdev) { - struct request *rq; - unsigned char *page22; - int err, len, cmd; - - if (csdev->flags & CLARIION_SHORT_TRESPASS) { - page22 = short_trespass; - if (!(csdev->flags & CLARIION_HONOR_RESERVATIONS)) - /* Set Honor Reservations bit */ - page22[6] |= 0x80; - len = sizeof(short_trespass); - cmd = MODE_SELECT; - } else { - page22 = long_trespass; - if (!(csdev->flags & CLARIION_HONOR_RESERVATIONS)) - /* Set Honor Reservations bit */ - page22[10] |= 0x80; - len = sizeof(long_trespass); - cmd = MODE_SELECT_10; - } - BUG_ON((len > CLARIION_BUFFER_SIZE)); - memcpy(csdev->buffer, page22, len); - - rq = get_req(sdev, cmd, csdev->buffer); - if (!rq) - return SCSI_DH_RES_TEMP_UNAVAIL; - - rq->sense = csdev->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = csdev->senselen = 0; + int result, done = 0; - err = blk_execute_rq(sdev->request_queue, NULL, rq, 1); - if (err == -EIO) { - if (rq->sense_len) { - err = trespass_endio(sdev, csdev->sense); - } else { - sdev_printk(KERN_INFO, sdev, - "%s: failed to send MODE SELECT: %x\n", - CLARIION_NAME, rq->errors); - } - } + result = send_cmd(sdev, INQUIRY); + result = sp_info_endio(sdev, result, 0, &done); + if (result || done) + goto done; - blk_put_request(rq); + result = send_cmd(sdev, MODE_SELECT); + result = trespass_endio(sdev, result); + if (result) + goto done; - return err; + result = send_cmd(sdev, INQUIRY); + result = sp_info_endio(sdev, result, 1, NULL); +done: + return result; } static int clariion_check_sense(struct scsi_device *sdev, @@ -443,215 +386,99 @@ static int clariion_check_sense(struct scsi_device *sdev, break; } - return SCSI_RETURN_NOT_HANDLED; -} - -static int clariion_prep_fn(struct scsi_device *sdev, struct request *req) -{ - struct clariion_dh_data *h = get_clariion_data(sdev); - int ret = BLKPREP_OK; - - if (h->lun_state != CLARIION_LUN_OWNED) { - ret = BLKPREP_KILL; - req->cmd_flags |= REQ_QUIET; - } - return ret; - -} - -static int clariion_std_inquiry(struct scsi_device *sdev, - struct clariion_dh_data *csdev) -{ - int err; - char *sp_model; - - err = send_inquiry_cmd(sdev, 0, csdev); - if (err != SCSI_DH_OK && csdev->senselen) { - struct scsi_sense_hdr sshdr; - - if (scsi_normalize_sense(csdev->sense, SCSI_SENSE_BUFFERSIZE, - &sshdr)) { - sdev_printk(KERN_ERR, sdev, "%s: INQUIRY sense code " - "%02x/%02x/%02x\n", CLARIION_NAME, - sshdr.sense_key, sshdr.asc, sshdr.ascq); - } - err = SCSI_DH_IO; - goto out; - } - - sp_model = parse_sp_model(sdev, csdev->buffer); - if (!sp_model) { - err = SCSI_DH_DEV_UNSUPP; - goto out; - } - - /* - * FC Series arrays do not support long trespass - */ - if (!strlen(sp_model) || !strncmp(sp_model, "FC",2)) - csdev->flags |= CLARIION_SHORT_TRESPASS; - - sdev_printk(KERN_INFO, sdev, - "%s: detected Clariion %s, flags %x\n", - CLARIION_NAME, sp_model, csdev->flags); -out: - return err; + /* success just means we do not care what scsi-ml does */ + return SUCCESS; } -static int clariion_send_inquiry(struct scsi_device *sdev, - struct clariion_dh_data *csdev) -{ - int err, retry = CLARIION_RETRIES; - -retry: - err = send_inquiry_cmd(sdev, 0xC0, csdev); - if (err != SCSI_DH_OK && csdev->senselen) { - struct scsi_sense_hdr sshdr; - - err = scsi_normalize_sense(csdev->sense, SCSI_SENSE_BUFFERSIZE, - &sshdr); - if (!err) - return SCSI_DH_IO; - - err = clariion_check_sense(sdev, &sshdr); - if (retry > 0 && err == NEEDS_RETRY) { - retry--; - goto retry; - } - sdev_printk(KERN_ERR, sdev, "%s: INQUIRY sense code " - "%02x/%02x/%02x\n", CLARIION_NAME, - sshdr.sense_key, sshdr.asc, sshdr.ascq); - err = SCSI_DH_IO; - } else { - err = parse_sp_info_reply(sdev, csdev); - } - return err; -} - -static int clariion_activate(struct scsi_device *sdev) -{ - struct clariion_dh_data *csdev = get_clariion_data(sdev); - int result; - - result = clariion_send_inquiry(sdev, csdev); - if (result != SCSI_DH_OK) - goto done; - - if (csdev->lun_state == CLARIION_LUN_OWNED) - goto done; - - result = send_trespass_cmd(sdev, csdev); - if (result != SCSI_DH_OK) - goto done; - sdev_printk(KERN_INFO, sdev,"%s: %s trespass command sent\n", - CLARIION_NAME, - csdev->flags&CLARIION_SHORT_TRESPASS?"short":"long" ); - - /* Update status */ - result = clariion_send_inquiry(sdev, csdev); - if (result != SCSI_DH_OK) - goto done; - -done: - sdev_printk(KERN_INFO, sdev, - "%s: at SP %c Port %d (%s, default SP %c)\n", - CLARIION_NAME, csdev->current_sp + 'A', - csdev->port, lun_state[csdev->lun_state], - csdev->default_sp + 'A'); - - return result; -} - -const struct scsi_dh_devlist clariion_dev_list[] = { +static const struct { + char *vendor; + char *model; +} clariion_dev_list[] = { {"DGC", "RAID"}, {"DGC", "DISK"}, - {"DGC", "VRAID"}, {NULL, NULL}, }; -static int clariion_bus_attach(struct scsi_device *sdev); -static void clariion_bus_detach(struct scsi_device *sdev); +static int clariion_bus_notify(struct notifier_block *, unsigned long, void *); static struct scsi_device_handler clariion_dh = { .name = CLARIION_NAME, .module = THIS_MODULE, - .devlist = clariion_dev_list, - .attach = clariion_bus_attach, - .detach = clariion_bus_detach, + .nb.notifier_call = clariion_bus_notify, .check_sense = clariion_check_sense, .activate = clariion_activate, - .prep_fn = clariion_prep_fn, }; /* * TODO: need some interface so we can set trespass values */ -static int clariion_bus_attach(struct scsi_device *sdev) +static int clariion_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) { + struct device *dev = data; + struct scsi_device *sdev; struct scsi_dh_data *scsi_dh_data; struct clariion_dh_data *h; + int i, found = 0; unsigned long flags; - int err; - scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) - + sizeof(*h) , GFP_KERNEL); - if (!scsi_dh_data) { - sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", - CLARIION_NAME); - return -ENOMEM; - } - - scsi_dh_data->scsi_dh = &clariion_dh; - h = (struct clariion_dh_data *) scsi_dh_data->buf; - h->lun_state = CLARIION_LUN_UNINITIALIZED; - h->default_sp = CLARIION_UNBOUND_LU; - h->current_sp = CLARIION_UNBOUND_LU; + if (!scsi_is_sdev_device(dev)) + return 0; - err = clariion_std_inquiry(sdev, h); - if (err != SCSI_DH_OK) - goto failed; + sdev = to_scsi_device(dev); - err = clariion_send_inquiry(sdev, h); - if (err != SCSI_DH_OK) - goto failed; - - if (!try_module_get(THIS_MODULE)) - goto failed; + if (action == BUS_NOTIFY_ADD_DEVICE) { + for (i = 0; clariion_dev_list[i].vendor; i++) { + if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor, + strlen(clariion_dev_list[i].vendor)) && + !strncmp(sdev->model, clariion_dev_list[i].model, + strlen(clariion_dev_list[i].model))) { + found = 1; + break; + } + } + if (!found) + goto out; + + scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) + + sizeof(*h) , GFP_KERNEL); + if (!scsi_dh_data) { + sdev_printk(KERN_ERR, sdev, "Attach failed %s.\n", + CLARIION_NAME); + goto out; + } - spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - sdev->scsi_dh_data = scsi_dh_data; - spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); + scsi_dh_data->scsi_dh = &clariion_dh; + h = (struct clariion_dh_data *) scsi_dh_data->buf; + h->default_sp = CLARIION_UNBOUND_LU; + h->current_sp = CLARIION_UNBOUND_LU; - sdev_printk(KERN_INFO, sdev, - "%s: connected to SP %c Port %d (%s, default SP %c)\n", - CLARIION_NAME, h->current_sp + 'A', - h->port, lun_state[h->lun_state], - h->default_sp + 'A'); + spin_lock_irqsave(sdev->request_queue->queue_lock, flags); + sdev->scsi_dh_data = scsi_dh_data; + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); - return 0; + sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", CLARIION_NAME); + try_module_get(THIS_MODULE); -failed: - kfree(scsi_dh_data); - sdev_printk(KERN_ERR, sdev, "%s: not attached\n", - CLARIION_NAME); - return -EINVAL; -} + } else if (action == BUS_NOTIFY_DEL_DEVICE) { + if (sdev->scsi_dh_data == NULL || + sdev->scsi_dh_data->scsi_dh != &clariion_dh) + goto out; -static void clariion_bus_detach(struct scsi_device *sdev) -{ - struct scsi_dh_data *scsi_dh_data; - unsigned long flags; + spin_lock_irqsave(sdev->request_queue->queue_lock, flags); + scsi_dh_data = sdev->scsi_dh_data; + sdev->scsi_dh_data = NULL; + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); - spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - scsi_dh_data = sdev->scsi_dh_data; - sdev->scsi_dh_data = NULL; - spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); + sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n", + CLARIION_NAME); - sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", - CLARIION_NAME); + kfree(scsi_dh_data); + module_put(THIS_MODULE); + } - kfree(scsi_dh_data); - module_put(THIS_MODULE); +out: + return 0; } static int __init clariion_init(void) @@ -660,8 +487,7 @@ static int __init clariion_init(void) r = scsi_register_device_handler(&clariion_dh); if (r != 0) - printk(KERN_ERR "%s: Failed to register scsi device handler.", - CLARIION_NAME); + printk(KERN_ERR "Failed to register scsi device handler."); return r; } diff --git a/trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 9c7a1f8ebb72..ae6be87d6a83 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -4,7 +4,6 @@ * * Copyright (C) 2006 Red Hat, Inc. All rights reserved. * Copyright (C) 2006 Mike Christie - * Copyright (C) 2008 Hannes Reinecke * * 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 @@ -26,18 +25,13 @@ #include #include -#define HP_SW_NAME "hp_sw" +#define HP_SW_NAME "hp_sw" -#define HP_SW_TIMEOUT (60 * HZ) -#define HP_SW_RETRIES 3 - -#define HP_SW_PATH_UNINITIALIZED -1 -#define HP_SW_PATH_ACTIVE 0 -#define HP_SW_PATH_PASSIVE 1 +#define HP_SW_TIMEOUT (60 * HZ) +#define HP_SW_RETRIES 3 struct hp_sw_dh_data { unsigned char sense[SCSI_SENSE_BUFFERSIZE]; - int path_state; int retries; }; @@ -48,161 +42,51 @@ static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev) return ((struct hp_sw_dh_data *) scsi_dh_data->buf); } -/* - * tur_done - Handle TEST UNIT READY return status - * @sdev: sdev the command has been sent to - * @errors: blk error code - * - * Returns SCSI_DH_DEV_OFFLINED if the sdev is on the passive path - */ -static int tur_done(struct scsi_device *sdev, unsigned char *sense) -{ - struct scsi_sense_hdr sshdr; - int ret; - - ret = scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr); - if (!ret) { - sdev_printk(KERN_WARNING, sdev, - "%s: sending tur failed, no sense available\n", - HP_SW_NAME); - ret = SCSI_DH_IO; - goto done; - } - switch (sshdr.sense_key) { - case UNIT_ATTENTION: - ret = SCSI_DH_IMM_RETRY; - break; - case NOT_READY: - if ((sshdr.asc == 0x04) && (sshdr.ascq == 2)) { - /* - * LUN not ready - Initialization command required - * - * This is the passive path - */ - ret = SCSI_DH_DEV_OFFLINED; - break; - } - /* Fallthrough */ - default: - sdev_printk(KERN_WARNING, sdev, - "%s: sending tur failed, sense %x/%x/%x\n", - HP_SW_NAME, sshdr.sense_key, sshdr.asc, - sshdr.ascq); - break; - } - -done: - return ret; -} - -/* - * hp_sw_tur - Send TEST UNIT READY - * @sdev: sdev command should be sent to - * - * Use the TEST UNIT READY command to determine - * the path state. - */ -static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) -{ - struct request *req; - int ret; - - req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); - if (!req) - return SCSI_DH_RES_TEMP_UNAVAIL; - - req->cmd_type = REQ_TYPE_BLOCK_PC; - req->cmd_flags |= REQ_FAILFAST; - req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY); - memset(req->cmd, 0, MAX_COMMAND_SIZE); - req->cmd[0] = TEST_UNIT_READY; - req->timeout = HP_SW_TIMEOUT; - req->sense = h->sense; - memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE); - req->sense_len = 0; - -retry: - ret = blk_execute_rq(req->q, NULL, req, 1); - if (ret == -EIO) { - if (req->sense_len > 0) { - ret = tur_done(sdev, h->sense); - } else { - sdev_printk(KERN_WARNING, sdev, - "%s: sending tur failed with %x\n", - HP_SW_NAME, req->errors); - ret = SCSI_DH_IO; - } - } else { - h->path_state = HP_SW_PATH_ACTIVE; - ret = SCSI_DH_OK; - } - if (ret == SCSI_DH_IMM_RETRY) - goto retry; - if (ret == SCSI_DH_DEV_OFFLINED) { - h->path_state = HP_SW_PATH_PASSIVE; - ret = SCSI_DH_OK; - } - - blk_put_request(req); - - return ret; -} - -/* - * start_done - Handle START STOP UNIT return status - * @sdev: sdev the command has been sent to - * @errors: blk error code - */ -static int start_done(struct scsi_device *sdev, unsigned char *sense) +static int hp_sw_done(struct scsi_device *sdev) { + struct hp_sw_dh_data *h = get_hp_sw_data(sdev); struct scsi_sense_hdr sshdr; int rc; - rc = scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr); - if (!rc) { - sdev_printk(KERN_WARNING, sdev, - "%s: sending start_stop_unit failed, " - "no sense available\n", - HP_SW_NAME); - return SCSI_DH_IO; - } + sdev_printk(KERN_INFO, sdev, "hp_sw_done\n"); + + rc = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sshdr); + if (!rc) + goto done; switch (sshdr.sense_key) { case NOT_READY: if ((sshdr.asc == 0x04) && (sshdr.ascq == 3)) { - /* - * LUN not ready - manual intervention required - * - * Switch-over in progress, retry. - */ rc = SCSI_DH_RETRY; + h->retries++; break; } /* fall through */ default: - sdev_printk(KERN_WARNING, sdev, - "%s: sending start_stop_unit failed, sense %x/%x/%x\n", - HP_SW_NAME, sshdr.sense_key, sshdr.asc, - sshdr.ascq); - rc = SCSI_DH_IO; + h->retries++; + rc = SCSI_DH_IMM_RETRY; } +done: + if (rc == SCSI_DH_OK || rc == SCSI_DH_IO) + h->retries = 0; + else if (h->retries > HP_SW_RETRIES) { + h->retries = 0; + rc = SCSI_DH_IO; + } return rc; } -/* - * hp_sw_start_stop - Send START STOP UNIT command - * @sdev: sdev command should be sent to - * - * Sending START STOP UNIT activates the SP. - */ -static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h) +static int hp_sw_activate(struct scsi_device *sdev) { + struct hp_sw_dh_data *h = get_hp_sw_data(sdev); struct request *req; - int ret, retry; + int ret = SCSI_DH_RES_TEMP_UNAVAIL; - req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); + req = blk_get_request(sdev->request_queue, WRITE, GFP_ATOMIC); if (!req) - return SCSI_DH_RES_TEMP_UNAVAIL; + goto done; + + sdev_printk(KERN_INFO, sdev, "sending START_STOP."); req->cmd_type = REQ_TYPE_BLOCK_PC; req->cmd_flags |= REQ_FAILFAST; @@ -214,153 +98,95 @@ static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h) req->sense = h->sense; memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE); req->sense_len = 0; - retry = h->retries; -retry: ret = blk_execute_rq(req->q, NULL, req, 1); - if (ret == -EIO) { - if (req->sense_len > 0) { - ret = start_done(sdev, h->sense); - } else { - sdev_printk(KERN_WARNING, sdev, - "%s: sending start_stop_unit failed with %x\n", - HP_SW_NAME, req->errors); - ret = SCSI_DH_IO; - } - } else - ret = SCSI_DH_OK; - - if (ret == SCSI_DH_RETRY) { - if (--retry) - goto retry; + if (!ret) /* SUCCESS */ + ret = hp_sw_done(sdev); + else ret = SCSI_DH_IO; - } - - blk_put_request(req); - - return ret; -} - -static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req) -{ - struct hp_sw_dh_data *h = get_hp_sw_data(sdev); - int ret = BLKPREP_OK; - - if (h->path_state != HP_SW_PATH_ACTIVE) { - ret = BLKPREP_KILL; - req->cmd_flags |= REQ_QUIET; - } - return ret; - -} - -/* - * hp_sw_activate - Activate a path - * @sdev: sdev on the path to be activated - * - * The HP Active/Passive firmware is pretty simple; - * the passive path reports NOT READY with sense codes - * 0x04/0x02; a START STOP UNIT command will then - * activate the passive path (and deactivate the - * previously active one). - */ -static int hp_sw_activate(struct scsi_device *sdev) -{ - int ret = SCSI_DH_OK; - struct hp_sw_dh_data *h = get_hp_sw_data(sdev); - - ret = hp_sw_tur(sdev, h); - - if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE) { - ret = hp_sw_start_stop(sdev, h); - if (ret == SCSI_DH_OK) - sdev_printk(KERN_INFO, sdev, - "%s: activated path\n", - HP_SW_NAME); - } - +done: return ret; } -const struct scsi_dh_devlist hp_sw_dh_data_list[] = { - {"COMPAQ", "MSA1000 VOLUME"}, - {"COMPAQ", "HSV110"}, - {"HP", "HSV100"}, +static const struct { + char *vendor; + char *model; +} hp_sw_dh_data_list[] = { + {"COMPAQ", "MSA"}, + {"HP", "HSV"}, {"DEC", "HSG80"}, {NULL, NULL}, }; -static int hp_sw_bus_attach(struct scsi_device *sdev); -static void hp_sw_bus_detach(struct scsi_device *sdev); +static int hp_sw_bus_notify(struct notifier_block *, unsigned long, void *); static struct scsi_device_handler hp_sw_dh = { .name = HP_SW_NAME, .module = THIS_MODULE, - .devlist = hp_sw_dh_data_list, - .attach = hp_sw_bus_attach, - .detach = hp_sw_bus_detach, + .nb.notifier_call = hp_sw_bus_notify, .activate = hp_sw_activate, - .prep_fn = hp_sw_prep_fn, }; -static int hp_sw_bus_attach(struct scsi_device *sdev) +static int hp_sw_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) { + struct device *dev = data; + struct scsi_device *sdev; struct scsi_dh_data *scsi_dh_data; - struct hp_sw_dh_data *h; + int i, found = 0; unsigned long flags; - int ret; - scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) - + sizeof(struct hp_sw_dh_data) , GFP_KERNEL); - if (!scsi_dh_data) { - sdev_printk(KERN_ERR, sdev, "%s: Attach Failed\n", - HP_SW_NAME); + if (!scsi_is_sdev_device(dev)) return 0; - } - scsi_dh_data->scsi_dh = &hp_sw_dh; - h = (struct hp_sw_dh_data *) scsi_dh_data->buf; - h->path_state = HP_SW_PATH_UNINITIALIZED; - h->retries = HP_SW_RETRIES; + sdev = to_scsi_device(dev); + + if (action == BUS_NOTIFY_ADD_DEVICE) { + for (i = 0; hp_sw_dh_data_list[i].vendor; i++) { + if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor, + strlen(hp_sw_dh_data_list[i].vendor)) && + !strncmp(sdev->model, hp_sw_dh_data_list[i].model, + strlen(hp_sw_dh_data_list[i].model))) { + found = 1; + break; + } + } + if (!found) + goto out; - ret = hp_sw_tur(sdev, h); - if (ret != SCSI_DH_OK || h->path_state == HP_SW_PATH_UNINITIALIZED) - goto failed; + scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) + + sizeof(struct hp_sw_dh_data) , GFP_KERNEL); + if (!scsi_dh_data) { + sdev_printk(KERN_ERR, sdev, "Attach Failed %s.\n", + HP_SW_NAME); + goto out; + } - if (!try_module_get(THIS_MODULE)) - goto failed; + scsi_dh_data->scsi_dh = &hp_sw_dh; + spin_lock_irqsave(sdev->request_queue->queue_lock, flags); + sdev->scsi_dh_data = scsi_dh_data; + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); + try_module_get(THIS_MODULE); - spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - sdev->scsi_dh_data = scsi_dh_data; - spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); + sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", HP_SW_NAME); + } else if (action == BUS_NOTIFY_DEL_DEVICE) { + if (sdev->scsi_dh_data == NULL || + sdev->scsi_dh_data->scsi_dh != &hp_sw_dh) + goto out; - sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n", - HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE? - "active":"passive"); + spin_lock_irqsave(sdev->request_queue->queue_lock, flags); + scsi_dh_data = sdev->scsi_dh_data; + sdev->scsi_dh_data = NULL; + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); + module_put(THIS_MODULE); - return 0; + sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n", HP_SW_NAME); -failed: - kfree(scsi_dh_data); - sdev_printk(KERN_ERR, sdev, "%s: not attached\n", - HP_SW_NAME); - return -EINVAL; -} - -static void hp_sw_bus_detach( struct scsi_device *sdev ) -{ - struct scsi_dh_data *scsi_dh_data; - unsigned long flags; - - spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - scsi_dh_data = sdev->scsi_dh_data; - sdev->scsi_dh_data = NULL; - spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); - module_put(THIS_MODULE); - - sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", HP_SW_NAME); + kfree(scsi_dh_data); + } - kfree(scsi_dh_data); +out: + return 0; } static int __init hp_sw_init(void) @@ -376,6 +202,6 @@ static void __exit hp_sw_exit(void) module_init(hp_sw_init); module_exit(hp_sw_exit); -MODULE_DESCRIPTION("HP Active/Passive driver"); +MODULE_DESCRIPTION("HP MSA 1000"); MODULE_AUTHOR("Mike Christie request_queue; + struct rdac_dh_data *h = get_rdac_data(sdev); - rq = blk_get_request(q, rw, GFP_NOIO); + rq = blk_get_request(q, rw, GFP_KERNEL); if (!rq) { sdev_printk(KERN_INFO, sdev, @@ -218,14 +207,17 @@ static struct request *get_rdac_req(struct scsi_device *sdev, return NULL; } - if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) { + if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_KERNEL)) { blk_put_request(rq); sdev_printk(KERN_INFO, sdev, "get_rdac_req: blk_rq_map_kern failed.\n"); return NULL; } - memset(rq->cmd, 0, BLK_MAX_CDB); + memset(&rq->cmd, 0, BLK_MAX_CDB); + rq->sense = h->sense; + memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); + rq->sense_len = 0; rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; @@ -235,12 +227,12 @@ static struct request *get_rdac_req(struct scsi_device *sdev, return rq; } -static struct request *rdac_failover_get(struct scsi_device *sdev, - struct rdac_dh_data *h) +static struct request *rdac_failover_get(struct scsi_device *sdev) { struct request *rq; struct rdac_mode_common *common; unsigned data_size; + struct rdac_dh_data *h = get_rdac_data(sdev); if (h->ctlr->use_ms10) { struct rdac_pg_expanded *rdac_pg; @@ -285,10 +277,6 @@ static struct request *rdac_failover_get(struct scsi_device *sdev, } rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = 0; - return rq; } @@ -333,10 +321,11 @@ static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id) } static int submit_inquiry(struct scsi_device *sdev, int page_code, - unsigned int len, struct rdac_dh_data *h) + unsigned int len) { struct request *rq; struct request_queue *q = sdev->request_queue; + struct rdac_dh_data *h = get_rdac_data(sdev); int err = SCSI_DH_RES_TEMP_UNAVAIL; rq = get_rdac_req(sdev, &h->inq, len, READ); @@ -349,68 +338,59 @@ static int submit_inquiry(struct scsi_device *sdev, int page_code, rq->cmd[2] = page_code; rq->cmd[4] = len; rq->cmd_len = COMMAND_SIZE(INQUIRY); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = 0; - err = blk_execute_rq(q, NULL, rq, 1); if (err == -EIO) err = SCSI_DH_IO; - - blk_put_request(rq); done: return err; } -static int get_lun(struct scsi_device *sdev, struct rdac_dh_data *h) +static int get_lun(struct scsi_device *sdev) { int err; struct c8_inquiry *inqp; + struct rdac_dh_data *h = get_rdac_data(sdev); - err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry), h); + err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry)); if (err == SCSI_DH_OK) { inqp = &h->inq.c8; - if (inqp->page_code != 0xc8) - return SCSI_DH_NOSYS; - if (inqp->page_id[0] != 'e' || inqp->page_id[1] != 'd' || - inqp->page_id[2] != 'i' || inqp->page_id[3] != 'd') - return SCSI_DH_NOSYS; - h->lun = scsilun_to_int((struct scsi_lun *)inqp->lun); + h->lun = inqp->lun[7]; /* currently it uses only one byte */ } return err; } -static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h) +#define RDAC_OWNED 0 +#define RDAC_UNOWNED 1 +#define RDAC_FAILED 2 +static int check_ownership(struct scsi_device *sdev) { int err; struct c9_inquiry *inqp; + struct rdac_dh_data *h = get_rdac_data(sdev); - err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h); + err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry)); if (err == SCSI_DH_OK) { + err = RDAC_UNOWNED; inqp = &h->inq.c9; - if ((inqp->avte_cvp >> 7) == 0x1) { - /* LUN in AVT mode */ - sdev_printk(KERN_NOTICE, sdev, - "%s: AVT mode detected\n", - RDAC_NAME); - h->lun_state = RDAC_LUN_AVT; - } else if ((inqp->avte_cvp & 0x1) != 0) { - /* LUN was owned by the controller */ - h->lun_state = RDAC_LUN_OWNED; - } - } - + /* + * If in AVT mode or if the path already owns the LUN, + * return RDAC_OWNED; + */ + if (((inqp->avte_cvp >> 7) == 0x1) || + ((inqp->avte_cvp & 0x1) != 0)) + err = RDAC_OWNED; + } else + err = RDAC_FAILED; return err; } -static int initialize_controller(struct scsi_device *sdev, - struct rdac_dh_data *h) +static int initialize_controller(struct scsi_device *sdev) { int err; struct c4_inquiry *inqp; + struct rdac_dh_data *h = get_rdac_data(sdev); - err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h); + err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry)); if (err == SCSI_DH_OK) { inqp = &h->inq.c4; h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id); @@ -420,12 +400,13 @@ static int initialize_controller(struct scsi_device *sdev, return err; } -static int set_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h) +static int set_mode_select(struct scsi_device *sdev) { int err; struct c2_inquiry *inqp; + struct rdac_dh_data *h = get_rdac_data(sdev); - err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry), h); + err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry)); if (err == SCSI_DH_OK) { inqp = &h->inq.c2; /* @@ -440,13 +421,13 @@ static int set_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h) return err; } -static int mode_select_handle_sense(struct scsi_device *sdev, - unsigned char *sensebuf) +static int mode_select_handle_sense(struct scsi_device *sdev) { struct scsi_sense_hdr sense_hdr; + struct rdac_dh_data *h = get_rdac_data(sdev); int sense, err = SCSI_DH_IO, ret; - ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr); + ret = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr); if (!ret) goto done; @@ -470,13 +451,14 @@ static int mode_select_handle_sense(struct scsi_device *sdev, return err; } -static int send_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h) +static int send_mode_select(struct scsi_device *sdev) { struct request *rq; struct request_queue *q = sdev->request_queue; + struct rdac_dh_data *h = get_rdac_data(sdev); int err = SCSI_DH_RES_TEMP_UNAVAIL; - rq = rdac_failover_get(sdev, h); + rq = rdac_failover_get(sdev); if (!rq) goto done; @@ -484,11 +466,9 @@ static int send_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h) err = blk_execute_rq(q, NULL, rq, 1); if (err != SCSI_DH_OK) - err = mode_select_handle_sense(sdev, h->sense); + err = mode_select_handle_sense(sdev); if (err == SCSI_DH_OK) h->state = RDAC_STATE_ACTIVE; - - blk_put_request(rq); done: return err; } @@ -498,23 +478,38 @@ static int rdac_activate(struct scsi_device *sdev) struct rdac_dh_data *h = get_rdac_data(sdev); int err = SCSI_DH_OK; - err = check_ownership(sdev, h); - if (err != SCSI_DH_OK) + if (h->lun == UNINITIALIZED_LUN) { + err = get_lun(sdev); + if (err != SCSI_DH_OK) + goto done; + } + + err = check_ownership(sdev); + switch (err) { + case RDAC_UNOWNED: + break; + case RDAC_OWNED: + err = SCSI_DH_OK; goto done; + case RDAC_FAILED: + default: + err = SCSI_DH_IO; + goto done; + } if (!h->ctlr) { - err = initialize_controller(sdev, h); + err = initialize_controller(sdev); if (err != SCSI_DH_OK) goto done; } if (h->ctlr->use_ms10 == -1) { - err = set_mode_select(sdev, h); + err = set_mode_select(sdev); if (err != SCSI_DH_OK) goto done; } - if (h->lun_state == RDAC_LUN_UNOWNED) - err = send_mode_select(sdev, h); + + err = send_mode_select(sdev); done: return err; } @@ -574,7 +569,10 @@ static int rdac_check_sense(struct scsi_device *sdev, return SCSI_RETURN_NOT_HANDLED; } -const struct scsi_dh_devlist rdac_dev_list[] = { +static const struct { + char *vendor; + char *model; +} rdac_dev_list[] = { {"IBM", "1722"}, {"IBM", "1724"}, {"IBM", "1726"}, @@ -592,89 +590,89 @@ const struct scsi_dh_devlist rdac_dev_list[] = { {NULL, NULL}, }; -static int rdac_bus_attach(struct scsi_device *sdev); -static void rdac_bus_detach(struct scsi_device *sdev); +static int rdac_bus_notify(struct notifier_block *, unsigned long, void *); static struct scsi_device_handler rdac_dh = { .name = RDAC_NAME, .module = THIS_MODULE, - .devlist = rdac_dev_list, + .nb.notifier_call = rdac_bus_notify, .prep_fn = rdac_prep_fn, .check_sense = rdac_check_sense, - .attach = rdac_bus_attach, - .detach = rdac_bus_detach, .activate = rdac_activate, }; -static int rdac_bus_attach(struct scsi_device *sdev) +/* + * TODO: need some interface so we can set trespass values + */ +static int rdac_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) { + struct device *dev = data; + struct scsi_device *sdev; struct scsi_dh_data *scsi_dh_data; struct rdac_dh_data *h; + int i, found = 0; unsigned long flags; - int err; - scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) - + sizeof(*h) , GFP_KERNEL); - if (!scsi_dh_data) { - sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n", - RDAC_NAME); + if (!scsi_is_sdev_device(dev)) return 0; - } - scsi_dh_data->scsi_dh = &rdac_dh; - h = (struct rdac_dh_data *) scsi_dh_data->buf; - h->lun = UNINITIALIZED_LUN; - h->state = RDAC_STATE_ACTIVE; - - err = get_lun(sdev, h); - if (err != SCSI_DH_OK) - goto failed; - - err = check_ownership(sdev, h); - if (err != SCSI_DH_OK) - goto failed; - - if (!try_module_get(THIS_MODULE)) - goto failed; + sdev = to_scsi_device(dev); + + if (action == BUS_NOTIFY_ADD_DEVICE) { + for (i = 0; rdac_dev_list[i].vendor; i++) { + if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor, + strlen(rdac_dev_list[i].vendor)) && + !strncmp(sdev->model, rdac_dev_list[i].model, + strlen(rdac_dev_list[i].model))) { + found = 1; + break; + } + } + if (!found) + goto out; - spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - sdev->scsi_dh_data = scsi_dh_data; - spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); + scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *) + + sizeof(*h) , GFP_KERNEL); + if (!scsi_dh_data) { + sdev_printk(KERN_ERR, sdev, "Attach failed %s.\n", + RDAC_NAME); + goto out; + } - sdev_printk(KERN_NOTICE, sdev, - "%s: LUN %d (%s)\n", - RDAC_NAME, h->lun, lun_state[(int)h->lun_state]); + scsi_dh_data->scsi_dh = &rdac_dh; + h = (struct rdac_dh_data *) scsi_dh_data->buf; + h->lun = UNINITIALIZED_LUN; + h->state = RDAC_STATE_ACTIVE; + spin_lock_irqsave(sdev->request_queue->queue_lock, flags); + sdev->scsi_dh_data = scsi_dh_data; + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); + try_module_get(THIS_MODULE); + + sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", RDAC_NAME); + + } else if (action == BUS_NOTIFY_DEL_DEVICE) { + if (sdev->scsi_dh_data == NULL || + sdev->scsi_dh_data->scsi_dh != &rdac_dh) + goto out; + + spin_lock_irqsave(sdev->request_queue->queue_lock, flags); + scsi_dh_data = sdev->scsi_dh_data; + sdev->scsi_dh_data = NULL; + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); + + h = (struct rdac_dh_data *) scsi_dh_data->buf; + if (h->ctlr) + kref_put(&h->ctlr->kref, release_controller); + kfree(scsi_dh_data); + module_put(THIS_MODULE); + sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n", RDAC_NAME); + } +out: return 0; - -failed: - kfree(scsi_dh_data); - sdev_printk(KERN_ERR, sdev, "%s: not attached\n", - RDAC_NAME); - return -EINVAL; -} - -static void rdac_bus_detach( struct scsi_device *sdev ) -{ - struct scsi_dh_data *scsi_dh_data; - struct rdac_dh_data *h; - unsigned long flags; - - spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - scsi_dh_data = sdev->scsi_dh_data; - sdev->scsi_dh_data = NULL; - spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); - - h = (struct rdac_dh_data *) scsi_dh_data->buf; - if (h->ctlr) - kref_put(&h->ctlr->kref, release_controller); - kfree(scsi_dh_data); - module_put(THIS_MODULE); - sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", RDAC_NAME); } - - static int __init rdac_init(void) { int r; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c index ae560bc04f9d..c4a7c06793c5 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c @@ -521,10 +521,9 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost, static void ibmvfc_reinit_host(struct ibmvfc_host *vhost) { if (vhost->action == IBMVFC_HOST_ACTION_NONE) { - if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) { - scsi_block_requests(vhost->host); - ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); - } + scsi_block_requests(vhost->host); + ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING); + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); } else vhost->reinit = 1; @@ -855,41 +854,39 @@ static void ibmvfc_retry_host_init(struct ibmvfc_host *vhost) } /** - * __ibmvfc_get_target - Find the specified scsi_target (no locking) + * __ibmvfc_find_target - Find the specified scsi_target (no locking) * @starget: scsi target struct * * Return value: * ibmvfc_target struct / NULL if not found **/ -static struct ibmvfc_target *__ibmvfc_get_target(struct scsi_target *starget) +static struct ibmvfc_target *__ibmvfc_find_target(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct ibmvfc_host *vhost = shost_priv(shost); struct ibmvfc_target *tgt; list_for_each_entry(tgt, &vhost->targets, queue) - if (tgt->target_id == starget->id) { - kref_get(&tgt->kref); + if (tgt->target_id == starget->id) return tgt; - } return NULL; } /** - * ibmvfc_get_target - Find the specified scsi_target + * ibmvfc_find_target - Find the specified scsi_target * @starget: scsi target struct * * Return value: * ibmvfc_target struct / NULL if not found **/ -static struct ibmvfc_target *ibmvfc_get_target(struct scsi_target *starget) +static struct ibmvfc_target *ibmvfc_find_target(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct ibmvfc_target *tgt; unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); - tgt = __ibmvfc_get_target(starget); + tgt = __ibmvfc_find_target(starget); spin_unlock_irqrestore(shost->host_lock, flags); return tgt; } @@ -966,9 +963,6 @@ static void ibmvfc_get_host_port_state(struct Scsi_Host *shost) case IBMVFC_HALTED: fc_host_port_state(shost) = FC_PORTSTATE_BLOCKED; break; - case IBMVFC_NO_CRQ: - fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; - break; default: ibmvfc_log(vhost, 3, "Unknown port state: %d\n", vhost->state); fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; @@ -993,17 +987,6 @@ static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) rport->dev_loss_tmo = 1; } -/** - * ibmvfc_release_tgt - Free memory allocated for a target - * @kref: kref struct - * - **/ -static void ibmvfc_release_tgt(struct kref *kref) -{ - struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); - kfree(tgt); -} - /** * ibmvfc_get_starget_node_name - Get SCSI target's node name * @starget: scsi target struct @@ -1013,10 +996,8 @@ static void ibmvfc_release_tgt(struct kref *kref) **/ static void ibmvfc_get_starget_node_name(struct scsi_target *starget) { - struct ibmvfc_target *tgt = ibmvfc_get_target(starget); + struct ibmvfc_target *tgt = ibmvfc_find_target(starget); fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; - if (tgt) - kref_put(&tgt->kref, ibmvfc_release_tgt); } /** @@ -1028,10 +1009,8 @@ static void ibmvfc_get_starget_node_name(struct scsi_target *starget) **/ static void ibmvfc_get_starget_port_name(struct scsi_target *starget) { - struct ibmvfc_target *tgt = ibmvfc_get_target(starget); + struct ibmvfc_target *tgt = ibmvfc_find_target(starget); fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; - if (tgt) - kref_put(&tgt->kref, ibmvfc_release_tgt); } /** @@ -1043,10 +1022,8 @@ static void ibmvfc_get_starget_port_name(struct scsi_target *starget) **/ static void ibmvfc_get_starget_port_id(struct scsi_target *starget) { - struct ibmvfc_target *tgt = ibmvfc_get_target(starget); + struct ibmvfc_target *tgt = ibmvfc_find_target(starget); fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; - if (tgt) - kref_put(&tgt->kref, ibmvfc_release_tgt); } /** @@ -1136,7 +1113,7 @@ static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ; login_info->capabilities = IBMVFC_CAN_MIGRATE; login_info->async.va = vhost->async_crq.msg_token; - login_info->async.len = vhost->async_crq.size * sizeof(*vhost->async_crq.msgs); + login_info->async.len = vhost->async_crq.size; strncpy(login_info->partition_name, vhost->partition_name, IBMVFC_MAX_NAME); strncpy(login_info->device_name, vhost->host->shost_gendev.bus_id, IBMVFC_MAX_NAME); @@ -1427,7 +1404,7 @@ static void ibmvfc_log_error(struct ibmvfc_event *evt) err = cmd_status[index].name; } - if (!logerr && (vhost->log_level <= (IBMVFC_DEFAULT_LOG_LEVEL + 1))) + if (!logerr && (vhost->log_level <= IBMVFC_DEFAULT_LOG_LEVEL)) return; if (rsp->flags & FCP_RSP_LEN_VALID) @@ -2077,7 +2054,7 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, { const char *desc = ibmvfc_get_ae_desc(crq->event); - ibmvfc_log(vhost, 3, "%s event received\n", desc); + ibmvfc_log(vhost, 2, "%s event received\n", desc); switch (crq->event) { case IBMVFC_AE_LINK_UP: @@ -2670,6 +2647,17 @@ static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt, ibmvfc_init_tgt(tgt, job_step); } +/** + * ibmvfc_release_tgt - Free memory allocated for a target + * @kref: kref struct + * + **/ +static void ibmvfc_release_tgt(struct kref *kref) +{ + struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); + kfree(tgt); +} + /** * ibmvfc_tgt_prli_done - Completion handler for Process Login * @evt: ibmvfc event struct @@ -2913,139 +2901,6 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) tgt_dbg(tgt, "Sent Implicit Logout\n"); } -/** - * ibmvfc_adisc_needs_plogi - Does device need PLOGI? - * @mad: ibmvfc passthru mad struct - * @tgt: ibmvfc target struct - * - * Returns: - * 1 if PLOGI needed / 0 if PLOGI not needed - **/ -static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad, - struct ibmvfc_target *tgt) -{ - if (memcmp(&mad->fc_iu.response[2], &tgt->ids.port_name, - sizeof(tgt->ids.port_name))) - return 1; - if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name, - sizeof(tgt->ids.node_name))) - return 1; - if (mad->fc_iu.response[6] != tgt->scsi_id) - return 1; - return 0; -} - -/** - * ibmvfc_tgt_adisc_done - Completion handler for ADISC - * @evt: ibmvfc event struct - * - **/ -static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt) -{ - struct ibmvfc_target *tgt = evt->tgt; - struct ibmvfc_host *vhost = evt->vhost; - struct ibmvfc_passthru_mad *mad = &evt->xfer_iu->passthru; - u32 status = mad->common.status; - u8 fc_reason, fc_explain; - - vhost->discovery_threads--; - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); - - switch (status) { - case IBMVFC_MAD_SUCCESS: - tgt_dbg(tgt, "ADISC succeeded\n"); - if (ibmvfc_adisc_needs_plogi(mad, tgt)) - tgt->need_login = 1; - break; - case IBMVFC_MAD_DRIVER_FAILED: - break; - case IBMVFC_MAD_FAILED: - default: - tgt->need_login = 1; - fc_reason = (mad->fc_iu.response[1] & 0x00ff0000) >> 16; - fc_explain = (mad->fc_iu.response[1] & 0x0000ff00) >> 8; - tgt_info(tgt, "ADISC failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n", - ibmvfc_get_cmd_error(mad->iu.status, mad->iu.error), - mad->iu.status, mad->iu.error, - ibmvfc_get_fc_type(fc_reason), fc_reason, - ibmvfc_get_ls_explain(fc_explain), fc_explain, status); - break; - }; - - kref_put(&tgt->kref, ibmvfc_release_tgt); - ibmvfc_free_event(evt); - wake_up(&vhost->work_wait_q); -} - -/** - * ibmvfc_init_passthru - Initialize an event struct for FC passthru - * @evt: ibmvfc event struct - * - **/ -static void ibmvfc_init_passthru(struct ibmvfc_event *evt) -{ - struct ibmvfc_passthru_mad *mad = &evt->iu.passthru; - - memset(mad, 0, sizeof(*mad)); - mad->common.version = 1; - mad->common.opcode = IBMVFC_PASSTHRU; - mad->common.length = sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu); - mad->cmd_ioba.va = (u64)evt->crq.ioba + - offsetof(struct ibmvfc_passthru_mad, iu); - mad->cmd_ioba.len = sizeof(mad->iu); - mad->iu.cmd_len = sizeof(mad->fc_iu.payload); - mad->iu.rsp_len = sizeof(mad->fc_iu.response); - mad->iu.cmd.va = (u64)evt->crq.ioba + - offsetof(struct ibmvfc_passthru_mad, fc_iu) + - offsetof(struct ibmvfc_passthru_fc_iu, payload); - mad->iu.cmd.len = sizeof(mad->fc_iu.payload); - mad->iu.rsp.va = (u64)evt->crq.ioba + - offsetof(struct ibmvfc_passthru_mad, fc_iu) + - offsetof(struct ibmvfc_passthru_fc_iu, response); - mad->iu.rsp.len = sizeof(mad->fc_iu.response); -} - -/** - * ibmvfc_tgt_adisc - Initiate an ADISC for specified target - * @tgt: ibmvfc target struct - * - **/ -static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt) -{ - struct ibmvfc_passthru_mad *mad; - struct ibmvfc_host *vhost = tgt->vhost; - struct ibmvfc_event *evt; - - if (vhost->discovery_threads >= disc_threads) - return; - - kref_get(&tgt->kref); - evt = ibmvfc_get_event(vhost); - vhost->discovery_threads++; - ibmvfc_init_event(evt, ibmvfc_tgt_adisc_done, IBMVFC_MAD_FORMAT); - evt->tgt = tgt; - - ibmvfc_init_passthru(evt); - mad = &evt->iu.passthru; - mad->iu.flags = IBMVFC_FC_ELS; - mad->iu.scsi_id = tgt->scsi_id; - - mad->fc_iu.payload[0] = IBMVFC_ADISC; - memcpy(&mad->fc_iu.payload[2], &vhost->login_buf->resp.port_name, - sizeof(vhost->login_buf->resp.port_name)); - memcpy(&mad->fc_iu.payload[4], &vhost->login_buf->resp.node_name, - sizeof(vhost->login_buf->resp.node_name)); - mad->fc_iu.payload[6] = vhost->login_buf->resp.scsi_id & 0x00ffffff; - - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); - if (ibmvfc_send_event(evt, vhost, default_timeout)) { - vhost->discovery_threads--; - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); - kref_put(&tgt->kref, ibmvfc_release_tgt); - } else - tgt_dbg(tgt, "Sent ADISC\n"); -} - /** * ibmvfc_tgt_query_target_done - Completion handler for Query Target MAD * @evt: ibmvfc event struct @@ -3066,8 +2921,6 @@ static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt) tgt->new_scsi_id = rsp->scsi_id; if (rsp->scsi_id != tgt->scsi_id) ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); - else - ibmvfc_init_tgt(tgt, ibmvfc_tgt_adisc); break; case IBMVFC_MAD_DRIVER_FAILED: break; @@ -3483,7 +3336,6 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) tgt_dbg(tgt, "rport add succeeded\n"); rport->maxframe_size = tgt->service_parms.common.bb_rcv_sz & 0x0fff; rport->supported_classes = 0; - tgt->target_id = rport->scsi_target_id; if (tgt->service_parms.class1_parms[0] & 0x80000000) rport->supported_classes |= FC_COS_CLASS1; if (tgt->service_parms.class2_parms[0] & 0x80000000) @@ -3673,7 +3525,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost) crq->msg_token = dma_map_single(dev, crq->msgs, PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(dev, crq->msg_token)) + if (dma_mapping_error(crq->msg_token)) goto map_failed; retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, @@ -3766,7 +3618,7 @@ static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost) async_q->size * sizeof(*async_q->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(dev, async_q->msg_token)) { + if (dma_mapping_error(async_q->msg_token)) { dev_err(dev, "Failed to map async queue\n"); goto free_async_crq; } @@ -3948,12 +3800,10 @@ static int ibmvfc_remove(struct vio_dev *vdev) ENTER; ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); - ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE); - ibmvfc_wait_while_resetting(vhost); - ibmvfc_release_crq_queue(vhost); kthread_stop(vhost->work_thread); fc_remove_host(vhost->host); scsi_remove_host(vhost->host); + ibmvfc_release_crq_queue(vhost); spin_lock_irqsave(vhost->host->host_lock, flags); ibmvfc_purge_requests(vhost, DID_ERROR); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.h b/trunk/drivers/scsi/ibmvscsi/ibmvfc.h index 4bf6e374f076..057f3c01ed61 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.h @@ -29,8 +29,8 @@ #include "viosrp.h" #define IBMVFC_NAME "ibmvfc" -#define IBMVFC_DRIVER_VERSION "1.0.1" -#define IBMVFC_DRIVER_DATE "(July 11, 2008)" +#define IBMVFC_DRIVER_VERSION "1.0.0" +#define IBMVFC_DRIVER_DATE "(July 1, 2008)" #define IBMVFC_DEFAULT_TIMEOUT 15 #define IBMVFC_INIT_TIMEOUT 30 @@ -119,7 +119,6 @@ enum ibmvfc_mad_types { IBMVFC_PROCESS_LOGIN = 0x0008, IBMVFC_QUERY_TARGET = 0x0010, IBMVFC_IMPLICIT_LOGOUT = 0x0040, - IBMVFC_PASSTHRU = 0x0200, IBMVFC_TMF_MAD = 0x0100, }; @@ -440,37 +439,6 @@ struct ibmvfc_cmd { struct ibmvfc_fcp_rsp rsp; }__attribute__((packed, aligned (8))); -struct ibmvfc_passthru_fc_iu { - u32 payload[7]; -#define IBMVFC_ADISC 0x52000000 - u32 response[7]; -}; - -struct ibmvfc_passthru_iu { - u64 task_tag; - u32 cmd_len; - u32 rsp_len; - u16 status; - u16 error; - u32 flags; -#define IBMVFC_FC_ELS 0x01 - u32 cancel_key; - u32 reserved; - struct srp_direct_buf cmd; - struct srp_direct_buf rsp; - u64 correlation; - u64 scsi_id; - u64 tag; - u64 reserved2[2]; -}__attribute__((packed, aligned (8))); - -struct ibmvfc_passthru_mad { - struct ibmvfc_mad_common common; - struct srp_direct_buf cmd_ioba; - struct ibmvfc_passthru_iu iu; - struct ibmvfc_passthru_fc_iu fc_iu; -}__attribute__((packed, aligned (8))); - struct ibmvfc_trace_start_entry { u32 xfer_len; }__attribute__((packed)); @@ -563,7 +531,6 @@ union ibmvfc_iu { struct ibmvfc_implicit_logout implicit_logout; struct ibmvfc_tmf tmf; struct ibmvfc_cmd cmd; - struct ibmvfc_passthru_mad passthru; }__attribute__((packed, aligned (8))); enum ibmvfc_target_action { @@ -689,9 +656,6 @@ struct ibmvfc_host { #define tgt_dbg(t, fmt, ...) \ DBG_CMD(dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__)) -#define tgt_info(t, fmt, ...) \ - dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__) - #define tgt_err(t, fmt, ...) \ dev_err((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__) @@ -704,8 +668,8 @@ struct ibmvfc_host { dev_err((vhost)->dev, ##__VA_ARGS__); \ } while (0) -#define ENTER DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Entering %s\n", __func__)) -#define LEAVE DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Leaving %s\n", __func__)) +#define ENTER DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Entering %s\n", __FUNCTION__)) +#define LEAVE DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Leaving %s\n", __FUNCTION__)) #ifdef CONFIG_SCSI_IBMVFC_TRACE #define ibmvfc_create_trace_file(kobj, attr) sysfs_create_bin_file(kobj, attr) diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index 6b24b9cdb04c..20000ec79b04 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -859,7 +859,7 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) sizeof(hostdata->madapter_info), DMA_BIDIRECTIONAL); - if (dma_mapping_error(hostdata->dev, req->buffer)) { + if (dma_mapping_error(req->buffer)) { if (!firmware_has_feature(FW_FEATURE_CMO)) dev_err(hostdata->dev, "Unable to map request_buffer for " @@ -1407,7 +1407,7 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, length, DMA_BIDIRECTIONAL); - if (dma_mapping_error(hostdata->dev, host_config->buffer)) { + if (dma_mapping_error(host_config->buffer)) { if (!firmware_has_feature(FW_FEATURE_CMO)) dev_err(hostdata->dev, "dma_mapping error getting host config\n"); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c b/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c index 2a5b29d12172..3b9514c8f1f1 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -55,7 +55,7 @@ /* tmp - will replace with SCSI logging stuff */ #define eprintk(fmt, args...) \ do { \ - printk("%s(%d) " fmt, __func__, __LINE__, ##args); \ + printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ } while (0) /* #define dprintk eprintk */ #define dprintk(fmt, args...) @@ -564,7 +564,7 @@ static int crq_queue_create(struct crq_queue *queue, struct srp_target *target) queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(target->dev, queue->msg_token)) + if (dma_mapping_error(queue->msg_token)) goto map_failed; err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, diff --git a/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c b/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c index 462a8574dad9..182146100dc1 100644 --- a/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -253,7 +253,7 @@ static int rpavscsi_init_crq_queue(struct crq_queue *queue, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(hostdata->dev, queue->msg_token)) + if (dma_mapping_error(queue->msg_token)) goto map_failed; gather_partition_info(); diff --git a/trunk/drivers/scsi/imm.c b/trunk/drivers/scsi/imm.c index c2a9a13d788f..f97d172844be 100644 --- a/trunk/drivers/scsi/imm.c +++ b/trunk/drivers/scsi/imm.c @@ -163,7 +163,7 @@ static int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start, #if IMM_DEBUG > 0 #define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\ - y, __func__, __LINE__); imm_fail_func(x,y); + y, __FUNCTION__, __LINE__); imm_fail_func(x,y); static inline void imm_fail_func(imm_struct *dev, int error_code) #else diff --git a/trunk/drivers/scsi/ipr.h b/trunk/drivers/scsi/ipr.h index 4871dd1f2582..d93156671e93 100644 --- a/trunk/drivers/scsi/ipr.h +++ b/trunk/drivers/scsi/ipr.h @@ -1403,10 +1403,10 @@ struct ipr_ucode_image_header { } #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ - __FILE__, __func__, __LINE__) + __FILE__, __FUNCTION__, __LINE__) -#define ENTER IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Entering %s\n", __func__)) -#define LEAVE IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Leaving %s\n", __func__)) +#define ENTER IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Entering %s\n", __FUNCTION__)) +#define LEAVE IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Leaving %s\n", __FUNCTION__)) #define ipr_err_separator \ ipr_err("----------------------------------------------------------\n") diff --git a/trunk/drivers/scsi/libsas/sas_ata.c b/trunk/drivers/scsi/libsas/sas_ata.c index 48ee8c7f5bdd..744f06d04a36 100644 --- a/trunk/drivers/scsi/libsas/sas_ata.c +++ b/trunk/drivers/scsi/libsas/sas_ata.c @@ -74,7 +74,7 @@ static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts) case SAS_OPEN_TO: case SAS_OPEN_REJECT: SAS_DPRINTK("%s: Saw error %d. What to do?\n", - __func__, ts->stat); + __FUNCTION__, ts->stat); return AC_ERR_OTHER; case SAS_ABORTED_TASK: @@ -115,7 +115,7 @@ static void sas_ata_task_done(struct sas_task *task) } else if (stat->stat != SAM_STAT_GOOD) { ac = sas_to_ata_err(stat); if (ac) { - SAS_DPRINTK("%s: SAS error %x\n", __func__, + SAS_DPRINTK("%s: SAS error %x\n", __FUNCTION__, stat->stat); /* We saw a SAS error. Send a vague error. */ qc->err_mask = ac; @@ -244,20 +244,20 @@ static void sas_ata_phy_reset(struct ata_port *ap) res = i->dft->lldd_I_T_nexus_reset(dev); if (res != TMF_RESP_FUNC_COMPLETE) - SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __func__); + SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__); switch (dev->sata_dev.command_set) { case ATA_COMMAND_SET: - SAS_DPRINTK("%s: Found ATA device.\n", __func__); + SAS_DPRINTK("%s: Found ATA device.\n", __FUNCTION__); ap->link.device[0].class = ATA_DEV_ATA; break; case ATAPI_COMMAND_SET: - SAS_DPRINTK("%s: Found ATAPI device.\n", __func__); + SAS_DPRINTK("%s: Found ATAPI device.\n", __FUNCTION__); ap->link.device[0].class = ATA_DEV_ATAPI; break; default: SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", - __func__, + __FUNCTION__, dev->sata_dev.command_set); ap->link.device[0].class = ATA_DEV_UNKNOWN; break; @@ -299,7 +299,7 @@ static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in, { struct domain_device *dev = ap->private_data; - SAS_DPRINTK("STUB %s\n", __func__); + SAS_DPRINTK("STUB %s\n", __FUNCTION__); switch (sc_reg_in) { case SCR_STATUS: dev->sata_dev.sstatus = val; @@ -324,7 +324,7 @@ static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in, { struct domain_device *dev = ap->private_data; - SAS_DPRINTK("STUB %s\n", __func__); + SAS_DPRINTK("STUB %s\n", __FUNCTION__); switch (sc_reg_in) { case SCR_STATUS: *val = dev->sata_dev.sstatus; diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index 3da02e436788..aefd865a5788 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -121,7 +121,7 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size, break; } else { SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " - "status 0x%x\n", __func__, + "status 0x%x\n", __FUNCTION__, SAS_ADDR(dev->sas_addr), task->task_status.resp, task->task_status.stat); @@ -1279,7 +1279,7 @@ static int sas_configure_present(struct domain_device *dev, int phy_id, goto out; } else if (res != SMP_RESP_FUNC_ACC) { SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x " - "result 0x%x\n", __func__, + "result 0x%x\n", __FUNCTION__, SAS_ADDR(dev->sas_addr), phy_id, i, res); goto out; } @@ -1901,7 +1901,7 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, if (!rsp) { printk("%s: space for a smp response is missing\n", - __func__); + __FUNCTION__); return -EINVAL; } @@ -1914,20 +1914,20 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, if (type != SAS_EDGE_EXPANDER_DEVICE && type != SAS_FANOUT_EXPANDER_DEVICE) { printk("%s: can we send a smp request to a device?\n", - __func__); + __FUNCTION__); return -EINVAL; } dev = sas_find_dev_by_rphy(rphy); if (!dev) { - printk("%s: fail to find a domain_device?\n", __func__); + printk("%s: fail to find a domain_device?\n", __FUNCTION__); return -EINVAL; } /* do we need to support multiple segments? */ if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { printk("%s: multiple segments req %u %u, rsp %u %u\n", - __func__, req->bio->bi_vcnt, req->data_len, + __FUNCTION__, req->bio->bi_vcnt, req->data_len, rsp->bio->bi_vcnt, rsp->data_len); return -EINVAL; } diff --git a/trunk/drivers/scsi/libsas/sas_port.c b/trunk/drivers/scsi/libsas/sas_port.c index 139935a121b4..39ae68a3b0ef 100644 --- a/trunk/drivers/scsi/libsas/sas_port.c +++ b/trunk/drivers/scsi/libsas/sas_port.c @@ -50,7 +50,7 @@ static void sas_form_port(struct asd_sas_phy *phy) sas_deform_port(phy); else { SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", - __func__, phy->id, phy->port->id, + __FUNCTION__, phy->id, phy->port->id, phy->port->num_phys); return; } @@ -78,7 +78,7 @@ static void sas_form_port(struct asd_sas_phy *phy) if (i >= sas_ha->num_phys) { printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", - __func__); + __FUNCTION__); spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); return; } diff --git a/trunk/drivers/scsi/libsas/sas_scsi_host.c b/trunk/drivers/scsi/libsas/sas_scsi_host.c index a8e3ef309070..601ec5b6a7f6 100644 --- a/trunk/drivers/scsi/libsas/sas_scsi_host.c +++ b/trunk/drivers/scsi/libsas/sas_scsi_host.c @@ -343,7 +343,7 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) flags); SAS_DPRINTK("%s: task 0x%p aborted from " "task_queue\n", - __func__, task); + __FUNCTION__, task); return TASK_IS_ABORTED; } } @@ -351,13 +351,13 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) } for (i = 0; i < 5; i++) { - SAS_DPRINTK("%s: aborting task 0x%p\n", __func__, task); + SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); res = si->dft->lldd_abort_task(task); spin_lock_irqsave(&task->task_state_lock, flags); if (task->task_state_flags & SAS_TASK_STATE_DONE) { spin_unlock_irqrestore(&task->task_state_lock, flags); - SAS_DPRINTK("%s: task 0x%p is done\n", __func__, + SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, task); return TASK_IS_DONE; } @@ -365,24 +365,24 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) if (res == TMF_RESP_FUNC_COMPLETE) { SAS_DPRINTK("%s: task 0x%p is aborted\n", - __func__, task); + __FUNCTION__, task); return TASK_IS_ABORTED; } else if (si->dft->lldd_query_task) { SAS_DPRINTK("%s: querying task 0x%p\n", - __func__, task); + __FUNCTION__, task); res = si->dft->lldd_query_task(task); switch (res) { case TMF_RESP_FUNC_SUCC: SAS_DPRINTK("%s: task 0x%p at LU\n", - __func__, task); + __FUNCTION__, task); return TASK_IS_AT_LU; case TMF_RESP_FUNC_COMPLETE: SAS_DPRINTK("%s: task 0x%p not at LU\n", - __func__, task); + __FUNCTION__, task); return TASK_IS_NOT_AT_LU; case TMF_RESP_FUNC_FAILED: SAS_DPRINTK("%s: task 0x%p failed to abort\n", - __func__, task); + __FUNCTION__, task); return TASK_ABORT_FAILED; } @@ -545,7 +545,7 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, if (need_reset) { SAS_DPRINTK("%s: task 0x%p requests reset\n", - __func__, task); + __FUNCTION__, task); goto reset; } @@ -556,13 +556,13 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, switch (res) { case TASK_IS_DONE: - SAS_DPRINTK("%s: task 0x%p is done\n", __func__, + SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, task); sas_eh_finish_cmd(cmd); continue; case TASK_IS_ABORTED: SAS_DPRINTK("%s: task 0x%p is aborted\n", - __func__, task); + __FUNCTION__, task); sas_eh_finish_cmd(cmd); continue; case TASK_IS_AT_LU: @@ -633,7 +633,7 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, } return list_empty(work_q); clear_q: - SAS_DPRINTK("--- Exit %s -- clear_q\n", __func__); + SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__); list_for_each_entry_safe(cmd, n, work_q, eh_entry) sas_eh_finish_cmd(cmd); @@ -650,7 +650,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) list_splice_init(&shost->eh_cmd_q, &eh_work_q); spin_unlock_irqrestore(shost->host_lock, flags); - SAS_DPRINTK("Enter %s\n", __func__); + SAS_DPRINTK("Enter %s\n", __FUNCTION__); /* * Deal with commands that still have SAS tasks (i.e. they didn't * complete via the normal sas_task completion mechanism) @@ -669,7 +669,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) out: scsi_eh_flush_done_q(&ha->eh_done_q); - SAS_DPRINTK("--- Exit %s\n", __func__); + SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); return; } @@ -990,7 +990,7 @@ int __sas_task_abort(struct sas_task *task) if (task->task_state_flags & SAS_TASK_STATE_ABORTED || task->task_state_flags & SAS_TASK_STATE_DONE) { spin_unlock_irqrestore(&task->task_state_lock, flags); - SAS_DPRINTK("%s: Task %p already finished.\n", __func__, + SAS_DPRINTK("%s: Task %p already finished.\n", __FUNCTION__, task); return 0; } diff --git a/trunk/drivers/scsi/libsrp.c b/trunk/drivers/scsi/libsrp.c index 15e2d132e8b9..6d6a76e65a6c 100644 --- a/trunk/drivers/scsi/libsrp.c +++ b/trunk/drivers/scsi/libsrp.c @@ -39,7 +39,7 @@ enum srp_task_attributes { /* tmp - will replace with SCSI logging stuff */ #define eprintk(fmt, args...) \ do { \ - printk("%s(%d) " fmt, __func__, __LINE__, ##args); \ + printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ } while (0) /* #define dprintk eprintk */ #define dprintk(fmt, args...) diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index d51a2a4b43eb..5b6e5395c8eb 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -2083,7 +2083,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) if (iocbq_entry == NULL) { printk(KERN_ERR "%s: only allocated %d iocbs of " "expected %d count. Unloading driver.\n", - __func__, i, LPFC_IOCB_LIST_CNT); + __FUNCTION__, i, LPFC_IOCB_LIST_CNT); error = -ENOMEM; goto out_free_iocbq; } @@ -2093,7 +2093,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) kfree (iocbq_entry); printk(KERN_ERR "%s: failed to allocate IOTAG. " "Unloading driver.\n", - __func__); + __FUNCTION__); error = -ENOMEM; goto out_free_iocbq; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index 1bcebbd3dfac..c94da4f2b8a6 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -341,7 +341,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { printk(KERN_ERR "%s: Too many sg segments from " "dma_map_sg. Config %d, seg_cnt %d", - __func__, phba->cfg_sg_seg_cnt, + __FUNCTION__, phba->cfg_sg_seg_cnt, lpfc_cmd->seg_cnt); scsi_dma_unmap(scsi_cmnd); return 1; diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index 50fe07646738..f40aa7b905f7 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -219,7 +219,7 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) case CMD_IOCB_LOGENTRY_CN: case CMD_IOCB_LOGENTRY_ASYNC_CN: printk("%s - Unhandled SLI-3 Command x%x\n", - __func__, iocb_cmnd); + __FUNCTION__, iocb_cmnd); type = LPFC_UNKNOWN_IOCB; break; default: @@ -1715,7 +1715,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, rspiocbp = __lpfc_sli_get_iocbq(phba); if (rspiocbp == NULL) { printk(KERN_ERR "%s: out of buffers! Failing " - "completion.\n", __func__); + "completion.\n", __FUNCTION__); break; } @@ -3793,7 +3793,7 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, break; default: printk(KERN_ERR "%s: Unknown context cmd type, value %d\n", - __func__, ctx_cmd); + __FUNCTION__, ctx_cmd); break; } diff --git a/trunk/drivers/scsi/megaraid/mega_common.h b/trunk/drivers/scsi/megaraid/mega_common.h index 5ead1283a844..f62ed468ada0 100644 --- a/trunk/drivers/scsi/megaraid/mega_common.h +++ b/trunk/drivers/scsi/megaraid/mega_common.h @@ -265,7 +265,7 @@ typedef struct { #define ASSERT(expression) \ if (!(expression)) { \ ASSERT_ACTION("assertion failed:(%s), file: %s, line: %d:%s\n", \ - #expression, __FILE__, __LINE__, __func__); \ + #expression, __FILE__, __LINE__, __FUNCTION__); \ } #else #define ASSERT(expression) diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.c b/trunk/drivers/scsi/megaraid/megaraid_mbox.c index 805bb61dde18..70a0f11f48b2 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.c @@ -458,7 +458,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (adapter == NULL) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d.\n", __func__, __LINE__)); + "megaraid: out of memory, %s %d.\n", __FUNCTION__, __LINE__)); goto out_probe_one; } @@ -1002,7 +1002,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) if (!raid_dev->una_mbox64) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __func__, + "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); return -1; } @@ -1030,7 +1030,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) if (!adapter->ibuf) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __func__, + "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); goto out_free_common_mbox; @@ -1052,7 +1052,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) if (adapter->kscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __func__, + "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); goto out_free_ibuf; } @@ -1060,7 +1060,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) // memory allocation for our command packets if (megaraid_mbox_setup_dma_pools(adapter) != 0) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __func__, + "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); goto out_free_scb_list; } @@ -2981,7 +2981,7 @@ megaraid_mbox_product_info(adapter_t *adapter) if (pinfo == NULL) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __func__, + "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); return -1; @@ -3508,7 +3508,7 @@ megaraid_cmm_register(adapter_t *adapter) if (adapter->uscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __func__, + "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); return -1; } @@ -3879,7 +3879,7 @@ megaraid_sysfs_alloc_resources(adapter_t *adapter) !raid_dev->sysfs_buffer) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __func__, + "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); rval = -ENOMEM; diff --git a/trunk/drivers/scsi/megaraid/megaraid_mm.c b/trunk/drivers/scsi/megaraid/megaraid_mm.c index f680561d2c6f..ac3b280c2a72 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mm.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mm.c @@ -929,7 +929,7 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) !adapter->pthru_dma_pool) { con_log(CL_ANN, (KERN_WARNING - "megaraid cmm: out of memory, %s %d\n", __func__, + "megaraid cmm: out of memory, %s %d\n", __FUNCTION__, __LINE__)); rval = (-ENOMEM); @@ -957,7 +957,7 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) con_log(CL_ANN, (KERN_WARNING "megaraid cmm: out of memory, %s %d\n", - __func__, __LINE__)); + __FUNCTION__, __LINE__)); rval = (-ENOMEM); diff --git a/trunk/drivers/scsi/nsp32.c b/trunk/drivers/scsi/nsp32.c index edf9fdb3cb3c..7fed35372150 100644 --- a/trunk/drivers/scsi/nsp32.c +++ b/trunk/drivers/scsi/nsp32.c @@ -299,9 +299,9 @@ static struct scsi_host_template nsp32_template = { #else # define NSP32_DEBUG_MASK 0xffffff # define nsp32_msg(type, args...) \ - nsp32_message (__func__, __LINE__, (type), args) + nsp32_message (__FUNCTION__, __LINE__, (type), args) # define nsp32_dbg(mask, args...) \ - nsp32_dmessage(__func__, __LINE__, (mask), args) + nsp32_dmessage(__FUNCTION__, __LINE__, (mask), args) #endif #define NSP32_DEBUG_QUEUECOMMAND BIT(0) diff --git a/trunk/drivers/scsi/nsp32_debug.c b/trunk/drivers/scsi/nsp32_debug.c index 2fb3fb58858d..ef3c59cbcff6 100644 --- a/trunk/drivers/scsi/nsp32_debug.c +++ b/trunk/drivers/scsi/nsp32_debug.c @@ -88,7 +88,7 @@ static void print_commandk (unsigned char *command) int i,s; // printk(KERN_DEBUG); print_opcodek(command[0]); - /*printk(KERN_DEBUG "%s ", __func__);*/ + /*printk(KERN_DEBUG "%s ", __FUNCTION__);*/ if ((command[0] >> 5) == 6 || (command[0] >> 5) == 7 ) { s = 12; /* vender specific */ diff --git a/trunk/drivers/scsi/pcmcia/nsp_cs.c b/trunk/drivers/scsi/pcmcia/nsp_cs.c index a221b6ef9fa9..5082ca3c6876 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_cs.c +++ b/trunk/drivers/scsi/pcmcia/nsp_cs.c @@ -107,9 +107,9 @@ static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ #else # define NSP_DEBUG_MASK 0xffffff # define nsp_msg(type, args...) \ - nsp_cs_message (__func__, __LINE__, (type), args) + nsp_cs_message (__FUNCTION__, __LINE__, (type), args) # define nsp_dbg(mask, args...) \ - nsp_cs_dmessage(__func__, __LINE__, (mask), args) + nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args) #endif #define NSP_DEBUG_QUEUECOMMAND BIT(0) diff --git a/trunk/drivers/scsi/pcmcia/nsp_debug.c b/trunk/drivers/scsi/pcmcia/nsp_debug.c index 3c6ef64fcbff..2f75fe6e35a7 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_debug.c +++ b/trunk/drivers/scsi/pcmcia/nsp_debug.c @@ -90,7 +90,7 @@ static void print_commandk (unsigned char *command) int i, s; printk(KERN_DEBUG); print_opcodek(command[0]); - /*printk(KERN_DEBUG "%s ", __func__);*/ + /*printk(KERN_DEBUG "%s ", __FUNCTION__);*/ if ((command[0] >> 5) == 6 || (command[0] >> 5) == 7 ) { s = 12; /* vender specific */ diff --git a/trunk/drivers/scsi/ppa.c b/trunk/drivers/scsi/ppa.c index 8aa0bd987e29..f655ae320b48 100644 --- a/trunk/drivers/scsi/ppa.c +++ b/trunk/drivers/scsi/ppa.c @@ -171,7 +171,7 @@ static int device_check(ppa_struct *dev); #if PPA_DEBUG > 0 #define ppa_fail(x,y) printk("ppa: ppa_fail(%i) from %s at line %d\n",\ - y, __func__, __LINE__); ppa_fail_func(x,y); + y, __FUNCTION__, __LINE__); ppa_fail_func(x,y); static inline void ppa_fail_func(ppa_struct *dev, int error_code) #else static inline void ppa_fail(ppa_struct *dev, int error_code) diff --git a/trunk/drivers/scsi/qla1280.c b/trunk/drivers/scsi/qla1280.c index 37f9ba0cd798..3754ab87f89a 100644 --- a/trunk/drivers/scsi/qla1280.c +++ b/trunk/drivers/scsi/qla1280.c @@ -1695,7 +1695,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; dprintk(1, "%s: DMA RISC code (%i) words\n", - __func__, risc_code_size); + __FUNCTION__, risc_code_size); num = 0; while (risc_code_size > 0) { @@ -1721,7 +1721,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff; mb[6] = pci_dma_hi32(ha->request_dma) >> 16; dprintk(2, "%s: op=%d 0x%p = 0x%4x,0x%4x,0x%4x,0x%4x\n", - __func__, mb[0], + __FUNCTION__, mb[0], (void *)(long)ha->request_dma, mb[6], mb[7], mb[2], mb[3]); err = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 | @@ -1753,10 +1753,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) if (tbuf[i] != sp[i] && warn++ < 10) { printk(KERN_ERR "%s: FW compare error @ " "byte(0x%x) loop#=%x\n", - __func__, i, num); + __FUNCTION__, i, num); printk(KERN_ERR "%s: FWbyte=%x " "FWfromChip=%x\n", - __func__, sp[i], tbuf[i]); + __FUNCTION__, sp[i], tbuf[i]); /*break; */ } } @@ -1781,7 +1781,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) int err; dprintk(1, "%s: Verifying checksum of loaded RISC code.\n", - __func__); + __FUNCTION__); /* Verify checksum of loaded RISC code. */ mb[0] = MBC_VERIFY_CHECKSUM; @@ -1794,7 +1794,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) } /* Start firmware execution. */ - dprintk(1, "%s: start firmware running.\n", __func__); + dprintk(1, "%s: start firmware running.\n", __FUNCTION__); mb[0] = MBC_EXECUTE_FIRMWARE; mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index 7a4409ab30ea..8dd88fc1244a 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -20,12 +20,18 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, { struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); + char *rbuf = (char *)ha->fw_dump; if (ha->fw_dump_reading == 0) return 0; + if (off > ha->fw_dump_len) + return 0; + if (off + count > ha->fw_dump_len) + count = ha->fw_dump_len - off; - return memory_read_from_buffer(buf, count, &off, ha->fw_dump, - ha->fw_dump_len); + memcpy(buf, &rbuf[off], count); + + return (count); } static ssize_t @@ -88,13 +94,20 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, { struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); + int size = ha->nvram_size; + char *nvram_cache = ha->nvram; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) || off > size || count == 0) return 0; + if (off + count > size) { + size -= off; + count = size; + } /* Read NVRAM data from cache. */ - return memory_read_from_buffer(buf, count, &off, ha->nvram, - ha->nvram_size); + memcpy(buf, &nvram_cache[off], count); + + return count; } static ssize_t @@ -162,9 +175,14 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, if (ha->optrom_state != QLA_SREADING) return 0; + if (off > ha->optrom_region_size) + return 0; + if (off + count > ha->optrom_region_size) + count = ha->optrom_region_size - off; + + memcpy(buf, &ha->optrom_buffer[off], count); - return memory_read_from_buffer(buf, count, &off, ha->optrom_buffer, - ha->optrom_region_size); + return count; } static ssize_t @@ -356,12 +374,20 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, { struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); + int size = ha->vpd_size; + char *vpd_cache = ha->vpd; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) || off > size || count == 0) return 0; + if (off + count > size) { + size -= off; + count = size; + } /* Read NVRAM data from cache. */ - return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size); + memcpy(buf, &vpd_cache[off], count); + + return count; } static ssize_t @@ -531,10 +557,8 @@ qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr, scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); uint32_t sn; - if (IS_FWI2_CAPABLE(ha)) { - qla2xxx_get_vpd_field(ha, "SN", buf, PAGE_SIZE); - return snprintf(buf, PAGE_SIZE, "%s\n", buf); - } + if (IS_FWI2_CAPABLE(ha)) + return snprintf(buf, PAGE_SIZE, "\n"); sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, @@ -785,16 +809,6 @@ qla2x00_optrom_fw_version_show(struct device *dev, ha->fw_revision[3]); } -static ssize_t -qla2x00_total_isp_aborts_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); - - return snprintf(buf, PAGE_SIZE, "%d\n", - ha->qla_stats.total_isp_aborts); -} - static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); @@ -817,8 +831,6 @@ static DEVICE_ATTR(optrom_fcode_version, S_IRUGO, qla2x00_optrom_fcode_version_show, NULL); static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show, NULL); -static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show, - NULL); struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_driver_version, @@ -837,7 +849,6 @@ struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_optrom_efi_version, &dev_attr_optrom_fcode_version, &dev_attr_optrom_fw_version, - &dev_attr_total_isp_aborts, NULL, }; @@ -961,39 +972,26 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) } static void -qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) +qla2x00_get_rport_loss_tmo(struct fc_rport *rport) { - if (timeout) - rport->dev_loss_tmo = timeout; - else - rport->dev_loss_tmo = 1; + struct Scsi_Host *host = rport_to_shost(rport); + scsi_qla_host_t *ha = shost_priv(host); + + rport->dev_loss_tmo = ha->port_down_retry_count + 5; } static void -qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) +qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) { struct Scsi_Host *host = rport_to_shost(rport); - fc_port_t *fcport = *(fc_port_t **)rport->dd_data; - - qla2x00_abort_fcport_cmds(fcport); - - /* - * Transport has effectively 'deleted' the rport, clear - * all local references. - */ - spin_lock_irq(host->host_lock); - fcport->rport = NULL; - *((fc_port_t **)rport->dd_data) = NULL; - spin_unlock_irq(host->host_lock); -} + scsi_qla_host_t *ha = shost_priv(host); -static void -qla2x00_terminate_rport_io(struct fc_rport *rport) -{ - fc_port_t *fcport = *(fc_port_t **)rport->dd_data; + if (timeout) + ha->port_down_retry_count = timeout; + else + ha->port_down_retry_count = 1; - qla2x00_abort_fcport_cmds(fcport); - scsi_target_unblock(&rport->dev); + rport->dev_loss_tmo = ha->port_down_retry_count + 5; } static int @@ -1047,7 +1045,6 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) pfc_host_stat->invalid_tx_word_count = stats->inval_xmit_word_cnt; pfc_host_stat->invalid_crc_count = stats->inval_crc_cnt; if (IS_FWI2_CAPABLE(ha)) { - pfc_host_stat->lip_count = stats->lip_cnt; pfc_host_stat->tx_frames = stats->tx_frames; pfc_host_stat->rx_frames = stats->rx_frames; pfc_host_stat->dumped_frames = stats->dumped_frames; @@ -1176,16 +1173,17 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) static int qla24xx_vport_delete(struct fc_vport *fc_vport) { + scsi_qla_host_t *ha = shost_priv(fc_vport->shost); scsi_qla_host_t *vha = fc_vport->dd_data; - scsi_qla_host_t *pha = to_qla_parent(vha); - - while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) || - test_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags)) - msleep(1000); qla24xx_disable_vp(vha); qla24xx_deallocate_vp_id(vha); + mutex_lock(&ha->vport_lock); + ha->cur_vport_count--; + clear_bit(vha->vp_idx, ha->vp_idx_map); + mutex_unlock(&ha->vport_lock); + kfree(vha->node_name); kfree(vha->port_name); @@ -1250,12 +1248,11 @@ struct fc_function_template qla2xxx_transport_functions = { .get_starget_port_id = qla2x00_get_starget_port_id, .show_starget_port_id = 1, + .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, .show_rport_dev_loss_tmo = 1, .issue_fc_host_lip = qla2x00_issue_lip, - .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, - .terminate_rport_io = qla2x00_terminate_rport_io, .get_fc_host_stats = qla2x00_get_fc_host_stats, .vport_create = qla24xx_vport_create, @@ -1294,12 +1291,11 @@ struct fc_function_template qla2xxx_transport_vport_functions = { .get_starget_port_id = qla2x00_get_starget_port_id, .show_starget_port_id = 1, + .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, .show_rport_dev_loss_tmo = 1, .issue_fc_host_lip = qla2x00_issue_lip, - .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, - .terminate_rport_io = qla2x00_terminate_rport_io, .get_fc_host_stats = qla2x00_get_fc_host_stats, }; diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.c b/trunk/drivers/scsi/qla2xxx/qla_dbg.c index 510ba64bc286..cbef785765cf 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.c @@ -216,7 +216,7 @@ qla24xx_soft_reset(scsi_qla_host_t *ha) static int qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram, - uint32_t ram_words, void **nxt) + uint16_t ram_words, void **nxt) { int rval; uint32_t cnt, stat, timer, words, idx; diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index 6da31ba94404..8dd600013bd1 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -864,8 +864,7 @@ struct link_statistics { uint32_t prim_seq_err_cnt; uint32_t inval_xmit_word_cnt; uint32_t inval_crc_cnt; - uint32_t lip_cnt; - uint32_t unused1[0x1a]; + uint32_t unused1[0x1b]; uint32_t tx_frames; uint32_t rx_frames; uint32_t dumped_frames; @@ -1545,6 +1544,7 @@ typedef struct fc_port { int login_retry; atomic_t port_down_timer; + spinlock_t rport_lock; struct fc_rport *rport, *drport; u32 supported_classes; @@ -2155,10 +2155,6 @@ struct qla_chip_state_84xx { uint32_t gold_fw_version; }; -struct qla_statistics { - uint32_t total_isp_aborts; -}; - /* * Linux Host Adapter structure */ @@ -2170,6 +2166,7 @@ typedef struct scsi_qla_host { struct pci_dev *pdev; unsigned long host_no; + unsigned long instance; volatile struct { uint32_t init_done :1; @@ -2518,7 +2515,7 @@ typedef struct scsi_qla_host { uint8_t model_number[16+1]; #define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - char model_desc[80]; + char *model_desc; uint8_t adapter_id[16+1]; uint8_t *node_name; @@ -2599,7 +2596,6 @@ typedef struct scsi_qla_host { int cur_vport_count; struct qla_chip_state_84xx *cs84xx; - struct qla_statistics qla_stats; } scsi_qla_host_t; diff --git a/trunk/drivers/scsi/qla2xxx/qla_gbl.h b/trunk/drivers/scsi/qla2xxx/qla_gbl.h index 0b156735e9a6..9b4bebee6879 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_gbl.h @@ -62,7 +62,7 @@ extern int ql2xfdmienable; extern int ql2xallocfwdump; extern int ql2xextended_error_logging; extern int ql2xqfullrampup; -extern int ql2xiidmaenable; +extern int num_hosts; extern int qla2x00_loop_reset(scsi_qla_host_t *); extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); @@ -71,8 +71,6 @@ extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, uint16_t, uint16_t); -extern void qla2x00_abort_fcport_cmds(fc_port_t *); - /* * Global Functions in qla_mid.c source file. */ @@ -314,7 +312,6 @@ extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, uint16_t, uint16_t); extern void qla2xxx_get_flash_info(scsi_qla_host_t *); -extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); /* * Global Function Prototypes in qla_dbg.c source file. diff --git a/trunk/drivers/scsi/qla2xxx/qla_gs.c b/trunk/drivers/scsi/qla2xxx/qla_gs.c index c2a4bfbcb05b..4cb80b476c85 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gs.c +++ b/trunk/drivers/scsi/qla2xxx/qla_gs.c @@ -1661,12 +1661,6 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha) { int rval; - if (IS_QLA2100(ha) || IS_QLA2200(ha)) { - DEBUG2(printk("scsi(%ld): FDMI unsupported on " - "ISP2100/ISP2200.\n", ha->host_no)); - return QLA_SUCCESS; - } - rval = qla2x00_mgmt_svr_login(ha); if (rval) return rval; diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 601a6b29750c..bbbc5a632a1d 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -334,8 +334,6 @@ static int qla2x00_isp_firmware(scsi_qla_host_t *ha) { int rval; - uint16_t loop_id, topo, sw_cap; - uint8_t domain, area, al_pa; /* Assume loading risc code */ rval = QLA_FUNCTION_FAILED; @@ -347,11 +345,6 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha) /* Verify checksum of loaded RISC code. */ rval = qla2x00_verify_checksum(ha, ha->fw_srisc_address); - if (rval == QLA_SUCCESS) { - /* And, verify we are not in ROM code. */ - rval = qla2x00_get_adapter_id(ha, &loop_id, &al_pa, - &area, &domain, &topo, &sw_cap); - } } if (rval) { @@ -729,7 +722,7 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) /* Perform RISC reset. */ qla24xx_reset_risc(ha); - ha->fw_transfer_size = REQUEST_ENTRY_SIZE * ha->request_q_length; + ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024; rval = qla2x00_mbx_reg_test(ha); if (rval) { @@ -775,16 +768,42 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) mem_size = (ha->fw_memory_size - 0x100000 + 1) * sizeof(uint32_t); + /* Allocate memory for Extended Trace Buffer. */ + tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, + GFP_KERNEL); + if (!tc) { + qla_printk(KERN_WARNING, ha, "Unable to allocate " + "(%d KB) for EFT.\n", EFT_SIZE / 1024); + goto cont_alloc; + } + + memset(tc, 0, EFT_SIZE); + rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS); + if (rval) { + qla_printk(KERN_WARNING, ha, "Unable to initialize " + "EFT (%d).\n", rval); + dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, + tc_dma); + goto cont_alloc; + } + + qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", + EFT_SIZE / 1024); + + eft_size = EFT_SIZE; + ha->eft_dma = tc_dma; + ha->eft = tc; + /* Allocate memory for Fibre Channel Event Buffer. */ if (!IS_QLA25XX(ha)) - goto try_eft; + goto cont_alloc; tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, GFP_KERNEL); if (!tc) { qla_printk(KERN_WARNING, ha, "Unable to allocate " "(%d KB) for FCE.\n", FCE_SIZE / 1024); - goto try_eft; + goto cont_alloc; } memset(tc, 0, FCE_SIZE); @@ -796,7 +815,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma); ha->flags.fce_enabled = 0; - goto try_eft; + goto cont_alloc; } qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", @@ -806,32 +825,6 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) ha->flags.fce_enabled = 1; ha->fce_dma = tc_dma; ha->fce = tc; -try_eft: - /* Allocate memory for Extended Trace Buffer. */ - tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, - GFP_KERNEL); - if (!tc) { - qla_printk(KERN_WARNING, ha, "Unable to allocate " - "(%d KB) for EFT.\n", EFT_SIZE / 1024); - goto cont_alloc; - } - - memset(tc, 0, EFT_SIZE); - rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS); - if (rval) { - qla_printk(KERN_WARNING, ha, "Unable to initialize " - "EFT (%d).\n", rval); - dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, - tc_dma); - goto cont_alloc; - } - - qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", - EFT_SIZE / 1024); - - eft_size = EFT_SIZE; - ha->eft_dma = tc_dma; - ha->eft = tc; } cont_alloc: req_q_size = ha->request_q_length * sizeof(request_t); @@ -1508,25 +1501,18 @@ qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *de index = (ha->pdev->subsystem_device & 0xff); if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && index < QLA_MODEL_NAMES) - strncpy(ha->model_desc, - qla2x00_model_name[index * 2 + 1], - sizeof(ha->model_desc) - 1); + ha->model_desc = qla2x00_model_name[index * 2 + 1]; } else { index = (ha->pdev->subsystem_device & 0xff); if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && index < QLA_MODEL_NAMES) { strcpy(ha->model_number, qla2x00_model_name[index * 2]); - strncpy(ha->model_desc, - qla2x00_model_name[index * 2 + 1], - sizeof(ha->model_desc) - 1); + ha->model_desc = qla2x00_model_name[index * 2 + 1]; } else { strcpy(ha->model_number, def); } } - if (IS_FWI2_CAPABLE(ha)) - qla2xxx_get_vpd_field(ha, "\x82", ha->model_desc, - sizeof(ha->model_desc)); } /* On sparc systems, obtain port and node WWN from firmware @@ -1878,11 +1864,12 @@ qla2x00_rport_del(void *data) { fc_port_t *fcport = data; struct fc_rport *rport; + unsigned long flags; - spin_lock_irq(fcport->ha->host->host_lock); + spin_lock_irqsave(&fcport->rport_lock, flags); rport = fcport->drport; fcport->drport = NULL; - spin_unlock_irq(fcport->ha->host->host_lock); + spin_unlock_irqrestore(&fcport->rport_lock, flags); if (rport) fc_remote_port_delete(rport); } @@ -1911,6 +1898,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) atomic_set(&fcport->state, FCS_UNCONFIGURED); fcport->flags = FCF_RLC_SUPPORT; fcport->supported_classes = FC_COS_UNSPECIFIED; + spin_lock_init(&fcport->rport_lock); return fcport; } @@ -2019,10 +2007,8 @@ qla2x00_configure_loop(scsi_qla_host_t *ha) if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); - if (test_bit(RSCN_UPDATE, &save_flags)) { - ha->flags.rscn_queue_overflow = 1; + if (test_bit(RSCN_UPDATE, &save_flags)) set_bit(RSCN_UPDATE, &ha->dpc_flags); - } } return (rval); @@ -2257,24 +2243,28 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) { struct fc_rport_identifiers rport_ids; struct fc_rport *rport; + unsigned long flags; if (fcport->drport) qla2x00_rport_del(fcport); + if (fcport->rport) + return; rport_ids.node_name = wwn_to_u64(fcport->node_name); rport_ids.port_name = wwn_to_u64(fcport->port_name); rport_ids.port_id = fcport->d_id.b.domain << 16 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; - fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); + rport = fc_remote_port_add(ha->host, 0, &rport_ids); if (!rport) { qla_printk(KERN_WARNING, ha, "Unable to allocate fc remote port!\n"); return; } - spin_lock_irq(fcport->ha->host->host_lock); + spin_lock_irqsave(&fcport->rport_lock, flags); + fcport->rport = rport; *((fc_port_t **)rport->dd_data) = fcport; - spin_unlock_irq(fcport->ha->host->host_lock); + spin_unlock_irqrestore(&fcport->rport_lock, flags); rport->supported_classes = fcport->supported_classes; @@ -2575,8 +2565,7 @@ 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 (ql2xiidmaenable && - qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { + } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { qla2x00_gpsc(ha, swl); } } @@ -3231,8 +3220,7 @@ qla2x00_update_fcports(scsi_qla_host_t *ha) /* Go with deferred removal of rport references. */ list_for_each_entry(fcport, &ha->fcports, list) - if (fcport->drport && - atomic_read(&fcport->state) != FCS_UNCONFIGURED) + if (fcport->drport) qla2x00_rport_del(fcport); } @@ -3255,7 +3243,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) if (ha->flags.online) { ha->flags.online = 0; clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); - ha->qla_stats.total_isp_aborts++; qla_printk(KERN_INFO, ha, "Performing ISP error recovery - ha= %p.\n", ha); @@ -3296,6 +3283,17 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) ha->isp_abort_cnt = 0; clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); + if (ha->eft) { + memset(ha->eft, 0, EFT_SIZE); + rval = qla2x00_enable_eft_trace(ha, + ha->eft_dma, EFT_NUM_BUFFERS); + if (rval) { + qla_printk(KERN_WARNING, ha, + "Unable to reinitialize EFT " + "(%d).\n", rval); + } + } + if (ha->fce) { ha->flags.fce_enabled = 1; memset(ha->fce, 0, @@ -3310,17 +3308,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) ha->flags.fce_enabled = 0; } } - - if (ha->eft) { - memset(ha->eft, 0, EFT_SIZE); - rval = qla2x00_enable_eft_trace(ha, - ha->eft_dma, EFT_NUM_BUFFERS); - if (rval) { - qla_printk(KERN_WARNING, ha, - "Unable to reinitialize EFT " - "(%d).\n", rval); - } - } } else { /* failed the ISP abort */ ha->flags.online = 1; if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { @@ -4039,8 +4026,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) ret = qla2x00_stop_firmware(ha); for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && retries ; retries--) { - ha->isp_ops->reset_chip(ha); - if (ha->isp_ops->chip_diag(ha) != QLA_SUCCESS) + qla2x00_reset_chip(ha); + if (qla2x00_chip_diag(ha) != QLA_SUCCESS) continue; if (qla2x00_setup_chip(ha) != QLA_SUCCESS) continue; @@ -4062,7 +4049,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) rval = qla2x00_fw_ready(ha->parent); if (rval == QLA_SUCCESS) { clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); - qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); + qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL); } ha->flags.management_server_logged_in = 0; diff --git a/trunk/drivers/scsi/qla2xxx/qla_iocb.c b/trunk/drivers/scsi/qla2xxx/qla_iocb.c index d57669aa4615..5489d5024673 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_iocb.c +++ b/trunk/drivers/scsi/qla2xxx/qla_iocb.c @@ -454,11 +454,10 @@ qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun, { int ret; unsigned long flags = 0; - scsi_qla_host_t *pha = to_qla_parent(ha); - spin_lock_irqsave(&pha->hardware_lock, flags); + spin_lock_irqsave(&ha->hardware_lock, flags); ret = __qla2x00_marker(ha, loop_id, lun, type); - spin_unlock_irqrestore(&pha->hardware_lock, flags); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return (ret); } @@ -673,7 +672,7 @@ qla24xx_start_scsi(srb_t *sp) { int ret, nseg; unsigned long flags; - scsi_qla_host_t *ha, *pha; + scsi_qla_host_t *ha; struct scsi_cmnd *cmd; uint32_t *clr_ptr; uint32_t index; @@ -687,7 +686,6 @@ qla24xx_start_scsi(srb_t *sp) /* Setup device pointers. */ ret = 0; ha = sp->ha; - pha = to_qla_parent(ha); reg = &ha->iobase->isp24; cmd = sp->cmd; /* So we know we haven't pci_map'ed anything yet */ @@ -702,7 +700,7 @@ qla24xx_start_scsi(srb_t *sp) } /* Acquire ring specific lock */ - spin_lock_irqsave(&pha->hardware_lock, flags); + spin_lock_irqsave(&ha->hardware_lock, flags); /* Check for room in outstanding command list. */ handle = ha->current_outstanding_cmd; @@ -797,14 +795,14 @@ qla24xx_start_scsi(srb_t *sp) ha->response_ring_ptr->signature != RESPONSE_PROCESSED) qla24xx_process_response_queue(ha); - spin_unlock_irqrestore(&pha->hardware_lock, flags); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_SUCCESS; queuing_error: if (tot_dsds) scsi_dma_unmap(cmd); - spin_unlock_irqrestore(&pha->hardware_lock, flags); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_FUNCTION_FAILED; } diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index 874d802edb7d..ec63b79f900a 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -542,6 +542,10 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) break; case MBA_PORT_UPDATE: /* Port database update */ + /* Only handle SCNs for our Vport index. */ + if (ha->parent && ha->vp_idx != (mb[3] & 0xff)) + break; + /* * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET * event etc. earlier indicating loop is down) then process diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index bc90d6b8d0a0..250d2f604397 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -918,8 +918,6 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, rval = qla2x00_mailbox_command(ha, mcp); if (mcp->mb[0] == MBS_COMMAND_ERROR) rval = QLA_COMMAND_ERROR; - else if (mcp->mb[0] == MBS_INVALID_COMMAND) - rval = QLA_INVALID_COMMAND; /* Return data. */ *id = mcp->mb[1]; @@ -2163,18 +2161,17 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) struct abort_entry_24xx *abt; dma_addr_t abt_dma; uint32_t handle; - scsi_qla_host_t *pha = to_qla_parent(ha); DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); fcport = sp->fcport; - spin_lock_irqsave(&pha->hardware_lock, flags); + spin_lock_irqsave(&ha->hardware_lock, flags); for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { - if (pha->outstanding_cmds[handle] == sp) + if (ha->outstanding_cmds[handle] == sp) break; } - spin_unlock_irqrestore(&pha->hardware_lock, flags); + spin_unlock_irqrestore(&ha->hardware_lock, flags); if (handle == MAX_OUTSTANDING_COMMANDS) { /* Command not found. */ return QLA_FUNCTION_FAILED; diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index 50baf6a1d67c..62a3ad6e8ecb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -43,7 +43,6 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) set_bit(vp_id, ha->vp_idx_map); ha->num_vhosts++; - ha->cur_vport_count++; vha->vp_idx = vp_id; list_add_tail(&vha->vp_list, &ha->vp_list); mutex_unlock(&ha->vport_lock); @@ -59,7 +58,6 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) mutex_lock(&ha->vport_lock); vp_id = vha->vp_idx; ha->num_vhosts--; - ha->cur_vport_count--; clear_bit(vp_id, ha->vp_idx_map); list_del(&vha->vp_list); mutex_unlock(&ha->vport_lock); @@ -105,8 +103,8 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) "loop_id=0x%04x :%x\n", vha->host_no, fcport->loop_id, fcport->vp_idx)); + atomic_set(&fcport->state, FCS_DEVICE_DEAD); qla2x00_mark_device_lost(vha, fcport, 0, 0); - atomic_set(&fcport->state, FCS_UNCONFIGURED); } } @@ -278,8 +276,7 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha) clear_bit(RESET_ACTIVE, &vha->dpc_flags); } - if (atomic_read(&vha->vp_state) == VP_ACTIVE && - test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { + if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) { qla2x00_loop_resync(vha); clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags); @@ -393,6 +390,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) vha->parent = ha; vha->fc_vport = fc_vport; vha->device_flags = 0; + vha->instance = num_hosts; vha->vp_idx = qla24xx_allocate_vp_id(vha); if (vha->vp_idx > ha->max_npiv_vports) { DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n", @@ -430,7 +428,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) host->max_cmd_len = MAX_CMDSZ; host->max_channel = MAX_BUSES - 1; host->max_lun = MAX_LUNS; - host->unique_id = host->host_no; + host->unique_id = vha->instance; host->max_id = MAX_TARGETS_2200; host->transportt = qla2xxx_transport_vport_template; @@ -438,6 +436,12 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) vha->host_no, vha)); vha->flags.init_done = 1; + num_hosts++; + + mutex_lock(&ha->vport_lock); + set_bit(vha->vp_idx, ha->vp_idx_map); + ha->cur_vport_count++; + mutex_unlock(&ha->vport_lock); return vha; diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 7c8af7ed2a5d..48eaa3bb5433 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -27,6 +27,7 @@ char qla2x00_version_str[40]; */ static struct kmem_cache *srb_cachep; +int num_hosts; int ql2xlogintimeout = 20; module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xlogintimeout, @@ -86,13 +87,6 @@ MODULE_PARM_DESC(ql2xqfullrampup, "depth for a device after a queue-full condition has been " "detected. Default is 120 seconds."); -int ql2xiidmaenable=1; -module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR); -MODULE_PARM_DESC(ql2xiidmaenable, - "Enables iIDMA settings " - "Default is 1 - perform iIDMA. 0 - no iIDMA."); - - /* * SCSI host template entry points */ @@ -394,7 +388,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) } /* Close window on fcport/rport state-transitioning. */ - if (fcport->drport) { + if (!*(fc_port_t **)rport->dd_data) { cmd->result = DID_IMM_RETRY << 16; goto qc_fail_command; } @@ -449,7 +443,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) int rval; scsi_qla_host_t *pha = to_qla_parent(ha); - if (unlikely(pci_channel_offline(pha->pdev))) { + if (unlikely(pci_channel_offline(ha->pdev))) { cmd->result = DID_REQUEUE << 16; goto qc24_fail_command; } @@ -461,7 +455,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) } /* Close window on fcport/rport state-transitioning. */ - if (fcport->drport) { + if (!*(fc_port_t **)rport->dd_data) { cmd->result = DID_IMM_RETRY << 16; goto qc24_fail_command; } @@ -623,40 +617,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) return (return_status); } -void -qla2x00_abort_fcport_cmds(fc_port_t *fcport) -{ - int cnt; - unsigned long flags; - srb_t *sp; - scsi_qla_host_t *ha = fcport->ha; - scsi_qla_host_t *pha = to_qla_parent(ha); - - spin_lock_irqsave(&pha->hardware_lock, flags); - for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - sp = pha->outstanding_cmds[cnt]; - if (!sp) - continue; - if (sp->fcport != fcport) - continue; - - spin_unlock_irqrestore(&pha->hardware_lock, flags); - if (ha->isp_ops->abort_command(ha, sp)) { - DEBUG2(qla_printk(KERN_WARNING, ha, - "Abort failed -- %lx\n", sp->cmd->serial_number)); - } else { - if (qla2x00_eh_wait_on_command(ha, sp->cmd) != - QLA_SUCCESS) - DEBUG2(qla_printk(KERN_WARNING, ha, - "Abort failed while waiting -- %lx\n", - sp->cmd->serial_number)); - - } - spin_lock_irqsave(&pha->hardware_lock, flags); - } - spin_unlock_irqrestore(&pha->hardware_lock, flags); -} - static void qla2x00_block_error_handler(struct scsi_cmnd *cmnd) { @@ -1113,7 +1073,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev) else scsi_deactivate_tcq(sdev, ha->max_q_depth); - rport->dev_loss_tmo = ha->port_down_retry_count; + rport->dev_loss_tmo = ha->port_down_retry_count + 5; return 0; } @@ -1669,6 +1629,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) } host->can_queue = ha->request_q_length + 128; + /* load the F/W, read paramaters, and init the H/W */ + ha->instance = num_hosts; + mutex_init(&ha->vport_lock); init_completion(&ha->mbx_cmd_comp); complete(&ha->mbx_cmd_comp); @@ -1716,7 +1679,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->this_id = 255; host->cmd_per_lun = 3; - host->unique_id = host->host_no; + host->unique_id = ha->instance; host->max_cmd_len = MAX_CMDSZ; host->max_channel = MAX_BUSES - 1; host->max_lun = MAX_LUNS; @@ -1737,6 +1700,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->flags.init_done = 1; ha->flags.online = 1; + num_hosts++; + ret = scsi_add_host(host, &pdev->dev); if (ret) goto probe_failed; @@ -1848,21 +1813,27 @@ static inline void qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, int defer) { + unsigned long flags; struct fc_rport *rport; - scsi_qla_host_t *pha = to_qla_parent(ha); if (!fcport->rport) return; rport = fcport->rport; if (defer) { - spin_lock_irq(ha->host->host_lock); + spin_lock_irqsave(&fcport->rport_lock, flags); fcport->drport = rport; - spin_unlock_irq(ha->host->host_lock); - set_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags); - qla2xxx_wake_dpc(pha); - } else + fcport->rport = NULL; + *(fc_port_t **)rport->dd_data = NULL; + spin_unlock_irqrestore(&fcport->rport_lock, flags); + set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); + } else { + spin_lock_irqsave(&fcport->rport_lock, flags); + fcport->rport = NULL; + *(fc_port_t **)rport->dd_data = NULL; + spin_unlock_irqrestore(&fcport->rport_lock, flags); fc_remote_port_delete(rport); + } } /* @@ -1932,7 +1903,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) scsi_qla_host_t *pha = to_qla_parent(ha); list_for_each_entry(fcport, &pha->fcports, list) { - if (ha->vp_idx != fcport->vp_idx) + if (ha->vp_idx != 0 && ha->vp_idx != fcport->vp_idx) continue; /* * No point in marking the device as lost, if the device is @@ -1940,10 +1911,17 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) */ if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) continue; - if (atomic_read(&fcport->state) == FCS_ONLINE) - qla2x00_schedule_rport_del(ha, fcport, defer); + if (atomic_read(&fcport->state) == FCS_ONLINE) { + if (defer) + qla2x00_schedule_rport_del(ha, fcport, defer); + else if (ha->vp_idx == fcport->vp_idx) + qla2x00_schedule_rport_del(ha, fcport, defer); + } atomic_set(&fcport->state, FCS_DEVICE_LOST); } + + if (defer) + qla2xxx_wake_dpc(ha); } /* @@ -2178,7 +2156,7 @@ qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, static int qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) { - unsigned long uninitialized_var(flags); + unsigned long flags; scsi_qla_host_t *pha = to_qla_parent(ha); if (!locked) @@ -2335,10 +2313,8 @@ qla2x00_do_dpc(void *data) ha->host_no)); } - if (test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) { + if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) qla2x00_update_fcports(ha); - clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); - } if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_sup.c b/trunk/drivers/scsi/qla2xxx/qla_sup.c index 1bca74474935..1728ab3ccb20 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_sup.c +++ b/trunk/drivers/scsi/qla2xxx/qla_sup.c @@ -869,9 +869,11 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, uint32_t i; uint32_t *dwptr; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + unsigned long flags; ret = QLA_SUCCESS; + spin_lock_irqsave(&ha->hardware_lock, flags); /* Enable flash write. */ WRT_REG_DWORD(®->ctrl_status, RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); @@ -905,6 +907,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, WRT_REG_DWORD(®->ctrl_status, RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ + spin_unlock_irqrestore(&ha->hardware_lock, flags); return ret; } @@ -2302,51 +2305,6 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf) return ret; } -static int -qla2xxx_is_vpd_valid(uint8_t *pos, uint8_t *end) -{ - if (pos >= end || *pos != 0x82) - return 0; - - pos += 3 + pos[1]; - if (pos >= end || *pos != 0x90) - return 0; - - pos += 3 + pos[1]; - if (pos >= end || *pos != 0x78) - return 0; - - return 1; -} - -int -qla2xxx_get_vpd_field(scsi_qla_host_t *ha, char *key, char *str, size_t size) -{ - uint8_t *pos = ha->vpd; - uint8_t *end = pos + ha->vpd_size; - int len = 0; - - if (!IS_FWI2_CAPABLE(ha) || !qla2xxx_is_vpd_valid(pos, end)) - return 0; - - while (pos < end && *pos != 0x78) { - len = (*pos == 0x82) ? pos[1] : pos[2]; - - if (!strncmp(pos, key, strlen(key))) - break; - - if (*pos != 0x90 && *pos != 0x91) - pos += len; - - pos += 3; - } - - if (pos < end - len && *pos != 0x78) - return snprintf(str, size, "%.*s", len, pos + 3); - - return 0; -} - static int qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index 676c390db354..d058c8862b35 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.02.01-k6" +#define QLA2XXX_VERSION "8.02.01-k4" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 2 diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index 88bebb13bc52..5822dd595826 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -46,8 +46,6 @@ MODULE_PARM_DESC(ql4xextended_error_logging, int ql4_mod_unload = 0; -#define QL4_DEF_QDEPTH 32 - /* * SCSI host template entry points */ @@ -1389,7 +1387,7 @@ static int qla4xxx_slave_alloc(struct scsi_device *sdev) sdev->hostdata = ddb; sdev->tagged_supported = 1; - scsi_activate_tcq(sdev, QL4_DEF_QDEPTH); + scsi_activate_tcq(sdev, sdev->host->can_queue); return 0; } diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index ee6be596503d..36c92f961e15 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -197,42 +197,10 @@ static void scsi_pool_free_command(struct scsi_host_cmd_pool *pool, struct scsi_cmnd *cmd) { - if (cmd->prot_sdb) - kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb); - kmem_cache_free(pool->sense_slab, cmd->sense_buffer); kmem_cache_free(pool->cmd_slab, cmd); } -/** - * scsi_host_alloc_command - internal function to allocate command - * @shost: SCSI host whose pool to allocate from - * @gfp_mask: mask for the allocation - * - * Returns a fully allocated command with sense buffer and protection - * data buffer (where applicable) or NULL on failure - */ -static struct scsi_cmnd * -scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) -{ - struct scsi_cmnd *cmd; - - cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); - if (!cmd) - return NULL; - - if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) { - cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask); - - if (!cmd->prot_sdb) { - scsi_pool_free_command(shost->cmd_pool, cmd); - return NULL; - } - } - - return cmd; -} - /** * __scsi_get_command - Allocate a struct scsi_cmnd * @shost: host to transmit command @@ -246,7 +214,7 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) struct scsi_cmnd *cmd; unsigned char *buf; - cmd = scsi_host_alloc_command(shost, gfp_mask); + cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); if (unlikely(!cmd)) { unsigned long flags; @@ -489,7 +457,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) /* * Get one backup command for this host. */ - cmd = scsi_host_alloc_command(shost, gfp_mask); + cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); if (!cmd) { scsi_put_host_cmd_pool(gfp_mask); shost->cmd_pool = NULL; @@ -934,20 +902,11 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags) spin_lock_irqsave(sdev->request_queue->queue_lock, flags); - /* - * Check to see if the queue is managed by the block layer. - * If it is, and we fail to adjust the depth, exit. - * - * Do not resize the tag map if it is a host wide share bqt, - * because the size should be the hosts's can_queue. If there - * is more IO than the LLD's can_queue (so there are not enuogh - * tags) request_fn's host queue ready check will handle it. - */ - if (!sdev->host->bqt) { - if (blk_queue_tagged(sdev->request_queue) && - blk_queue_resize_tags(sdev->request_queue, tags) != 0) - goto out; - } + /* Check to see if the queue is managed by the block layer. + * If it is, and we fail to adjust the depth, exit. */ + if (blk_queue_tagged(sdev->request_queue) && + blk_queue_resize_tags(sdev->request_queue, tags) != 0) + goto out; sdev->queue_depth = tags; switch (tagged) { diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c index 27c633f55794..01d11a01ffbf 100644 --- a/trunk/drivers/scsi/scsi_debug.c +++ b/trunk/drivers/scsi/scsi_debug.c @@ -1753,7 +1753,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) open_devip = sdebug_device_create(sdbg_host, GFP_ATOMIC); if (!open_devip) { printk(KERN_ERR "%s: out of memory at line %d\n", - __func__, __LINE__); + __FUNCTION__, __LINE__); return NULL; } } @@ -2656,7 +2656,7 @@ static int sdebug_add_adapter(void) sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); if (NULL == sdbg_host) { printk(KERN_ERR "%s: out of memory at line %d\n", - __func__, __LINE__); + __FUNCTION__, __LINE__); return -ENOMEM; } @@ -2667,7 +2667,7 @@ static int sdebug_add_adapter(void) sdbg_devinfo = sdebug_device_create(sdbg_host, GFP_KERNEL); if (!sdbg_devinfo) { printk(KERN_ERR "%s: out of memory at line %d\n", - __func__, __LINE__); + __FUNCTION__, __LINE__); error = -ENOMEM; goto clean; } @@ -2987,7 +2987,7 @@ static int sdebug_driver_probe(struct device * dev) hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host)); if (NULL == hpnt) { - printk(KERN_ERR "%s: scsi_register failed\n", __func__); + printk(KERN_ERR "%s: scsi_register failed\n", __FUNCTION__); error = -ENODEV; return error; } @@ -3002,7 +3002,7 @@ static int sdebug_driver_probe(struct device * dev) error = scsi_add_host(hpnt, &sdbg_host->dev); if (error) { - printk(KERN_ERR "%s: scsi_add_host failed\n", __func__); + printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__); error = -ENODEV; scsi_host_put(hpnt); } else @@ -3021,7 +3021,7 @@ static int sdebug_driver_remove(struct device * dev) if (!sdbg_host) { printk(KERN_ERR "%s: Unable to locate host info\n", - __func__); + __FUNCTION__); return -ENODEV; } diff --git a/trunk/drivers/scsi/scsi_devinfo.c b/trunk/drivers/scsi/scsi_devinfo.c index 4969e4ec75ea..a235802f2981 100644 --- a/trunk/drivers/scsi/scsi_devinfo.c +++ b/trunk/drivers/scsi/scsi_devinfo.c @@ -272,7 +272,7 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length, } if (from_length > to_length) printk(KERN_WARNING "%s: %s string '%s' is too long\n", - __func__, name, from); + __FUNCTION__, name, from); } /** @@ -298,7 +298,7 @@ static int scsi_dev_info_list_add(int compatible, char *vendor, char *model, devinfo = kmalloc(sizeof(*devinfo), GFP_KERNEL); if (!devinfo) { - printk(KERN_ERR "%s: no memory\n", __func__); + printk(KERN_ERR "%s: no memory\n", __FUNCTION__); return -ENOMEM; } @@ -363,7 +363,7 @@ static int scsi_dev_info_list_add_str(char *dev_list) strflags = strsep(&next, next_check); if (!model || !strflags) { printk(KERN_ERR "%s: bad dev info string '%s' '%s'" - " '%s'\n", __func__, vendor, model, + " '%s'\n", __FUNCTION__, vendor, model, strflags); res = -EINVAL; } else diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 880051c89bde..006a95916f72 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -139,7 +139,7 @@ void scsi_add_timer(struct scsi_cmnd *scmd, int timeout, scmd->eh_timeout.function = (void (*)(unsigned long)) complete; SCSI_LOG_ERROR_RECOVERY(5, printk("%s: scmd: %p, time:" - " %d, (%p)\n", __func__, + " %d, (%p)\n", __FUNCTION__, scmd, timeout, complete)); add_timer(&scmd->eh_timeout); @@ -163,7 +163,7 @@ int scsi_delete_timer(struct scsi_cmnd *scmd) rtn = del_timer(&scmd->eh_timeout); SCSI_LOG_ERROR_RECOVERY(5, printk("%s: scmd: %p," - " rtn: %d\n", __func__, + " rtn: %d\n", __FUNCTION__, scmd, rtn)); scmd->eh_timeout.data = (unsigned long)NULL; @@ -233,7 +233,7 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev) online = scsi_device_online(sdev); - SCSI_LOG_ERROR_RECOVERY(5, printk("%s: rtn: %d\n", __func__, + SCSI_LOG_ERROR_RECOVERY(5, printk("%s: rtn: %d\n", __FUNCTION__, online)); return online; @@ -271,7 +271,7 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost, SCSI_LOG_ERROR_RECOVERY(3, sdev_printk(KERN_INFO, sdev, "%s: cmds failed: %d, cancel: %d\n", - __func__, cmd_failed, + __FUNCTION__, cmd_failed, cmd_cancel)); cmd_cancel = 0; cmd_failed = 0; @@ -344,9 +344,6 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) return /* soft_error */ SUCCESS; case ABORTED_COMMAND: - if (sshdr.asc == 0x10) /* DIF */ - return SUCCESS; - return NEEDS_RETRY; case NOT_READY: case UNIT_ATTENTION: @@ -473,7 +470,7 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n", - __func__, scmd, scmd->result)); + __FUNCTION__, scmd, scmd->result)); eh_action = scmd->device->host->eh_action; if (eh_action) @@ -490,7 +487,7 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd) int rtn; SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n", - __func__)); + __FUNCTION__)); if (!scmd->device->host->hostt->eh_host_reset_handler) return FAILED; @@ -519,7 +516,7 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd) int rtn; SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n", - __func__)); + __FUNCTION__)); if (!scmd->device->host->hostt->eh_bus_reset_handler) return FAILED; @@ -667,10 +664,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, ses->sdb = scmd->sdb; ses->next_rq = scmd->request->next_rq; ses->result = scmd->result; - ses->underflow = scmd->underflow; - ses->prot_op = scmd->prot_op; - scmd->prot_op = SCSI_PROT_NORMAL; scmd->cmnd = ses->eh_cmnd; memset(scmd->cmnd, 0, BLK_MAX_CDB); memset(&scmd->sdb, 0, sizeof(scmd->sdb)); @@ -728,8 +722,6 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) scmd->sdb = ses->sdb; scmd->request->next_rq = ses->next_rq; scmd->result = ses->result; - scmd->underflow = ses->underflow; - scmd->prot_op = ses->prot_op; } EXPORT_SYMBOL(scsi_eh_restore_cmnd); @@ -774,7 +766,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, timeleft: %ld\n", - __func__, scmd, timeleft)); + __FUNCTION__, scmd, timeleft)); /* * If there is time left scsi_eh_done got called, and we will @@ -786,7 +778,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, rtn = scsi_eh_completed_normally(scmd); SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scsi_eh_completed_normally %x\n", - __func__, rtn)); + __FUNCTION__, rtn)); switch (rtn) { case SUCCESS: @@ -921,7 +913,7 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd) rtn = scsi_send_eh_cmnd(scmd, tur_command, 6, SENSE_TIMEOUT, 0); SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", - __func__, scmd, rtn)); + __FUNCTION__, scmd, rtn)); switch (rtn) { case NEEDS_RETRY: @@ -1304,7 +1296,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) if (!scsi_device_online(scmd->device)) { SCSI_LOG_ERROR_RECOVERY(5, printk("%s: device offline - report" " as SUCCESS\n", - __func__)); + __FUNCTION__)); return SUCCESS; } @@ -1519,7 +1511,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost) * ioctls to queued block devices. */ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n", - __func__)); + __FUNCTION__)); spin_lock_irqsave(shost->host_lock, flags); if (scsi_host_set_state(shost, SHOST_RUNNING)) @@ -1843,7 +1835,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag) */ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart after TMF\n", - __func__)); + __FUNCTION__)); wake_up(&shost->host_wait); diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index ff5d56b3ee4d..88d1b5f44e59 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -65,7 +65,7 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = { }; #undef SP -struct kmem_cache *scsi_sdb_cache; +static struct kmem_cache *scsi_sdb_cache; static void scsi_run_queue(struct request_queue *q); @@ -787,9 +787,6 @@ void scsi_release_buffers(struct scsi_cmnd *cmd) kmem_cache_free(scsi_sdb_cache, bidi_sdb); cmd->request->next_rq->special = NULL; } - - if (scsi_prot_sg_count(cmd)) - scsi_free_sgtable(cmd->prot_sdb); } EXPORT_SYMBOL(scsi_release_buffers); @@ -950,14 +947,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) * 6-byte command. */ scsi_requeue_command(q, cmd); - } else if (sshdr.asc == 0x10) /* DIX */ - scsi_end_request(cmd, -EIO, this_count, 0); - else + return; + } else { scsi_end_request(cmd, -EIO, this_count, 1); - return; - case ABORTED_COMMAND: - if (sshdr.asc == 0x10) { /* DIF */ - scsi_end_request(cmd, -EIO, this_count, 0); return; } break; @@ -1080,26 +1072,6 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask) goto err_exit; } - if (blk_integrity_rq(cmd->request)) { - struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; - int ivecs, count; - - BUG_ON(prot_sdb == NULL); - ivecs = blk_rq_count_integrity_sg(cmd->request); - - if (scsi_alloc_sgtable(prot_sdb, ivecs, gfp_mask)) { - error = BLKPREP_DEFER; - goto err_exit; - } - - count = blk_rq_map_integrity_sg(cmd->request, - prot_sdb->table.sgl); - BUG_ON(unlikely(count > ivecs)); - - cmd->prot_sdb = prot_sdb; - cmd->prot_sdb->table.nents = count; - } - return BLKPREP_OK ; err_exit: @@ -1395,7 +1367,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) if (unlikely(cmd == NULL)) { printk(KERN_CRIT "impossible request in %s.\n", - __func__); + __FUNCTION__); BUG(); } @@ -1519,27 +1491,12 @@ static void scsi_request_fn(struct request_queue *q) printk(KERN_CRIT "impossible request in %s.\n" "please mail a stack trace to " "linux-scsi@vger.kernel.org\n", - __func__); + __FUNCTION__); blk_dump_rq_flags(req, "foo"); BUG(); } spin_lock(shost->host_lock); - /* - * We hit this when the driver is using a host wide - * tag map. For device level tag maps the queue_depth check - * in the device ready fn would prevent us from trying - * to allocate a tag. Since the map is a shared host resource - * we add the dev to the starved list so it eventually gets - * a run when a tag is freed. - */ - if (blk_queue_tagged(q) && !blk_rq_tagged(req)) { - if (list_empty(&sdev->starved_entry)) - list_add_tail(&sdev->starved_entry, - &shost->starved_list); - goto not_ready; - } - if (!scsi_host_queue_ready(q, shost, sdev)) goto not_ready; if (scsi_target(sdev)->single_lun) { @@ -2529,7 +2486,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count, if (unlikely(i == sg_count)) { printk(KERN_ERR "%s: Bytes in sg: %zu, requested offset %zu, " "elements %d\n", - __func__, sg_len, *offset, sg_count); + __FUNCTION__, sg_len, *offset, sg_count); WARN_ON(1); return NULL; } diff --git a/trunk/drivers/scsi/scsi_netlink.c b/trunk/drivers/scsi/scsi_netlink.c index ae7ed9a22662..370c78cc1cb5 100644 --- a/trunk/drivers/scsi/scsi_netlink.c +++ b/trunk/drivers/scsi/scsi_netlink.c @@ -55,7 +55,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) if ((nlh->nlmsg_len < (sizeof(*nlh) + sizeof(*hdr))) || (skb->len < nlh->nlmsg_len)) { printk(KERN_WARNING "%s: discarding partial skb\n", - __func__); + __FUNCTION__); return; } @@ -82,7 +82,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) if (nlh->nlmsg_len < (sizeof(*nlh) + hdr->msglen)) { printk(KERN_WARNING "%s: discarding partial message\n", - __func__); + __FUNCTION__); return; } @@ -139,7 +139,7 @@ scsi_netlink_init(void) error = netlink_register_notifier(&scsi_netlink_notifier); if (error) { printk(KERN_ERR "%s: register of event handler failed - %d\n", - __func__, error); + __FUNCTION__, error); return; } @@ -148,7 +148,7 @@ scsi_netlink_init(void) THIS_MODULE); if (!scsi_nl_sock) { printk(KERN_ERR "%s: register of recieve handler failed\n", - __func__); + __FUNCTION__); netlink_unregister_notifier(&scsi_netlink_notifier); } diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index 79f0f7511204..b33e72516ef8 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -77,7 +77,6 @@ extern void scsi_exit_queue(void); struct request_queue; struct request; extern int scsi_prep_fn(struct request_queue *, struct request *); -extern struct kmem_cache *scsi_sdb_cache; /* scsi_proc.c */ #ifdef CONFIG_SCSI_PROC_FS diff --git a/trunk/drivers/scsi/scsi_proc.c b/trunk/drivers/scsi/scsi_proc.c index c6a904a45bf9..e4a0d2f9b357 100644 --- a/trunk/drivers/scsi/scsi_proc.c +++ b/trunk/drivers/scsi/scsi_proc.c @@ -114,7 +114,7 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht) sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi); if (!sht->proc_dir) printk(KERN_ERR "%s: proc_mkdir failed for %s\n", - __func__, sht->proc_name); + __FUNCTION__, sht->proc_name); else sht->proc_dir->owner = sht->module; } @@ -157,7 +157,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost) sht->proc_dir, proc_scsi_read, shost); if (!p) { printk(KERN_ERR "%s: Failed to register host %d in" - "%s\n", __func__, shost->host_no, + "%s\n", __FUNCTION__, shost->host_no, sht->proc_name); return; } diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index 84b4879cff11..196fe3af0d5e 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -318,7 +318,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, put_device(&sdev->sdev_gendev); out: if (display_failure_msg) - printk(ALLOC_FAILURE_MSG, __func__); + printk(ALLOC_FAILURE_MSG, __FUNCTION__); return NULL; } @@ -404,7 +404,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, starget = kzalloc(size, GFP_KERNEL); if (!starget) { - printk(KERN_ERR "%s: allocation failure\n", __func__); + printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); return NULL; } dev = &starget->dev; @@ -1337,7 +1337,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, lun_data = kmalloc(length, GFP_ATOMIC | (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); if (!lun_data) { - printk(ALLOC_FAILURE_MSG, __func__); + printk(ALLOC_FAILURE_MSG, __FUNCTION__); goto out; } @@ -1649,7 +1649,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, { SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost, "%s: <%u:%u:%u>\n", - __func__, channel, id, lun)); + __FUNCTION__, channel, id, lun)); if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || @@ -1703,7 +1703,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) return NULL; if (shost->async_scan) { - printk("%s called twice for host %d", __func__, + printk("%s called twice for host %d", __FUNCTION__, shost->host_no); dump_stack(); return NULL; @@ -1757,10 +1757,9 @@ static void scsi_finish_async_scan(struct async_scan_data *data) mutex_lock(&shost->scan_mutex); if (!shost->async_scan) { - printk("%s called twice for host %d", __func__, + printk("%s called twice for host %d", __FUNCTION__, shost->host_no); dump_stack(); - mutex_unlock(&shost->scan_mutex); return; } diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index ab3c71869be5..b6e561059779 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -249,8 +249,6 @@ 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_attr(prot_capabilities, "%u\n"); -shost_rd_attr(prot_guard_type, "%hd\n"); shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); static struct attribute *scsi_sysfs_shost_attrs[] = { @@ -265,8 +263,6 @@ static struct attribute *scsi_sysfs_shost_attrs[] = { &dev_attr_hstate.attr, &dev_attr_supported_mode.attr, &dev_attr_active_mode.attr, - &dev_attr_prot_capabilities.attr, - &dev_attr_prot_guard_type.attr, NULL }; diff --git a/trunk/drivers/scsi/scsi_tgt_priv.h b/trunk/drivers/scsi/scsi_tgt_priv.h index fe4c62177f78..cb92888948f9 100644 --- a/trunk/drivers/scsi/scsi_tgt_priv.h +++ b/trunk/drivers/scsi/scsi_tgt_priv.h @@ -6,7 +6,7 @@ struct task_struct; /* tmp - will replace with SCSI logging stuff */ #define eprintk(fmt, args...) \ do { \ - printk("%s(%d) " fmt, __func__, __LINE__, ##args); \ + printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ } while (0) #define dprintk(fmt, args...) diff --git a/trunk/drivers/scsi/scsi_transport_fc.c b/trunk/drivers/scsi/scsi_transport_fc.c index 56823fd1fb84..a272b9a2c869 100644 --- a/trunk/drivers/scsi/scsi_transport_fc.c +++ b/trunk/drivers/scsi/scsi_transport_fc.c @@ -571,7 +571,7 @@ fc_host_post_event(struct Scsi_Host *shost, u32 event_number, name = get_fc_host_event_code_name(event_code); printk(KERN_WARNING "%s: Dropped Event : host %d %s data 0x%08x - err %d\n", - __func__, shost->host_no, + __FUNCTION__, shost->host_no, (name) ? name : "", event_data, err); return; } @@ -644,7 +644,7 @@ fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, send_vendor_fail: printk(KERN_WARNING "%s: Dropped Event : host %d vendor_unique - err %d\n", - __func__, shost->host_no, err); + __FUNCTION__, shost->host_no, err); return; } EXPORT_SYMBOL(fc_host_post_vendor_event); @@ -2464,7 +2464,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel, size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size); rport = kzalloc(size, GFP_KERNEL); if (unlikely(!rport)) { - printk(KERN_ERR "%s: allocation failure\n", __func__); + printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); return NULL; } @@ -3137,7 +3137,7 @@ fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev, size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size); vport = kzalloc(size, GFP_KERNEL); if (unlikely(!vport)) { - printk(KERN_ERR "%s: allocation failure\n", __func__); + printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); return -ENOMEM; } @@ -3201,7 +3201,7 @@ fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev, printk(KERN_ERR "%s: Cannot create vport symlinks for " "%s, err=%d\n", - __func__, dev->bus_id, error); + __FUNCTION__, dev->bus_id, error); } spin_lock_irqsave(shost->host_lock, flags); vport->flags &= ~FC_VPORT_CREATING; @@ -3314,7 +3314,7 @@ fc_vport_sched_delete(struct work_struct *work) if (stat) dev_printk(KERN_ERR, vport->dev.parent, "%s: %s could not be deleted created via " - "shost%d channel %d - error %d\n", __func__, + "shost%d channel %d - error %d\n", __FUNCTION__, vport->dev.bus_id, vport->shost->host_no, vport->channel, stat); } diff --git a/trunk/drivers/scsi/scsi_transport_sas.c b/trunk/drivers/scsi/scsi_transport_sas.c index 366609386be1..f4461d35ffb9 100644 --- a/trunk/drivers/scsi/scsi_transport_sas.c +++ b/trunk/drivers/scsi/scsi_transport_sas.c @@ -779,7 +779,7 @@ static void sas_port_create_link(struct sas_port *port, return; err: printk(KERN_ERR "%s: Cannot create port links, err=%d\n", - __func__, res); + __FUNCTION__, res); } static void sas_port_delete_link(struct sas_port *port, @@ -1029,7 +1029,7 @@ void sas_port_mark_backlink(struct sas_port *port) return; err: printk(KERN_ERR "%s: Cannot create port backlink, err=%d\n", - __func__, res); + __FUNCTION__, res); } EXPORT_SYMBOL(sas_port_mark_backlink); diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index e5e7d7856454..0c63947d8a9d 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -99,7 +99,8 @@ static void scsi_disk_release(struct device *cdev); static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); static void sd_print_result(struct scsi_disk *, int); -static DEFINE_IDA(sd_index_ida); +static DEFINE_IDR(sd_index_idr); +static DEFINE_SPINLOCK(sd_index_lock); /* This semaphore is used to mediate the 0->1 reference get in the * face of object destruction (i.e. we can't allow a get on an @@ -233,24 +234,6 @@ sd_show_allow_restart(struct device *dev, struct device_attribute *attr, return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); } -static ssize_t -sd_show_protection_type(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(dev); - - return snprintf(buf, 20, "%u\n", sdkp->protection_type); -} - -static ssize_t -sd_show_app_tag_own(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(dev); - - return snprintf(buf, 20, "%u\n", sdkp->ATO); -} - static struct device_attribute sd_disk_attrs[] = { __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, sd_store_cache_type), @@ -259,8 +242,6 @@ static struct device_attribute sd_disk_attrs[] = { sd_store_allow_restart), __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, sd_store_manage_start_stop), - __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL), - __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), __ATTR_NULL, }; @@ -373,9 +354,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) struct scsi_cmnd *SCpnt; struct scsi_device *sdp = q->queuedata; struct gendisk *disk = rq->rq_disk; - struct scsi_disk *sdkp; sector_t block = rq->sector; - sector_t threshold; unsigned int this_count = rq->nr_sectors; unsigned int timeout = sdp->timeout; int ret; @@ -391,7 +370,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) if (ret != BLKPREP_OK) goto out; SCpnt = rq->special; - sdkp = scsi_disk(disk); /* from here on until we're complete, any goto out * is used for a killable error condition */ @@ -423,21 +401,13 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } /* - * Some SD card readers can't handle multi-sector accesses which touch - * the last one or two hardware sectors. Split accesses as needed. + * Some devices (some sdcards for one) don't like it if the + * last sector gets read in a larger then 1 sector read. */ - threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS * - (sdp->sector_size / 512); - - if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) { - if (block < threshold) { - /* Access up to the threshold but not beyond */ - this_count = threshold - block; - } else { - /* Access only a single hardware sector */ - this_count = sdp->sector_size / 512; - } - } + if (unlikely(sdp->last_sector_bug && + rq->nr_sectors > sdp->sector_size / 512 && + block + this_count == get_capacity(disk))) + this_count -= sdp->sector_size / 512; SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", (unsigned long long)block)); @@ -489,11 +459,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } SCpnt->cmnd[0] = WRITE_6; SCpnt->sc_data_direction = DMA_TO_DEVICE; - - if (blk_integrity_rq(rq) && - sd_dif_prepare(rq, block, sdp->sector_size) == -EIO) - goto out; - } else if (rq_data_dir(rq) == READ) { SCpnt->cmnd[0] = READ_6; SCpnt->sc_data_direction = DMA_FROM_DEVICE; @@ -508,12 +473,8 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) "writing" : "reading", this_count, rq->nr_sectors)); - /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */ - if (scsi_host_dif_capable(sdp->host, sdkp->protection_type)) - SCpnt->cmnd[1] = 1 << 5; - else - SCpnt->cmnd[1] = 0; - + SCpnt->cmnd[1] = 0; + if (block > 0xffffffff) { SCpnt->cmnd[0] += READ_16 - READ_6; SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; @@ -531,7 +492,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->cmnd[13] = (unsigned char) this_count & 0xff; SCpnt->cmnd[14] = SCpnt->cmnd[15] = 0; } else if ((this_count > 0xff) || (block > 0x1fffff) || - scsi_device_protection(SCpnt->device) || SCpnt->device->use_10_for_rw) { if (this_count > 0xffff) this_count = 0xffff; @@ -566,10 +526,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } SCpnt->sdb.length = this_count * sdp->sector_size; - /* If DIF or DIX is enabled, tell HBA how to handle request */ - if (sdkp->protection_type || scsi_prot_sg_count(SCpnt)) - sd_dif_op(SCpnt, sdkp->protection_type, scsi_prot_sg_count(SCpnt)); - /* * We shouldn't disconnect in the middle of a sector, so with a dumb * host adapter, it's safe to assume that we can at least transfer @@ -964,48 +920,6 @@ static struct block_device_operations sd_fops = { .revalidate_disk = sd_revalidate_disk, }; -static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) -{ - u64 start_lba = scmd->request->sector; - u64 end_lba = scmd->request->sector + (scsi_bufflen(scmd) / 512); - u64 bad_lba; - int info_valid; - - if (!blk_fs_request(scmd->request)) - return 0; - - info_valid = scsi_get_sense_info_fld(scmd->sense_buffer, - SCSI_SENSE_BUFFERSIZE, - &bad_lba); - if (!info_valid) - return 0; - - if (scsi_bufflen(scmd) <= scmd->device->sector_size) - return 0; - - if (scmd->device->sector_size < 512) { - /* only legitimate sector_size here is 256 */ - start_lba <<= 1; - end_lba <<= 1; - } else { - /* be careful ... don't want any overflows */ - u64 factor = scmd->device->sector_size / 512; - do_div(start_lba, factor); - do_div(end_lba, factor); - } - - /* The bad lba was reported incorrectly, we have no idea where - * the error is. - */ - if (bad_lba < start_lba || bad_lba >= end_lba) - return 0; - - /* This computation should always be done in terms of - * the resolution of the device's medium. - */ - return (bad_lba - start_lba) * scmd->device->sector_size; -} - /** * sd_done - bottom half handler: called when the lower level * driver has completed (successfully or otherwise) a scsi command. @@ -1016,10 +930,15 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) static int sd_done(struct scsi_cmnd *SCpnt) { int result = SCpnt->result; - unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); + unsigned int xfer_size = scsi_bufflen(SCpnt); + unsigned int good_bytes = result ? 0 : xfer_size; + u64 start_lba = SCpnt->request->sector; + u64 end_lba = SCpnt->request->sector + (xfer_size / 512); + u64 bad_lba; struct scsi_sense_hdr sshdr; int sense_valid = 0; int sense_deferred = 0; + int info_valid; if (result) { sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); @@ -1044,7 +963,36 @@ static int sd_done(struct scsi_cmnd *SCpnt) switch (sshdr.sense_key) { case HARDWARE_ERROR: case MEDIUM_ERROR: - good_bytes = sd_completed_bytes(SCpnt); + if (!blk_fs_request(SCpnt->request)) + goto out; + info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer, + SCSI_SENSE_BUFFERSIZE, + &bad_lba); + if (!info_valid) + goto out; + if (xfer_size <= SCpnt->device->sector_size) + goto out; + if (SCpnt->device->sector_size < 512) { + /* only legitimate sector_size here is 256 */ + start_lba <<= 1; + end_lba <<= 1; + } else { + /* be careful ... don't want any overflows */ + u64 factor = SCpnt->device->sector_size / 512; + do_div(start_lba, factor); + do_div(end_lba, factor); + } + + if (bad_lba < start_lba || bad_lba >= end_lba) + /* the bad lba was reported incorrectly, we have + * no idea where the error is + */ + goto out; + + /* This computation should always be done in terms of + * the resolution of the device's medium. + */ + good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size; break; case RECOVERED_ERROR: case NO_SENSE: @@ -1054,23 +1002,10 @@ static int sd_done(struct scsi_cmnd *SCpnt) scsi_print_sense("sd", SCpnt); SCpnt->result = 0; memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); - good_bytes = scsi_bufflen(SCpnt); - break; - case ABORTED_COMMAND: - if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */ - scsi_print_result(SCpnt); - scsi_print_sense("sd", SCpnt); - good_bytes = sd_completed_bytes(SCpnt); - } + good_bytes = xfer_size; break; case ILLEGAL_REQUEST: - if (sshdr.asc == 0x10) { /* DIX: HBA detected corruption */ - scsi_print_result(SCpnt); - scsi_print_sense("sd", SCpnt); - good_bytes = sd_completed_bytes(SCpnt); - } - if (!scsi_device_protection(SCpnt->device) && - SCpnt->device->use_10_for_rw && + if (SCpnt->device->use_10_for_rw && (SCpnt->cmnd[0] == READ_10 || SCpnt->cmnd[0] == WRITE_10)) SCpnt->device->use_10_for_rw = 0; @@ -1083,9 +1018,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) break; } out: - if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) - sd_dif_complete(SCpnt, good_bytes); - return good_bytes; } @@ -1233,49 +1165,6 @@ sd_spinup_disk(struct scsi_disk *sdkp) } } - -/* - * Determine whether disk supports Data Integrity Field. - */ -void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) -{ - struct scsi_device *sdp = sdkp->device; - u8 type; - - if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) - type = 0; - else - type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ - - switch (type) { - case SD_DIF_TYPE0_PROTECTION: - sdkp->protection_type = 0; - break; - - case SD_DIF_TYPE1_PROTECTION: - case SD_DIF_TYPE3_PROTECTION: - sdkp->protection_type = type; - break; - - case SD_DIF_TYPE2_PROTECTION: - sd_printk(KERN_ERR, sdkp, "formatted with DIF Type 2 " \ - "protection which is currently unsupported. " \ - "Disabling disk!\n"); - goto disable; - - default: - sd_printk(KERN_ERR, sdkp, "formatted with unknown " \ - "protection type %d. Disabling disk!\n", type); - goto disable; - } - - return; - -disable: - sdkp->protection_type = 0; - sdkp->capacity = 0; -} - /* * read disk capacity */ @@ -1285,8 +1174,7 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) unsigned char cmd[16]; int the_result, retries; int sector_size = 0; - /* Force READ CAPACITY(16) when PROTECT=1 */ - int longrc = scsi_device_protection(sdkp->device) ? 1 : 0; + int longrc = 0; struct scsi_sense_hdr sshdr; int sense_valid = 0; struct scsi_device *sdp = sdkp->device; @@ -1298,8 +1186,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) memset((void *) cmd, 0, 16); cmd[0] = SERVICE_ACTION_IN; cmd[1] = SAI_READ_CAPACITY_16; - cmd[13] = 13; - memset((void *) buffer, 0, 13); + cmd[13] = 12; + memset((void *) buffer, 0, 12); } else { cmd[0] = READ_CAPACITY; memset((void *) &cmd[1], 0, 9); @@ -1307,7 +1195,7 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) } the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, - buffer, longrc ? 13 : 8, &sshdr, + buffer, longrc ? 12 : 8, &sshdr, SD_TIMEOUT, SD_MAX_RETRIES); if (media_not_present(sdkp, &sshdr)) @@ -1382,8 +1270,6 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) sector_size = (buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) | buffer[11]; - - sd_read_protection_type(sdkp, buffer); } /* Some devices return the total number of sectors, not the @@ -1645,52 +1531,6 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) sdkp->DPOFUA = 0; } -/* - * The ATO bit indicates whether the DIF application tag is available - * for use by the operating system. - */ -void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) -{ - int res, offset; - struct scsi_device *sdp = sdkp->device; - struct scsi_mode_data data; - struct scsi_sense_hdr sshdr; - - if (sdp->type != TYPE_DISK) - return; - - if (sdkp->protection_type == 0) - return; - - res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT, - SD_MAX_RETRIES, &data, &sshdr); - - if (!scsi_status_is_good(res) || !data.header_length || - data.length < 6) { - sd_printk(KERN_WARNING, sdkp, - "getting Control mode page failed, assume no ATO\n"); - - if (scsi_sense_valid(&sshdr)) - sd_print_sense_hdr(sdkp, &sshdr); - - return; - } - - offset = data.header_length + data.block_descriptor_length; - - if ((buffer[offset] & 0x3f) != 0x0a) { - sd_printk(KERN_ERR, sdkp, "ATO Got wrong page\n"); - return; - } - - if ((buffer[offset + 5] & 0x80) == 0) - return; - - sdkp->ATO = 1; - - return; -} - /** * sd_revalidate_disk - called the first time a new disk is seen, * performs disk spin up, read_capacity, etc. @@ -1727,7 +1567,6 @@ static int sd_revalidate_disk(struct gendisk *disk) sdkp->write_prot = 0; sdkp->WCE = 0; sdkp->RCD = 0; - sdkp->ATO = 0; sd_spinup_disk(sdkp); @@ -1739,7 +1578,6 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_capacity(sdkp, buffer); sd_read_write_protect_flag(sdkp, buffer); sd_read_cache_type(sdkp, buffer); - sd_read_app_tag_own(sdkp, buffer); } /* @@ -1805,20 +1643,18 @@ static int sd_probe(struct device *dev) if (!gd) goto out_free; - do { - if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) - goto out_put; + if (!idr_pre_get(&sd_index_idr, GFP_KERNEL)) + goto out_put; - error = ida_get_new(&sd_index_ida, &index); - } while (error == -EAGAIN); + spin_lock(&sd_index_lock); + error = idr_get_new(&sd_index_idr, NULL, &index); + spin_unlock(&sd_index_lock); + if (index >= SD_MAX_DISKS) + error = -EBUSY; if (error) goto out_put; - error = -EBUSY; - if (index >= SD_MAX_DISKS) - goto out_free_index; - sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd; @@ -1839,7 +1675,7 @@ static int sd_probe(struct device *dev) strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); if (device_add(&sdkp->dev)) - goto out_free_index; + goto out_put; get_device(&sdp->sdev_gendev); @@ -1875,15 +1711,12 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); add_disk(gd); - sd_dif_config_host(sdkp); sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", sdp->removable ? "removable " : ""); return 0; - out_free_index: - ida_remove(&sd_index_ida, index); out_put: put_disk(gd); out_free: @@ -1933,7 +1766,9 @@ static void scsi_disk_release(struct device *dev) struct scsi_disk *sdkp = to_scsi_disk(dev); struct gendisk *disk = sdkp->disk; - ida_remove(&sd_index_ida, sdkp->index); + spin_lock(&sd_index_lock); + idr_remove(&sd_index_idr, sdkp->index); + spin_unlock(&sd_index_lock); disk->private_data = NULL; put_disk(disk); diff --git a/trunk/drivers/scsi/sd.h b/trunk/drivers/scsi/sd.h index 95b9f06534d5..03a3d45cfa42 100644 --- a/trunk/drivers/scsi/sd.h +++ b/trunk/drivers/scsi/sd.h @@ -31,12 +31,6 @@ */ #define SD_BUF_SIZE 512 -/* - * Number of sectors at the end of the device to avoid multi-sector - * accesses to in the case of last_sector_bug - */ -#define SD_LAST_BUGGY_SECTORS 8 - struct scsi_disk { struct scsi_driver *driver; /* always &sd_template */ struct scsi_device *device; @@ -47,9 +41,7 @@ struct scsi_disk { u32 index; u8 media_present; u8 write_prot; - u8 protection_type;/* Data Integrity Field */ unsigned previous_state : 1; - unsigned ATO : 1; /* state of disk ATO bit */ unsigned WCE : 1; /* state of disk WCE bit */ unsigned RCD : 1; /* state of disk RCD bit, unused */ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ @@ -67,50 +59,4 @@ static inline struct scsi_disk *scsi_disk(struct gendisk *disk) (sdsk)->disk->disk_name, ##a) : \ sdev_printk(prefix, (sdsk)->device, fmt, ##a) -/* - * A DIF-capable target device can be formatted with different - * protection schemes. Currently 0 through 3 are defined: - * - * Type 0 is regular (unprotected) I/O - * - * Type 1 defines the contents of the guard and reference tags - * - * Type 2 defines the contents of the guard and reference tags and - * uses 32-byte commands to seed the latter - * - * Type 3 defines the contents of the guard tag only - */ - -enum sd_dif_target_protection_types { - SD_DIF_TYPE0_PROTECTION = 0x0, - SD_DIF_TYPE1_PROTECTION = 0x1, - SD_DIF_TYPE2_PROTECTION = 0x2, - SD_DIF_TYPE3_PROTECTION = 0x3, -}; - -/* - * Data Integrity Field tuple. - */ -struct sd_dif_tuple { - __be16 guard_tag; /* Checksum */ - __be16 app_tag; /* Opaque storage */ - __be32 ref_tag; /* Target LBA or indirect LBA */ -}; - -#if defined(CONFIG_BLK_DEV_INTEGRITY) - -extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int); -extern void sd_dif_config_host(struct scsi_disk *); -extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int); -extern void sd_dif_complete(struct scsi_cmnd *, unsigned int); - -#else /* CONFIG_BLK_DEV_INTEGRITY */ - -#define sd_dif_op(a, b, c) do { } while (0) -#define sd_dif_config_host(a) do { } while (0) -#define sd_dif_prepare(a, b, c) (0) -#define sd_dif_complete(a, b) (0) - -#endif /* CONFIG_BLK_DEV_INTEGRITY */ - #endif /* _SCSI_DISK_H */ diff --git a/trunk/drivers/scsi/sd_dif.c b/trunk/drivers/scsi/sd_dif.c deleted file mode 100644 index 4d17f3d35aac..000000000000 --- a/trunk/drivers/scsi/sd_dif.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * sd_dif.c - SCSI Data Integrity Field - * - * Copyright (C) 2007, 2008 Oracle Corporation - * Written by: Martin K. Petersen - * - * 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 License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "sd.h" - -typedef __u16 (csum_fn) (void *, unsigned int); - -static __u16 sd_dif_crc_fn(void *data, unsigned int len) -{ - return cpu_to_be16(crc_t10dif(data, len)); -} - -static __u16 sd_dif_ip_fn(void *data, unsigned int len) -{ - return ip_compute_csum(data, len); -} - -/* - * Type 1 and Type 2 protection use the same format: 16 bit guard tag, - * 16 bit app tag, 32 bit reference tag. - */ -static void sd_dif_type1_generate(struct blk_integrity_exchg *bix, csum_fn *fn) -{ - void *buf = bix->data_buf; - struct sd_dif_tuple *sdt = bix->prot_buf; - sector_t sector = bix->sector; - unsigned int i; - - for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) { - sdt->guard_tag = fn(buf, bix->sector_size); - sdt->ref_tag = cpu_to_be32(sector & 0xffffffff); - sdt->app_tag = 0; - - buf += bix->sector_size; - sector++; - } -} - -static void sd_dif_type1_generate_crc(struct blk_integrity_exchg *bix) -{ - sd_dif_type1_generate(bix, sd_dif_crc_fn); -} - -static void sd_dif_type1_generate_ip(struct blk_integrity_exchg *bix) -{ - sd_dif_type1_generate(bix, sd_dif_ip_fn); -} - -static int sd_dif_type1_verify(struct blk_integrity_exchg *bix, csum_fn *fn) -{ - void *buf = bix->data_buf; - struct sd_dif_tuple *sdt = bix->prot_buf; - sector_t sector = bix->sector; - unsigned int i; - __u16 csum; - - for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) { - /* Unwritten sectors */ - if (sdt->app_tag == 0xffff) - return 0; - - /* Bad ref tag received from disk */ - if (sdt->ref_tag == 0xffffffff) { - printk(KERN_ERR - "%s: bad phys ref tag on sector %lu\n", - bix->disk_name, (unsigned long)sector); - return -EIO; - } - - if (be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) { - printk(KERN_ERR - "%s: ref tag error on sector %lu (rcvd %u)\n", - bix->disk_name, (unsigned long)sector, - be32_to_cpu(sdt->ref_tag)); - return -EIO; - } - - csum = fn(buf, bix->sector_size); - - if (sdt->guard_tag != csum) { - printk(KERN_ERR "%s: guard tag error on sector %lu " \ - "(rcvd %04x, data %04x)\n", bix->disk_name, - (unsigned long)sector, - be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); - return -EIO; - } - - buf += bix->sector_size; - sector++; - } - - return 0; -} - -static int sd_dif_type1_verify_crc(struct blk_integrity_exchg *bix) -{ - return sd_dif_type1_verify(bix, sd_dif_crc_fn); -} - -static int sd_dif_type1_verify_ip(struct blk_integrity_exchg *bix) -{ - return sd_dif_type1_verify(bix, sd_dif_ip_fn); -} - -/* - * Functions for interleaving and deinterleaving application tags - */ -static void sd_dif_type1_set_tag(void *prot, void *tag_buf, unsigned int sectors) -{ - struct sd_dif_tuple *sdt = prot; - char *tag = tag_buf; - unsigned int i, j; - - for (i = 0, j = 0 ; i < sectors ; i++, j += 2, sdt++) { - sdt->app_tag = tag[j] << 8 | tag[j+1]; - BUG_ON(sdt->app_tag == 0xffff); - } -} - -static void sd_dif_type1_get_tag(void *prot, void *tag_buf, unsigned int sectors) -{ - struct sd_dif_tuple *sdt = prot; - char *tag = tag_buf; - unsigned int i, j; - - for (i = 0, j = 0 ; i < sectors ; i++, j += 2, sdt++) { - tag[j] = (sdt->app_tag & 0xff00) >> 8; - tag[j+1] = sdt->app_tag & 0xff; - } -} - -static struct blk_integrity dif_type1_integrity_crc = { - .name = "T10-DIF-TYPE1-CRC", - .generate_fn = sd_dif_type1_generate_crc, - .verify_fn = sd_dif_type1_verify_crc, - .get_tag_fn = sd_dif_type1_get_tag, - .set_tag_fn = sd_dif_type1_set_tag, - .tuple_size = sizeof(struct sd_dif_tuple), - .tag_size = 0, -}; - -static struct blk_integrity dif_type1_integrity_ip = { - .name = "T10-DIF-TYPE1-IP", - .generate_fn = sd_dif_type1_generate_ip, - .verify_fn = sd_dif_type1_verify_ip, - .get_tag_fn = sd_dif_type1_get_tag, - .set_tag_fn = sd_dif_type1_set_tag, - .tuple_size = sizeof(struct sd_dif_tuple), - .tag_size = 0, -}; - - -/* - * Type 3 protection has a 16-bit guard tag and 16 + 32 bits of opaque - * tag space. - */ -static void sd_dif_type3_generate(struct blk_integrity_exchg *bix, csum_fn *fn) -{ - void *buf = bix->data_buf; - struct sd_dif_tuple *sdt = bix->prot_buf; - unsigned int i; - - for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) { - sdt->guard_tag = fn(buf, bix->sector_size); - sdt->ref_tag = 0; - sdt->app_tag = 0; - - buf += bix->sector_size; - } -} - -static void sd_dif_type3_generate_crc(struct blk_integrity_exchg *bix) -{ - sd_dif_type3_generate(bix, sd_dif_crc_fn); -} - -static void sd_dif_type3_generate_ip(struct blk_integrity_exchg *bix) -{ - sd_dif_type3_generate(bix, sd_dif_ip_fn); -} - -static int sd_dif_type3_verify(struct blk_integrity_exchg *bix, csum_fn *fn) -{ - void *buf = bix->data_buf; - struct sd_dif_tuple *sdt = bix->prot_buf; - sector_t sector = bix->sector; - unsigned int i; - __u16 csum; - - for (i = 0 ; i < bix->data_size ; i += bix->sector_size, sdt++) { - /* Unwritten sectors */ - if (sdt->app_tag == 0xffff && sdt->ref_tag == 0xffffffff) - return 0; - - csum = fn(buf, bix->sector_size); - - if (sdt->guard_tag != csum) { - printk(KERN_ERR "%s: guard tag error on sector %lu " \ - "(rcvd %04x, data %04x)\n", bix->disk_name, - (unsigned long)sector, - be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); - return -EIO; - } - - buf += bix->sector_size; - sector++; - } - - return 0; -} - -static int sd_dif_type3_verify_crc(struct blk_integrity_exchg *bix) -{ - return sd_dif_type3_verify(bix, sd_dif_crc_fn); -} - -static int sd_dif_type3_verify_ip(struct blk_integrity_exchg *bix) -{ - return sd_dif_type3_verify(bix, sd_dif_ip_fn); -} - -static void sd_dif_type3_set_tag(void *prot, void *tag_buf, unsigned int sectors) -{ - struct sd_dif_tuple *sdt = prot; - char *tag = tag_buf; - unsigned int i, j; - - for (i = 0, j = 0 ; i < sectors ; i++, j += 6, sdt++) { - sdt->app_tag = tag[j] << 8 | tag[j+1]; - sdt->ref_tag = tag[j+2] << 24 | tag[j+3] << 16 | - tag[j+4] << 8 | tag[j+5]; - } -} - -static void sd_dif_type3_get_tag(void *prot, void *tag_buf, unsigned int sectors) -{ - struct sd_dif_tuple *sdt = prot; - char *tag = tag_buf; - unsigned int i, j; - - for (i = 0, j = 0 ; i < sectors ; i++, j += 2, sdt++) { - tag[j] = (sdt->app_tag & 0xff00) >> 8; - tag[j+1] = sdt->app_tag & 0xff; - tag[j+2] = (sdt->ref_tag & 0xff000000) >> 24; - tag[j+3] = (sdt->ref_tag & 0xff0000) >> 16; - tag[j+4] = (sdt->ref_tag & 0xff00) >> 8; - tag[j+5] = sdt->ref_tag & 0xff; - BUG_ON(sdt->app_tag == 0xffff || sdt->ref_tag == 0xffffffff); - } -} - -static struct blk_integrity dif_type3_integrity_crc = { - .name = "T10-DIF-TYPE3-CRC", - .generate_fn = sd_dif_type3_generate_crc, - .verify_fn = sd_dif_type3_verify_crc, - .get_tag_fn = sd_dif_type3_get_tag, - .set_tag_fn = sd_dif_type3_set_tag, - .tuple_size = sizeof(struct sd_dif_tuple), - .tag_size = 0, -}; - -static struct blk_integrity dif_type3_integrity_ip = { - .name = "T10-DIF-TYPE3-IP", - .generate_fn = sd_dif_type3_generate_ip, - .verify_fn = sd_dif_type3_verify_ip, - .get_tag_fn = sd_dif_type3_get_tag, - .set_tag_fn = sd_dif_type3_set_tag, - .tuple_size = sizeof(struct sd_dif_tuple), - .tag_size = 0, -}; - -/* - * Configure exchange of protection information between OS and HBA. - */ -void sd_dif_config_host(struct scsi_disk *sdkp) -{ - struct scsi_device *sdp = sdkp->device; - struct gendisk *disk = sdkp->disk; - u8 type = sdkp->protection_type; - - /* If this HBA doesn't support DIX, resort to normal I/O or DIF */ - if (scsi_host_dix_capable(sdp->host, type) == 0) { - - if (type == SD_DIF_TYPE0_PROTECTION) - return; - - if (scsi_host_dif_capable(sdp->host, type) == 0) { - sd_printk(KERN_INFO, sdkp, "Type %d protection " \ - "unsupported by HBA. Disabling DIF.\n", type); - sdkp->protection_type = 0; - return; - } - - sd_printk(KERN_INFO, sdkp, "Enabling DIF Type %d protection\n", - type); - - return; - } - - /* Enable DMA of protection information */ - if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) - if (type == SD_DIF_TYPE3_PROTECTION) - blk_integrity_register(disk, &dif_type3_integrity_ip); - else - blk_integrity_register(disk, &dif_type1_integrity_ip); - else - if (type == SD_DIF_TYPE3_PROTECTION) - blk_integrity_register(disk, &dif_type3_integrity_crc); - else - blk_integrity_register(disk, &dif_type1_integrity_crc); - - sd_printk(KERN_INFO, sdkp, - "Enabling %s integrity protection\n", disk->integrity->name); - - /* Signal to block layer that we support sector tagging */ - if (type && sdkp->ATO) { - if (type == SD_DIF_TYPE3_PROTECTION) - disk->integrity->tag_size = sizeof(u16) + sizeof(u32); - else - disk->integrity->tag_size = sizeof(u16); - - sd_printk(KERN_INFO, sdkp, "DIF application tag size %u\n", - disk->integrity->tag_size); - } -} - -/* - * DIF DMA operation magic decoder ring. - */ -void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix) -{ - int csum_convert, prot_op; - - prot_op = 0; - - /* Convert checksum? */ - if (scsi_host_get_guard(scmd->device->host) != SHOST_DIX_GUARD_CRC) - csum_convert = 1; - else - csum_convert = 0; - - switch (scmd->cmnd[0]) { - case READ_10: - case READ_12: - case READ_16: - if (dif && dix) - if (csum_convert) - prot_op = SCSI_PROT_READ_CONVERT; - else - prot_op = SCSI_PROT_READ_PASS; - else if (dif && !dix) - prot_op = SCSI_PROT_READ_STRIP; - else if (!dif && dix) - prot_op = SCSI_PROT_READ_INSERT; - - break; - - case WRITE_10: - case WRITE_12: - case WRITE_16: - if (dif && dix) - if (csum_convert) - prot_op = SCSI_PROT_WRITE_CONVERT; - else - prot_op = SCSI_PROT_WRITE_PASS; - else if (dif && !dix) - prot_op = SCSI_PROT_WRITE_INSERT; - else if (!dif && dix) - prot_op = SCSI_PROT_WRITE_STRIP; - - break; - } - - scsi_set_prot_op(scmd, prot_op); - scsi_set_prot_type(scmd, dif); -} - -/* - * The virtual start sector is the one that was originally submitted - * by the block layer. Due to partitioning, MD/DM cloning, etc. the - * actual physical start sector is likely to be different. Remap - * protection information to match the physical LBA. - * - * From a protocol perspective there's a slight difference between - * Type 1 and 2. The latter uses 32-byte CDBs exclusively, and the - * reference tag is seeded in the CDB. This gives us the potential to - * avoid virt->phys remapping during write. However, at read time we - * don't know whether the virt sector is the same as when we wrote it - * (we could be reading from real disk as opposed to MD/DM device. So - * we always remap Type 2 making it identical to Type 1. - * - * Type 3 does not have a reference tag so no remapping is required. - */ -int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_sz) -{ - const int tuple_sz = sizeof(struct sd_dif_tuple); - struct bio *bio; - struct scsi_disk *sdkp; - struct sd_dif_tuple *sdt; - unsigned int i, j; - u32 phys, virt; - - /* Already remapped? */ - if (rq->cmd_flags & REQ_INTEGRITY) - return 0; - - sdkp = rq->bio->bi_bdev->bd_disk->private_data; - - if (sdkp->protection_type == SD_DIF_TYPE3_PROTECTION) - return 0; - - rq->cmd_flags |= REQ_INTEGRITY; - phys = hw_sector & 0xffffffff; - - __rq_for_each_bio(bio, rq) { - struct bio_vec *iv; - - virt = bio->bi_integrity->bip_sector & 0xffffffff; - - bip_for_each_vec(iv, bio->bi_integrity, i) { - sdt = kmap_atomic(iv->bv_page, KM_USER0) - + iv->bv_offset; - - for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) { - - if (be32_to_cpu(sdt->ref_tag) != virt) - goto error; - - sdt->ref_tag = cpu_to_be32(phys); - virt++; - phys++; - } - - kunmap_atomic(sdt, KM_USER0); - } - } - - return 0; - -error: - kunmap_atomic(sdt, KM_USER0); - sd_printk(KERN_ERR, sdkp, "%s: virt %u, phys %u, ref %u\n", - __func__, virt, phys, be32_to_cpu(sdt->ref_tag)); - - return -EIO; -} - -/* - * Remap physical sector values in the reference tag to the virtual - * values expected by the block layer. - */ -void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes) -{ - const int tuple_sz = sizeof(struct sd_dif_tuple); - struct scsi_disk *sdkp; - struct bio *bio; - struct sd_dif_tuple *sdt; - unsigned int i, j, sectors, sector_sz; - u32 phys, virt; - - sdkp = scsi_disk(scmd->request->rq_disk); - - if (sdkp->protection_type == SD_DIF_TYPE3_PROTECTION || good_bytes == 0) - return; - - sector_sz = scmd->device->sector_size; - sectors = good_bytes / sector_sz; - - phys = scmd->request->sector & 0xffffffff; - if (sector_sz == 4096) - phys >>= 3; - - __rq_for_each_bio(bio, scmd->request) { - struct bio_vec *iv; - - virt = bio->bi_integrity->bip_sector & 0xffffffff; - - bip_for_each_vec(iv, bio->bi_integrity, i) { - sdt = kmap_atomic(iv->bv_page, KM_USER0) - + iv->bv_offset; - - for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) { - - if (sectors == 0) { - kunmap_atomic(sdt, KM_USER0); - return; - } - - if (be32_to_cpu(sdt->ref_tag) != phys && - sdt->app_tag != 0xffff) - sdt->ref_tag = 0xffffffff; /* Bad ref */ - else - sdt->ref_tag = cpu_to_be32(virt); - - virt++; - phys++; - sectors--; - } - - kunmap_atomic(sdt, KM_USER0); - } - } -} - diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index c2bb53e3d941..4684cc716aa4 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch Devfs support */ -static const char *verstr = "20080504"; +static const char *verstr = "20080224"; #include @@ -631,7 +631,7 @@ static int cross_eof(struct scsi_tape * STp, int forward) /* Flush the write buffer (never need to write if variable blocksize). */ static int st_flush_write_buffer(struct scsi_tape * STp) { - int transfer, blks; + int offset, transfer, blks; int result; unsigned char cmd[MAX_COMMAND_SIZE]; struct st_request *SRpnt; @@ -644,10 +644,14 @@ static int st_flush_write_buffer(struct scsi_tape * STp) result = 0; if (STp->dirty == 1) { - transfer = STp->buffer->buffer_bytes; + offset = (STp->buffer)->buffer_bytes; + transfer = ((offset + STp->block_size - 1) / + STp->block_size) * STp->block_size; DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n", tape_name(STp), transfer)); + memset((STp->buffer)->b_data + offset, 0, transfer - offset); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = WRITE_6; cmd[1] = 1; @@ -1666,7 +1670,6 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) if (undone <= do_count) { /* Only data from this write is not written */ count += undone; - b_point -= undone; do_count -= undone; if (STp->block_size) blks = (transfer - undone) / STp->block_size; diff --git a/trunk/drivers/scsi/stex.c b/trunk/drivers/scsi/stex.c index 3790906a77d1..f308a0308829 100644 --- a/trunk/drivers/scsi/stex.c +++ b/trunk/drivers/scsi/stex.c @@ -467,7 +467,7 @@ stex_slave_alloc(struct scsi_device *sdev) /* Cheat: usually extracted from Inquiry data */ sdev->tagged_supported = 1; - scsi_activate_tcq(sdev, ST_CMD_PER_LUN); + scsi_activate_tcq(sdev, sdev->host->can_queue); return 0; } diff --git a/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c b/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c index 98df1651404f..22a6aae78699 100644 --- a/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -5741,8 +5741,6 @@ void sym_hcb_free(struct sym_hcb *np) for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) { tp = &np->target[target]; - if (tp->luntbl) - sym_mfree_dma(tp->luntbl, 256, "LUNTBL"); #if SYM_CONF_MAX_LUN > 1 kfree(tp->lunmp); #endif diff --git a/trunk/drivers/scsi/tmscsim.c b/trunk/drivers/scsi/tmscsim.c index 1723d71cbf3f..5b04ddfed26c 100644 --- a/trunk/drivers/scsi/tmscsim.c +++ b/trunk/drivers/scsi/tmscsim.c @@ -452,7 +452,7 @@ static int dc390_pci_map (struct dc390_srb* pSRB) /* TODO: error handling */ if (pSRB->SGcount != 1) error = 1; - DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __func__, pcmd->sense_buffer, cmdp->saved_dma_handle)); + DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle)); /* Map SG list */ } else if (scsi_sg_count(pcmd)) { int nseg; @@ -466,7 +466,7 @@ static int dc390_pci_map (struct dc390_srb* pSRB) if (nseg < 0) error = 1; DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\ - __func__, scsi_sglist(pcmd), nseg, scsi_sg_count(pcmd))); + __FUNCTION__, scsi_sglist(pcmd), nseg, scsi_sg_count(pcmd))); /* Map single segment */ } else pSRB->SGcount = 0; @@ -483,11 +483,11 @@ static void dc390_pci_unmap (struct dc390_srb* pSRB) if (pSRB->SRBFlag) { pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE); - DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __func__, cmdp->saved_dma_handle)); + DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle)); } else { scsi_dma_unmap(pcmd); DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", - __func__, scsi_sglist(pcmd), scsi_sg_count(pcmd))); + __FUNCTION__, scsi_sglist(pcmd), scsi_sg_count(pcmd))); } } diff --git a/trunk/drivers/scsi/wd7000.c b/trunk/drivers/scsi/wd7000.c index d4c13561f4a6..c975c01b3a02 100644 --- a/trunk/drivers/scsi/wd7000.c +++ b/trunk/drivers/scsi/wd7000.c @@ -148,7 +148,7 @@ * * 2002/10/04 - Alan Cox * - * Use dev_id for interrupts, kill __func__ pasting + * Use dev_id for interrupts, kill __FUNCTION__ pasting * Add a lock for the scb pool, clean up all other cli/sti usage stuff * Use the adapter lock for the other places we had the cli's * @@ -640,12 +640,12 @@ static int __init wd7000_setup(char *str) (void) get_options(str, ARRAY_SIZE(ints), ints); if (wd7000_card_num >= NUM_CONFIGS) { - printk(KERN_ERR "%s: Too many \"wd7000=\" configurations in " "command line!\n", __func__); + printk(KERN_ERR "%s: Too many \"wd7000=\" configurations in " "command line!\n", __FUNCTION__); return 0; } if ((ints[0] < 3) || (ints[0] > 5)) { - printk(KERN_ERR "%s: Error in command line! " "Usage: wd7000=,,IO>[," "[,]]\n", __func__); + printk(KERN_ERR "%s: Error in command line! " "Usage: wd7000=,,IO>[," "[,]]\n", __FUNCTION__); } else { for (i = 0; i < NUM_IRQS; i++) if (ints[1] == wd7000_irq[i]) @@ -1642,7 +1642,7 @@ static int wd7000_biosparam(struct scsi_device *sdev, ip[2] = info[2]; if (info[0] == 255) - printk(KERN_INFO "%s: current partition table is " "using extended translation.\n", __func__); + printk(KERN_INFO "%s: current partition table is " "using extended translation.\n", __FUNCTION__); } } diff --git a/trunk/drivers/scsi/zalon.c b/trunk/drivers/scsi/zalon.c index 3c4a300494a4..4b5f908d35c3 100644 --- a/trunk/drivers/scsi/zalon.c +++ b/trunk/drivers/scsi/zalon.c @@ -68,11 +68,11 @@ lasi_scsi_clock(void * hpa, int defaultclock) if (status == PDC_RET_OK) { clock = (int) pdc_result[16]; } else { - printk(KERN_WARNING "%s: pdc_iodc_read returned %d\n", __func__, status); + printk(KERN_WARNING "%s: pdc_iodc_read returned %d\n", __FUNCTION__, status); clock = defaultclock; } - printk(KERN_DEBUG "%s: SCSI clock %d\n", __func__, clock); + printk(KERN_DEBUG "%s: SCSI clock %d\n", __FUNCTION__, clock); return clock; } #endif @@ -108,13 +108,13 @@ zalon_probe(struct parisc_device *dev) */ dev->irq = gsc_alloc_irq(&gsc_irq); - printk(KERN_INFO "%s: Zalon version %d, IRQ %d\n", __func__, + printk(KERN_INFO "%s: Zalon version %d, IRQ %d\n", __FUNCTION__, zalon_vers, dev->irq); __raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, zalon + IO_MODULE_EIM); if (zalon_vers == 0) - printk(KERN_WARNING "%s: Zalon 1.1 or earlier\n", __func__); + printk(KERN_WARNING "%s: Zalon 1.1 or earlier\n", __FUNCTION__); memset(&device, 0, sizeof(struct ncr_device)); diff --git a/trunk/drivers/spi/atmel_spi.c b/trunk/drivers/spi/atmel_spi.c index 0c7165660853..e81d59d78910 100644 --- a/trunk/drivers/spi/atmel_spi.c +++ b/trunk/drivers/spi/atmel_spi.c @@ -313,14 +313,14 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) xfer->tx_dma = dma_map_single(dev, (void *) xfer->tx_buf, xfer->len, DMA_TO_DEVICE); - if (dma_mapping_error(dev, xfer->tx_dma)) + if (dma_mapping_error(xfer->tx_dma)) return -ENOMEM; } if (xfer->rx_buf) { xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, xfer->len, DMA_FROM_DEVICE); - if (dma_mapping_error(dev, xfer->rx_dma)) { + if (dma_mapping_error(xfer->rx_dma)) { if (xfer->tx_buf) dma_unmap_single(dev, xfer->tx_dma, xfer->len, diff --git a/trunk/drivers/spi/au1550_spi.c b/trunk/drivers/spi/au1550_spi.c index 87b73e0169c5..9149689c79d9 100644 --- a/trunk/drivers/spi/au1550_spi.c +++ b/trunk/drivers/spi/au1550_spi.c @@ -334,7 +334,7 @@ static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size) hw->dma_rx_tmpbuf_size = size; hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf, size, DMA_FROM_DEVICE); - if (dma_mapping_error(hw->dev, hw->dma_rx_tmpbuf_addr)) { + if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) { kfree(hw->dma_rx_tmpbuf); hw->dma_rx_tmpbuf = 0; hw->dma_rx_tmpbuf_size = 0; @@ -378,7 +378,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) dma_rx_addr = dma_map_single(hw->dev, (void *)t->rx_buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(hw->dev, dma_rx_addr)) + if (dma_mapping_error(dma_rx_addr)) dev_err(hw->dev, "rx dma map error\n"); } } else { @@ -401,7 +401,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) dma_tx_addr = dma_map_single(hw->dev, (void *)t->tx_buf, t->len, DMA_TO_DEVICE); - if (dma_mapping_error(hw->dev, dma_tx_addr)) + if (dma_mapping_error(dma_tx_addr)) dev_err(hw->dev, "tx dma map error\n"); } } else { diff --git a/trunk/drivers/spi/omap2_mcspi.c b/trunk/drivers/spi/omap2_mcspi.c index f6f987bb71ca..b1cc148036c1 100644 --- a/trunk/drivers/spi/omap2_mcspi.c +++ b/trunk/drivers/spi/omap2_mcspi.c @@ -836,7 +836,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) if (tx_buf != NULL) { t->tx_dma = dma_map_single(&spi->dev, (void *) tx_buf, len, DMA_TO_DEVICE); - if (dma_mapping_error(&spi->dev, t->tx_dma)) { + if (dma_mapping_error(t->tx_dma)) { dev_dbg(&spi->dev, "dma %cX %d bytes error\n", 'T', len); return -EINVAL; @@ -845,7 +845,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) if (rx_buf != NULL) { t->rx_dma = dma_map_single(&spi->dev, rx_buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(&spi->dev, t->rx_dma)) { + if (dma_mapping_error(t->rx_dma)) { dev_dbg(&spi->dev, "dma %cX %d bytes error\n", 'R', len); if (tx_buf != NULL) diff --git a/trunk/drivers/spi/pxa2xx_spi.c b/trunk/drivers/spi/pxa2xx_spi.c index 067299d6d192..0c452c46ab07 100644 --- a/trunk/drivers/spi/pxa2xx_spi.c +++ b/trunk/drivers/spi/pxa2xx_spi.c @@ -353,7 +353,7 @@ static int map_dma_buffers(struct driver_data *drv_data) drv_data->rx_dma = dma_map_single(dev, drv_data->rx, drv_data->rx_map_len, DMA_FROM_DEVICE); - if (dma_mapping_error(dev, drv_data->rx_dma)) + if (dma_mapping_error(drv_data->rx_dma)) return 0; /* Stream map the tx buffer */ @@ -361,7 +361,7 @@ static int map_dma_buffers(struct driver_data *drv_data) drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(dev, drv_data->tx_dma)) { + if (dma_mapping_error(drv_data->tx_dma)) { dma_unmap_single(dev, drv_data->rx_dma, drv_data->rx_map_len, DMA_FROM_DEVICE); return 0; diff --git a/trunk/drivers/spi/spi_imx.c b/trunk/drivers/spi/spi_imx.c index 6fb77fcc4971..54ac7bea5f8c 100644 --- a/trunk/drivers/spi/spi_imx.c +++ b/trunk/drivers/spi/spi_imx.c @@ -491,7 +491,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(dev, drv_data->tx_dma)) + if (dma_mapping_error(drv_data->tx_dma)) return -1; drv_data->tx_dma_needs_unmap = 1; @@ -516,7 +516,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->len, DMA_FROM_DEVICE); - if (dma_mapping_error(dev, drv_data->rx_dma)) + if (dma_mapping_error(drv_data->rx_dma)) return -1; drv_data->rx_dma_needs_unmap = 1; } @@ -534,7 +534,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(dev, drv_data->tx_dma)) { + if (dma_mapping_error(drv_data->tx_dma)) { if (drv_data->rx_dma) { dma_unmap_single(dev, drv_data->rx_dma, diff --git a/trunk/drivers/usb/mon/mon_text.c b/trunk/drivers/usb/mon/mon_text.c index 1f715436d6d3..5e3e4e9b6c77 100644 --- a/trunk/drivers/usb/mon/mon_text.c +++ b/trunk/drivers/usb/mon/mon_text.c @@ -87,7 +87,7 @@ struct mon_reader_text { static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */ -static void mon_text_ctor(void *); +static void mon_text_ctor(struct kmem_cache *, void *); struct mon_text_ptr { int cnt, limit; @@ -720,7 +720,7 @@ void mon_text_del(struct mon_bus *mbus) /* * Slab interface: constructor. */ -static void mon_text_ctor(void *mem) +static void mon_text_ctor(struct kmem_cache *slab, void *mem) { /* * Nothing to initialize. No, really! diff --git a/trunk/drivers/usb/serial/ipaq.c b/trunk/drivers/usb/serial/ipaq.c index cd9a2e138c8b..832a5a4f3cb3 100644 --- a/trunk/drivers/usb/serial/ipaq.c +++ b/trunk/drivers/usb/serial/ipaq.c @@ -651,17 +651,15 @@ static int ipaq_open(struct tty_struct *tty, */ kfree(port->bulk_in_buffer); - kfree(port->bulk_out_buffer); - /* make sure the generic serial code knows */ - port->bulk_out_buffer = NULL; - port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); - if (port->bulk_in_buffer == NULL) + if (port->bulk_in_buffer == NULL) { + port->bulk_out_buffer = NULL; /* prevent double free */ goto enomem; + } + kfree(port->bulk_out_buffer); port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); if (port->bulk_out_buffer == NULL) { - /* the buffer is useless, free it */ kfree(port->bulk_in_buffer); port->bulk_in_buffer = NULL; goto enomem; diff --git a/trunk/drivers/video/console/sticon.c b/trunk/drivers/video/console/sticon.c index 4055dbdd1b42..a11cc2fdd4cd 100644 --- a/trunk/drivers/video/console/sticon.c +++ b/trunk/drivers/video/console/sticon.c @@ -370,7 +370,7 @@ static const struct consw sti_con = { -static int __init sticonsole_init(void) +int __init sticonsole_init(void) { /* already initialized ? */ if (sticon_sti) diff --git a/trunk/drivers/video/console/sticore.c b/trunk/drivers/video/console/sticore.c index d7822af0e00a..e9ab657f0bb7 100644 --- a/trunk/drivers/video/console/sticore.c +++ b/trunk/drivers/video/console/sticore.c @@ -29,7 +29,7 @@ #define STI_DRIVERVERSION "Version 0.9a" -static struct sti_struct *default_sti __read_mostly; +struct sti_struct *default_sti __read_mostly; /* number of STI ROMS found and their ptrs to each struct */ static int num_sti_roms __read_mostly; @@ -68,7 +68,8 @@ static const struct sti_init_flags default_init_flags = { .init_cmap_tx = 1, }; -static int sti_init_graph(struct sti_struct *sti) +int +sti_init_graph(struct sti_struct *sti) { struct sti_init_inptr_ext inptr_ext = { 0, }; struct sti_init_inptr inptr = { @@ -99,7 +100,8 @@ static const struct sti_conf_flags default_conf_flags = { .wait = STI_WAIT, }; -static void sti_inq_conf(struct sti_struct *sti) +void +sti_inq_conf(struct sti_struct *sti) { struct sti_conf_inptr inptr = { 0, }; unsigned long flags; @@ -235,8 +237,8 @@ static void sti_flush(unsigned long start, unsigned long end) flush_icache_range(start, end); } -static void __devinit sti_rom_copy(unsigned long base, unsigned long count, - void *dest) +void __devinit +sti_rom_copy(unsigned long base, unsigned long count, void *dest) { unsigned long dest_start = (unsigned long) dest; @@ -476,8 +478,8 @@ sti_init_glob_cfg(struct sti_struct *sti, } #ifdef CONFIG_FB -static struct sti_cooked_font __devinit -*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) +struct sti_cooked_font * __devinit +sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) { const struct font_desc *fbfont; unsigned int size, bpc; @@ -532,16 +534,16 @@ static struct sti_cooked_font __devinit return cooked_font; } #else -static struct sti_cooked_font __devinit -*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) +struct sti_cooked_font * __devinit +sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) { return NULL; } #endif -static struct sti_cooked_font __devinit -*sti_select_font(struct sti_cooked_rom *rom, - int (*search_font_fnc)(struct sti_cooked_rom *, int, int)) +struct sti_cooked_font * __devinit +sti_select_font(struct sti_cooked_rom *rom, + int (*search_font_fnc) (struct sti_cooked_rom *,int,int) ) { struct sti_cooked_font *font; int i; @@ -705,7 +707,8 @@ sti_get_bmode_rom (unsigned long address) return raw; } -static struct sti_rom __devinit *sti_get_wmode_rom(unsigned long address) +struct sti_rom * __devinit +sti_get_wmode_rom (unsigned long address) { struct sti_rom *raw; unsigned long size; @@ -720,8 +723,8 @@ static struct sti_rom __devinit *sti_get_wmode_rom(unsigned long address) return raw; } -static int __devinit sti_read_rom(int wordmode, struct sti_struct *sti, - unsigned long address) +int __devinit +sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address) { struct sti_cooked_rom *cooked; struct sti_rom *raw = NULL; diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index 6b487801eeae..5d84b3431098 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/trunk/drivers/video/macfb.c b/trunk/drivers/video/macfb.c index b790ddff76f9..aa8c714d6245 100644 --- a/trunk/drivers/video/macfb.c +++ b/trunk/drivers/video/macfb.c @@ -596,7 +596,7 @@ static struct fb_ops macfb_ops = { .fb_imageblit = cfb_imageblit, }; -static void __init macfb_setup(char *options) +void __init macfb_setup(char *options) { char *this_opt; diff --git a/trunk/drivers/video/sticore.h b/trunk/drivers/video/sticore.h index 7fe5be4bc70e..1a9a60c74be3 100644 --- a/trunk/drivers/video/sticore.h +++ b/trunk/drivers/video/sticore.h @@ -352,6 +352,8 @@ struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ /* functions to call the STI ROM directly */ +int sti_init_graph(struct sti_struct *sti); +void sti_inq_conf(struct sti_struct *sti); void sti_putc(struct sti_struct *sti, int c, int y, int x); void sti_set(struct sti_struct *sti, int src_y, int src_x, int height, int width, u8 color); diff --git a/trunk/drivers/video/stifb.c b/trunk/drivers/video/stifb.c index 166481402412..598d35eff935 100644 --- a/trunk/drivers/video/stifb.c +++ b/trunk/drivers/video/stifb.c @@ -1078,7 +1078,8 @@ static struct fb_ops stifb_ops = { * Initialization */ -static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) +int __init +stifb_init_fb(struct sti_struct *sti, int bpp_pref) { struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; @@ -1314,7 +1315,8 @@ static int stifb_disabled __initdata; int __init stifb_setup(char *options); -static int __init stifb_init(void) +int __init +stifb_init(void) { struct sti_struct *sti; struct sti_struct *def_sti; diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index d3873583360b..97e3bdedb1e6 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -1383,19 +1383,6 @@ config MINIX_FS partition (the one containing the directory /) cannot be compiled as a module. -config OMFS_FS - tristate "SonicBlue Optimized MPEG File System support" - depends on BLOCK - select CRC_ITU_T - help - This is the proprietary file system used by the Rio Karma music - player and ReplayTV DVR. Despite the name, this filesystem is not - more efficient than a standard FS for MPEG files, in fact likely - the opposite is true. Say Y if you have either of these devices - and wish to mount its disk. - - To compile this file system support as a module, choose M here: the - module will be called omfs. If unsure, say N. config HPFS_FS tristate "OS/2 HPFS file system support" diff --git a/trunk/fs/Makefile b/trunk/fs/Makefile index a1482a5eff15..3b2178b4bb66 100644 --- a/trunk/fs/Makefile +++ b/trunk/fs/Makefile @@ -111,7 +111,6 @@ obj-$(CONFIG_ADFS_FS) += adfs/ obj-$(CONFIG_FUSE_FS) += fuse/ obj-$(CONFIG_UDF_FS) += udf/ obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ -obj-$(CONFIG_OMFS_FS) += omfs/ obj-$(CONFIG_JFS_FS) += jfs/ obj-$(CONFIG_XFS_FS) += xfs/ obj-$(CONFIG_9P_FS) += 9p/ diff --git a/trunk/fs/adfs/super.c b/trunk/fs/adfs/super.c index 26f3b43726bb..9e421eeb672b 100644 --- a/trunk/fs/adfs/super.c +++ b/trunk/fs/adfs/super.c @@ -249,7 +249,7 @@ static void adfs_destroy_inode(struct inode *inode) kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; diff --git a/trunk/fs/affs/affs.h b/trunk/fs/affs/affs.h index e9ec915f7553..223b1917093e 100644 --- a/trunk/fs/affs/affs.h +++ b/trunk/fs/affs/affs.h @@ -2,7 +2,6 @@ #include #include #include -#include /* AmigaOS allows file names with up to 30 characters length. * Names longer than that will be silently truncated. If you @@ -99,7 +98,7 @@ struct affs_sb_info { gid_t s_gid; /* gid to override */ umode_t s_mode; /* mode to override */ struct buffer_head *s_root_bh; /* Cached root block. */ - struct mutex s_bmlock; /* Protects bitmap access. */ + struct semaphore s_bmlock; /* Protects bitmap access. */ struct affs_bm_info *s_bitmap; /* Bitmap infos. */ u32 s_bmap_count; /* # of bitmap blocks. */ u32 s_bmap_bits; /* # of bits in one bitmap blocks */ diff --git a/trunk/fs/affs/bitmap.c b/trunk/fs/affs/bitmap.c index dc5ef14bdc1c..c4a5ad09ddf2 100644 --- a/trunk/fs/affs/bitmap.c +++ b/trunk/fs/affs/bitmap.c @@ -45,14 +45,14 @@ affs_count_free_blocks(struct super_block *sb) if (sb->s_flags & MS_RDONLY) return 0; - mutex_lock(&AFFS_SB(sb)->s_bmlock); + down(&AFFS_SB(sb)->s_bmlock); bm = AFFS_SB(sb)->s_bitmap; free = 0; for (i = AFFS_SB(sb)->s_bmap_count; i > 0; bm++, i--) free += bm->bm_free; - mutex_unlock(&AFFS_SB(sb)->s_bmlock); + up(&AFFS_SB(sb)->s_bmlock); return free; } @@ -76,7 +76,7 @@ affs_free_block(struct super_block *sb, u32 block) bit = blk % sbi->s_bmap_bits; bm = &sbi->s_bitmap[bmap]; - mutex_lock(&sbi->s_bmlock); + down(&sbi->s_bmlock); bh = sbi->s_bmap_bh; if (sbi->s_last_bmap != bmap) { @@ -105,19 +105,19 @@ affs_free_block(struct super_block *sb, u32 block) sb->s_dirt = 1; bm->bm_free++; - mutex_unlock(&sbi->s_bmlock); + up(&sbi->s_bmlock); return; err_free: affs_warning(sb,"affs_free_block","Trying to free block %u which is already free", block); - mutex_unlock(&sbi->s_bmlock); + up(&sbi->s_bmlock); return; err_bh_read: affs_error(sb,"affs_free_block","Cannot read bitmap block %u", bm->bm_key); sbi->s_bmap_bh = NULL; sbi->s_last_bmap = ~0; - mutex_unlock(&sbi->s_bmlock); + up(&sbi->s_bmlock); return; err_range: @@ -168,7 +168,7 @@ affs_alloc_block(struct inode *inode, u32 goal) bmap = blk / sbi->s_bmap_bits; bm = &sbi->s_bitmap[bmap]; - mutex_lock(&sbi->s_bmlock); + down(&sbi->s_bmlock); if (bm->bm_free) goto find_bmap_bit; @@ -249,7 +249,7 @@ affs_alloc_block(struct inode *inode, u32 goal) mark_buffer_dirty(bh); sb->s_dirt = 1; - mutex_unlock(&sbi->s_bmlock); + up(&sbi->s_bmlock); pr_debug("%d\n", blk); return blk; @@ -259,7 +259,7 @@ affs_alloc_block(struct inode *inode, u32 goal) sbi->s_bmap_bh = NULL; sbi->s_last_bmap = ~0; err_full: - mutex_unlock(&sbi->s_bmlock); + up(&sbi->s_bmlock); pr_debug("failed\n"); return 0; } diff --git a/trunk/fs/affs/file.c b/trunk/fs/affs/file.c index 1377b1240b6e..6eac7bdeec94 100644 --- a/trunk/fs/affs/file.c +++ b/trunk/fs/affs/file.c @@ -46,6 +46,8 @@ const struct inode_operations affs_file_inode_operations = { static int affs_file_open(struct inode *inode, struct file *filp) { + if (atomic_read(&filp->f_count) != 1) + return 0; pr_debug("AFFS: open(%lu,%d)\n", inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); atomic_inc(&AFFS_I(inode)->i_opencnt); @@ -55,6 +57,8 @@ affs_file_open(struct inode *inode, struct file *filp) static int affs_file_release(struct inode *inode, struct file *filp) { + if (atomic_read(&filp->f_count) != 0) + return 0; pr_debug("AFFS: release(%lu, %d)\n", inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); diff --git a/trunk/fs/affs/super.c b/trunk/fs/affs/super.c index 3a89094f93d0..d214837d5e42 100644 --- a/trunk/fs/affs/super.c +++ b/trunk/fs/affs/super.c @@ -90,7 +90,7 @@ static void affs_destroy_inode(struct inode *inode) kmem_cache_free(affs_inode_cachep, AFFS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct affs_inode_info *ei = (struct affs_inode_info *) foo; @@ -290,7 +290,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) if (!sbi) return -ENOMEM; sb->s_fs_info = sbi; - mutex_init(&sbi->s_bmlock); + init_MUTEX(&sbi->s_bmlock); if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block, &blocksize,&sbi->s_prefix, diff --git a/trunk/fs/afs/internal.h b/trunk/fs/afs/internal.h index 3cb6920ff30b..7102824ba847 100644 --- a/trunk/fs/afs/internal.h +++ b/trunk/fs/afs/internal.h @@ -469,6 +469,8 @@ extern bool afs_cm_incoming_call(struct afs_call *); extern const struct inode_operations afs_dir_inode_operations; extern const struct file_operations afs_dir_file_operations; +extern int afs_permission(struct inode *, int, struct nameidata *); + /* * file.c */ @@ -603,7 +605,7 @@ extern void afs_clear_permits(struct afs_vnode *); extern void afs_cache_permit(struct afs_vnode *, struct key *, long); extern void afs_zap_permits(struct rcu_head *); extern struct key *afs_request_key(struct afs_cell *); -extern int afs_permission(struct inode *, int); +extern int afs_permission(struct inode *, int, struct nameidata *); /* * server.c diff --git a/trunk/fs/afs/security.c b/trunk/fs/afs/security.c index 3ef504370034..3bcbeceba1bb 100644 --- a/trunk/fs/afs/security.c +++ b/trunk/fs/afs/security.c @@ -284,7 +284,7 @@ static int afs_check_permit(struct afs_vnode *vnode, struct key *key, * - AFS ACLs are attached to directories only, and a file is controlled by its * parent directory's ACL */ -int afs_permission(struct inode *inode, int mask) +int afs_permission(struct inode *inode, int mask, struct nameidata *nd) { struct afs_vnode *vnode = AFS_FS_I(inode); afs_access_t uninitialized_var(access); diff --git a/trunk/fs/afs/super.c b/trunk/fs/afs/super.c index 250d8c4d66e4..7e3faeef6818 100644 --- a/trunk/fs/afs/super.c +++ b/trunk/fs/afs/super.c @@ -27,7 +27,7 @@ #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ -static void afs_i_init_once(void *foo); +static void afs_i_init_once(struct kmem_cache *cachep, void *foo); static int afs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt); @@ -449,7 +449,7 @@ static void afs_put_super(struct super_block *sb) /* * initialise an inode cache slab element prior to any use */ -static void afs_i_init_once(void *_vnode) +static void afs_i_init_once(struct kmem_cache *cachep, void *_vnode) { struct afs_vnode *vnode = _vnode; diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index f658441d5666..0051fd94b44e 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -512,8 +512,8 @@ static void aio_fput_routine(struct work_struct *data) */ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) { - dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n", - req, atomic_long_read(&req->ki_filp->f_count)); + dprintk(KERN_DEBUG "aio_put(%p): f_count=%d\n", + req, atomic_read(&req->ki_filp->f_count)); assert_spin_locked(&ctx->ctx_lock); @@ -528,7 +528,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) /* Must be done under the lock to serialise against cancellation. * Call this aio_fput as it duplicates fput via the fput_work. */ - if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) { + if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) { get_ioctx(ctx); spin_lock(&fput_lock); list_add(&req->ki_list, &fput_head); diff --git a/trunk/fs/attr.c b/trunk/fs/attr.c index 26c71ba1eed4..966b73e25f82 100644 --- a/trunk/fs/attr.c +++ b/trunk/fs/attr.c @@ -51,7 +51,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) } /* Check for setting the inode time. */ - if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) { + if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) { if (!is_owner_or_cap(inode)) goto error; } @@ -108,11 +108,6 @@ int notify_change(struct dentry * dentry, struct iattr * attr) struct timespec now; unsigned int ia_valid = attr->ia_valid; - if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) { - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - return -EPERM; - } - now = current_fs_time(inode->i_sb); attr->ia_ctime = now; diff --git a/trunk/fs/bad_inode.c b/trunk/fs/bad_inode.c index 5f1538c03b1b..f1c2ea8342f5 100644 --- a/trunk/fs/bad_inode.c +++ b/trunk/fs/bad_inode.c @@ -243,7 +243,8 @@ static int bad_inode_readlink(struct dentry *dentry, char __user *buffer, return -EIO; } -static int bad_inode_permission(struct inode *inode, int mask) +static int bad_inode_permission(struct inode *inode, int mask, + struct nameidata *nd) { return -EIO; } diff --git a/trunk/fs/befs/linuxvfs.c b/trunk/fs/befs/linuxvfs.c index 02c6e62b72f8..e8717de3bab3 100644 --- a/trunk/fs/befs/linuxvfs.c +++ b/trunk/fs/befs/linuxvfs.c @@ -289,7 +289,7 @@ befs_destroy_inode(struct inode *inode) kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct befs_inode_info *bi = (struct befs_inode_info *) foo; diff --git a/trunk/fs/bfs/bfs.h b/trunk/fs/bfs/bfs.h index 7109e451abf7..70f5d3a8eede 100644 --- a/trunk/fs/bfs/bfs.h +++ b/trunk/fs/bfs/bfs.h @@ -16,9 +16,8 @@ struct bfs_sb_info { unsigned long si_freei; unsigned long si_lf_eblk; unsigned long si_lasti; - unsigned long *si_imap; - struct buffer_head *si_sbh; /* buffer header w/superblock */ - struct mutex bfs_lock; + unsigned long * si_imap; + struct buffer_head * si_sbh; /* buffer header w/superblock */ }; /* diff --git a/trunk/fs/bfs/dir.c b/trunk/fs/bfs/dir.c index 87ee5ccee348..034950cb3cbe 100644 --- a/trunk/fs/bfs/dir.c +++ b/trunk/fs/bfs/dir.c @@ -32,17 +32,16 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) struct inode *dir = f->f_path.dentry->d_inode; struct buffer_head *bh; struct bfs_dirent *de; - struct bfs_sb_info *info = BFS_SB(dir->i_sb); unsigned int offset; int block; - mutex_lock(&info->bfs_lock); + lock_kernel(); if (f->f_pos & (BFS_DIRENT_SIZE - 1)) { printf("Bad f_pos=%08lx for %s:%08lx\n", (unsigned long)f->f_pos, dir->i_sb->s_id, dir->i_ino); - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return -EBADF; } @@ -62,7 +61,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) le16_to_cpu(de->ino), DT_UNKNOWN) < 0) { brelse(bh); - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return 0; } } @@ -72,7 +71,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) brelse(bh); } - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return 0; } @@ -96,10 +95,10 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, inode = new_inode(s); if (!inode) return -ENOSPC; - mutex_lock(&info->bfs_lock); + lock_kernel(); ino = find_first_zero_bit(info->si_imap, info->si_lasti); if (ino > info->si_lasti) { - mutex_unlock(&info->bfs_lock); + unlock_kernel(); iput(inode); return -ENOSPC; } @@ -126,10 +125,10 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, if (err) { inode_dec_link_count(inode); iput(inode); - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return err; } - mutex_unlock(&info->bfs_lock); + unlock_kernel(); d_instantiate(dentry, inode); return 0; } @@ -140,23 +139,22 @@ static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry, struct inode *inode = NULL; struct buffer_head *bh; struct bfs_dirent *de; - struct bfs_sb_info *info = BFS_SB(dir->i_sb); if (dentry->d_name.len > BFS_NAMELEN) return ERR_PTR(-ENAMETOOLONG); - mutex_lock(&info->bfs_lock); + lock_kernel(); bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); if (bh) { unsigned long ino = (unsigned long)le16_to_cpu(de->ino); brelse(bh); inode = bfs_iget(dir->i_sb, ino); if (IS_ERR(inode)) { - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return ERR_CAST(inode); } } - mutex_unlock(&info->bfs_lock); + unlock_kernel(); d_add(dentry, inode); return NULL; } @@ -165,14 +163,13 @@ static int bfs_link(struct dentry *old, struct inode *dir, struct dentry *new) { struct inode *inode = old->d_inode; - struct bfs_sb_info *info = BFS_SB(inode->i_sb); int err; - mutex_lock(&info->bfs_lock); + lock_kernel(); err = bfs_add_entry(dir, new->d_name.name, new->d_name.len, inode->i_ino); if (err) { - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return err; } inc_nlink(inode); @@ -180,19 +177,19 @@ static int bfs_link(struct dentry *old, struct inode *dir, mark_inode_dirty(inode); atomic_inc(&inode->i_count); d_instantiate(new, inode); - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return 0; } static int bfs_unlink(struct inode *dir, struct dentry *dentry) { int error = -ENOENT; - struct inode *inode = dentry->d_inode; + struct inode *inode; struct buffer_head *bh; struct bfs_dirent *de; - struct bfs_sb_info *info = BFS_SB(inode->i_sb); - mutex_lock(&info->bfs_lock); + inode = dentry->d_inode; + lock_kernel(); bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); if (!bh || (le16_to_cpu(de->ino) != inode->i_ino)) goto out_brelse; @@ -213,7 +210,7 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry) out_brelse: brelse(bh); - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return error; } @@ -223,7 +220,6 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *old_inode, *new_inode; struct buffer_head *old_bh, *new_bh; struct bfs_dirent *old_de, *new_de; - struct bfs_sb_info *info; int error = -ENOENT; old_bh = new_bh = NULL; @@ -231,9 +227,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (S_ISDIR(old_inode->i_mode)) return -EINVAL; - info = BFS_SB(old_inode->i_sb); - - mutex_lock(&info->bfs_lock); + lock_kernel(); old_bh = bfs_find_entry(old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de); @@ -270,7 +264,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, error = 0; end_rename: - mutex_unlock(&info->bfs_lock); + unlock_kernel(); brelse(old_bh); brelse(new_bh); return error; diff --git a/trunk/fs/bfs/file.c b/trunk/fs/bfs/file.c index 6a021265f018..b11e63e8fbcd 100644 --- a/trunk/fs/bfs/file.c +++ b/trunk/fs/bfs/file.c @@ -99,7 +99,7 @@ static int bfs_get_block(struct inode *inode, sector_t block, return -ENOSPC; /* The rest has to be protected against itself. */ - mutex_lock(&info->bfs_lock); + lock_kernel(); /* * If the last data block for this file is the last allocated @@ -151,7 +151,7 @@ static int bfs_get_block(struct inode *inode, sector_t block, mark_buffer_dirty(sbh); map_bh(bh_result, sb, phys); out: - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return err; } diff --git a/trunk/fs/bfs/inode.c b/trunk/fs/bfs/inode.c index 0ed57b5ee012..8db623838b50 100644 --- a/trunk/fs/bfs/inode.c +++ b/trunk/fs/bfs/inode.c @@ -104,7 +104,6 @@ static int bfs_write_inode(struct inode *inode, int unused) struct bfs_inode *di; struct buffer_head *bh; int block, off; - struct bfs_sb_info *info = BFS_SB(inode->i_sb); dprintf("ino=%08x\n", ino); @@ -113,13 +112,13 @@ static int bfs_write_inode(struct inode *inode, int unused) return -EIO; } - mutex_lock(&info->bfs_lock); + lock_kernel(); block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; bh = sb_bread(inode->i_sb, block); if (!bh) { printf("Unable to read inode %s:%08x\n", inode->i_sb->s_id, ino); - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return -EIO; } @@ -146,7 +145,7 @@ static int bfs_write_inode(struct inode *inode, int unused) mark_buffer_dirty(bh); brelse(bh); - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return 0; } @@ -171,7 +170,7 @@ static void bfs_delete_inode(struct inode *inode) inode->i_size = 0; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; - mutex_lock(&info->bfs_lock); + lock_kernel(); mark_inode_dirty(inode); block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; @@ -179,7 +178,7 @@ static void bfs_delete_inode(struct inode *inode) if (!bh) { printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino); - mutex_unlock(&info->bfs_lock); + unlock_kernel(); return; } off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; @@ -205,16 +204,14 @@ static void bfs_delete_inode(struct inode *inode) info->si_lf_eblk = bi->i_sblock - 1; mark_buffer_dirty(info->si_sbh); } - mutex_unlock(&info->bfs_lock); + unlock_kernel(); clear_inode(inode); } static void bfs_put_super(struct super_block *s) { struct bfs_sb_info *info = BFS_SB(s); - brelse(info->si_sbh); - mutex_destroy(&info->bfs_lock); kfree(info->si_imap); kfree(info); s->s_fs_info = NULL; @@ -239,13 +236,11 @@ static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf) static void bfs_write_super(struct super_block *s) { - struct bfs_sb_info *info = BFS_SB(s); - - mutex_lock(&info->bfs_lock); + lock_kernel(); if (!(s->s_flags & MS_RDONLY)) - mark_buffer_dirty(info->si_sbh); + mark_buffer_dirty(BFS_SB(s)->si_sbh); s->s_dirt = 0; - mutex_unlock(&info->bfs_lock); + unlock_kernel(); } static struct kmem_cache *bfs_inode_cachep; @@ -264,7 +259,7 @@ static void bfs_destroy_inode(struct inode *inode) kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct bfs_inode_info *bi = foo; @@ -385,7 +380,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) struct bfs_inode *di; int block = (i - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; - unsigned long eblock; + unsigned long sblock, eblock; if (!off) { brelse(bh); @@ -404,6 +399,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) set_bit(i, info->si_imap); info->si_freeb -= BFS_FILEBLOCKS(di); + sblock = le32_to_cpu(di->i_sblock); eblock = le32_to_cpu(di->i_eblock); if (eblock > info->si_lf_eblk) info->si_lf_eblk = eblock; @@ -414,7 +410,6 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) s->s_dirt = 1; } dump_imap("read_super", s); - mutex_init(&info->bfs_lock); return 0; out: diff --git a/trunk/fs/binfmt_aout.c b/trunk/fs/binfmt_aout.c index 204cfd1d7676..ba4cddb92f1d 100644 --- a/trunk/fs/binfmt_aout.c +++ b/trunk/fs/binfmt_aout.c @@ -444,6 +444,12 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) regs->gp = ex.a_gpvalue; #endif start_thread(regs, ex.a_entry, current->mm->start_stack); + if (unlikely(current->ptrace & PT_PTRACED)) { + if (current->ptrace & PT_TRACE_EXEC) + ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP); + else + send_sig(SIGTRAP, current, 0); + } return 0; } diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 655ed8d30a86..3b6ff854d983 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -1003,6 +1003,12 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) #endif start_thread(regs, elf_entry, bprm->p); + if (unlikely(current->ptrace & PT_PTRACED)) { + if (current->ptrace & PT_TRACE_EXEC) + ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP); + else + send_sig(SIGTRAP, current, 0); + } retval = 0; out: kfree(loc); diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index fdeadab2f18b..1b59b1edf26d 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -433,6 +433,13 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, entryaddr = interp_params.entry_addr ?: exec_params.entry_addr; start_thread(regs, entryaddr, current->mm->start_stack); + if (unlikely(current->ptrace & PT_PTRACED)) { + if (current->ptrace & PT_TRACE_EXEC) + ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP); + else + send_sig(SIGTRAP, current, 0); + } + retval = 0; error: diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 56372ecf1690..2cb1acda3a82 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -920,6 +920,9 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) start_thread(regs, start_addr, current->mm->start_stack); + if (current->ptrace & PT_PTRACED) + send_sig(SIGTRAP, current, 0); + return 0; } diff --git a/trunk/fs/binfmt_som.c b/trunk/fs/binfmt_som.c index 68be580ba289..fdc36bfd6a7b 100644 --- a/trunk/fs/binfmt_som.c +++ b/trunk/fs/binfmt_som.c @@ -274,6 +274,8 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs) map_hpux_gateway_page(current,current->mm); start_thread_som(regs, som_entry, bprm->p); + if (current->ptrace & PT_PTRACED) + send_sig(SIGTRAP, current, 0); return 0; /* error cleanup */ diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 25f1af0d81e5..88322b066acb 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -721,8 +721,12 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, const int local_nr_pages = end - start; const int page_limit = cur_page + local_nr_pages; - ret = get_user_pages_fast(uaddr, local_nr_pages, - write_to_vm, &pages[cur_page]); + down_read(¤t->mm->mmap_sem); + ret = get_user_pages(current, current->mm, uaddr, + local_nr_pages, + write_to_vm, 0, &pages[cur_page], NULL); + up_read(¤t->mm->mmap_sem); + if (ret < local_nr_pages) { ret = -EFAULT; goto out_unmap; diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index dcf37cada369..10d8a0aa871a 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -271,7 +271,7 @@ static void bdev_destroy_inode(struct inode *inode) kmem_cache_free(bdev_cachep, bdi); } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct bdev_inode *ei = (struct bdev_inode *) foo; struct block_device *bdev = &ei->bdev; diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index f95805019639..d48caee12e2a 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -706,7 +706,7 @@ static int __set_page_dirty(struct page *page, if (TestSetPageDirty(page)) return 0; - spin_lock_irq(&mapping->tree_lock); + write_lock_irq(&mapping->tree_lock); if (page->mapping) { /* Race with truncate? */ WARN_ON_ONCE(warn && !PageUptodate(page)); @@ -719,7 +719,7 @@ static int __set_page_dirty(struct page *page, radix_tree_tag_set(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); } - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); return 1; @@ -1214,7 +1214,8 @@ void __brelse(struct buffer_head * buf) put_bh(buf); return; } - WARN(1, KERN_ERR "VFS: brelse: Trying to free free buffer\n"); + printk(KERN_ERR "VFS: brelse: Trying to free free buffer\n"); + WARN_ON(1); } /* @@ -3271,7 +3272,7 @@ int bh_submit_read(struct buffer_head *bh) EXPORT_SYMBOL(bh_submit_read); static void -init_buffer_head(void *data) +init_buffer_head(struct kmem_cache *cachep, void *data) { struct buffer_head *bh = data; diff --git a/trunk/fs/cifs/asn1.c b/trunk/fs/cifs/asn1.c index 6bb440b257b0..f58e41d3ba48 100644 --- a/trunk/fs/cifs/asn1.c +++ b/trunk/fs/cifs/asn1.c @@ -400,7 +400,7 @@ asn1_oid_decode(struct asn1_ctx *ctx, size = eoc - ctx->pointer + 1; /* first subid actually encodes first two subids */ - if (size < 2 || size > UINT_MAX/sizeof(unsigned long)) + if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) return 0; *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); @@ -494,7 +494,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, /* remember to free obj->oid */ rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (rc) { - if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { + if ((tag == ASN1_OJI) && (cls == ASN1_PRI)) { rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); if (rc) { rc = compare_oid(oid, oidlen, diff --git a/trunk/fs/cifs/cifs_debug.c b/trunk/fs/cifs/cifs_debug.c index 688a2d42153f..cc950f69e51e 100644 --- a/trunk/fs/cifs/cifs_debug.c +++ b/trunk/fs/cifs/cifs_debug.c @@ -107,7 +107,9 @@ void cifs_dump_mids(struct TCP_Server_Info *server) #endif /* CONFIG_CIFS_DEBUG2 */ #ifdef CONFIG_PROC_FS -static int cifs_debug_data_proc_show(struct seq_file *m, void *v) +static int +cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, + int count, int *eof, void *data) { struct list_head *tmp; struct list_head *tmp1; @@ -115,13 +117,23 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) struct cifsSesInfo *ses; struct cifsTconInfo *tcon; int i; + int length = 0; + char *original_buf = buf; - seq_puts(m, + *beginBuffer = buf + offset; + + length = + sprintf(buf, "Display Internal CIFS Data Structures for Debugging\n" "---------------------------------------------------\n"); - seq_printf(m, "CIFS Version %s\n", CIFS_VERSION); - seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); - seq_printf(m, "Servers:"); + buf += length; + length = sprintf(buf, "CIFS Version %s\n", CIFS_VERSION); + buf += length; + length = sprintf(buf, + "Active VFS Requests: %d\n", GlobalTotalActiveXid); + buf += length; + length = sprintf(buf, "Servers:"); + buf += length; i = 0; read_lock(&GlobalSMBSeslock); @@ -130,10 +142,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) || (ses->serverNOS == NULL)) { - seq_printf(m, "\nentry for %s not fully " + buf += sprintf(buf, "\nentry for %s not fully " "displayed\n\t", ses->serverName); } else { - seq_printf(m, + length = + sprintf(buf, "\n%d) Name: %s Domain: %s Mounts: %d OS:" " %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB" " session status: %d\t", @@ -141,9 +154,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) atomic_read(&ses->inUse), ses->serverOS, ses->serverNOS, ses->capabilities, ses->status); + buf += length; } if (ses->server) { - seq_printf(m, "TCP status: %d\n\tLocal Users To " + buf += sprintf(buf, "TCP status: %d\n\tLocal Users To " "Server: %d SecMode: 0x%x Req On Wire: %d", ses->server->tcpStatus, atomic_read(&ses->server->socketUseCount), @@ -151,12 +165,13 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) atomic_read(&ses->server->inFlight)); #ifdef CONFIG_CIFS_STATS2 - seq_printf(m, " In Send: %d In MaxReq Wait: %d", + buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d", atomic_read(&ses->server->inSend), atomic_read(&ses->server->num_waiters)); #endif - seq_puts(m, "\nMIDs:\n"); + length = sprintf(buf, "\nMIDs:\n"); + buf += length; spin_lock(&GlobalMid_Lock); list_for_each(tmp1, &ses->server->pending_mid_q) { @@ -164,7 +179,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) mid_q_entry, qhead); if (mid_entry) { - seq_printf(m, + length = sprintf(buf, "State: %d com: %d pid:" " %d tsk: %p mid %d\n", mid_entry->midState, @@ -172,6 +187,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) mid_entry->pid, mid_entry->tsk, mid_entry->mid); + buf += length; } } spin_unlock(&GlobalMid_Lock); @@ -179,9 +195,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) } read_unlock(&GlobalSMBSeslock); - seq_putc(m, '\n'); + sprintf(buf, "\n"); + buf++; - seq_puts(m, "Shares:"); + length = sprintf(buf, "Shares:"); + buf += length; i = 0; read_lock(&GlobalSMBSeslock); @@ -190,52 +208,62 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) i++; tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); - seq_printf(m, "\n%d) %s Uses: %d ", i, + length = sprintf(buf, "\n%d) %s Uses: %d ", i, tcon->treeName, atomic_read(&tcon->useCount)); + buf += length; if (tcon->nativeFileSystem) { - seq_printf(m, "Type: %s ", + length = sprintf(buf, "Type: %s ", tcon->nativeFileSystem); + buf += length; } - seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x" + length = sprintf(buf, "DevInfo: 0x%x Attributes: 0x%x" "\nPathComponentMax: %d Status: %d", le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), le32_to_cpu(tcon->fsAttrInfo.Attributes), le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), tcon->tidStatus); + buf += length; if (dev_type == FILE_DEVICE_DISK) - seq_puts(m, " type: DISK "); + length = sprintf(buf, " type: DISK "); else if (dev_type == FILE_DEVICE_CD_ROM) - seq_puts(m, " type: CDROM "); + length = sprintf(buf, " type: CDROM "); else - seq_printf(m, " type: %d ", dev_type); - - if (tcon->tidStatus == CifsNeedReconnect) - seq_puts(m, "\tDISCONNECTED "); + length = + sprintf(buf, " type: %d ", dev_type); + buf += length; + if (tcon->tidStatus == CifsNeedReconnect) { + buf += sprintf(buf, "\tDISCONNECTED "); + length += 14; + } } read_unlock(&GlobalSMBSeslock); - seq_putc(m, '\n'); + length = sprintf(buf, "\n"); + buf += length; /* BB add code to dump additional info such as TCP session info now */ - return 0; -} + /* Now calculate total size of returned data */ + length = buf - original_buf; + + if (offset + count >= length) + *eof = 1; + if (length < offset) { + *eof = 1; + return 0; + } else { + length = length - offset; + } + if (length > count) + length = count; -static int cifs_debug_data_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cifs_debug_data_proc_show, NULL); + return length; } -static const struct file_operations cifs_debug_data_proc_fops = { - .owner = THIS_MODULE, - .open = cifs_debug_data_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - #ifdef CONFIG_CIFS_STATS -static ssize_t cifs_stats_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *ppos) + +static int +cifs_stats_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char c; int rc; @@ -279,132 +307,236 @@ static ssize_t cifs_stats_proc_write(struct file *file, return count; } -static int cifs_stats_proc_show(struct seq_file *m, void *v) +static int +cifs_stats_read(char *buf, char **beginBuffer, off_t offset, + int count, int *eof, void *data) { - int i; + int item_length, i, length; struct list_head *tmp; struct cifsTconInfo *tcon; - seq_printf(m, + *beginBuffer = buf + offset; + + length = sprintf(buf, "Resources in use\nCIFS Session: %d\n", sesInfoAllocCount.counter); - seq_printf(m, "Share (unique mount targets): %d\n", + buf += length; + item_length = + sprintf(buf, "Share (unique mount targets): %d\n", tconInfoAllocCount.counter); - seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n", + length += item_length; + buf += item_length; + item_length = + sprintf(buf, "SMB Request/Response Buffer: %d Pool size: %d\n", bufAllocCount.counter, cifs_min_rcv + tcpSesAllocCount.counter); - seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", + length += item_length; + buf += item_length; + item_length = + sprintf(buf, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", smBufAllocCount.counter, cifs_min_small); + length += item_length; + buf += item_length; #ifdef CONFIG_CIFS_STATS2 - seq_printf(m, "Total Large %d Small %d Allocations\n", + item_length = sprintf(buf, "Total Large %d Small %d Allocations\n", atomic_read(&totBufAllocCount), atomic_read(&totSmBufAllocCount)); + length += item_length; + buf += item_length; #endif /* CONFIG_CIFS_STATS2 */ - seq_printf(m, "Operations (MIDs): %d\n", midCount.counter); - seq_printf(m, + item_length = + sprintf(buf, "Operations (MIDs): %d\n", + midCount.counter); + length += item_length; + buf += item_length; + item_length = sprintf(buf, "\n%d session %d share reconnects\n", tcpSesReconnectCount.counter, tconInfoReconnectCount.counter); + length += item_length; + buf += item_length; - seq_printf(m, + item_length = sprintf(buf, "Total vfs operations: %d maximum at one time: %d\n", GlobalCurrentXid, GlobalMaxActiveXid); + length += item_length; + buf += item_length; i = 0; read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalTreeConnectionList) { i++; tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); - seq_printf(m, "\n%d) %s", i, tcon->treeName); - if (tcon->tidStatus == CifsNeedReconnect) - seq_puts(m, "\tDISCONNECTED "); - seq_printf(m, "\nSMBs: %d Oplock Breaks: %d", + item_length = sprintf(buf, "\n%d) %s", i, tcon->treeName); + buf += item_length; + length += item_length; + if (tcon->tidStatus == CifsNeedReconnect) { + buf += sprintf(buf, "\tDISCONNECTED "); + length += 14; + } + item_length = sprintf(buf, "\nSMBs: %d Oplock Breaks: %d", atomic_read(&tcon->num_smbs_sent), atomic_read(&tcon->num_oplock_brks)); - seq_printf(m, "\nReads: %d Bytes: %lld", + buf += item_length; + length += item_length; + item_length = sprintf(buf, "\nReads: %d Bytes: %lld", atomic_read(&tcon->num_reads), (long long)(tcon->bytes_read)); - seq_printf(m, "\nWrites: %d Bytes: %lld", + buf += item_length; + length += item_length; + item_length = sprintf(buf, "\nWrites: %d Bytes: %lld", atomic_read(&tcon->num_writes), (long long)(tcon->bytes_written)); - seq_printf(m, + buf += item_length; + length += item_length; + item_length = sprintf(buf, "\nLocks: %d HardLinks: %d Symlinks: %d", atomic_read(&tcon->num_locks), atomic_read(&tcon->num_hardlinks), atomic_read(&tcon->num_symlinks)); + buf += item_length; + length += item_length; - seq_printf(m, "\nOpens: %d Closes: %d Deletes: %d", + item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d", atomic_read(&tcon->num_opens), atomic_read(&tcon->num_closes), atomic_read(&tcon->num_deletes)); - seq_printf(m, "\nMkdirs: %d Rmdirs: %d", + buf += item_length; + length += item_length; + item_length = sprintf(buf, "\nMkdirs: %d Rmdirs: %d", atomic_read(&tcon->num_mkdirs), atomic_read(&tcon->num_rmdirs)); - seq_printf(m, "\nRenames: %d T2 Renames %d", + buf += item_length; + length += item_length; + item_length = sprintf(buf, "\nRenames: %d T2 Renames %d", atomic_read(&tcon->num_renames), atomic_read(&tcon->num_t2renames)); - seq_printf(m, "\nFindFirst: %d FNext %d FClose %d", + buf += item_length; + length += item_length; + item_length = sprintf(buf, "\nFindFirst: %d FNext %d FClose %d", atomic_read(&tcon->num_ffirst), atomic_read(&tcon->num_fnext), atomic_read(&tcon->num_fclose)); + buf += item_length; + length += item_length; } read_unlock(&GlobalSMBSeslock); - seq_putc(m, '\n'); - return 0; -} + buf += sprintf(buf, "\n"); + length++; -static int cifs_stats_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cifs_stats_proc_show, NULL); -} + if (offset + count >= length) + *eof = 1; + if (length < offset) { + *eof = 1; + return 0; + } else { + length = length - offset; + } + if (length > count) + length = count; -static const struct file_operations cifs_stats_proc_fops = { - .owner = THIS_MODULE, - .open = cifs_stats_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = cifs_stats_proc_write, -}; + return length; +} #endif /* STATS */ static struct proc_dir_entry *proc_fs_cifs; -static const struct file_operations cifsFYI_proc_fops; -static const struct file_operations cifs_oplock_proc_fops; -static const struct file_operations cifs_lookup_cache_proc_fops; -static const struct file_operations traceSMB_proc_fops; -static const struct file_operations cifs_multiuser_mount_proc_fops; -static const struct file_operations cifs_security_flags_proc_fops; -static const struct file_operations cifs_experimental_proc_fops; -static const struct file_operations cifs_linux_ext_proc_fops; +read_proc_t cifs_txanchor_read; +static read_proc_t cifsFYI_read; +static write_proc_t cifsFYI_write; +static read_proc_t oplockEnabled_read; +static write_proc_t oplockEnabled_write; +static read_proc_t lookupFlag_read; +static write_proc_t lookupFlag_write; +static read_proc_t traceSMB_read; +static write_proc_t traceSMB_write; +static read_proc_t multiuser_mount_read; +static write_proc_t multiuser_mount_write; +static read_proc_t security_flags_read; +static write_proc_t security_flags_write; +/* static read_proc_t ntlmv2_enabled_read; +static write_proc_t ntlmv2_enabled_write; +static read_proc_t packet_signing_enabled_read; +static write_proc_t packet_signing_enabled_write;*/ +static read_proc_t experimEnabled_read; +static write_proc_t experimEnabled_write; +static read_proc_t linuxExtensionsEnabled_read; +static write_proc_t linuxExtensionsEnabled_write; void cifs_proc_init(void) { + struct proc_dir_entry *pde; + proc_fs_cifs = proc_mkdir("fs/cifs", NULL); if (proc_fs_cifs == NULL) return; proc_fs_cifs->owner = THIS_MODULE; - proc_create("DebugData", 0, proc_fs_cifs, &cifs_debug_data_proc_fops); + create_proc_read_entry("DebugData", 0, proc_fs_cifs, + cifs_debug_data_read, NULL); #ifdef CONFIG_CIFS_STATS - proc_create("Stats", 0, proc_fs_cifs, &cifs_stats_proc_fops); + pde = create_proc_read_entry("Stats", 0, proc_fs_cifs, + cifs_stats_read, NULL); + if (pde) + pde->write_proc = cifs_stats_write; #endif /* STATS */ - proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops); - proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops); - proc_create("OplockEnabled", 0, proc_fs_cifs, &cifs_oplock_proc_fops); - proc_create("Experimental", 0, proc_fs_cifs, - &cifs_experimental_proc_fops); - proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs, - &cifs_linux_ext_proc_fops); - proc_create("MultiuserMount", 0, proc_fs_cifs, - &cifs_multiuser_mount_proc_fops); - proc_create("SecurityFlags", 0, proc_fs_cifs, - &cifs_security_flags_proc_fops); - proc_create("LookupCacheEnabled", 0, proc_fs_cifs, - &cifs_lookup_cache_proc_fops); + pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, + cifsFYI_read, NULL); + if (pde) + pde->write_proc = cifsFYI_write; + + pde = + create_proc_read_entry("traceSMB", 0, proc_fs_cifs, + traceSMB_read, NULL); + if (pde) + pde->write_proc = traceSMB_write; + + pde = create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs, + oplockEnabled_read, NULL); + if (pde) + pde->write_proc = oplockEnabled_write; + + pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs, + experimEnabled_read, NULL); + if (pde) + pde->write_proc = experimEnabled_write; + + pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs, + linuxExtensionsEnabled_read, NULL); + if (pde) + pde->write_proc = linuxExtensionsEnabled_write; + + pde = + create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs, + multiuser_mount_read, NULL); + if (pde) + pde->write_proc = multiuser_mount_write; + + pde = + create_proc_read_entry("SecurityFlags", 0, proc_fs_cifs, + security_flags_read, NULL); + if (pde) + pde->write_proc = security_flags_write; + + pde = + create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs, + lookupFlag_read, NULL); + if (pde) + pde->write_proc = lookupFlag_write; + +/* pde = + create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs, + ntlmv2_enabled_read, NULL); + if (pde) + pde->write_proc = ntlmv2_enabled_write; + + pde = + create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs, + packet_signing_enabled_read, NULL); + if (pde) + pde->write_proc = packet_signing_enabled_write;*/ } void @@ -421,26 +553,39 @@ cifs_proc_clean(void) #endif remove_proc_entry("MultiuserMount", proc_fs_cifs); remove_proc_entry("OplockEnabled", proc_fs_cifs); +/* remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */ remove_proc_entry("SecurityFlags", proc_fs_cifs); +/* remove_proc_entry("PacketSigningEnabled", proc_fs_cifs); */ remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); remove_proc_entry("Experimental", proc_fs_cifs); remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); remove_proc_entry("fs/cifs", NULL); } -static int cifsFYI_proc_show(struct seq_file *m, void *v) +static int +cifsFYI_read(char *page, char **start, off_t off, int count, + int *eof, void *data) { - seq_printf(m, "%d\n", cifsFYI); - return 0; -} + int len; -static int cifsFYI_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cifsFYI_proc_show, NULL); -} + len = sprintf(page, "%d\n", cifsFYI); -static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) + len -= off; + *start = page + off; + + if (len > count) + len = count; + else + *eof = 1; + + if (len < 0) + len = 0; + + return len; +} +static int +cifsFYI_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char c; int rc; @@ -458,28 +603,30 @@ static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer, return count; } -static const struct file_operations cifsFYI_proc_fops = { - .owner = THIS_MODULE, - .open = cifsFYI_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = cifsFYI_proc_write, -}; - -static int cifs_oplock_proc_show(struct seq_file *m, void *v) +static int +oplockEnabled_read(char *page, char **start, off_t off, + int count, int *eof, void *data) { - seq_printf(m, "%d\n", oplockEnabled); - return 0; -} + int len; -static int cifs_oplock_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cifs_oplock_proc_show, NULL); -} + len = sprintf(page, "%d\n", oplockEnabled); + + len -= off; + *start = page + off; + + if (len > count) + len = count; + else + *eof = 1; -static ssize_t cifs_oplock_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *ppos) + if (len < 0) + len = 0; + + return len; +} +static int +oplockEnabled_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char c; int rc; @@ -495,28 +642,30 @@ static ssize_t cifs_oplock_proc_write(struct file *file, return count; } -static const struct file_operations cifs_oplock_proc_fops = { - .owner = THIS_MODULE, - .open = cifs_oplock_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = cifs_oplock_proc_write, -}; - -static int cifs_experimental_proc_show(struct seq_file *m, void *v) +static int +experimEnabled_read(char *page, char **start, off_t off, + int count, int *eof, void *data) { - seq_printf(m, "%d\n", experimEnabled); - return 0; -} + int len; -static int cifs_experimental_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cifs_experimental_proc_show, NULL); -} + len = sprintf(page, "%d\n", experimEnabled); + + len -= off; + *start = page + off; + + if (len > count) + len = count; + else + *eof = 1; + + if (len < 0) + len = 0; -static ssize_t cifs_experimental_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *ppos) + return len; +} +static int +experimEnabled_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char c; int rc; @@ -534,28 +683,29 @@ static ssize_t cifs_experimental_proc_write(struct file *file, return count; } -static const struct file_operations cifs_experimental_proc_fops = { - .owner = THIS_MODULE, - .open = cifs_experimental_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = cifs_experimental_proc_write, -}; - -static int cifs_linux_ext_proc_show(struct seq_file *m, void *v) +static int +linuxExtensionsEnabled_read(char *page, char **start, off_t off, + int count, int *eof, void *data) { - seq_printf(m, "%d\n", linuxExtEnabled); - return 0; -} + int len; -static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cifs_linux_ext_proc_show, NULL); -} + len = sprintf(page, "%d\n", linuxExtEnabled); + len -= off; + *start = page + off; -static ssize_t cifs_linux_ext_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *ppos) + if (len > count) + len = count; + else + *eof = 1; + + if (len < 0) + len = 0; + + return len; +} +static int +linuxExtensionsEnabled_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char c; int rc; @@ -571,28 +721,31 @@ static ssize_t cifs_linux_ext_proc_write(struct file *file, return count; } -static const struct file_operations cifs_linux_ext_proc_fops = { - .owner = THIS_MODULE, - .open = cifs_linux_ext_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = cifs_linux_ext_proc_write, -}; -static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v) +static int +lookupFlag_read(char *page, char **start, off_t off, + int count, int *eof, void *data) { - seq_printf(m, "%d\n", lookupCacheEnabled); - return 0; -} + int len; -static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cifs_lookup_cache_proc_show, NULL); -} + len = sprintf(page, "%d\n", lookupCacheEnabled); + + len -= off; + *start = page + off; + + if (len > count) + len = count; + else + *eof = 1; -static ssize_t cifs_lookup_cache_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *ppos) + if (len < 0) + len = 0; + + return len; +} +static int +lookupFlag_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char c; int rc; @@ -607,29 +760,30 @@ static ssize_t cifs_lookup_cache_proc_write(struct file *file, return count; } +static int +traceSMB_read(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int len; -static const struct file_operations cifs_lookup_cache_proc_fops = { - .owner = THIS_MODULE, - .open = cifs_lookup_cache_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = cifs_lookup_cache_proc_write, -}; + len = sprintf(page, "%d\n", traceSMB); -static int traceSMB_proc_show(struct seq_file *m, void *v) -{ - seq_printf(m, "%d\n", traceSMB); - return 0; -} + len -= off; + *start = page + off; -static int traceSMB_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, traceSMB_proc_show, NULL); -} + if (len > count) + len = count; + else + *eof = 1; -static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) + if (len < 0) + len = 0; + + return len; +} +static int +traceSMB_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char c; int rc; @@ -645,28 +799,30 @@ static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer, return count; } -static const struct file_operations traceSMB_proc_fops = { - .owner = THIS_MODULE, - .open = traceSMB_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = traceSMB_proc_write, -}; - -static int cifs_multiuser_mount_proc_show(struct seq_file *m, void *v) +static int +multiuser_mount_read(char *page, char **start, off_t off, + int count, int *eof, void *data) { - seq_printf(m, "%d\n", multiuser_mount); - return 0; -} + int len; -static int cifs_multiuser_mount_proc_open(struct inode *inode, struct file *fh) -{ - return single_open(fh, cifs_multiuser_mount_proc_show, NULL); -} + len = sprintf(page, "%d\n", multiuser_mount); + + len -= off; + *start = page + off; + + if (len > count) + len = count; + else + *eof = 1; -static ssize_t cifs_multiuser_mount_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *ppos) + if (len < 0) + len = 0; + + return len; +} +static int +multiuser_mount_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char c; int rc; @@ -682,28 +838,30 @@ static ssize_t cifs_multiuser_mount_proc_write(struct file *file, return count; } -static const struct file_operations cifs_multiuser_mount_proc_fops = { - .owner = THIS_MODULE, - .open = cifs_multiuser_mount_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = cifs_multiuser_mount_proc_write, -}; - -static int cifs_security_flags_proc_show(struct seq_file *m, void *v) +static int +security_flags_read(char *page, char **start, off_t off, + int count, int *eof, void *data) { - seq_printf(m, "0x%x\n", extended_security); - return 0; -} + int len; -static int cifs_security_flags_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cifs_security_flags_proc_show, NULL); -} + len = sprintf(page, "0x%x\n", extended_security); + + len -= off; + *start = page + off; -static ssize_t cifs_security_flags_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *ppos) + if (len > count) + len = count; + else + *eof = 1; + + if (len < 0) + len = 0; + + return len; +} +static int +security_flags_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { unsigned int flags; char flags_string[12]; @@ -759,15 +917,6 @@ static ssize_t cifs_security_flags_proc_write(struct file *file, /* BB should we turn on MAY flags for other MUST options? */ return count; } - -static const struct file_operations cifs_security_flags_proc_fops = { - .owner = THIS_MODULE, - .open = cifs_security_flags_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = cifs_security_flags_proc_write, -}; #else inline void cifs_proc_init(void) { diff --git a/trunk/fs/cifs/cifsacl.c b/trunk/fs/cifs/cifsacl.c index 57ecdc83c26f..0e9fc2ba90ee 100644 --- a/trunk/fs/cifs/cifsacl.c +++ b/trunk/fs/cifs/cifsacl.c @@ -56,7 +56,7 @@ int match_sid(struct cifs_sid *ctsid) struct cifs_sid *cwsid; if (!ctsid) - return -1; + return (-1); for (i = 0; i < NUM_WK_SIDS; ++i) { cwsid = &(wksidarr[i].cifssid); @@ -87,11 +87,11 @@ int match_sid(struct cifs_sid *ctsid) } cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname)); - return 0; /* sids compare/match */ + return (0); /* sids compare/match */ } cFYI(1, ("No matching sid")); - return -1; + return (-1); } /* if the two SIDs (roughly equivalent to a UUID for a user or group) are @@ -102,16 +102,16 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) int num_subauth, num_sat, num_saw; if ((!ctsid) || (!cwsid)) - return 0; + return (0); /* compare the revision */ if (ctsid->revision != cwsid->revision) - return 0; + return (0); /* compare all of the six auth values */ for (i = 0; i < 6; ++i) { if (ctsid->authority[i] != cwsid->authority[i]) - return 0; + return (0); } /* compare all of the subauth values if any */ @@ -121,11 +121,11 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) if (num_subauth) { for (i = 0; i < num_subauth; ++i) { if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) - return 0; + return (0); } } - return 1; /* sids compare/match */ + return (1); /* sids compare/match */ } @@ -169,7 +169,8 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, for (i = 0; i < 6; i++) ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; for (i = 0; i < 5; i++) - ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i]; + ngroup_sid_ptr->sub_auth[i] = + cpu_to_le32(group_sid_ptr->sub_auth[i]); return; } @@ -284,7 +285,7 @@ static __u16 fill_ace_for_sid(struct cifs_ace *pntace, size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4); pntace->size = cpu_to_le16(size); - return size; + return (size); } @@ -425,7 +426,7 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); pndacl->num_aces = cpu_to_le32(3); - return 0; + return (0); } @@ -509,7 +510,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, sizeof(struct cifs_sid)); */ - return 0; + return (0); } @@ -526,7 +527,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL)) - return -EIO; + return (-EIO); owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); @@ -549,7 +550,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, /* copy security descriptor control portion and owner and group sid */ copy_sec_desc(pntsd, pnntsd, sidsoffset); - return rc; + return (rc); } @@ -628,11 +629,11 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); if (!inode) - return rc; + return (rc); sb = inode->i_sb; if (sb == NULL) - return rc; + return (rc); cifs_sb = CIFS_SB(sb); xid = GetXid(); @@ -651,7 +652,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, if (rc != 0) { cERROR(1, ("Unable to open file to set ACL")); FreeXid(xid); - return rc; + return (rc); } } @@ -664,7 +665,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, FreeXid(xid); - return rc; + return (rc); } /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ @@ -714,7 +715,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) if (!pnntsd) { cERROR(1, ("Unable to allocate security descriptor")); kfree(pntsd); - return -ENOMEM; + return (-ENOMEM); } rc = build_sec_desc(pntsd, pnntsd, inode, nmode); @@ -731,6 +732,6 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) kfree(pntsd); } - return rc; + return (rc); } #endif /* CONFIG_CIFS_EXPERIMENTAL */ diff --git a/trunk/fs/cifs/cifsencrypt.c b/trunk/fs/cifs/cifsencrypt.c index 83fd40dc1ef0..4ff8939c6cc7 100644 --- a/trunk/fs/cifs/cifsencrypt.c +++ b/trunk/fs/cifs/cifsencrypt.c @@ -310,8 +310,9 @@ void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key) utf8 and other multibyte codepages each need their own strupper function since a byte at a time will ont work. */ - for (i = 0; i < CIFS_ENCPWD_SIZE; i++) + for (i = 0; i < CIFS_ENCPWD_SIZE; i++) { password_with_pad[i] = toupper(password_with_pad[i]); + } SMBencrypt(password_with_pad, ses->server->cryptKey, lnm_session_key); /* clear password before we return/free memory */ diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 1ec7076f7b24..22857c639df5 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -267,7 +267,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } -static int cifs_permission(struct inode *inode, int mask) +static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd) { struct cifs_sb_info *cifs_sb; @@ -766,7 +766,7 @@ const struct file_operations cifs_dir_ops = { }; static void -cifs_init_once(void *inode) +cifs_init_once(struct kmem_cache *cachep, void *inode) { struct cifsInodeInfo *cifsi = inode; diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index 7e1cf262effe..9cfcf326ead3 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -27,7 +27,7 @@ #define MAX_SES_INFO 2 #define MAX_TCON_INFO 4 -#define MAX_TREE_SIZE (2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1) +#define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1 #define MAX_SERVER_SIZE 15 #define MAX_SHARE_SIZE 64 /* used to be 20, this should still be enough */ #define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null @@ -537,8 +537,8 @@ require use of the stronger protocol */ #endif /* WEAK_PW_HASH */ #define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ -#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2) -#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2) +#define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 +#define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2 #define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5) /* ***************************************************************** diff --git a/trunk/fs/cifs/cifspdu.h b/trunk/fs/cifs/cifspdu.h index 409abce12732..0f327c224da3 100644 --- a/trunk/fs/cifs/cifspdu.h +++ b/trunk/fs/cifs/cifspdu.h @@ -31,7 +31,7 @@ #else #define CIFS_PROT 0 #endif -#define POSIX_PROT (CIFS_PROT+1) +#define POSIX_PROT CIFS_PROT+1 #define BAD_PROT 0xFFFF /* SMB command codes */ @@ -341,7 +341,7 @@ #define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */ #define CREATE_NO_EA_KNOWLEDGE 0x00000200 #define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete - "open for recovery" flag should + "open for recovery" flag - should be zero in any case */ #define CREATE_OPEN_FOR_RECOVERY 0x00000400 #define CREATE_RANDOM_ACCESS 0x00000800 @@ -414,8 +414,8 @@ struct smb_hdr { __u8 WordCount; } __attribute__((packed)); /* given a pointer to an smb_hdr retrieve the value of byte count */ -#define BCC(smb_var) (*(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) -#define BCC_LE(smb_var) (*(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) +#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) +#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) /* given a pointer to an smb_hdr retrieve the pointer to the byte area */ #define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount) + 2) diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index c621ffa2ca90..4511b708f0f3 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -686,10 +686,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) SecurityBlob, count - 16, &server->secType); - if (rc == 1) + if (rc == 1) { rc = 0; - else + } else { rc = -EINVAL; + } } } else server->capabilities &= ~CAP_EXTENDED_SECURITY; @@ -3913,10 +3914,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, bool is_unicode; struct dfs_referral_level_3 *ref; - if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) - is_unicode = true; - else - is_unicode = false; + is_unicode = pSMBr->hdr.Flags2 & SMBFLG2_UNICODE; *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals); if (*num_of_nodes < 1) { diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index b51d5777cde6..e8fa46c7cff2 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -455,7 +455,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) /* Note that FC 1001 length is big endian on the wire, but we convert it here so it is always manipulated as host byte order */ - pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length); + pdu_length = ntohl(smb_buffer->smb_buf_length); smb_buffer->smb_buf_length = pdu_length; cFYI(1, ("rfc1002 length 0x%x", pdu_length+4)); @@ -1461,39 +1461,6 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, return rc; } -#ifdef CONFIG_DEBUG_LOCK_ALLOC -static struct lock_class_key cifs_key[2]; -static struct lock_class_key cifs_slock_key[2]; - -static inline void -cifs_reclassify_socket4(struct socket *sock) -{ - struct sock *sk = sock->sk; - BUG_ON(sock_owned_by_user(sk)); - sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS", - &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]); -} - -static inline void -cifs_reclassify_socket6(struct socket *sock) -{ - struct sock *sk = sock->sk; - BUG_ON(sock_owned_by_user(sk)); - sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS", - &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]); -} -#else -static inline void -cifs_reclassify_socket4(struct socket *sock) -{ -} - -static inline void -cifs_reclassify_socket6(struct socket *sock) -{ -} -#endif - /* See RFC1001 section 14 on representation of Netbios names */ static void rfc1002mangle(char *target, char *source, unsigned int length) { @@ -1528,7 +1495,6 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, /* BB other socket options to set KEEPALIVE, NODELAY? */ cFYI(1, ("Socket created")); (*csocket)->sk->sk_allocation = GFP_NOFS; - cifs_reclassify_socket4(*csocket); } } @@ -1661,7 +1627,6 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) /* BB other socket options to set KEEPALIVE, NODELAY? */ cFYI(1, ("ipv6 Socket created")); (*csocket)->sk->sk_allocation = GFP_NOFS; - cifs_reclassify_socket6(*csocket); } } diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 46e54d39461d..2e904bd111c8 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -1413,82 +1413,6 @@ static int cifs_vmtruncate(struct inode *inode, loff_t offset) return -ETXTBSY; } -static int -cifs_set_file_size(struct inode *inode, struct iattr *attrs, - int xid, char *full_path) -{ - int rc; - struct cifsFileInfo *open_file; - struct cifsInodeInfo *cifsInode = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsTconInfo *pTcon = cifs_sb->tcon; - - /* - * To avoid spurious oplock breaks from server, in the case of - * inodes that we already have open, avoid doing path based - * setting of file size if we can do it by handle. - * This keeps our caching token (oplock) and avoids timeouts - * when the local oplock break takes longer to flush - * writebehind data than the SMB timeout for the SetPathInfo - * request would allow - */ - open_file = find_writable_file(cifsInode); - if (open_file) { - __u16 nfid = open_file->netfid; - __u32 npid = open_file->pid; - rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, - npid, false); - atomic_dec(&open_file->wrtPending); - cFYI(1, ("SetFSize for attrs rc = %d", rc)); - if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { - unsigned int bytes_written; - rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size, - &bytes_written, NULL, NULL, 1); - cFYI(1, ("Wrt seteof rc %d", rc)); - } - } else - rc = -EINVAL; - - if (rc != 0) { - /* Set file size by pathname rather than by handle - either because no valid, writeable file handle for - it was found or because there was an error setting - it by handle */ - rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, - false, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); - if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { - __u16 netfid; - int oplock = 0; - - rc = SMBLegacyOpen(xid, pTcon, full_path, - FILE_OPEN, GENERIC_WRITE, - CREATE_NOT_DIR, &netfid, &oplock, NULL, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - if (rc == 0) { - unsigned int bytes_written; - rc = CIFSSMBWrite(xid, pTcon, netfid, 0, - attrs->ia_size, - &bytes_written, NULL, - NULL, 1); - cFYI(1, ("wrt seteof rc %d", rc)); - CIFSSMBClose(xid, pTcon, netfid); - } - } - } - - if (rc == 0) { - rc = cifs_vmtruncate(inode, attrs->ia_size); - cifs_truncate_page(inode->i_mapping, inode->i_size); - } - - return rc; -} - int cifs_setattr(struct dentry *direntry, struct iattr *attrs) { int xid; @@ -1496,6 +1420,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) struct cifsTconInfo *pTcon; char *full_path = NULL; int rc = -EACCES; + struct cifsFileInfo *open_file = NULL; FILE_BASIC_INFO time_buf; bool set_time = false; bool set_dosattr = false; @@ -1547,8 +1472,78 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) } if (attrs->ia_valid & ATTR_SIZE) { - rc = cifs_set_file_size(inode, attrs, xid, full_path); - if (rc != 0) + /* To avoid spurious oplock breaks from server, in the case of + inodes that we already have open, avoid doing path based + setting of file size if we can do it by handle. + This keeps our caching token (oplock) and avoids timeouts + when the local oplock break takes longer to flush + writebehind data than the SMB timeout for the SetPathInfo + request would allow */ + + open_file = find_writable_file(cifsInode); + if (open_file) { + __u16 nfid = open_file->netfid; + __u32 npid = open_file->pid; + rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, + nfid, npid, false); + atomic_dec(&open_file->wrtPending); + cFYI(1, ("SetFSize for attrs rc = %d", rc)); + if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { + unsigned int bytes_written; + rc = CIFSSMBWrite(xid, pTcon, + nfid, 0, attrs->ia_size, + &bytes_written, NULL, NULL, + 1 /* 45 seconds */); + cFYI(1, ("Wrt seteof rc %d", rc)); + } + } else + rc = -EINVAL; + + if (rc != 0) { + /* Set file size by pathname rather than by handle + either because no valid, writeable file handle for + it was found or because there was an error setting + it by handle */ + rc = CIFSSMBSetEOF(xid, pTcon, full_path, + attrs->ia_size, false, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); + if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { + __u16 netfid; + int oplock = 0; + + rc = SMBLegacyOpen(xid, pTcon, full_path, + FILE_OPEN, GENERIC_WRITE, + CREATE_NOT_DIR, &netfid, &oplock, + NULL, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc == 0) { + unsigned int bytes_written; + rc = CIFSSMBWrite(xid, pTcon, + netfid, 0, + attrs->ia_size, + &bytes_written, NULL, + NULL, 1 /* 45 sec */); + cFYI(1, ("wrt seteof rc %d", rc)); + CIFSSMBClose(xid, pTcon, netfid); + } + + } + } + + /* Server is ok setting allocation size implicitly - no need + to call: + CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true, + cifs_sb->local_nls); + */ + + if (rc == 0) { + rc = cifs_vmtruncate(inode, attrs->ia_size); + cifs_truncate_page(inode->i_mapping, inode->i_size); + } else goto cifs_setattr_exit; } diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index 5f40ed3473f5..83f306954883 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -690,7 +690,6 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, else cifs_buf_release(cifsFile->srch_inf. ntwrk_buf_start); - cifsFile->srch_inf.ntwrk_buf_start = NULL; } rc = initiate_cifs_search(xid, file); if (rc) { diff --git a/trunk/fs/coda/dir.c b/trunk/fs/coda/dir.c index c5916228243c..3d2580e00a3e 100644 --- a/trunk/fs/coda/dir.c +++ b/trunk/fs/coda/dir.c @@ -137,11 +137,9 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struc } -int coda_permission(struct inode *inode, int mask) +int coda_permission(struct inode *inode, int mask, struct nameidata *nd) { int error = 0; - - mask &= MAY_READ | MAY_WRITE | MAY_EXEC; if (!mask) return 0; diff --git a/trunk/fs/coda/inode.c b/trunk/fs/coda/inode.c index 830f51abb971..2f58dfc70083 100644 --- a/trunk/fs/coda/inode.c +++ b/trunk/fs/coda/inode.c @@ -58,7 +58,7 @@ static void coda_destroy_inode(struct inode *inode) kmem_cache_free(coda_inode_cachep, ITOC(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct coda_inode_info *ei = (struct coda_inode_info *) foo; diff --git a/trunk/fs/coda/pioctl.c b/trunk/fs/coda/pioctl.c index c51365422aa8..c21a1f552a63 100644 --- a/trunk/fs/coda/pioctl.c +++ b/trunk/fs/coda/pioctl.c @@ -24,7 +24,8 @@ #include /* pioctl ops */ -static int coda_ioctl_permission(struct inode *inode, int mask); +static int coda_ioctl_permission(struct inode *inode, int mask, + struct nameidata *nd); static int coda_pioctl(struct inode * inode, struct file * filp, unsigned int cmd, unsigned long user_data); @@ -41,7 +42,8 @@ const struct file_operations coda_ioctl_operations = { }; /* the coda pioctl inode ops */ -static int coda_ioctl_permission(struct inode *inode, int mask) +static int coda_ioctl_permission(struct inode *inode, int mask, + struct nameidata *nd) { return 0; } @@ -49,7 +51,7 @@ static int coda_ioctl_permission(struct inode *inode, int mask) static int coda_pioctl(struct inode * inode, struct file * filp, unsigned int cmd, unsigned long user_data) { - struct path path; + struct nameidata nd; int error; struct PioctlData data; struct inode *target_inode = NULL; @@ -64,21 +66,21 @@ static int coda_pioctl(struct inode * inode, struct file * filp, * Look up the pathname. Note that the pathname is in * user memory, and namei takes care of this */ - if (data.follow) { - error = user_path(data.path, &path); + if ( data.follow ) { + error = user_path_walk(data.path, &nd); } else { - error = user_lpath(data.path, &path); + error = user_path_walk_link(data.path, &nd); } if ( error ) { return error; } else { - target_inode = path.dentry->d_inode; + target_inode = nd.path.dentry->d_inode; } /* return if it is not a Coda inode */ if ( target_inode->i_sb != inode->i_sb ) { - path_put(&path); + path_put(&nd.path); return -EINVAL; } @@ -87,7 +89,7 @@ static int coda_pioctl(struct inode * inode, struct file * filp, error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); - path_put(&path); + path_put(&nd.path); return error; } diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index c9d1472e65c5..106eba28ec5a 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -234,18 +234,18 @@ static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs * * The following statfs calls are copies of code from fs/open.c and * should be checked against those from time to time */ -asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_statfs __user *buf) +asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs __user *buf) { - struct path path; + struct nameidata nd; int error; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (!error) { struct kstatfs tmp; - error = vfs_statfs(path.dentry, &tmp); + error = vfs_statfs(nd.path.dentry, &tmp); if (!error) error = put_compat_statfs(buf, &tmp); - path_put(&path); + path_put(&nd.path); } return error; } @@ -299,21 +299,21 @@ static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstat return 0; } -asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t sz, struct compat_statfs64 __user *buf) +asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, struct compat_statfs64 __user *buf) { - struct path path; + struct nameidata nd; int error; if (sz != sizeof(*buf)) return -EINVAL; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (!error) { struct kstatfs tmp; - error = vfs_statfs(path.dentry, &tmp); + error = vfs_statfs(nd.path.dentry, &tmp); if (!error) error = put_compat_statfs64(buf, &tmp); - path_put(&path); + path_put(&nd.path); } return error; } diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index f2584d22cb45..3818d6ab76ca 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -487,7 +487,6 @@ static void __shrink_dcache_sb(struct super_block *sb, int *count, int flags) if (!cnt) break; } - cond_resched_lock(&dcache_lock); } } while (!list_empty(&tmp)) { diff --git a/trunk/fs/direct-io.c b/trunk/fs/direct-io.c index 9606ee848fd8..9e81addbd6ea 100644 --- a/trunk/fs/direct-io.c +++ b/trunk/fs/direct-io.c @@ -150,11 +150,17 @@ static int dio_refill_pages(struct dio *dio) int nr_pages; nr_pages = min(dio->total_pages - dio->curr_page, DIO_PAGES); - ret = get_user_pages_fast( + down_read(¤t->mm->mmap_sem); + ret = get_user_pages( + current, /* Task for fault acounting */ + current->mm, /* whose pages? */ dio->curr_user_address, /* Where from? */ nr_pages, /* How many pages? */ dio->rw == READ, /* Write to memory? */ - &dio->pages[0]); /* Put results here */ + 0, /* force (?) */ + &dio->pages[0], + NULL); /* vmas */ + up_read(¤t->mm->mmap_sem); if (ret < 0 && dio->blocks_available && (dio->rw & WRITE)) { struct page *page = ZERO_PAGE(0); diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 89209f00f9c7..d755455e3bff 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -465,6 +465,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, int rc; struct dentry *lower_dentry; struct dentry *lower_dir_dentry; + umode_t mode; char *encoded_symname; int encoded_symlen; struct ecryptfs_crypt_stat *crypt_stat = NULL; @@ -472,6 +473,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, lower_dentry = ecryptfs_dentry_to_lower(dentry); dget(lower_dentry); lower_dir_dentry = lock_parent(lower_dentry); + mode = S_IALLUGO; encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, strlen(symname), &encoded_symname); @@ -480,7 +482,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, goto out_lock; } rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, - encoded_symname); + encoded_symname, mode); kfree(encoded_symname); if (rc || !lower_dentry->d_inode) goto out_lock; @@ -828,9 +830,22 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) } static int -ecryptfs_permission(struct inode *inode, int mask) +ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd) { - return inode_permission(ecryptfs_inode_to_lower(inode), mask); + int rc; + + if (nd) { + struct vfsmount *vfsmnt_save = nd->path.mnt; + struct dentry *dentry_save = nd->path.dentry; + + nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry); + nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry); + rc = permission(ecryptfs_inode_to_lower(inode), mask, nd); + nd->path.mnt = vfsmnt_save; + nd->path.dentry = dentry_save; + } else + rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL); + return rc; } /** diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index 448dfd597b5f..6f403cfba14f 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -578,7 +578,7 @@ static struct file_system_type ecryptfs_fs_type = { * Initializes the ecryptfs_inode_info_cache when it is created */ static void -inode_info_init_once(void *vptr) +inode_info_init_once(struct kmem_cache *cachep, void *vptr) { struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; @@ -589,7 +589,7 @@ static struct ecryptfs_cache_info { struct kmem_cache **cache; const char *name; size_t size; - void (*ctor)(void *obj); + void (*ctor)(struct kmem_cache *cache, void *obj); } ecryptfs_cache_infos[] = { { .cache = &ecryptfs_auth_tok_list_item_cache, diff --git a/trunk/fs/efs/super.c b/trunk/fs/efs/super.c index 567b134fa1f1..d733531b55e2 100644 --- a/trunk/fs/efs/super.c +++ b/trunk/fs/efs/super.c @@ -70,7 +70,7 @@ static void efs_destroy_inode(struct inode *inode) kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct efs_inode_info *ei = (struct efs_inode_info *) foo; diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 9696bbf0f0b1..5e559013e303 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -42,13 +42,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include @@ -106,17 +106,11 @@ static inline void put_binfmt(struct linux_binfmt * fmt) */ asmlinkage long sys_uselib(const char __user * library) { - struct file *file; + struct file * file; struct nameidata nd; - char *tmp = getname(library); - int error = PTR_ERR(tmp); - - if (!IS_ERR(tmp)) { - error = path_lookup_open(AT_FDCWD, tmp, - LOOKUP_FOLLOW, &nd, - FMODE_READ|FMODE_EXEC); - putname(tmp); - } + int error; + + error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); if (error) goto out; @@ -124,11 +118,7 @@ asmlinkage long sys_uselib(const char __user * library) if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) goto exit; - error = -EACCES; - if (nd.path.mnt->mnt_flags & MNT_NOEXEC) - goto exit; - - error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); + error = vfs_permission(&nd, MAY_READ | MAY_EXEC); if (error) goto exit; @@ -666,43 +656,38 @@ EXPORT_SYMBOL(setup_arg_pages); struct file *open_exec(const char *name) { struct nameidata nd; - struct file *file; int err; + struct file *file; - err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, - FMODE_READ|FMODE_EXEC); - if (err) - goto out; - - err = -EACCES; - if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) - goto out_path_put; - - if (nd.path.mnt->mnt_flags & MNT_NOEXEC) - goto out_path_put; - - err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); - if (err) - goto out_path_put; - - file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); - if (IS_ERR(file)) - return file; - - err = deny_write_access(file); - if (err) { - fput(file); - goto out; + err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); + file = ERR_PTR(err); + + if (!err) { + struct inode *inode = nd.path.dentry->d_inode; + file = ERR_PTR(-EACCES); + if (S_ISREG(inode->i_mode)) { + int err = vfs_permission(&nd, MAY_EXEC); + file = ERR_PTR(err); + if (!err) { + file = nameidata_to_filp(&nd, + O_RDONLY|O_LARGEFILE); + if (!IS_ERR(file)) { + err = deny_write_access(file); + if (err) { + fput(file); + file = ERR_PTR(err); + } + } +out: + return file; + } + } + release_open_intent(&nd); + path_put(&nd.path); } - - return file; - - out_path_put: - release_open_intent(&nd); - path_put(&nd.path); - out: - return ERR_PTR(err); + goto out; } + EXPORT_SYMBOL(open_exec); int kernel_read(struct file *file, unsigned long offset, @@ -1086,8 +1071,13 @@ EXPORT_SYMBOL(prepare_binprm); static int unsafe_exec(struct task_struct *p) { - int unsafe = tracehook_unsafe_exec(p); - + int unsafe = 0; + if (p->ptrace & PT_PTRACED) { + if (p->ptrace & PT_PTRACE_CAP) + unsafe |= LSM_UNSAFE_PTRACE_CAP; + else + unsafe |= LSM_UNSAFE_PTRACE; + } if (atomic_read(&p->fs->count) > 1 || atomic_read(&p->files->count) > 1 || atomic_read(&p->sighand->count) > 1) @@ -1224,7 +1214,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) read_unlock(&binfmt_lock); retval = fn(bprm, regs); if (retval >= 0) { - tracehook_report_exec(fmt, bprm, regs); put_binfmt(fmt); allow_write_access(bprm->file); if (bprm->file) diff --git a/trunk/fs/ext2/acl.c b/trunk/fs/ext2/acl.c index ae8c4f850b27..e58669e1b87c 100644 --- a/trunk/fs/ext2/acl.c +++ b/trunk/fs/ext2/acl.c @@ -294,7 +294,7 @@ ext2_check_acl(struct inode *inode, int mask) } int -ext2_permission(struct inode *inode, int mask) +ext2_permission(struct inode *inode, int mask, struct nameidata *nd) { return generic_permission(inode, mask, ext2_check_acl); } diff --git a/trunk/fs/ext2/acl.h b/trunk/fs/ext2/acl.h index b42cf578554b..0bde85bafe38 100644 --- a/trunk/fs/ext2/acl.h +++ b/trunk/fs/ext2/acl.h @@ -58,7 +58,7 @@ static inline int ext2_acl_count(size_t size) #define EXT2_ACL_NOT_CACHED ((void *)-1) /* acl.c */ -extern int ext2_permission (struct inode *, int); +extern int ext2_permission (struct inode *, int, struct nameidata *); extern int ext2_acl_chmod (struct inode *); extern int ext2_init_acl (struct inode *, struct inode *); diff --git a/trunk/fs/ext2/super.c b/trunk/fs/ext2/super.c index fd88c7b43e66..31308a3b0b8b 100644 --- a/trunk/fs/ext2/super.c +++ b/trunk/fs/ext2/super.c @@ -159,7 +159,7 @@ static void ext2_destroy_inode(struct inode *inode) kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; diff --git a/trunk/fs/ext3/acl.c b/trunk/fs/ext3/acl.c index b60bb241880c..a754d1848173 100644 --- a/trunk/fs/ext3/acl.c +++ b/trunk/fs/ext3/acl.c @@ -299,7 +299,7 @@ ext3_check_acl(struct inode *inode, int mask) } int -ext3_permission(struct inode *inode, int mask) +ext3_permission(struct inode *inode, int mask, struct nameidata *nd) { return generic_permission(inode, mask, ext3_check_acl); } diff --git a/trunk/fs/ext3/acl.h b/trunk/fs/ext3/acl.h index 42da16b8cac0..0d1e6279cbfd 100644 --- a/trunk/fs/ext3/acl.h +++ b/trunk/fs/ext3/acl.h @@ -58,7 +58,7 @@ static inline int ext3_acl_count(size_t size) #define EXT3_ACL_NOT_CACHED ((void *)-1) /* acl.c */ -extern int ext3_permission (struct inode *, int); +extern int ext3_permission (struct inode *, int, struct nameidata *); extern int ext3_acl_chmod (struct inode *); extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 8ddced384674..615788c6843a 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -472,7 +472,7 @@ static void ext3_destroy_inode(struct inode *inode) kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; diff --git a/trunk/fs/ext4/acl.c b/trunk/fs/ext4/acl.c index c7d04e165446..3c8dab880d91 100644 --- a/trunk/fs/ext4/acl.c +++ b/trunk/fs/ext4/acl.c @@ -299,7 +299,7 @@ ext4_check_acl(struct inode *inode, int mask) } int -ext4_permission(struct inode *inode, int mask) +ext4_permission(struct inode *inode, int mask, struct nameidata *nd) { return generic_permission(inode, mask, ext4_check_acl); } diff --git a/trunk/fs/ext4/acl.h b/trunk/fs/ext4/acl.h index cd2b855a07d6..26a5c1abf147 100644 --- a/trunk/fs/ext4/acl.h +++ b/trunk/fs/ext4/acl.h @@ -58,7 +58,7 @@ static inline int ext4_acl_count(size_t size) #define EXT4_ACL_NOT_CACHED ((void *)-1) /* acl.c */ -extern int ext4_permission (struct inode *, int); +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 *); diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index b5479b1dff14..1cb371dcd609 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -595,7 +595,7 @@ static void ext4_destroy_inode(struct inode *inode) kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; diff --git a/trunk/fs/fat/cache.c b/trunk/fs/fat/cache.c index 3222f51c41cf..3a9ecac8d61f 100644 --- a/trunk/fs/fat/cache.c +++ b/trunk/fs/fat/cache.c @@ -36,7 +36,7 @@ static inline int fat_max_cache(struct inode *inode) static struct kmem_cache *fat_cache_cachep; -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct fat_cache *cache = (struct fat_cache *)foo; diff --git a/trunk/fs/fat/file.c b/trunk/fs/fat/file.c index 8707a8cfa02c..c672df4036e9 100644 --- a/trunk/fs/fat/file.c +++ b/trunk/fs/fat/file.c @@ -15,8 +15,6 @@ #include #include #include -#include -#include int fat_generic_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -66,7 +64,6 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, /* Equivalent to a chmod() */ ia.ia_valid = ATTR_MODE | ATTR_CTIME; - ia.ia_ctime = current_fs_time(inode->i_sb); if (is_dir) { ia.ia_mode = MSDOS_MKMODE(attr, S_IRWXUGO & ~sbi->options.fs_dmask) @@ -93,21 +90,11 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, } } - /* - * The security check is questionable... We single - * out the RO attribute for checking by the security - * module, just because it maps to a file mode. - */ - err = security_inode_setattr(filp->f_path.dentry, &ia); - if (err) - goto up; - /* This MUST be done before doing anything irreversible... */ - err = fat_setattr(filp->f_path.dentry, &ia); + err = notify_change(filp->f_path.dentry, &ia); if (err) goto up; - fsnotify_change(filp->f_path.dentry, ia.ia_valid); if (sbi->options.sys_immutable) { if (attr & ATTR_SYS) inode->i_flags |= S_IMMUTABLE; diff --git a/trunk/fs/fat/inode.c b/trunk/fs/fat/inode.c index 6d266d793e2c..23676f9d79ce 100644 --- a/trunk/fs/fat/inode.c +++ b/trunk/fs/fat/inode.c @@ -498,7 +498,7 @@ static void fat_destroy_inode(struct inode *inode) kmem_cache_free(fat_inode_cachep, MSDOS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index 61d625136813..9679fcbdeaa0 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -64,6 +64,11 @@ static int locate_fd(unsigned int orig_start, int cloexec) struct fdtable *fdt; spin_lock(&files->file_lock); + + error = -EINVAL; + if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) + goto out; + repeat: fdt = files_fdtable(files); /* @@ -78,6 +83,10 @@ static int locate_fd(unsigned int orig_start, int cloexec) if (start < fdt->max_fds) newfd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, start); + + error = -EMFILE; + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) + goto out; error = expand_files(files, newfd); if (error < 0) @@ -126,20 +135,20 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags) if ((flags & ~O_CLOEXEC) != 0) return -EINVAL; - if (unlikely(oldfd == newfd)) - return -EINVAL; - spin_lock(&files->file_lock); if (!(file = fcheck(oldfd))) goto out_unlock; + err = newfd; + if (newfd == oldfd) + goto out_unlock; + err = -EBADF; + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) + goto out_unlock; get_file(file); /* We are now finished with oldfd */ err = expand_files(files, newfd); - if (unlikely(err < 0)) { - if (err == -EMFILE) - err = -EBADF; + if (err < 0) goto out_fput; - } /* To avoid races with open() and dup(), we will mark the fd as * in-use in the open-file bitmap throughout the entire dup2() @@ -180,14 +189,6 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags) asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) { - if (unlikely(newfd == oldfd)) { /* corner case */ - struct files_struct *files = current->files; - rcu_read_lock(); - if (!fcheck_files(files, oldfd)) - oldfd = -EBADF; - rcu_read_unlock(); - return oldfd; - } return sys_dup3(oldfd, newfd, 0); } @@ -320,8 +321,6 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, switch (cmd) { case F_DUPFD: case F_DUPFD_CLOEXEC: - if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) - break; get_file(filp); err = dupfd(filp, arg, cmd == F_DUPFD_CLOEXEC); break; diff --git a/trunk/fs/fifo.c b/trunk/fs/fifo.c index 987bf9411495..9785e36f81e7 100644 --- a/trunk/fs/fifo.c +++ b/trunk/fs/fifo.c @@ -57,7 +57,7 @@ static int fifo_open(struct inode *inode, struct file *filp) * POSIX.1 says that O_NONBLOCK means return with the FIFO * opened, even when there is no process writing the FIFO. */ - filp->f_op = &read_pipefifo_fops; + filp->f_op = &read_fifo_fops; pipe->r_counter++; if (pipe->readers++ == 0) wake_up_partner(inode); @@ -86,7 +86,7 @@ static int fifo_open(struct inode *inode, struct file *filp) if ((filp->f_flags & O_NONBLOCK) && !pipe->readers) goto err; - filp->f_op = &write_pipefifo_fops; + filp->f_op = &write_fifo_fops; pipe->w_counter++; if (!pipe->writers++) wake_up_partner(inode); @@ -105,7 +105,7 @@ static int fifo_open(struct inode *inode, struct file *filp) * This implementation will NEVER block on a O_RDWR open, since * the process can at least talk to itself. */ - filp->f_op = &rdwr_pipefifo_fops; + filp->f_op = &rdwr_fifo_fops; pipe->readers++; pipe->writers++; @@ -151,5 +151,5 @@ static int fifo_open(struct inode *inode, struct file *filp) * depending on the access mode of the file... */ const struct file_operations def_fifo_fops = { - .open = fifo_open, /* will set read_ or write_pipefifo_fops */ + .open = fifo_open, /* will set read or write pipe_fops */ }; diff --git a/trunk/fs/file.c b/trunk/fs/file.c index d8773b19fe47..7b3887e054d0 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -250,18 +250,9 @@ int expand_files(struct files_struct *files, int nr) struct fdtable *fdt; fdt = files_fdtable(files); - - /* - * N.B. For clone tasks sharing a files structure, this test - * will limit the total number of files that can be opened. - */ - if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) - return -EMFILE; - /* Do we need to expand? */ if (nr < fdt->max_fds) return 0; - /* Can we expand? */ if (nr >= sysctl_nr_open) return -EMFILE; diff --git a/trunk/fs/file_table.c b/trunk/fs/file_table.c index f45a4493f9e7..83084225b4c3 100644 --- a/trunk/fs/file_table.c +++ b/trunk/fs/file_table.c @@ -120,7 +120,7 @@ struct file *get_empty_filp(void) tsk = current; INIT_LIST_HEAD(&f->f_u.fu_list); - atomic_long_set(&f->f_count, 1); + atomic_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); f->f_uid = tsk->fsuid; f->f_gid = tsk->fsgid; @@ -219,7 +219,7 @@ EXPORT_SYMBOL(init_file); void fput(struct file *file) { - if (atomic_long_dec_and_test(&file->f_count)) + if (atomic_dec_and_test(&file->f_count)) __fput(file); } @@ -294,7 +294,7 @@ struct file *fget(unsigned int fd) rcu_read_lock(); file = fcheck_files(files, fd); if (file) { - if (!atomic_long_inc_not_zero(&file->f_count)) { + if (!atomic_inc_not_zero(&file->f_count)) { /* File object ref couldn't be taken */ rcu_read_unlock(); return NULL; @@ -326,7 +326,7 @@ struct file *fget_light(unsigned int fd, int *fput_needed) rcu_read_lock(); file = fcheck_files(files, fd); if (file) { - if (atomic_long_inc_not_zero(&file->f_count)) + if (atomic_inc_not_zero(&file->f_count)) *fput_needed = 1; else /* Didn't get the reference, someone's freed */ @@ -341,7 +341,7 @@ struct file *fget_light(unsigned int fd, int *fput_needed) void put_filp(struct file *file) { - if (atomic_long_dec_and_test(&file->f_count)) { + if (atomic_dec_and_test(&file->f_count)) { security_file_free(file); file_kill(file); file_free(file); diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index fd03330cadeb..51d0035ff07e 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -898,7 +898,7 @@ static int fuse_access(struct inode *inode, int mask) return PTR_ERR(req); memset(&inarg, 0, sizeof(inarg)); - inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC); + inarg.mask = mask; req->in.h.opcode = FUSE_ACCESS; req->in.h.nodeid = get_node_id(inode); req->in.numargs = 1; @@ -927,7 +927,7 @@ static int fuse_access(struct inode *inode, int mask) * access request is sent. Execute permission is still checked * locally based on file mode. */ -static int fuse_permission(struct inode *inode, int mask) +static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) { struct fuse_conn *fc = get_fuse_conn(inode); bool refreshed = false; @@ -962,7 +962,7 @@ static int fuse_permission(struct inode *inode, int mask) exist. So if permissions are revoked this won't be noticed immediately, only after the attribute timeout has expired */ - } else if (mask & MAY_ACCESS) { + } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) { err = fuse_access(inode, mask); } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { if (!(inode->i_mode & S_IXUGO)) { diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 2bada6bbc317..67ff2c6a8f63 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -893,7 +893,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, if (count == 0) goto out; - err = file_remove_suid(file); + err = remove_suid(file->f_path.dentry); if (err) goto out; diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index d2249f174e20..7d2f7d6e22e2 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -956,7 +956,7 @@ static inline void unregister_fuseblk(void) } #endif -static void fuse_inode_init_once(void *foo) +static void fuse_inode_init_once(struct kmem_cache *cachep, void *foo) { struct inode * inode = foo; diff --git a/trunk/fs/gfs2/inode.c b/trunk/fs/gfs2/inode.c index 8b0806a32948..6da0ab355b8a 100644 --- a/trunk/fs/gfs2/inode.c +++ b/trunk/fs/gfs2/inode.c @@ -448,7 +448,7 @@ struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) struct qstr qstr; struct inode *inode; gfs2_str2qstr(&qstr, name); - inode = gfs2_lookupi(dip, &qstr, 1); + inode = gfs2_lookupi(dip, &qstr, 1, NULL); /* gfs2_lookupi has inconsistent callers: vfs * related routines expect NULL for no entry found, * gfs2_lookup_simple callers expect ENOENT @@ -477,7 +477,7 @@ struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) */ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, - int is_root) + int is_root, struct nameidata *nd) { struct super_block *sb = dir->i_sb; struct gfs2_inode *dip = GFS2_I(dir); @@ -1173,7 +1173,7 @@ int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) break; } - tmp = gfs2_lookupi(dir, &dotdot, 1); + tmp = gfs2_lookupi(dir, &dotdot, 1, NULL); if (IS_ERR(tmp)) { error = PTR_ERR(tmp); break; diff --git a/trunk/fs/gfs2/inode.h b/trunk/fs/gfs2/inode.h index 58f9607d6a86..6074c2506f75 100644 --- a/trunk/fs/gfs2/inode.h +++ b/trunk/fs/gfs2/inode.h @@ -83,7 +83,7 @@ int gfs2_inode_refresh(struct gfs2_inode *ip); int gfs2_dinode_dealloc(struct gfs2_inode *inode); int gfs2_change_nlink(struct gfs2_inode *ip, int diff); struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, - int is_root); + int is_root, struct nameidata *nd); struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, unsigned int mode, dev_t dev); int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, diff --git a/trunk/fs/gfs2/main.c b/trunk/fs/gfs2/main.c index bb2cc303ac29..bcc668d0fadd 100644 --- a/trunk/fs/gfs2/main.c +++ b/trunk/fs/gfs2/main.c @@ -24,7 +24,7 @@ #include "util.h" #include "glock.h" -static void gfs2_init_inode_once(void *foo) +static void gfs2_init_inode_once(struct kmem_cache *cachep, void *foo) { struct gfs2_inode *ip = foo; @@ -33,7 +33,7 @@ static void gfs2_init_inode_once(void *foo) ip->i_alloc = NULL; } -static void gfs2_init_glock_once(void *foo) +static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo) { struct gfs2_glock *gl = foo; diff --git a/trunk/fs/gfs2/ops_export.c b/trunk/fs/gfs2/ops_export.c index 9cda8536530c..990d9f4bc463 100644 --- a/trunk/fs/gfs2/ops_export.c +++ b/trunk/fs/gfs2/ops_export.c @@ -134,7 +134,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child) struct dentry *dentry; gfs2_str2qstr(&dotdot, ".."); - inode = gfs2_lookupi(child->d_inode, &dotdot, 1); + inode = gfs2_lookupi(child->d_inode, &dotdot, 1, NULL); if (!inode) return ERR_PTR(-ENOENT); diff --git a/trunk/fs/gfs2/ops_inode.c b/trunk/fs/gfs2/ops_inode.c index e2c62f73a778..1e252dfc5294 100644 --- a/trunk/fs/gfs2/ops_inode.c +++ b/trunk/fs/gfs2/ops_inode.c @@ -74,7 +74,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, return PTR_ERR(inode); } - inode = gfs2_lookupi(dir, &dentry->d_name, 0); + inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd); if (inode) { if (!IS_ERR(inode)) { gfs2_holder_uninit(ghs); @@ -109,7 +109,7 @@ static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, dentry->d_op = &gfs2_dops; - inode = gfs2_lookupi(dir, &dentry->d_name, 0); + inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd); if (inode && IS_ERR(inode)) return ERR_CAST(inode); @@ -915,6 +915,12 @@ int gfs2_permission(struct inode *inode, int mask) return error; } +static int gfs2_iop_permission(struct inode *inode, int mask, + struct nameidata *nd) +{ + return gfs2_permission(inode, mask); +} + static int setattr_size(struct inode *inode, struct iattr *attr) { struct gfs2_inode *ip = GFS2_I(inode); @@ -1144,7 +1150,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name) } const struct inode_operations gfs2_file_iops = { - .permission = gfs2_permission, + .permission = gfs2_iop_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, .setxattr = gfs2_setxattr, @@ -1163,7 +1169,7 @@ const struct inode_operations gfs2_dir_iops = { .rmdir = gfs2_rmdir, .mknod = gfs2_mknod, .rename = gfs2_rename, - .permission = gfs2_permission, + .permission = gfs2_iop_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, .setxattr = gfs2_setxattr, @@ -1175,7 +1181,7 @@ const struct inode_operations gfs2_dir_iops = { const struct inode_operations gfs2_symlink_iops = { .readlink = gfs2_readlink, .follow_link = gfs2_follow_link, - .permission = gfs2_permission, + .permission = gfs2_iop_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, .setxattr = gfs2_setxattr, diff --git a/trunk/fs/gfs2/super.c b/trunk/fs/gfs2/super.c index ca831991cbc2..63a8a902d9db 100644 --- a/trunk/fs/gfs2/super.c +++ b/trunk/fs/gfs2/super.c @@ -389,7 +389,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) break; INIT_LIST_HEAD(&jd->extent_list); - jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1); + jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1, NULL); if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { if (!jd->jd_inode) error = -ENOENT; diff --git a/trunk/fs/hfs/inode.c b/trunk/fs/hfs/inode.c index 7e19835efa2e..dc4ec640e875 100644 --- a/trunk/fs/hfs/inode.c +++ b/trunk/fs/hfs/inode.c @@ -511,7 +511,8 @@ void hfs_clear_inode(struct inode *inode) } } -static int hfs_permission(struct inode *inode, int mask) +static int hfs_permission(struct inode *inode, int mask, + struct nameidata *nd) { if (S_ISREG(inode->i_mode) && mask & MAY_EXEC) return 0; @@ -522,6 +523,8 @@ static int hfs_file_open(struct inode *inode, struct file *file) { if (HFS_IS_RSRC(inode)) inode = HFS_I(inode)->rsrc_inode; + if (atomic_read(&file->f_count) != 1) + return 0; atomic_inc(&HFS_I(inode)->opencnt); return 0; } @@ -532,6 +535,8 @@ static int hfs_file_release(struct inode *inode, struct file *file) if (HFS_IS_RSRC(inode)) inode = HFS_I(inode)->rsrc_inode; + if (atomic_read(&file->f_count) != 0) + return 0; if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) { mutex_lock(&inode->i_mutex); hfs_file_truncate(inode); diff --git a/trunk/fs/hfs/super.c b/trunk/fs/hfs/super.c index 4abb1047c689..ac2ec5ef66e4 100644 --- a/trunk/fs/hfs/super.c +++ b/trunk/fs/hfs/super.c @@ -432,7 +432,7 @@ static struct file_system_type hfs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void hfs_init_once(void *p) +static void hfs_init_once(struct kmem_cache *cachep, void *p) { struct hfs_inode_info *i = p; diff --git a/trunk/fs/hfsplus/inode.c b/trunk/fs/hfsplus/inode.c index b085d64a2b67..cc3b5e24339b 100644 --- a/trunk/fs/hfsplus/inode.c +++ b/trunk/fs/hfsplus/inode.c @@ -238,7 +238,7 @@ static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms) perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev); } -static int hfsplus_permission(struct inode *inode, int mask) +static int hfsplus_permission(struct inode *inode, int mask, struct nameidata *nd) { /* MAY_EXEC is also used for lookup, if no x bit is set allow lookup, * open_exec has the same test, so it's still not executable, if a x bit @@ -254,6 +254,8 @@ static int hfsplus_file_open(struct inode *inode, struct file *file) { if (HFSPLUS_IS_RSRC(inode)) inode = HFSPLUS_I(inode).rsrc_inode; + if (atomic_read(&file->f_count) != 1) + return 0; atomic_inc(&HFSPLUS_I(inode).opencnt); return 0; } @@ -264,6 +266,8 @@ static int hfsplus_file_release(struct inode *inode, struct file *file) if (HFSPLUS_IS_RSRC(inode)) inode = HFSPLUS_I(inode).rsrc_inode; + if (atomic_read(&file->f_count) != 0) + return 0; if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) { mutex_lock(&inode->i_mutex); hfsplus_file_truncate(inode); diff --git a/trunk/fs/hfsplus/super.c b/trunk/fs/hfsplus/super.c index e834e578c93f..3859118531c7 100644 --- a/trunk/fs/hfsplus/super.c +++ b/trunk/fs/hfsplus/super.c @@ -485,7 +485,7 @@ static struct file_system_type hfsplus_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void hfsplus_init_once(void *p) +static void hfsplus_init_once(struct kmem_cache *cachep, void *p) { struct hfsplus_inode_info *i = p; diff --git a/trunk/fs/hostfs/hostfs_kern.c b/trunk/fs/hostfs/hostfs_kern.c index d6ecabf4d231..5222345ddccf 100644 --- a/trunk/fs/hostfs/hostfs_kern.c +++ b/trunk/fs/hostfs/hostfs_kern.c @@ -822,7 +822,7 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from, return err; } -int hostfs_permission(struct inode *ino, int desired) +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd) { char *name; int r = 0, w = 0, x = 0, err; diff --git a/trunk/fs/hpfs/namei.c b/trunk/fs/hpfs/namei.c index d9c59a775449..d256559b4104 100644 --- a/trunk/fs/hpfs/namei.c +++ b/trunk/fs/hpfs/namei.c @@ -415,7 +415,7 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry) d_drop(dentry); spin_lock(&dentry->d_lock); if (atomic_read(&dentry->d_count) > 1 || - generic_permission(inode, MAY_WRITE, NULL) || + permission(inode, MAY_WRITE, NULL) || !S_ISREG(inode->i_mode) || get_write_access(inode)) { spin_unlock(&dentry->d_lock); diff --git a/trunk/fs/hpfs/super.c b/trunk/fs/hpfs/super.c index b8ae9c90ada0..f63a699ec659 100644 --- a/trunk/fs/hpfs/super.c +++ b/trunk/fs/hpfs/super.c @@ -173,7 +173,7 @@ static void hpfs_destroy_inode(struct inode *inode) kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; diff --git a/trunk/fs/hppfs/hppfs.c b/trunk/fs/hppfs/hppfs.c index 2b3d1828db99..65077aa90f0a 100644 --- a/trunk/fs/hppfs/hppfs.c +++ b/trunk/fs/hppfs/hppfs.c @@ -655,13 +655,20 @@ static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd); } +int hppfs_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + return generic_permission(inode, mask, NULL); +} + static const struct inode_operations hppfs_dir_iops = { .lookup = hppfs_lookup, + .permission = hppfs_permission, }; static const struct inode_operations hppfs_link_iops = { .readlink = hppfs_readlink, .follow_link = hppfs_follow_link, + .permission = hppfs_permission, }; static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index 3f58923fb39b..dbd01d262ca4 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -705,7 +705,7 @@ static const struct address_space_operations hugetlbfs_aops = { }; -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index b6726f644530..c36d9480335c 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -209,7 +209,7 @@ void inode_init_once(struct inode *inode) INIT_LIST_HEAD(&inode->i_dentry); INIT_LIST_HEAD(&inode->i_devices); INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC); - spin_lock_init(&inode->i_data.tree_lock); + rwlock_init(&inode->i_data.tree_lock); spin_lock_init(&inode->i_data.i_mmap_lock); INIT_LIST_HEAD(&inode->i_data.private_list); spin_lock_init(&inode->i_data.private_lock); @@ -224,7 +224,7 @@ void inode_init_once(struct inode *inode) EXPORT_SYMBOL(inode_init_once); -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct inode * inode = (struct inode *) foo; diff --git a/trunk/fs/inotify_user.c b/trunk/fs/inotify_user.c index 60249429a253..fe79c25d95dc 100644 --- a/trunk/fs/inotify_user.c +++ b/trunk/fs/inotify_user.c @@ -354,20 +354,20 @@ static void inotify_dev_event_dequeue(struct inotify_device *dev) } /* - * find_inode - resolve a user-given path to a specific inode + * find_inode - resolve a user-given path to a specific inode and return a nd */ -static int find_inode(const char __user *dirname, struct path *path, +static int find_inode(const char __user *dirname, struct nameidata *nd, unsigned flags) { int error; - error = user_path_at(AT_FDCWD, dirname, flags, path); + error = __user_walk(dirname, flags, nd); if (error) return error; /* you can only watch an inode if you have read permissions on it */ - error = inode_permission(path->dentry->d_inode, MAY_READ); + error = vfs_permission(nd, MAY_READ); if (error) - path_put(path); + path_put(&nd->path); return error; } @@ -650,11 +650,11 @@ asmlinkage long sys_inotify_init(void) return sys_inotify_init1(0); } -asmlinkage long sys_inotify_add_watch(int fd, const char __user *pathname, u32 mask) +asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) { struct inode *inode; struct inotify_device *dev; - struct path path; + struct nameidata nd; struct file *filp; int ret, fput_needed; unsigned flags = 0; @@ -674,12 +674,12 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *pathname, u32 m if (mask & IN_ONLYDIR) flags |= LOOKUP_DIRECTORY; - ret = find_inode(pathname, &path, flags); + ret = find_inode(path, &nd, flags); if (unlikely(ret)) goto fput_and_out; - /* inode held in place by reference to path; dev by fget on fd */ - inode = path.dentry->d_inode; + /* inode held in place by reference to nd; dev by fget on fd */ + inode = nd.path.dentry->d_inode; dev = filp->private_data; mutex_lock(&dev->up_mutex); @@ -688,7 +688,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *pathname, u32 m ret = create_watch(dev, inode, mask); mutex_unlock(&dev->up_mutex); - path_put(&path); + path_put(&nd.path); fput_and_out: fput_light(filp, fput_needed); return ret; diff --git a/trunk/fs/isofs/inode.c b/trunk/fs/isofs/inode.c index 26948a6033b6..044a254d526b 100644 --- a/trunk/fs/isofs/inode.c +++ b/trunk/fs/isofs/inode.c @@ -73,7 +73,7 @@ static void isofs_destroy_inode(struct inode *inode) kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct iso_inode_info *ei = foo; diff --git a/trunk/fs/jffs2/acl.c b/trunk/fs/jffs2/acl.c index d98713777a1b..4c80404a9aba 100644 --- a/trunk/fs/jffs2/acl.c +++ b/trunk/fs/jffs2/acl.c @@ -314,7 +314,7 @@ static int jffs2_check_acl(struct inode *inode, int mask) return -EAGAIN; } -int jffs2_permission(struct inode *inode, int mask) +int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd) { return generic_permission(inode, mask, jffs2_check_acl); } diff --git a/trunk/fs/jffs2/acl.h b/trunk/fs/jffs2/acl.h index 8ca058aed384..0bb7f003fd80 100644 --- a/trunk/fs/jffs2/acl.h +++ b/trunk/fs/jffs2/acl.h @@ -28,7 +28,7 @@ struct jffs2_acl_header { #define JFFS2_ACL_NOT_CACHED ((void *)-1) -extern int jffs2_permission(struct inode *, int); +extern int jffs2_permission(struct inode *, int, struct nameidata *); extern int jffs2_acl_chmod(struct inode *); extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); extern int jffs2_init_acl_post(struct inode *); diff --git a/trunk/fs/jffs2/dir.c b/trunk/fs/jffs2/dir.c index cd219ef55254..c0c141f6fde1 100644 --- a/trunk/fs/jffs2/dir.c +++ b/trunk/fs/jffs2/dir.c @@ -38,7 +38,7 @@ const struct file_operations jffs2_dir_operations = { .read = generic_read_dir, .readdir = jffs2_readdir, - .unlocked_ioctl=jffs2_ioctl, + .ioctl = jffs2_ioctl, .fsync = jffs2_fsync }; diff --git a/trunk/fs/jffs2/file.c b/trunk/fs/jffs2/file.c index 5a98aa87c853..5e920343b2c5 100644 --- a/trunk/fs/jffs2/file.c +++ b/trunk/fs/jffs2/file.c @@ -46,7 +46,7 @@ const struct file_operations jffs2_file_operations = .aio_read = generic_file_aio_read, .write = do_sync_write, .aio_write = generic_file_aio_write, - .unlocked_ioctl=jffs2_ioctl, + .ioctl = jffs2_ioctl, .mmap = generic_file_readonly_mmap, .fsync = jffs2_fsync, .splice_read = generic_file_splice_read, diff --git a/trunk/fs/jffs2/ioctl.c b/trunk/fs/jffs2/ioctl.c index 9d41f43e47bb..e2177210f621 100644 --- a/trunk/fs/jffs2/ioctl.c +++ b/trunk/fs/jffs2/ioctl.c @@ -12,7 +12,8 @@ #include #include "nodelist.h" -long jffs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +int jffs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) { /* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which will include compression support etc. */ diff --git a/trunk/fs/jffs2/os-linux.h b/trunk/fs/jffs2/os-linux.h index 5e194a5c8e29..2cc866cf134f 100644 --- a/trunk/fs/jffs2/os-linux.h +++ b/trunk/fs/jffs2/os-linux.h @@ -167,7 +167,7 @@ int jffs2_fsync(struct file *, struct dentry *, int); int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg); /* ioctl.c */ -long jffs2_ioctl(struct file *, unsigned int, unsigned long); +int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long); /* symlink.c */ extern const struct inode_operations jffs2_symlink_inode_operations; diff --git a/trunk/fs/jffs2/super.c b/trunk/fs/jffs2/super.c index efd401257ed9..7da69eae49e4 100644 --- a/trunk/fs/jffs2/super.c +++ b/trunk/fs/jffs2/super.c @@ -44,7 +44,7 @@ static void jffs2_destroy_inode(struct inode *inode) kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); } -static void jffs2_i_init_once(void *foo) +static void jffs2_i_init_once(struct kmem_cache *cachep, void *foo) { struct jffs2_inode_info *f = foo; diff --git a/trunk/fs/jfs/acl.c b/trunk/fs/jfs/acl.c index d3e5c33665de..4d84bdc88299 100644 --- a/trunk/fs/jfs/acl.c +++ b/trunk/fs/jfs/acl.c @@ -140,7 +140,7 @@ static int jfs_check_acl(struct inode *inode, int mask) return -EAGAIN; } -int jfs_permission(struct inode *inode, int mask) +int jfs_permission(struct inode *inode, int mask, struct nameidata *nd) { return generic_permission(inode, mask, jfs_check_acl); } diff --git a/trunk/fs/jfs/jfs_acl.h b/trunk/fs/jfs/jfs_acl.h index 88475f10a389..455fa4292045 100644 --- a/trunk/fs/jfs/jfs_acl.h +++ b/trunk/fs/jfs/jfs_acl.h @@ -20,7 +20,7 @@ #ifdef CONFIG_JFS_POSIX_ACL -int jfs_permission(struct inode *, int); +int jfs_permission(struct inode *, int, struct nameidata *); int jfs_init_acl(tid_t, struct inode *, struct inode *); int jfs_setattr(struct dentry *, struct iattr *); diff --git a/trunk/fs/jfs/jfs_metapage.c b/trunk/fs/jfs/jfs_metapage.c index c350057087dd..854ff0ec574f 100644 --- a/trunk/fs/jfs/jfs_metapage.c +++ b/trunk/fs/jfs/jfs_metapage.c @@ -182,7 +182,7 @@ static inline void remove_metapage(struct page *page, struct metapage *mp) #endif -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct metapage *mp = (struct metapage *)foo; diff --git a/trunk/fs/jfs/super.c b/trunk/fs/jfs/super.c index 3630718be395..359c091d8965 100644 --- a/trunk/fs/jfs/super.c +++ b/trunk/fs/jfs/super.c @@ -760,7 +760,7 @@ static struct file_system_type jfs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 5eb259e3cd38..01490300f7cb 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -201,7 +201,7 @@ EXPORT_SYMBOL(locks_init_lock); * Initialises the fields of the file lock which are invariant for * free file_locks. */ -static void init_once(void *foo) +static void init_once(struct kmem_cache *cache, void *foo) { struct file_lock *lock = (struct file_lock *) foo; diff --git a/trunk/fs/minix/inode.c b/trunk/fs/minix/inode.c index d1d1eb84679d..523d73713418 100644 --- a/trunk/fs/minix/inode.c +++ b/trunk/fs/minix/inode.c @@ -68,7 +68,7 @@ static void minix_destroy_inode(struct inode *inode) kmem_cache_free(minix_inode_cachep, minix_i(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct minix_inode_info *ei = (struct minix_inode_info *) foo; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index a7b0a0b80128..01e67dddcc3d 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) @@ -184,8 +185,6 @@ int generic_permission(struct inode *inode, int mask, { umode_t mode = inode->i_mode; - mask &= MAY_READ | MAY_WRITE | MAY_EXEC; - if (current->fsuid == inode->i_uid) mode >>= 6; else { @@ -204,7 +203,7 @@ int generic_permission(struct inode *inode, int mask, /* * If the DACs are ok we don't need any capability check. */ - if ((mask & ~mode) == 0) + if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) return 0; check_capabilities: @@ -227,9 +226,13 @@ int generic_permission(struct inode *inode, int mask, return -EACCES; } -int inode_permission(struct inode *inode, int mask) +int permission(struct inode *inode, int mask, struct nameidata *nd) { - int retval; + int retval, submask; + struct vfsmount *mnt = NULL; + + if (nd) + mnt = nd->path.mnt; if (mask & MAY_WRITE) { umode_t mode = inode->i_mode; @@ -248,9 +251,19 @@ int inode_permission(struct inode *inode, int mask) return -EACCES; } + if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { + /* + * MAY_EXEC on regular files is denied if the fs is mounted + * with the "noexec" flag. + */ + if (mnt && (mnt->mnt_flags & MNT_NOEXEC)) + return -EACCES; + } + /* Ordinary permission routines do not understand MAY_APPEND. */ + submask = mask & ~MAY_APPEND; if (inode->i_op && inode->i_op->permission) { - retval = inode->i_op->permission(inode, mask); + retval = inode->i_op->permission(inode, submask, nd); if (!retval) { /* * Exec permission on a regular file is denied if none @@ -264,7 +277,7 @@ int inode_permission(struct inode *inode, int mask) return -EACCES; } } else { - retval = generic_permission(inode, mask, NULL); + retval = generic_permission(inode, submask, NULL); } if (retval) return retval; @@ -273,8 +286,7 @@ int inode_permission(struct inode *inode, int mask) if (retval) return retval; - return security_inode_permission(inode, - mask & (MAY_READ|MAY_WRITE|MAY_EXEC)); + return security_inode_permission(inode, mask, nd); } /** @@ -289,7 +301,7 @@ int inode_permission(struct inode *inode, int mask) */ int vfs_permission(struct nameidata *nd, int mask) { - return inode_permission(nd->path.dentry->d_inode, mask); + return permission(nd->path.dentry->d_inode, mask, nd); } /** @@ -306,7 +318,7 @@ int vfs_permission(struct nameidata *nd, int mask) */ int file_permission(struct file *file, int mask) { - return inode_permission(file->f_path.dentry->d_inode, mask); + return permission(file->f_path.dentry->d_inode, mask, NULL); } /* @@ -447,7 +459,8 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, * short-cut DAC fails, then call permission() to do more * complete permission check. */ -static int exec_permission_lite(struct inode *inode) +static int exec_permission_lite(struct inode *inode, + struct nameidata *nd) { umode_t mode = inode->i_mode; @@ -473,7 +486,7 @@ static int exec_permission_lite(struct inode *inode) return -EACCES; ok: - return security_inode_permission(inode, MAY_EXEC); + return security_inode_permission(inode, MAY_EXEC, nd); } /* @@ -506,14 +519,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s */ result = d_lookup(parent, name); if (!result) { - struct dentry *dentry; - - /* Don't create child dentry for a dead directory. */ - result = ERR_PTR(-ENOENT); - if (IS_DEADDIR(dir)) - goto out_unlock; - - dentry = d_alloc(parent, name); + struct dentry * dentry = d_alloc(parent, name); result = ERR_PTR(-ENOMEM); if (dentry) { result = dir->i_op->lookup(dir, dentry, nd); @@ -522,7 +528,6 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s else result = dentry; } -out_unlock: mutex_unlock(&dir->i_mutex); return result; } @@ -540,16 +545,27 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s return result; } +static int __emul_lookup_dentry(const char *, struct nameidata *); + /* SMP-safe */ -static __always_inline void +static __always_inline int walk_init_root(const char *name, struct nameidata *nd) { struct fs_struct *fs = current->fs; read_lock(&fs->lock); + if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { + nd->path = fs->altroot; + path_get(&fs->altroot); + read_unlock(&fs->lock); + if (__emul_lookup_dentry(name,nd)) + return 0; + read_lock(&fs->lock); + } nd->path = fs->root; path_get(&fs->root); read_unlock(&fs->lock); + return 1; } /* @@ -590,9 +606,12 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l if (*link == '/') { path_put(&nd->path); - walk_init_root(link, nd); + if (!walk_init_root(link, nd)) + /* weird __emul_prefix() stuff did it */ + goto out; } res = link_path_walk(link, nd); +out: if (nd->depth || res || nd->last_type!=LAST_NORM) return res; /* @@ -870,7 +889,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) unsigned int c; nd->flags |= LOOKUP_CONTINUE; - err = exec_permission_lite(inode); + err = exec_permission_lite(inode, nd); if (err == -EAGAIN) err = vfs_permission(nd, MAY_EXEC); if (err) @@ -1041,6 +1060,67 @@ static int path_walk(const char *name, struct nameidata *nd) return link_path_walk(name, nd); } +/* + * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if + * everything is done. Returns 0 and drops input nd, if lookup failed; + */ +static int __emul_lookup_dentry(const char *name, struct nameidata *nd) +{ + if (path_walk(name, nd)) + return 0; /* something went wrong... */ + + if (!nd->path.dentry->d_inode || + S_ISDIR(nd->path.dentry->d_inode->i_mode)) { + struct path old_path = nd->path; + struct qstr last = nd->last; + int last_type = nd->last_type; + struct fs_struct *fs = current->fs; + + /* + * NAME was not found in alternate root or it's a directory. + * Try to find it in the normal root: + */ + nd->last_type = LAST_ROOT; + read_lock(&fs->lock); + nd->path = fs->root; + path_get(&fs->root); + read_unlock(&fs->lock); + if (path_walk(name, nd) == 0) { + if (nd->path.dentry->d_inode) { + path_put(&old_path); + return 1; + } + path_put(&nd->path); + } + nd->path = old_path; + nd->last = last; + nd->last_type = last_type; + } + return 1; +} + +void set_fs_altroot(void) +{ + char *emul = __emul_prefix(); + struct nameidata nd; + struct path path = {}, old_path; + int err; + struct fs_struct *fs = current->fs; + + if (!emul) + goto set_it; + err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); + if (!err) + path = nd.path; +set_it: + write_lock(&fs->lock); + old_path = fs->altroot; + fs->altroot = path; + write_unlock(&fs->lock); + if (old_path.dentry) + path_put(&old_path); +} + /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ static int do_path_lookup(int dfd, const char *name, unsigned int flags, struct nameidata *nd) @@ -1056,6 +1136,14 @@ static int do_path_lookup(int dfd, const char *name, if (*name=='/') { read_lock(&fs->lock); + if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { + nd->path = fs->altroot; + path_get(&fs->altroot); + read_unlock(&fs->lock); + if (__emul_lookup_dentry(name,nd)) + goto out; /* found in altroot */ + read_lock(&fs->lock); + } nd->path = fs->root; path_get(&fs->root); read_unlock(&fs->lock); @@ -1089,6 +1177,7 @@ static int do_path_lookup(int dfd, const char *name, } retval = path_walk(name, nd); +out: if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && nd->path.dentry->d_inode)) audit_inode(name, nd->path.dentry); @@ -1193,6 +1282,19 @@ static int path_lookup_create(int dfd, const char *name, nd, open_flags, create_mode); } +int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags, + struct nameidata *nd, int open_flags) +{ + char *tmp = getname(name); + int err = PTR_ERR(tmp); + + if (!IS_ERR(tmp)) { + err = __path_lookup_intent_open(AT_FDCWD, tmp, lookup_flags, nd, open_flags, 0); + putname(tmp); + } + return err; +} + static struct dentry *__lookup_hash(struct qstr *name, struct dentry *base, struct nameidata *nd) { @@ -1215,14 +1317,7 @@ static struct dentry *__lookup_hash(struct qstr *name, dentry = cached_lookup(base, name, nd); if (!dentry) { - struct dentry *new; - - /* Don't create child dentry for a dead directory. */ - dentry = ERR_PTR(-ENOENT); - if (IS_DEADDIR(inode)) - goto out; - - new = d_alloc(base, name); + struct dentry *new = d_alloc(base, name); dentry = ERR_PTR(-ENOMEM); if (!new) goto out; @@ -1245,7 +1340,7 @@ static struct dentry *lookup_hash(struct nameidata *nd) { int err; - err = inode_permission(nd->path.dentry->d_inode, MAY_EXEC); + err = permission(nd->path.dentry->d_inode, MAY_EXEC, nd); if (err) return ERR_PTR(err); return __lookup_hash(&nd->last, nd->path.dentry, nd); @@ -1293,7 +1388,7 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) if (err) return ERR_PTR(err); - err = inode_permission(base->d_inode, MAY_EXEC); + err = permission(base->d_inode, MAY_EXEC, NULL); if (err) return ERR_PTR(err); return __lookup_hash(&this, base, NULL); @@ -1321,40 +1416,22 @@ struct dentry *lookup_one_noperm(const char *name, struct dentry *base) return __lookup_hash(&this, base, NULL); } -int user_path_at(int dfd, const char __user *name, unsigned flags, - struct path *path) +int __user_walk_fd(int dfd, const char __user *name, unsigned flags, + struct nameidata *nd) { - struct nameidata nd; char *tmp = getname(name); int err = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - BUG_ON(flags & LOOKUP_PARENT); - - err = do_path_lookup(dfd, tmp, flags, &nd); + if (!IS_ERR(tmp)) { + err = do_path_lookup(dfd, tmp, flags, nd); putname(tmp); - if (!err) - *path = nd.path; } return err; } -static int user_path_parent(int dfd, const char __user *path, - struct nameidata *nd, char **name) +int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd) { - char *s = getname(path); - int error; - - if (IS_ERR(s)) - return PTR_ERR(s); - - error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd); - if (error) - putname(s); - else - *name = s; - - return error; + return __user_walk_fd(AT_FDCWD, name, flags, nd); } /* @@ -1401,7 +1478,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir) BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(victim->d_name.name, victim, dir); - error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); if (error) return error; if (IS_APPEND(dir)) @@ -1438,7 +1515,7 @@ static inline int may_create(struct inode *dir, struct dentry *child, return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; - return inode_permission(dir, MAY_WRITE | MAY_EXEC); + return permission(dir,MAY_WRITE | MAY_EXEC, nd); } /* @@ -1678,7 +1755,7 @@ struct file *do_filp_open(int dfd, const char *pathname, int will_write; int flag = open_to_namei_flags(open_flag); - acc_mode = MAY_OPEN | ACC_MODE(flag); + acc_mode = ACC_MODE(flag); /* O_TRUNC implies we need access checks for write permissions */ if (flag & O_TRUNC) @@ -1994,18 +2071,20 @@ static int may_mknod(mode_t mode) asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, unsigned dev) { - int error; - char *tmp; - struct dentry *dentry; + int error = 0; + char * tmp; + struct dentry * dentry; struct nameidata nd; if (S_ISDIR(mode)) return -EPERM; + tmp = getname(filename); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); - error = user_path_parent(dfd, filename, &nd, &tmp); + error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd); if (error) - return error; - + goto out; dentry = lookup_create(&nd, 0); if (IS_ERR(dentry)) { error = PTR_ERR(dentry); @@ -2037,6 +2116,7 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, out_unlock: mutex_unlock(&nd.path.dentry->d_inode->i_mutex); path_put(&nd.path); +out: putname(tmp); return error; @@ -2076,10 +2156,14 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) struct dentry *dentry; struct nameidata nd; - error = user_path_parent(dfd, pathname, &nd, &tmp); - if (error) + tmp = getname(pathname); + error = PTR_ERR(tmp); + if (IS_ERR(tmp)) goto out_err; + error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd); + if (error) + goto out; dentry = lookup_create(&nd, 1); error = PTR_ERR(dentry); if (IS_ERR(dentry)) @@ -2097,6 +2181,7 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) out_unlock: mutex_unlock(&nd.path.dentry->d_inode->i_mutex); path_put(&nd.path); +out: putname(tmp); out_err: return error; @@ -2174,9 +2259,13 @@ static long do_rmdir(int dfd, const char __user *pathname) struct dentry *dentry; struct nameidata nd; - error = user_path_parent(dfd, pathname, &nd, &name); + name = getname(pathname); + if(IS_ERR(name)) + return PTR_ERR(name); + + error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd); if (error) - return error; + goto exit; switch(nd.last_type) { case LAST_DOTDOT: @@ -2205,6 +2294,7 @@ static long do_rmdir(int dfd, const char __user *pathname) mutex_unlock(&nd.path.dentry->d_inode->i_mutex); exit1: path_put(&nd.path); +exit: putname(name); return error; } @@ -2253,16 +2343,19 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) */ static long do_unlinkat(int dfd, const char __user *pathname) { - int error; - char *name; + int error = 0; + char * name; struct dentry *dentry; struct nameidata nd; struct inode *inode = NULL; - error = user_path_parent(dfd, pathname, &nd, &name); - if (error) - return error; + name = getname(pathname); + if(IS_ERR(name)) + return PTR_ERR(name); + error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd); + if (error) + goto exit; error = -EISDIR; if (nd.last_type != LAST_NORM) goto exit1; @@ -2289,6 +2382,7 @@ static long do_unlinkat(int dfd, const char __user *pathname) iput(inode); /* truncate the inode here */ exit1: path_put(&nd.path); +exit: putname(name); return error; @@ -2314,7 +2408,7 @@ asmlinkage long sys_unlink(const char __user *pathname) return do_unlinkat(AT_FDCWD, pathname); } -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) +int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) { int error = may_create(dir, dentry, NULL); @@ -2338,20 +2432,23 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) asmlinkage long sys_symlinkat(const char __user *oldname, int newdfd, const char __user *newname) { - int error; - char *from; - char *to; + int error = 0; + char * from; + char * to; struct dentry *dentry; struct nameidata nd; from = getname(oldname); - if (IS_ERR(from)) + if(IS_ERR(from)) return PTR_ERR(from); - - error = user_path_parent(newdfd, newname, &nd, &to); - if (error) + to = getname(newname); + error = PTR_ERR(to); + if (IS_ERR(to)) goto out_putname; + error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); + if (error) + goto out; dentry = lookup_create(&nd, 0); error = PTR_ERR(dentry); if (IS_ERR(dentry)) @@ -2360,13 +2457,14 @@ asmlinkage long sys_symlinkat(const char __user *oldname, error = mnt_want_write(nd.path.mnt); if (error) goto out_dput; - error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); mnt_drop_write(nd.path.mnt); out_dput: dput(dentry); out_unlock: mutex_unlock(&nd.path.dentry->d_inode->i_mutex); path_put(&nd.path); +out: putname(to); out_putname: putname(from); @@ -2400,19 +2498,19 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de return -EPERM; if (!dir->i_op || !dir->i_op->link) return -EPERM; - if (S_ISDIR(inode->i_mode)) + if (S_ISDIR(old_dentry->d_inode->i_mode)) return -EPERM; error = security_inode_link(old_dentry, dir, new_dentry); if (error) return error; - mutex_lock(&inode->i_mutex); + mutex_lock(&old_dentry->d_inode->i_mutex); DQUOT_INIT(dir); error = dir->i_op->link(old_dentry, dir, new_dentry); - mutex_unlock(&inode->i_mutex); + mutex_unlock(&old_dentry->d_inode->i_mutex); if (!error) - fsnotify_link(dir, inode, new_dentry); + fsnotify_link(dir, old_dentry->d_inode, new_dentry); return error; } @@ -2430,25 +2528,27 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, int flags) { struct dentry *new_dentry; - struct nameidata nd; - struct path old_path; + struct nameidata nd, old_nd; int error; - char *to; + char * to; if ((flags & ~AT_SYMLINK_FOLLOW) != 0) return -EINVAL; - error = user_path_at(olddfd, oldname, - flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0, - &old_path); - if (error) - return error; + to = getname(newname); + if (IS_ERR(to)) + return PTR_ERR(to); - error = user_path_parent(newdfd, newname, &nd, &to); + error = __user_walk_fd(olddfd, oldname, + flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0, + &old_nd); + if (error) + goto exit; + error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); if (error) goto out; error = -EXDEV; - if (old_path.mnt != nd.path.mnt) + if (old_nd.path.mnt != nd.path.mnt) goto out_release; new_dentry = lookup_create(&nd, 0); error = PTR_ERR(new_dentry); @@ -2457,7 +2557,7 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, error = mnt_want_write(nd.path.mnt); if (error) goto out_dput; - error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); + error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); mnt_drop_write(nd.path.mnt); out_dput: dput(new_dentry); @@ -2465,9 +2565,10 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, mutex_unlock(&nd.path.dentry->d_inode->i_mutex); out_release: path_put(&nd.path); - putname(to); out: - path_put(&old_path); + path_put(&old_nd.path); +exit: + putname(to); return error; } @@ -2520,7 +2621,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, * we'll need to flip '..'. */ if (new_dir != old_dir) { - error = inode_permission(old_dentry->d_inode, MAY_WRITE); + error = permission(old_dentry->d_inode, MAY_WRITE, NULL); if (error) return error; } @@ -2623,22 +2724,20 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, return error; } -asmlinkage long sys_renameat(int olddfd, const char __user *oldname, - int newdfd, const char __user *newname) +static int do_rename(int olddfd, const char *oldname, + int newdfd, const char *newname) { - struct dentry *old_dir, *new_dir; - struct dentry *old_dentry, *new_dentry; - struct dentry *trap; + int error = 0; + struct dentry * old_dir, * new_dir; + struct dentry * old_dentry, *new_dentry; + struct dentry * trap; struct nameidata oldnd, newnd; - char *from; - char *to; - int error; - error = user_path_parent(olddfd, oldname, &oldnd, &from); + error = do_path_lookup(olddfd, oldname, LOOKUP_PARENT, &oldnd); if (error) goto exit; - error = user_path_parent(newdfd, newname, &newnd, &to); + error = do_path_lookup(newdfd, newname, LOOKUP_PARENT, &newnd); if (error) goto exit1; @@ -2700,14 +2799,32 @@ asmlinkage long sys_renameat(int olddfd, const char __user *oldname, unlock_rename(new_dir, old_dir); exit2: path_put(&newnd.path); - putname(to); exit1: path_put(&oldnd.path); - putname(from); exit: return error; } +asmlinkage long sys_renameat(int olddfd, const char __user *oldname, + int newdfd, const char __user *newname) +{ + int error; + char * from; + char * to; + + from = getname(oldname); + if(IS_ERR(from)) + return PTR_ERR(from); + to = getname(newname); + error = PTR_ERR(to); + if (!IS_ERR(to)) { + error = do_rename(olddfd, from, newdfd, to); + putname(to); + } + putname(from); + return error; +} + asmlinkage long sys_rename(const char __user *oldname, const char __user *newname) { return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname); @@ -2842,7 +2959,8 @@ const struct inode_operations page_symlink_inode_operations = { .put_link = page_put_link, }; -EXPORT_SYMBOL(user_path_at); +EXPORT_SYMBOL(__user_walk); +EXPORT_SYMBOL(__user_walk_fd); EXPORT_SYMBOL(follow_down); EXPORT_SYMBOL(follow_up); EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ @@ -2857,7 +2975,7 @@ EXPORT_SYMBOL(page_symlink); EXPORT_SYMBOL(page_symlink_inode_operations); EXPORT_SYMBOL(path_lookup); EXPORT_SYMBOL(vfs_path_lookup); -EXPORT_SYMBOL(inode_permission); +EXPORT_SYMBOL(permission); EXPORT_SYMBOL(vfs_permission); EXPORT_SYMBOL(file_permission); EXPORT_SYMBOL(unlock_rename); diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 411728c0c8bb..4f6f7635b59c 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -112,13 +112,9 @@ struct vfsmount *alloc_vfsmnt(const char *name) int err; err = mnt_alloc_id(mnt); - if (err) - goto out_free_cache; - - if (name) { - mnt->mnt_devname = kstrdup(name, GFP_KERNEL); - if (!mnt->mnt_devname) - goto out_free_id; + if (err) { + kmem_cache_free(mnt_cache, mnt); + return NULL; } atomic_set(&mnt->mnt_count, 1); @@ -131,14 +127,16 @@ struct vfsmount *alloc_vfsmnt(const char *name) INIT_LIST_HEAD(&mnt->mnt_slave_list); INIT_LIST_HEAD(&mnt->mnt_slave); atomic_set(&mnt->__mnt_writers, 0); + if (name) { + int size = strlen(name) + 1; + char *newname = kmalloc(size, GFP_KERNEL); + if (newname) { + memcpy(newname, name, size); + mnt->mnt_devname = newname; + } + } } return mnt; - -out_free_id: - mnt_free_id(mnt); -out_free_cache: - kmem_cache_free(mnt_cache, mnt); - return NULL; } /* @@ -311,9 +309,10 @@ static void handle_write_count_underflow(struct vfsmount *mnt) */ if ((atomic_read(&mnt->__mnt_writers) < 0) && !(mnt->mnt_flags & MNT_IMBALANCED_WRITE_COUNT)) { - WARN(1, KERN_DEBUG "leak detected on mount(%p) writers " + printk(KERN_DEBUG "leak detected on mount(%p) writers " "count: %d\n", mnt, atomic_read(&mnt->__mnt_writers)); + WARN_ON(1); /* use the flag to keep the dmesg spam down */ mnt->mnt_flags |= MNT_IMBALANCED_WRITE_COUNT; } @@ -1130,27 +1129,27 @@ static int do_umount(struct vfsmount *mnt, int flags) asmlinkage long sys_umount(char __user * name, int flags) { - struct path path; + struct nameidata nd; int retval; - retval = user_path(name, &path); + retval = __user_walk(name, LOOKUP_FOLLOW, &nd); if (retval) goto out; retval = -EINVAL; - if (path.dentry != path.mnt->mnt_root) + if (nd.path.dentry != nd.path.mnt->mnt_root) goto dput_and_out; - if (!check_mnt(path.mnt)) + if (!check_mnt(nd.path.mnt)) goto dput_and_out; retval = -EPERM; if (!capable(CAP_SYS_ADMIN)) goto dput_and_out; - retval = do_umount(path.mnt, flags); + retval = do_umount(nd.path.mnt, flags); dput_and_out: /* we mustn't call path_put() as that would clear mnt_expiry_mark */ - dput(path.dentry); - mntput_no_expire(path.mnt); + dput(nd.path.dentry); + mntput_no_expire(nd.path.mnt); out: return retval; } @@ -1974,7 +1973,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, struct fs_struct *fs) { struct mnt_namespace *new_ns; - struct vfsmount *rootmnt = NULL, *pwdmnt = NULL; + struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; struct vfsmount *p, *q; new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); @@ -2017,6 +2016,10 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, pwdmnt = p; fs->pwd.mnt = mntget(q); } + if (p == fs->altroot.mnt) { + altrootmnt = p; + fs->altroot.mnt = mntget(q); + } } p = next_mnt(p, mnt_ns->root); q = next_mnt(q, new_ns->root); @@ -2027,6 +2030,8 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, mntput(rootmnt); if (pwdmnt) mntput(pwdmnt); + if (altrootmnt) + mntput(altrootmnt); return new_ns; } @@ -2179,26 +2184,28 @@ asmlinkage long sys_pivot_root(const char __user * new_root, const char __user * put_old) { struct vfsmount *tmp; - struct path new, old, parent_path, root_parent, root; + struct nameidata new_nd, old_nd; + struct path parent_path, root_parent, root; int error; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - error = user_path_dir(new_root, &new); + error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, + &new_nd); if (error) goto out0; error = -EINVAL; - if (!check_mnt(new.mnt)) + if (!check_mnt(new_nd.path.mnt)) goto out1; - error = user_path_dir(put_old, &old); + error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd); if (error) goto out1; - error = security_sb_pivotroot(&old, &new); + error = security_sb_pivotroot(&old_nd.path, &new_nd.path); if (error) { - path_put(&old); + path_put(&old_nd.path); goto out1; } @@ -2207,69 +2214,69 @@ asmlinkage long sys_pivot_root(const char __user * new_root, path_get(¤t->fs->root); read_unlock(¤t->fs->lock); down_write(&namespace_sem); - mutex_lock(&old.dentry->d_inode->i_mutex); + mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); error = -EINVAL; - if (IS_MNT_SHARED(old.mnt) || - IS_MNT_SHARED(new.mnt->mnt_parent) || + if (IS_MNT_SHARED(old_nd.path.mnt) || + IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || IS_MNT_SHARED(root.mnt->mnt_parent)) goto out2; if (!check_mnt(root.mnt)) goto out2; error = -ENOENT; - if (IS_DEADDIR(new.dentry->d_inode)) + if (IS_DEADDIR(new_nd.path.dentry->d_inode)) goto out2; - if (d_unhashed(new.dentry) && !IS_ROOT(new.dentry)) + if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry)) goto out2; - if (d_unhashed(old.dentry) && !IS_ROOT(old.dentry)) + if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) goto out2; error = -EBUSY; - if (new.mnt == root.mnt || - old.mnt == root.mnt) + if (new_nd.path.mnt == root.mnt || + old_nd.path.mnt == root.mnt) goto out2; /* loop, on the same file system */ error = -EINVAL; if (root.mnt->mnt_root != root.dentry) goto out2; /* not a mountpoint */ if (root.mnt->mnt_parent == root.mnt) goto out2; /* not attached */ - if (new.mnt->mnt_root != new.dentry) + if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) goto out2; /* not a mountpoint */ - if (new.mnt->mnt_parent == new.mnt) + if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt) goto out2; /* not attached */ /* make sure we can reach put_old from new_root */ - tmp = old.mnt; + tmp = old_nd.path.mnt; spin_lock(&vfsmount_lock); - if (tmp != new.mnt) { + if (tmp != new_nd.path.mnt) { for (;;) { if (tmp->mnt_parent == tmp) goto out3; /* already mounted on put_old */ - if (tmp->mnt_parent == new.mnt) + if (tmp->mnt_parent == new_nd.path.mnt) break; tmp = tmp->mnt_parent; } - if (!is_subdir(tmp->mnt_mountpoint, new.dentry)) + if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry)) goto out3; - } else if (!is_subdir(old.dentry, new.dentry)) + } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) goto out3; - detach_mnt(new.mnt, &parent_path); + detach_mnt(new_nd.path.mnt, &parent_path); detach_mnt(root.mnt, &root_parent); /* mount old root on put_old */ - attach_mnt(root.mnt, &old); + attach_mnt(root.mnt, &old_nd.path); /* mount new_root on / */ - attach_mnt(new.mnt, &root_parent); + attach_mnt(new_nd.path.mnt, &root_parent); touch_mnt_namespace(current->nsproxy->mnt_ns); spin_unlock(&vfsmount_lock); - chroot_fs_refs(&root, &new); - security_sb_post_pivotroot(&root, &new); + chroot_fs_refs(&root, &new_nd.path); + security_sb_post_pivotroot(&root, &new_nd.path); error = 0; path_put(&root_parent); path_put(&parent_path); out2: - mutex_unlock(&old.dentry->d_inode->i_mutex); + mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); up_write(&namespace_sem); path_put(&root); - path_put(&old); + path_put(&old_nd.path); out1: - path_put(&new); + path_put(&new_nd.path); out0: return error; out3: diff --git a/trunk/fs/ncpfs/dir.c b/trunk/fs/ncpfs/dir.c index 07e9715b8658..011ef0b6d2d4 100644 --- a/trunk/fs/ncpfs/dir.c +++ b/trunk/fs/ncpfs/dir.c @@ -266,7 +266,7 @@ leave_me:; static int -__ncp_lookup_validate(struct dentry *dentry) +__ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd) { struct ncp_server *server; struct dentry *parent; @@ -340,7 +340,7 @@ ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd) { int res; lock_kernel(); - res = __ncp_lookup_validate(dentry); + res = __ncp_lookup_validate(dentry, nd); unlock_kernel(); return res; } diff --git a/trunk/fs/ncpfs/inode.c b/trunk/fs/ncpfs/inode.c index d642f0e5b365..2e5ab1204dec 100644 --- a/trunk/fs/ncpfs/inode.c +++ b/trunk/fs/ncpfs/inode.c @@ -64,7 +64,7 @@ static void ncp_destroy_inode(struct inode *inode) kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index 74f92b717f78..28a238dab23a 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -1884,7 +1884,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) return status; nfs_access_add_cache(inode, &cache); out: - if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) + if ((cache.mask & mask) == mask) return 0; return -EACCES; } @@ -1907,17 +1907,17 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags) return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); } -int nfs_permission(struct inode *inode, int mask) +int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) { struct rpc_cred *cred; int res = 0; nfs_inc_stats(inode, NFSIOS_VFSACCESS); - if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) + if (mask == 0) goto out; /* Is this sys_access() ? */ - if (mask & MAY_ACCESS) + if (nd != NULL && (nd->flags & LOOKUP_ACCESS)) goto force_lookup; switch (inode->i_mode & S_IFMT) { @@ -1926,7 +1926,8 @@ int nfs_permission(struct inode *inode, int mask) case S_IFREG: /* NFSv4 has atomic_open... */ if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) - && (mask & MAY_OPEN)) + && nd != NULL + && (nd->flags & LOOKUP_OPEN)) goto out; break; case S_IFDIR: diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 52daefa2f521..df23f987da6b 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -1242,7 +1242,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) #endif } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct nfs_inode *nfsi = (struct nfs_inode *) foo; diff --git a/trunk/fs/nfsd/nfsctl.c b/trunk/fs/nfsd/nfsctl.c index c53e65f8f3a2..1955a2702e60 100644 --- a/trunk/fs/nfsd/nfsctl.c +++ b/trunk/fs/nfsd/nfsctl.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/nfsd/nfsfh.c b/trunk/fs/nfsd/nfsfh.c index ea37c96f0445..f45451eb1e38 100644 --- a/trunk/fs/nfsd/nfsfh.c +++ b/trunk/fs/nfsd/nfsfh.c @@ -51,7 +51,7 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry) /* make sure parents give x permission to user */ int err; parent = dget_parent(tdentry); - err = inode_permission(parent->d_inode, MAY_EXEC); + err = permission(parent->d_inode, MAY_EXEC, NULL); if (err < 0) { dput(parent); break; diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 18060bed5267..0f4481e0502d 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -1516,6 +1516,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, struct dentry *dentry, *dnew; __be32 err, cerr; int host_err; + umode_t mode; err = nfserr_noent; if (!flen || !plen) @@ -1534,6 +1535,11 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (IS_ERR(dnew)) goto out_nfserr; + mode = S_IALLUGO; + /* Only the MODE ATTRibute is even vaguely meaningful */ + if (iap && (iap->ia_valid & ATTR_MODE)) + mode = iap->ia_mode & S_IALLUGO; + host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); if (host_err) goto out_nfserr; @@ -1545,11 +1551,11 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, else { strncpy(path_alloced, path, plen); path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced); + host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); kfree(path_alloced); } } else - host_err = vfs_symlink(dentry->d_inode, dnew, path); + host_err = vfs_symlink(dentry->d_inode, dnew, path, mode); if (!host_err) { if (EX_ISSYNC(fhp->fh_export)) @@ -1953,12 +1959,12 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, return 0; /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ - err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC)); + err = permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC), NULL); /* Allow read access to binaries even when mode 111 */ if (err == -EACCES && S_ISREG(inode->i_mode) && acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) - err = inode_permission(inode, MAY_EXEC); + err = permission(inode, MAY_EXEC, NULL); return err? nfserrno(err) : 0; } diff --git a/trunk/fs/ntfs/file.c b/trunk/fs/ntfs/file.c index d020866d4232..3c5550cd11d6 100644 --- a/trunk/fs/ntfs/file.c +++ b/trunk/fs/ntfs/file.c @@ -2118,7 +2118,7 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb, goto out; if (!count) goto out; - err = file_remove_suid(file); + err = remove_suid(file->f_path.dentry); if (err) goto out; file_update_time(file); diff --git a/trunk/fs/ntfs/super.c b/trunk/fs/ntfs/super.c index 4a46743b5077..3e76f3b216bc 100644 --- a/trunk/fs/ntfs/super.c +++ b/trunk/fs/ntfs/super.c @@ -3080,7 +3080,7 @@ struct kmem_cache *ntfs_inode_cache; struct kmem_cache *ntfs_big_inode_cache; /* Init once constructor for the inode slab cache. */ -static void ntfs_big_inode_init_once(void *foo) +static void ntfs_big_inode_init_once(struct kmem_cache *cachep, void *foo) { ntfs_inode *ni = (ntfs_inode *)foo; diff --git a/trunk/fs/ocfs2/dlm/dlmfs.c b/trunk/fs/ocfs2/dlm/dlmfs.c index 533a789c3ef8..e48aba698b77 100644 --- a/trunk/fs/ocfs2/dlm/dlmfs.c +++ b/trunk/fs/ocfs2/dlm/dlmfs.c @@ -267,7 +267,8 @@ static ssize_t dlmfs_file_write(struct file *filp, return writelen; } -static void dlmfs_init_once(void *foo) +static void dlmfs_init_once(struct kmem_cache *cachep, + void *foo) { struct dlmfs_inode_private *ip = (struct dlmfs_inode_private *) foo; diff --git a/trunk/fs/ocfs2/file.c b/trunk/fs/ocfs2/file.c index be2dd95d3a1d..e8514e8b6ce8 100644 --- a/trunk/fs/ocfs2/file.c +++ b/trunk/fs/ocfs2/file.c @@ -1176,7 +1176,7 @@ int ocfs2_getattr(struct vfsmount *mnt, return err; } -int ocfs2_permission(struct inode *inode, int mask) +int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd) { int ret; diff --git a/trunk/fs/ocfs2/file.h b/trunk/fs/ocfs2/file.h index 1e27b4d017ea..048ddcaf5c80 100644 --- a/trunk/fs/ocfs2/file.h +++ b/trunk/fs/ocfs2/file.h @@ -62,7 +62,8 @@ int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di, int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); -int ocfs2_permission(struct inode *inode, int mask); +int ocfs2_permission(struct inode *inode, int mask, + struct nameidata *nd); int ocfs2_should_update_atime(struct inode *inode, struct vfsmount *vfsmnt); diff --git a/trunk/fs/ocfs2/super.c b/trunk/fs/ocfs2/super.c index 2560b33889aa..ccecfe5094fa 100644 --- a/trunk/fs/ocfs2/super.c +++ b/trunk/fs/ocfs2/super.c @@ -1118,7 +1118,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) return status; } -static void ocfs2_inode_init_once(void *data) +static void ocfs2_inode_init_once(struct kmem_cache *cachep, void *data) { struct ocfs2_inode_info *oi = data; diff --git a/trunk/fs/omfs/Makefile b/trunk/fs/omfs/Makefile deleted file mode 100644 index 8b82b63f1129..000000000000 --- a/trunk/fs/omfs/Makefile +++ /dev/null @@ -1,4 +0,0 @@ - -obj-$(CONFIG_OMFS_FS) += omfs.o - -omfs-y := bitmap.o dir.o file.o inode.o diff --git a/trunk/fs/omfs/bitmap.c b/trunk/fs/omfs/bitmap.c deleted file mode 100644 index dc75f22be3f2..000000000000 --- a/trunk/fs/omfs/bitmap.c +++ /dev/null @@ -1,192 +0,0 @@ -#include -#include -#include -#include -#include "omfs.h" - -unsigned long omfs_count_free(struct super_block *sb) -{ - unsigned int i; - unsigned long sum = 0; - struct omfs_sb_info *sbi = OMFS_SB(sb); - int nbits = sb->s_blocksize * 8; - - for (i = 0; i < sbi->s_imap_size; i++) - sum += nbits - bitmap_weight(sbi->s_imap[i], nbits); - - return sum; -} - -/* - * Counts the run of zero bits starting at bit up to max. - * It handles the case where a run might spill over a buffer. - * Called with bitmap lock. - */ -static int count_run(unsigned long **addr, int nbits, - int addrlen, int bit, int max) -{ - int count = 0; - int x; - - for (; addrlen > 0; addrlen--, addr++) { - x = find_next_bit(*addr, nbits, bit); - count += x - bit; - - if (x < nbits || count > max) - return min(count, max); - - bit = 0; - } - return min(count, max); -} - -/* - * Sets or clears the run of count bits starting with bit. - * Called with bitmap lock. - */ -static int set_run(struct super_block *sb, int map, - int nbits, int bit, int count, int set) -{ - int i; - int err; - struct buffer_head *bh; - struct omfs_sb_info *sbi = OMFS_SB(sb); - - err = -ENOMEM; - bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map); - if (!bh) - goto out; - - for (i = 0; i < count; i++, bit++) { - if (bit >= nbits) { - bit = 0; - map++; - - mark_buffer_dirty(bh); - brelse(bh); - bh = sb_bread(sb, - clus_to_blk(sbi, sbi->s_bitmap_ino) + map); - if (!bh) - goto out; - } - if (set) { - set_bit(bit, sbi->s_imap[map]); - set_bit(bit, (long *) bh->b_data); - } else { - clear_bit(bit, sbi->s_imap[map]); - clear_bit(bit, (long *) bh->b_data); - } - } - mark_buffer_dirty(bh); - brelse(bh); - err = 0; -out: - return err; -} - -/* - * Tries to allocate exactly one block. Returns true if sucessful. - */ -int omfs_allocate_block(struct super_block *sb, u64 block) -{ - struct buffer_head *bh; - struct omfs_sb_info *sbi = OMFS_SB(sb); - int bits_per_entry = 8 * sb->s_blocksize; - int map, bit; - int ret = 0; - u64 tmp; - - tmp = block; - bit = do_div(tmp, bits_per_entry); - map = tmp; - - mutex_lock(&sbi->s_bitmap_lock); - if (map >= sbi->s_imap_size || test_and_set_bit(bit, sbi->s_imap[map])) - goto out; - - if (sbi->s_bitmap_ino > 0) { - bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map); - if (!bh) - goto out; - - set_bit(bit, (long *) bh->b_data); - mark_buffer_dirty(bh); - brelse(bh); - } - ret = 1; -out: - mutex_unlock(&sbi->s_bitmap_lock); - return ret; -} - - -/* - * Tries to allocate a set of blocks. The request size depends on the - * type: for inodes, we must allocate sbi->s_mirrors blocks, and for file - * blocks, we try to allocate sbi->s_clustersize, but can always get away - * with just one block. - */ -int omfs_allocate_range(struct super_block *sb, - int min_request, - int max_request, - u64 *return_block, - int *return_size) -{ - struct omfs_sb_info *sbi = OMFS_SB(sb); - int bits_per_entry = 8 * sb->s_blocksize; - int ret = 0; - int i, run, bit; - - mutex_lock(&sbi->s_bitmap_lock); - for (i = 0; i < sbi->s_imap_size; i++) { - bit = 0; - while (bit < bits_per_entry) { - bit = find_next_zero_bit(sbi->s_imap[i], bits_per_entry, - bit); - - if (bit == bits_per_entry) - break; - - run = count_run(&sbi->s_imap[i], bits_per_entry, - sbi->s_imap_size-i, bit, max_request); - - if (run >= min_request) - goto found; - bit += run; - } - } - ret = -ENOSPC; - goto out; - -found: - *return_block = i * bits_per_entry + bit; - *return_size = run; - ret = set_run(sb, i, bits_per_entry, bit, run, 1); - -out: - mutex_unlock(&sbi->s_bitmap_lock); - return ret; -} - -/* - * Clears count bits starting at a given block. - */ -int omfs_clear_range(struct super_block *sb, u64 block, int count) -{ - struct omfs_sb_info *sbi = OMFS_SB(sb); - int bits_per_entry = 8 * sb->s_blocksize; - u64 tmp; - int map, bit, ret; - - tmp = block; - bit = do_div(tmp, bits_per_entry); - map = tmp; - - if (map >= sbi->s_imap_size) - return 0; - - mutex_lock(&sbi->s_bitmap_lock); - ret = set_run(sb, map, bits_per_entry, bit, count, 0); - mutex_unlock(&sbi->s_bitmap_lock); - return ret; -} diff --git a/trunk/fs/omfs/dir.c b/trunk/fs/omfs/dir.c deleted file mode 100644 index 05a5bc31e4bd..000000000000 --- a/trunk/fs/omfs/dir.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * OMFS (as used by RIO Karma) directory operations. - * Copyright (C) 2005 Bob Copeland - * Released under GPL v2. - */ - -#include -#include -#include -#include "omfs.h" - -static int omfs_hash(const char *name, int namelen, int mod) -{ - int i, hash = 0; - for (i = 0; i < namelen; i++) - hash ^= tolower(name[i]) << (i % 24); - return hash % mod; -} - -/* - * Finds the bucket for a given name and reads the containing block; - * *ofs is set to the offset of the first list entry. - */ -static struct buffer_head *omfs_get_bucket(struct inode *dir, - const char *name, int namelen, int *ofs) -{ - int nbuckets = (dir->i_size - OMFS_DIR_START)/8; - int block = clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino); - int bucket = omfs_hash(name, namelen, nbuckets); - - *ofs = OMFS_DIR_START + bucket * 8; - return sb_bread(dir->i_sb, block); -} - -static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block, - const char *name, int namelen, - u64 *prev_block) -{ - struct buffer_head *bh; - struct omfs_inode *oi; - int err = -ENOENT; - *prev_block = ~0; - - while (block != ~0) { - bh = sb_bread(dir->i_sb, - clus_to_blk(OMFS_SB(dir->i_sb), block)); - if (!bh) { - err = -EIO; - goto err; - } - - oi = (struct omfs_inode *) bh->b_data; - if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, block)) { - brelse(bh); - goto err; - } - - if (strncmp(oi->i_name, name, namelen) == 0) - return bh; - - *prev_block = block; - block = be64_to_cpu(oi->i_sibling); - brelse(bh); - } -err: - return ERR_PTR(err); -} - -static struct buffer_head *omfs_find_entry(struct inode *dir, - const char *name, int namelen) -{ - struct buffer_head *bh; - int ofs; - u64 block, dummy; - - bh = omfs_get_bucket(dir, name, namelen, &ofs); - if (!bh) - return ERR_PTR(-EIO); - - block = be64_to_cpu(*((__be64 *) &bh->b_data[ofs])); - brelse(bh); - - return omfs_scan_list(dir, block, name, namelen, &dummy); -} - -int omfs_make_empty(struct inode *inode, struct super_block *sb) -{ - struct omfs_sb_info *sbi = OMFS_SB(sb); - int block = clus_to_blk(sbi, inode->i_ino); - struct buffer_head *bh; - struct omfs_inode *oi; - - bh = sb_bread(sb, block); - if (!bh) - return -ENOMEM; - - memset(bh->b_data, 0, sizeof(struct omfs_inode)); - - if (inode->i_mode & S_IFDIR) { - memset(&bh->b_data[OMFS_DIR_START], 0xff, - sbi->s_sys_blocksize - OMFS_DIR_START); - } else - omfs_make_empty_table(bh, OMFS_EXTENT_START); - - oi = (struct omfs_inode *) bh->b_data; - oi->i_head.h_self = cpu_to_be64(inode->i_ino); - oi->i_sibling = ~0ULL; - - mark_buffer_dirty(bh); - brelse(bh); - return 0; -} - -static int omfs_add_link(struct dentry *dentry, struct inode *inode) -{ - struct inode *dir = dentry->d_parent->d_inode; - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - struct omfs_inode *oi; - struct buffer_head *bh; - u64 block; - __be64 *entry; - int ofs; - - /* just prepend to head of queue in proper bucket */ - bh = omfs_get_bucket(dir, name, namelen, &ofs); - if (!bh) - goto out; - - entry = (__be64 *) &bh->b_data[ofs]; - block = be64_to_cpu(*entry); - *entry = cpu_to_be64(inode->i_ino); - mark_buffer_dirty(bh); - brelse(bh); - - /* now set the sibling and parent pointers on the new inode */ - bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), inode->i_ino)); - if (!bh) - goto out; - - oi = (struct omfs_inode *) bh->b_data; - memcpy(oi->i_name, name, namelen); - memset(oi->i_name + namelen, 0, OMFS_NAMELEN - namelen); - oi->i_sibling = cpu_to_be64(block); - oi->i_parent = cpu_to_be64(dir->i_ino); - mark_buffer_dirty(bh); - brelse(bh); - - dir->i_ctime = CURRENT_TIME_SEC; - - /* mark affected inodes dirty to rebuild checksums */ - mark_inode_dirty(dir); - mark_inode_dirty(inode); - return 0; -out: - return -ENOMEM; -} - -static int omfs_delete_entry(struct dentry *dentry) -{ - struct inode *dir = dentry->d_parent->d_inode; - struct inode *dirty; - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - struct omfs_inode *oi; - struct buffer_head *bh, *bh2; - __be64 *entry, next; - u64 block, prev; - int ofs; - int err = -ENOMEM; - - /* delete the proper node in the bucket's linked list */ - bh = omfs_get_bucket(dir, name, namelen, &ofs); - if (!bh) - goto out; - - entry = (__be64 *) &bh->b_data[ofs]; - block = be64_to_cpu(*entry); - - bh2 = omfs_scan_list(dir, block, name, namelen, &prev); - if (IS_ERR(bh2)) { - err = PTR_ERR(bh2); - goto out_free_bh; - } - - oi = (struct omfs_inode *) bh2->b_data; - next = oi->i_sibling; - brelse(bh2); - - if (prev != ~0) { - /* found in middle of list, get list ptr */ - brelse(bh); - bh = sb_bread(dir->i_sb, - clus_to_blk(OMFS_SB(dir->i_sb), prev)); - if (!bh) - goto out; - - oi = (struct omfs_inode *) bh->b_data; - entry = &oi->i_sibling; - } - - *entry = next; - mark_buffer_dirty(bh); - - if (prev != ~0) { - dirty = omfs_iget(dir->i_sb, prev); - if (!IS_ERR(dirty)) { - mark_inode_dirty(dirty); - iput(dirty); - } - } - - err = 0; -out_free_bh: - brelse(bh); -out: - return err; -} - -static int omfs_dir_is_empty(struct inode *inode) -{ - int nbuckets = (inode->i_size - OMFS_DIR_START) / 8; - struct buffer_head *bh; - u64 *ptr; - int i; - - bh = sb_bread(inode->i_sb, clus_to_blk(OMFS_SB(inode->i_sb), - inode->i_ino)); - - if (!bh) - return 0; - - ptr = (u64 *) &bh->b_data[OMFS_DIR_START]; - - for (i = 0; i < nbuckets; i++, ptr++) - if (*ptr != ~0) - break; - - brelse(bh); - return *ptr != ~0; -} - -static int omfs_unlink(struct inode *dir, struct dentry *dentry) -{ - int ret; - struct inode *inode = dentry->d_inode; - - ret = omfs_delete_entry(dentry); - if (ret) - goto end_unlink; - - inode_dec_link_count(inode); - mark_inode_dirty(dir); - -end_unlink: - return ret; -} - -static int omfs_rmdir(struct inode *dir, struct dentry *dentry) -{ - int err = -ENOTEMPTY; - struct inode *inode = dentry->d_inode; - - if (omfs_dir_is_empty(inode)) { - err = omfs_unlink(dir, dentry); - if (!err) - inode_dec_link_count(inode); - } - return err; -} - -static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode) -{ - int err; - struct inode *inode = omfs_new_inode(dir, mode); - - if (IS_ERR(inode)) - return PTR_ERR(inode); - - err = omfs_make_empty(inode, dir->i_sb); - if (err) - goto out_free_inode; - - err = omfs_add_link(dentry, inode); - if (err) - goto out_free_inode; - - d_instantiate(dentry, inode); - return 0; - -out_free_inode: - iput(inode); - return err; -} - -static int omfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ - return omfs_add_node(dir, dentry, mode | S_IFDIR); -} - -static int omfs_create(struct inode *dir, struct dentry *dentry, int mode, - struct nameidata *nd) -{ - return omfs_add_node(dir, dentry, mode | S_IFREG); -} - -static struct dentry *omfs_lookup(struct inode *dir, struct dentry *dentry, - struct nameidata *nd) -{ - struct buffer_head *bh; - struct inode *inode = NULL; - - if (dentry->d_name.len > OMFS_NAMELEN) - return ERR_PTR(-ENAMETOOLONG); - - bh = omfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len); - if (!IS_ERR(bh)) { - struct omfs_inode *oi = (struct omfs_inode *)bh->b_data; - ino_t ino = be64_to_cpu(oi->i_head.h_self); - brelse(bh); - inode = omfs_iget(dir->i_sb, ino); - if (IS_ERR(inode)) - return ERR_CAST(inode); - } - d_add(dentry, inode); - return NULL; -} - -/* sanity check block's self pointer */ -int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, - u64 fsblock) -{ - int is_bad; - u64 ino = be64_to_cpu(header->h_self); - is_bad = ((ino != fsblock) || (ino < sbi->s_root_ino) || - (ino > sbi->s_num_blocks)); - - if (is_bad) - printk(KERN_WARNING "omfs: bad hash chain detected\n"); - - return is_bad; -} - -static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir, - u64 fsblock, int hindex) -{ - struct inode *dir = filp->f_dentry->d_inode; - struct buffer_head *bh; - struct omfs_inode *oi; - u64 self; - int res = 0; - unsigned char d_type; - - /* follow chain in this bucket */ - while (fsblock != ~0) { - bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), - fsblock)); - if (!bh) - goto out; - - oi = (struct omfs_inode *) bh->b_data; - if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, fsblock)) { - brelse(bh); - goto out; - } - - self = fsblock; - fsblock = be64_to_cpu(oi->i_sibling); - - /* skip visited nodes */ - if (hindex) { - hindex--; - brelse(bh); - continue; - } - - d_type = (oi->i_type == OMFS_DIR) ? DT_DIR : DT_REG; - - res = filldir(dirent, oi->i_name, strnlen(oi->i_name, - OMFS_NAMELEN), filp->f_pos, self, d_type); - if (res == 0) - filp->f_pos++; - brelse(bh); - } -out: - return res; -} - -static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) -{ - struct inode *new_inode = new_dentry->d_inode; - struct inode *old_inode = old_dentry->d_inode; - struct buffer_head *bh; - int is_dir; - int err; - - is_dir = S_ISDIR(old_inode->i_mode); - - if (new_inode) { - /* overwriting existing file/dir */ - err = -ENOTEMPTY; - if (is_dir && !omfs_dir_is_empty(new_inode)) - goto out; - - err = -ENOENT; - bh = omfs_find_entry(new_dir, new_dentry->d_name.name, - new_dentry->d_name.len); - if (IS_ERR(bh)) - goto out; - brelse(bh); - - err = omfs_unlink(new_dir, new_dentry); - if (err) - goto out; - } - - /* since omfs locates files by name, we need to unlink _before_ - * adding the new link or we won't find the old one */ - inode_inc_link_count(old_inode); - err = omfs_unlink(old_dir, old_dentry); - if (err) { - inode_dec_link_count(old_inode); - goto out; - } - - err = omfs_add_link(new_dentry, old_inode); - if (err) - goto out; - - old_inode->i_ctime = CURRENT_TIME_SEC; -out: - return err; -} - -static int omfs_readdir(struct file *filp, void *dirent, filldir_t filldir) -{ - struct inode *dir = filp->f_dentry->d_inode; - struct buffer_head *bh; - loff_t offset, res; - unsigned int hchain, hindex; - int nbuckets; - u64 fsblock; - int ret = -EINVAL; - - if (filp->f_pos >> 32) - goto success; - - switch ((unsigned long) filp->f_pos) { - case 0: - if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0) - goto success; - filp->f_pos++; - /* fall through */ - case 1: - if (filldir(dirent, "..", 2, 1, - parent_ino(filp->f_dentry), DT_DIR) < 0) - goto success; - filp->f_pos = 1 << 20; - /* fall through */ - } - - nbuckets = (dir->i_size - OMFS_DIR_START) / 8; - - /* high 12 bits store bucket + 1 and low 20 bits store hash index */ - hchain = (filp->f_pos >> 20) - 1; - hindex = filp->f_pos & 0xfffff; - - bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino)); - if (!bh) - goto out; - - offset = OMFS_DIR_START + hchain * 8; - - for (; hchain < nbuckets; hchain++, offset += 8) { - fsblock = be64_to_cpu(*((__be64 *) &bh->b_data[offset])); - - res = omfs_fill_chain(filp, dirent, filldir, fsblock, hindex); - hindex = 0; - if (res < 0) - break; - - filp->f_pos = (hchain+2) << 20; - } - brelse(bh); -success: - ret = 0; -out: - return ret; -} - -struct inode_operations omfs_dir_inops = { - .lookup = omfs_lookup, - .mkdir = omfs_mkdir, - .rename = omfs_rename, - .create = omfs_create, - .unlink = omfs_unlink, - .rmdir = omfs_rmdir, -}; - -struct file_operations omfs_dir_operations = { - .read = generic_read_dir, - .readdir = omfs_readdir, -}; diff --git a/trunk/fs/omfs/file.c b/trunk/fs/omfs/file.c deleted file mode 100644 index 66e01fae4384..000000000000 --- a/trunk/fs/omfs/file.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * OMFS (as used by RIO Karma) file operations. - * Copyright (C) 2005 Bob Copeland - * Released under GPL v2. - */ - -#include -#include -#include -#include -#include -#include "omfs.h" - -static int omfs_sync_file(struct file *file, struct dentry *dentry, - int datasync) -{ - struct inode *inode = dentry->d_inode; - int err; - - err = sync_mapping_buffers(inode->i_mapping); - if (!(inode->i_state & I_DIRTY)) - return err; - if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) - return err; - err |= omfs_sync_inode(inode); - return err ? -EIO : 0; -} - -void omfs_make_empty_table(struct buffer_head *bh, int offset) -{ - struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset]; - - oe->e_next = ~0ULL; - oe->e_extent_count = cpu_to_be32(1), - oe->e_fill = cpu_to_be32(0x22), - oe->e_entry.e_cluster = ~0ULL; - oe->e_entry.e_blocks = ~0ULL; -} - -int omfs_shrink_inode(struct inode *inode) -{ - struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); - struct omfs_extent *oe; - struct omfs_extent_entry *entry; - struct buffer_head *bh; - u64 next, last; - u32 extent_count; - int ret; - - /* traverse extent table, freeing each entry that is greater - * than inode->i_size; - */ - next = inode->i_ino; - - /* only support truncate -> 0 for now */ - ret = -EIO; - if (inode->i_size != 0) - goto out; - - bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); - if (!bh) - goto out; - - oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); - - for (;;) { - - if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) { - brelse(bh); - goto out; - } - - extent_count = be32_to_cpu(oe->e_extent_count); - last = next; - next = be64_to_cpu(oe->e_next); - entry = &oe->e_entry; - - /* ignore last entry as it is the terminator */ - for (; extent_count > 1; extent_count--) { - u64 start, count; - start = be64_to_cpu(entry->e_cluster); - count = be64_to_cpu(entry->e_blocks); - - omfs_clear_range(inode->i_sb, start, (int) count); - entry++; - } - omfs_make_empty_table(bh, (char *) oe - bh->b_data); - mark_buffer_dirty(bh); - brelse(bh); - - if (last != inode->i_ino) - omfs_clear_range(inode->i_sb, last, sbi->s_mirrors); - - if (next == ~0) - break; - - bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); - if (!bh) - goto out; - oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); - } - ret = 0; -out: - return ret; -} - -static void omfs_truncate(struct inode *inode) -{ - omfs_shrink_inode(inode); - mark_inode_dirty(inode); -} - -/* - * Add new blocks to the current extent, or create new entries/continuations - * as necessary. - */ -static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe, - u64 *ret_block) -{ - struct omfs_extent_entry *terminator; - struct omfs_extent_entry *entry = &oe->e_entry; - struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); - u32 extent_count = be32_to_cpu(oe->e_extent_count); - u64 new_block = 0; - u32 max_count; - int new_count; - int ret = 0; - - /* reached the end of the extent table with no blocks mapped. - * there are three possibilities for adding: grow last extent, - * add a new extent to the current extent table, and add a - * continuation inode. in last two cases need an allocator for - * sbi->s_cluster_size - */ - - /* TODO: handle holes */ - - /* should always have a terminator */ - if (extent_count < 1) - return -EIO; - - /* trivially grow current extent, if next block is not taken */ - terminator = entry + extent_count - 1; - if (extent_count > 1) { - entry = terminator-1; - new_block = be64_to_cpu(entry->e_cluster) + - be64_to_cpu(entry->e_blocks); - - if (omfs_allocate_block(inode->i_sb, new_block)) { - entry->e_blocks = - cpu_to_be64(be64_to_cpu(entry->e_blocks) + 1); - terminator->e_blocks = ~(cpu_to_be64( - be64_to_cpu(~terminator->e_blocks) + 1)); - goto out; - } - } - max_count = (sbi->s_sys_blocksize - OMFS_EXTENT_START - - sizeof(struct omfs_extent)) / - sizeof(struct omfs_extent_entry) + 1; - - /* TODO: add a continuation block here */ - if (be32_to_cpu(oe->e_extent_count) > max_count-1) - return -EIO; - - /* try to allocate a new cluster */ - ret = omfs_allocate_range(inode->i_sb, 1, sbi->s_clustersize, - &new_block, &new_count); - if (ret) - goto out_fail; - - /* copy terminator down an entry */ - entry = terminator; - terminator++; - memcpy(terminator, entry, sizeof(struct omfs_extent_entry)); - - entry->e_cluster = cpu_to_be64(new_block); - entry->e_blocks = cpu_to_be64((u64) new_count); - - terminator->e_blocks = ~(cpu_to_be64( - be64_to_cpu(~terminator->e_blocks) + (u64) new_count)); - - /* write in new entry */ - oe->e_extent_count = cpu_to_be32(1 + be32_to_cpu(oe->e_extent_count)); - -out: - *ret_block = new_block; -out_fail: - return ret; -} - -/* - * Scans across the directory table for a given file block number. - * If block not found, return 0. - */ -static sector_t find_block(struct inode *inode, struct omfs_extent_entry *ent, - sector_t block, int count, int *left) -{ - /* count > 1 because of terminator */ - sector_t searched = 0; - for (; count > 1; count--) { - int numblocks = clus_to_blk(OMFS_SB(inode->i_sb), - be64_to_cpu(ent->e_blocks)); - - if (block >= searched && - block < searched + numblocks) { - /* - * found it at cluster + (block - searched) - * numblocks - (block - searched) is remainder - */ - *left = numblocks - (block - searched); - return clus_to_blk(OMFS_SB(inode->i_sb), - be64_to_cpu(ent->e_cluster)) + - block - searched; - } - searched += numblocks; - ent++; - } - return 0; -} - -static int omfs_get_block(struct inode *inode, sector_t block, - struct buffer_head *bh_result, int create) -{ - struct buffer_head *bh; - sector_t next, offset; - int ret; - u64 new_block; - int extent_count; - struct omfs_extent *oe; - struct omfs_extent_entry *entry; - struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); - int max_blocks = bh_result->b_size >> inode->i_blkbits; - int remain; - - ret = -EIO; - bh = sb_bread(inode->i_sb, clus_to_blk(sbi, inode->i_ino)); - if (!bh) - goto out; - - oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); - next = inode->i_ino; - - for (;;) { - - if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) - goto out_brelse; - - extent_count = be32_to_cpu(oe->e_extent_count); - next = be64_to_cpu(oe->e_next); - entry = &oe->e_entry; - - offset = find_block(inode, entry, block, extent_count, &remain); - if (offset > 0) { - ret = 0; - map_bh(bh_result, inode->i_sb, offset); - if (remain > max_blocks) - remain = max_blocks; - bh_result->b_size = (remain << inode->i_blkbits); - goto out_brelse; - } - if (next == ~0) - break; - - brelse(bh); - bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); - if (!bh) - goto out; - oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); - } - if (create) { - ret = omfs_grow_extent(inode, oe, &new_block); - if (ret == 0) { - mark_buffer_dirty(bh); - mark_inode_dirty(inode); - map_bh(bh_result, inode->i_sb, - clus_to_blk(sbi, new_block)); - } - } -out_brelse: - brelse(bh); -out: - return ret; -} - -static int omfs_readpage(struct file *file, struct page *page) -{ - return block_read_full_page(page, omfs_get_block); -} - -static int omfs_readpages(struct file *file, struct address_space *mapping, - struct list_head *pages, unsigned nr_pages) -{ - return mpage_readpages(mapping, pages, nr_pages, omfs_get_block); -} - -static int omfs_writepage(struct page *page, struct writeback_control *wbc) -{ - return block_write_full_page(page, omfs_get_block, wbc); -} - -static int -omfs_writepages(struct address_space *mapping, struct writeback_control *wbc) -{ - return mpage_writepages(mapping, wbc, omfs_get_block); -} - -static int omfs_write_begin(struct file *file, struct address_space *mapping, - loff_t pos, unsigned len, unsigned flags, - struct page **pagep, void **fsdata) -{ - *pagep = NULL; - return block_write_begin(file, mapping, pos, len, flags, - pagep, fsdata, omfs_get_block); -} - -static sector_t omfs_bmap(struct address_space *mapping, sector_t block) -{ - return generic_block_bmap(mapping, block, omfs_get_block); -} - -struct file_operations omfs_file_operations = { - .llseek = generic_file_llseek, - .read = do_sync_read, - .write = do_sync_write, - .aio_read = generic_file_aio_read, - .aio_write = generic_file_aio_write, - .mmap = generic_file_mmap, - .fsync = omfs_sync_file, - .splice_read = generic_file_splice_read, -}; - -struct inode_operations omfs_file_inops = { - .truncate = omfs_truncate -}; - -struct address_space_operations omfs_aops = { - .readpage = omfs_readpage, - .readpages = omfs_readpages, - .writepage = omfs_writepage, - .writepages = omfs_writepages, - .sync_page = block_sync_page, - .write_begin = omfs_write_begin, - .write_end = generic_write_end, - .bmap = omfs_bmap, -}; - diff --git a/trunk/fs/omfs/inode.c b/trunk/fs/omfs/inode.c deleted file mode 100644 index d865f5535436..000000000000 --- a/trunk/fs/omfs/inode.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Optimized MPEG FS - inode and super operations. - * Copyright (C) 2006 Bob Copeland - * Released under GPL v2. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "omfs.h" - -MODULE_AUTHOR("Bob Copeland "); -MODULE_DESCRIPTION("OMFS (ReplayTV/Karma) Filesystem for Linux"); -MODULE_LICENSE("GPL"); - -struct inode *omfs_new_inode(struct inode *dir, int mode) -{ - struct inode *inode; - u64 new_block; - int err; - int len; - struct omfs_sb_info *sbi = OMFS_SB(dir->i_sb); - - inode = new_inode(dir->i_sb); - if (!inode) - return ERR_PTR(-ENOMEM); - - err = omfs_allocate_range(dir->i_sb, sbi->s_mirrors, sbi->s_mirrors, - &new_block, &len); - if (err) - goto fail; - - inode->i_ino = new_block; - inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; - inode->i_blocks = 0; - inode->i_mapping->a_ops = &omfs_aops; - - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - switch (mode & S_IFMT) { - case S_IFDIR: - inode->i_op = &omfs_dir_inops; - inode->i_fop = &omfs_dir_operations; - inode->i_size = sbi->s_sys_blocksize; - inc_nlink(inode); - break; - case S_IFREG: - inode->i_op = &omfs_file_inops; - inode->i_fop = &omfs_file_operations; - inode->i_size = 0; - break; - } - - insert_inode_hash(inode); - mark_inode_dirty(inode); - return inode; -fail: - make_bad_inode(inode); - iput(inode); - return ERR_PTR(err); -} - -/* - * Update the header checksums for a dirty inode based on its contents. - * Caller is expected to hold the buffer head underlying oi and mark it - * dirty. - */ -static void omfs_update_checksums(struct omfs_inode *oi) -{ - int xor, i, ofs = 0, count; - u16 crc = 0; - unsigned char *ptr = (unsigned char *) oi; - - count = be32_to_cpu(oi->i_head.h_body_size); - ofs = sizeof(struct omfs_header); - - crc = crc_itu_t(crc, ptr + ofs, count); - oi->i_head.h_crc = cpu_to_be16(crc); - - xor = ptr[0]; - for (i = 1; i < OMFS_XOR_COUNT; i++) - xor ^= ptr[i]; - - oi->i_head.h_check_xor = xor; -} - -static int omfs_write_inode(struct inode *inode, int wait) -{ - struct omfs_inode *oi; - struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); - struct buffer_head *bh, *bh2; - unsigned int block; - u64 ctime; - int i; - int ret = -EIO; - int sync_failed = 0; - - /* get current inode since we may have written sibling ptrs etc. */ - block = clus_to_blk(sbi, inode->i_ino); - bh = sb_bread(inode->i_sb, block); - if (!bh) - goto out; - - oi = (struct omfs_inode *) bh->b_data; - - oi->i_head.h_self = cpu_to_be64(inode->i_ino); - if (S_ISDIR(inode->i_mode)) - oi->i_type = OMFS_DIR; - else if (S_ISREG(inode->i_mode)) - oi->i_type = OMFS_FILE; - else { - printk(KERN_WARNING "omfs: unknown file type: %d\n", - inode->i_mode); - goto out_brelse; - } - - oi->i_head.h_body_size = cpu_to_be32(sbi->s_sys_blocksize - - sizeof(struct omfs_header)); - oi->i_head.h_version = 1; - oi->i_head.h_type = OMFS_INODE_NORMAL; - oi->i_head.h_magic = OMFS_IMAGIC; - oi->i_size = cpu_to_be64(inode->i_size); - - ctime = inode->i_ctime.tv_sec * 1000LL + - ((inode->i_ctime.tv_nsec + 999)/1000); - oi->i_ctime = cpu_to_be64(ctime); - - omfs_update_checksums(oi); - - mark_buffer_dirty(bh); - if (wait) { - sync_dirty_buffer(bh); - if (buffer_req(bh) && !buffer_uptodate(bh)) - sync_failed = 1; - } - - /* if mirroring writes, copy to next fsblock */ - for (i = 1; i < sbi->s_mirrors; i++) { - bh2 = sb_bread(inode->i_sb, block + i * - (sbi->s_blocksize / sbi->s_sys_blocksize)); - if (!bh2) - goto out_brelse; - - memcpy(bh2->b_data, bh->b_data, bh->b_size); - mark_buffer_dirty(bh2); - if (wait) { - sync_dirty_buffer(bh2); - if (buffer_req(bh2) && !buffer_uptodate(bh2)) - sync_failed = 1; - } - brelse(bh2); - } - ret = (sync_failed) ? -EIO : 0; -out_brelse: - brelse(bh); -out: - return ret; -} - -int omfs_sync_inode(struct inode *inode) -{ - return omfs_write_inode(inode, 1); -} - -/* - * called when an entry is deleted, need to clear the bits in the - * bitmaps. - */ -static void omfs_delete_inode(struct inode *inode) -{ - truncate_inode_pages(&inode->i_data, 0); - - if (S_ISREG(inode->i_mode)) { - inode->i_size = 0; - omfs_shrink_inode(inode); - } - - omfs_clear_range(inode->i_sb, inode->i_ino, 2); - clear_inode(inode); -} - -struct inode *omfs_iget(struct super_block *sb, ino_t ino) -{ - struct omfs_sb_info *sbi = OMFS_SB(sb); - struct omfs_inode *oi; - struct buffer_head *bh; - unsigned int block; - u64 ctime; - unsigned long nsecs; - struct inode *inode; - - inode = iget_locked(sb, ino); - if (!inode) - return ERR_PTR(-ENOMEM); - if (!(inode->i_state & I_NEW)) - return inode; - - block = clus_to_blk(sbi, ino); - bh = sb_bread(inode->i_sb, block); - if (!bh) - goto iget_failed; - - oi = (struct omfs_inode *)bh->b_data; - - /* check self */ - if (ino != be64_to_cpu(oi->i_head.h_self)) - goto fail_bh; - - inode->i_uid = sbi->s_uid; - inode->i_gid = sbi->s_gid; - - ctime = be64_to_cpu(oi->i_ctime); - nsecs = do_div(ctime, 1000) * 1000L; - - inode->i_atime.tv_sec = ctime; - inode->i_mtime.tv_sec = ctime; - inode->i_ctime.tv_sec = ctime; - inode->i_atime.tv_nsec = nsecs; - inode->i_mtime.tv_nsec = nsecs; - inode->i_ctime.tv_nsec = nsecs; - - inode->i_mapping->a_ops = &omfs_aops; - - switch (oi->i_type) { - case OMFS_DIR: - inode->i_mode = S_IFDIR | (S_IRWXUGO & ~sbi->s_dmask); - inode->i_op = &omfs_dir_inops; - inode->i_fop = &omfs_dir_operations; - inode->i_size = be32_to_cpu(oi->i_head.h_body_size) + - sizeof(struct omfs_header); - inc_nlink(inode); - break; - case OMFS_FILE: - inode->i_mode = S_IFREG | (S_IRWXUGO & ~sbi->s_fmask); - inode->i_fop = &omfs_file_operations; - inode->i_size = be64_to_cpu(oi->i_size); - break; - } - brelse(bh); - unlock_new_inode(inode); - return inode; -fail_bh: - brelse(bh); -iget_failed: - iget_failed(inode); - return ERR_PTR(-EIO); -} - -static void omfs_put_super(struct super_block *sb) -{ - struct omfs_sb_info *sbi = OMFS_SB(sb); - kfree(sbi->s_imap); - kfree(sbi); - sb->s_fs_info = NULL; -} - -static int omfs_statfs(struct dentry *dentry, struct kstatfs *buf) -{ - struct super_block *s = dentry->d_sb; - struct omfs_sb_info *sbi = OMFS_SB(s); - buf->f_type = OMFS_MAGIC; - buf->f_bsize = sbi->s_blocksize; - buf->f_blocks = sbi->s_num_blocks; - buf->f_files = sbi->s_num_blocks; - buf->f_namelen = OMFS_NAMELEN; - - buf->f_bfree = buf->f_bavail = buf->f_ffree = - omfs_count_free(s); - return 0; -} - -static struct super_operations omfs_sops = { - .write_inode = omfs_write_inode, - .delete_inode = omfs_delete_inode, - .put_super = omfs_put_super, - .statfs = omfs_statfs, - .show_options = generic_show_options, -}; - -/* - * For Rio Karma, there is an on-disk free bitmap whose location is - * stored in the root block. For ReplayTV, there is no such free bitmap - * so we have to walk the tree. Both inodes and file data are allocated - * from the same map. This array can be big (300k) so we allocate - * in units of the blocksize. - */ -static int omfs_get_imap(struct super_block *sb) -{ - int bitmap_size; - int array_size; - int count; - struct omfs_sb_info *sbi = OMFS_SB(sb); - struct buffer_head *bh; - unsigned long **ptr; - sector_t block; - - bitmap_size = DIV_ROUND_UP(sbi->s_num_blocks, 8); - array_size = DIV_ROUND_UP(bitmap_size, sb->s_blocksize); - - if (sbi->s_bitmap_ino == ~0ULL) - goto out; - - sbi->s_imap_size = array_size; - sbi->s_imap = kzalloc(array_size * sizeof(unsigned long *), GFP_KERNEL); - if (!sbi->s_imap) - goto nomem; - - block = clus_to_blk(sbi, sbi->s_bitmap_ino); - ptr = sbi->s_imap; - for (count = bitmap_size; count > 0; count -= sb->s_blocksize) { - bh = sb_bread(sb, block++); - if (!bh) - goto nomem_free; - *ptr = kmalloc(sb->s_blocksize, GFP_KERNEL); - if (!*ptr) { - brelse(bh); - goto nomem_free; - } - memcpy(*ptr, bh->b_data, sb->s_blocksize); - if (count < sb->s_blocksize) - memset((void *)*ptr + count, 0xff, - sb->s_blocksize - count); - brelse(bh); - ptr++; - } -out: - return 0; - -nomem_free: - for (count = 0; count < array_size; count++) - kfree(sbi->s_imap[count]); - - kfree(sbi->s_imap); -nomem: - sbi->s_imap = NULL; - sbi->s_imap_size = 0; - return -ENOMEM; -} - -enum { - Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask -}; - -static match_table_t tokens = { - {Opt_uid, "uid=%u"}, - {Opt_gid, "gid=%u"}, - {Opt_umask, "umask=%o"}, - {Opt_dmask, "dmask=%o"}, - {Opt_fmask, "fmask=%o"}, -}; - -static int parse_options(char *options, struct omfs_sb_info *sbi) -{ - char *p; - substring_t args[MAX_OPT_ARGS]; - int option; - - if (!options) - return 1; - - while ((p = strsep(&options, ",")) != NULL) { - int token; - if (!*p) - continue; - - token = match_token(p, tokens, args); - switch (token) { - case Opt_uid: - if (match_int(&args[0], &option)) - return 0; - sbi->s_uid = option; - break; - case Opt_gid: - if (match_int(&args[0], &option)) - return 0; - sbi->s_gid = option; - break; - case Opt_umask: - if (match_octal(&args[0], &option)) - return 0; - sbi->s_fmask = sbi->s_dmask = option; - break; - case Opt_dmask: - if (match_octal(&args[0], &option)) - return 0; - sbi->s_dmask = option; - break; - case Opt_fmask: - if (match_octal(&args[0], &option)) - return 0; - sbi->s_fmask = option; - break; - default: - return 0; - } - } - return 1; -} - -static int omfs_fill_super(struct super_block *sb, void *data, int silent) -{ - struct buffer_head *bh, *bh2; - struct omfs_super_block *omfs_sb; - struct omfs_root_block *omfs_rb; - struct omfs_sb_info *sbi; - struct inode *root; - sector_t start; - int ret = -EINVAL; - - save_mount_options(sb, (char *) data); - - sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL); - if (!sbi) - return -ENOMEM; - - sb->s_fs_info = sbi; - - sbi->s_uid = current->uid; - sbi->s_gid = current->gid; - sbi->s_dmask = sbi->s_fmask = current->fs->umask; - - if (!parse_options((char *) data, sbi)) - goto end; - - sb->s_maxbytes = 0xffffffff; - - sb_set_blocksize(sb, 0x200); - - bh = sb_bread(sb, 0); - if (!bh) - goto end; - - omfs_sb = (struct omfs_super_block *)bh->b_data; - - if (omfs_sb->s_magic != cpu_to_be32(OMFS_MAGIC)) { - if (!silent) - printk(KERN_ERR "omfs: Invalid superblock (%x)\n", - omfs_sb->s_magic); - goto out_brelse_bh; - } - sb->s_magic = OMFS_MAGIC; - - sbi->s_num_blocks = be64_to_cpu(omfs_sb->s_num_blocks); - sbi->s_blocksize = be32_to_cpu(omfs_sb->s_blocksize); - sbi->s_mirrors = be32_to_cpu(omfs_sb->s_mirrors); - sbi->s_root_ino = be64_to_cpu(omfs_sb->s_root_block); - sbi->s_sys_blocksize = be32_to_cpu(omfs_sb->s_sys_blocksize); - mutex_init(&sbi->s_bitmap_lock); - - if (sbi->s_sys_blocksize > PAGE_SIZE) { - printk(KERN_ERR "omfs: sysblock size (%d) is out of range\n", - sbi->s_sys_blocksize); - goto out_brelse_bh; - } - - if (sbi->s_blocksize < sbi->s_sys_blocksize || - sbi->s_blocksize > OMFS_MAX_BLOCK_SIZE) { - printk(KERN_ERR "omfs: block size (%d) is out of range\n", - sbi->s_blocksize); - goto out_brelse_bh; - } - - /* - * Use sys_blocksize as the fs block since it is smaller than a - * page while the fs blocksize can be larger. - */ - sb_set_blocksize(sb, sbi->s_sys_blocksize); - - /* - * ...and the difference goes into a shift. sys_blocksize is always - * a power of two factor of blocksize. - */ - sbi->s_block_shift = get_bitmask_order(sbi->s_blocksize) - - get_bitmask_order(sbi->s_sys_blocksize); - - start = clus_to_blk(sbi, be64_to_cpu(omfs_sb->s_root_block)); - bh2 = sb_bread(sb, start); - if (!bh2) - goto out_brelse_bh; - - omfs_rb = (struct omfs_root_block *)bh2->b_data; - - sbi->s_bitmap_ino = be64_to_cpu(omfs_rb->r_bitmap); - sbi->s_clustersize = be32_to_cpu(omfs_rb->r_clustersize); - - if (sbi->s_num_blocks != be64_to_cpu(omfs_rb->r_num_blocks)) { - printk(KERN_ERR "omfs: block count discrepancy between " - "super and root blocks (%llx, %llx)\n", - sbi->s_num_blocks, be64_to_cpu(omfs_rb->r_num_blocks)); - goto out_brelse_bh2; - } - - ret = omfs_get_imap(sb); - if (ret) - goto out_brelse_bh2; - - sb->s_op = &omfs_sops; - - root = omfs_iget(sb, be64_to_cpu(omfs_rb->r_root_dir)); - if (IS_ERR(root)) { - ret = PTR_ERR(root); - goto out_brelse_bh2; - } - - sb->s_root = d_alloc_root(root); - if (!sb->s_root) { - iput(root); - goto out_brelse_bh2; - } - printk(KERN_DEBUG "omfs: Mounted volume %s\n", omfs_rb->r_name); - - ret = 0; -out_brelse_bh2: - brelse(bh2); -out_brelse_bh: - brelse(bh); -end: - return ret; -} - -static int omfs_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, - void *data, struct vfsmount *m) -{ - return get_sb_bdev(fs_type, flags, dev_name, data, omfs_fill_super, m); -} - -static struct file_system_type omfs_fs_type = { - .owner = THIS_MODULE, - .name = "omfs", - .get_sb = omfs_get_sb, - .kill_sb = kill_block_super, - .fs_flags = FS_REQUIRES_DEV, -}; - -static int __init init_omfs_fs(void) -{ - return register_filesystem(&omfs_fs_type); -} - -static void __exit exit_omfs_fs(void) -{ - unregister_filesystem(&omfs_fs_type); -} - -module_init(init_omfs_fs); -module_exit(exit_omfs_fs); diff --git a/trunk/fs/omfs/omfs.h b/trunk/fs/omfs/omfs.h deleted file mode 100644 index 2bc0f0670406..000000000000 --- a/trunk/fs/omfs/omfs.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _OMFS_H -#define _OMFS_H - -#include -#include - -#include "omfs_fs.h" - -/* In-memory structures */ -struct omfs_sb_info { - u64 s_num_blocks; - u64 s_bitmap_ino; - u64 s_root_ino; - u32 s_blocksize; - u32 s_mirrors; - u32 s_sys_blocksize; - u32 s_clustersize; - int s_block_shift; - unsigned long **s_imap; - int s_imap_size; - struct mutex s_bitmap_lock; - int s_uid; - int s_gid; - int s_dmask; - int s_fmask; -}; - -/* convert a cluster number to a scaled block number */ -static inline sector_t clus_to_blk(struct omfs_sb_info *sbi, sector_t block) -{ - return block << sbi->s_block_shift; -} - -static inline struct omfs_sb_info *OMFS_SB(struct super_block *sb) -{ - return sb->s_fs_info; -} - -/* bitmap.c */ -extern unsigned long omfs_count_free(struct super_block *sb); -extern int omfs_allocate_block(struct super_block *sb, u64 block); -extern int omfs_allocate_range(struct super_block *sb, int min_request, - int max_request, u64 *return_block, int *return_size); -extern int omfs_clear_range(struct super_block *sb, u64 block, int count); - -/* dir.c */ -extern struct file_operations omfs_dir_operations; -extern struct inode_operations omfs_dir_inops; -extern int omfs_make_empty(struct inode *inode, struct super_block *sb); -extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, - u64 fsblock); - -/* file.c */ -extern struct file_operations omfs_file_operations; -extern struct inode_operations omfs_file_inops; -extern struct address_space_operations omfs_aops; -extern void omfs_make_empty_table(struct buffer_head *bh, int offset); -extern int omfs_shrink_inode(struct inode *inode); - -/* inode.c */ -extern struct inode *omfs_iget(struct super_block *sb, ino_t inode); -extern struct inode *omfs_new_inode(struct inode *dir, int mode); -extern int omfs_reserve_block(struct super_block *sb, sector_t block); -extern int omfs_find_empty_block(struct super_block *sb, int mode, ino_t *ino); -extern int omfs_sync_inode(struct inode *inode); - -#endif diff --git a/trunk/fs/omfs/omfs_fs.h b/trunk/fs/omfs/omfs_fs.h deleted file mode 100644 index 12cca245d6e8..000000000000 --- a/trunk/fs/omfs/omfs_fs.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef _OMFS_FS_H -#define _OMFS_FS_H - -/* OMFS On-disk structures */ - -#define OMFS_MAGIC 0xC2993D87 -#define OMFS_IMAGIC 0xD2 - -#define OMFS_DIR 'D' -#define OMFS_FILE 'F' -#define OMFS_INODE_NORMAL 'e' -#define OMFS_INODE_CONTINUATION 'c' -#define OMFS_INODE_SYSTEM 's' -#define OMFS_NAMELEN 256 -#define OMFS_DIR_START 0x1b8 -#define OMFS_EXTENT_START 0x1d0 -#define OMFS_EXTENT_CONT 0x40 -#define OMFS_XOR_COUNT 19 -#define OMFS_MAX_BLOCK_SIZE 8192 - -struct omfs_super_block { - char s_fill1[256]; - __be64 s_root_block; /* block number of omfs_root_block */ - __be64 s_num_blocks; /* total number of FS blocks */ - __be32 s_magic; /* OMFS_MAGIC */ - __be32 s_blocksize; /* size of a block */ - __be32 s_mirrors; /* # of mirrors of system blocks */ - __be32 s_sys_blocksize; /* size of non-data blocks */ -}; - -struct omfs_header { - __be64 h_self; /* FS block where this is located */ - __be32 h_body_size; /* size of useful data after header */ - __be16 h_crc; /* crc-ccitt of body_size bytes */ - char h_fill1[2]; - u8 h_version; /* version, always 1 */ - char h_type; /* OMFS_INODE_X */ - u8 h_magic; /* OMFS_IMAGIC */ - u8 h_check_xor; /* XOR of header bytes before this */ - __be32 h_fill2; -}; - -struct omfs_root_block { - struct omfs_header r_head; /* header */ - __be64 r_fill1; - __be64 r_num_blocks; /* total number of FS blocks */ - __be64 r_root_dir; /* block # of root directory */ - __be64 r_bitmap; /* block # of free space bitmap */ - __be32 r_blocksize; /* size of a block */ - __be32 r_clustersize; /* size allocated for data blocks */ - __be64 r_mirrors; /* # of mirrors of system blocks */ - char r_name[OMFS_NAMELEN]; /* partition label */ -}; - -struct omfs_inode { - struct omfs_header i_head; /* header */ - __be64 i_parent; /* parent containing this inode */ - __be64 i_sibling; /* next inode in hash bucket */ - __be64 i_ctime; /* ctime, in milliseconds */ - char i_fill1[35]; - char i_type; /* OMFS_[DIR,FILE] */ - __be32 i_fill2; - char i_fill3[64]; - char i_name[OMFS_NAMELEN]; /* filename */ - __be64 i_size; /* size of file, in bytes */ -}; - -struct omfs_extent_entry { - __be64 e_cluster; /* start location of a set of blocks */ - __be64 e_blocks; /* number of blocks after e_cluster */ -}; - -struct omfs_extent { - __be64 e_next; /* next extent table location */ - __be32 e_extent_count; /* total # extents in this table */ - __be32 e_fill; - struct omfs_extent_entry e_entry; /* start of extent entries */ -}; - -#endif diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 52647be277a2..bb98d2fe809f 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -122,37 +122,37 @@ static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) return 0; } -asmlinkage long sys_statfs(const char __user *pathname, struct statfs __user * buf) +asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf) { - struct path path; + struct nameidata nd; int error; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (!error) { struct statfs tmp; - error = vfs_statfs_native(path.dentry, &tmp); + error = vfs_statfs_native(nd.path.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&path); + path_put(&nd.path); } return error; } -asmlinkage long sys_statfs64(const char __user *pathname, size_t sz, struct statfs64 __user *buf) +asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 __user *buf) { - struct path path; + struct nameidata nd; long error; if (sz != sizeof(*buf)) return -EINVAL; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (!error) { struct statfs64 tmp; - error = vfs_statfs64(path.dentry, &tmp); + error = vfs_statfs64(nd.path.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&path); + path_put(&nd.path); } return error; } @@ -223,20 +223,20 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, return err; } -static long do_sys_truncate(const char __user *pathname, loff_t length) +static long do_sys_truncate(const char __user * path, loff_t length) { - struct path path; - struct inode *inode; + struct nameidata nd; + struct inode * inode; int error; error = -EINVAL; if (length < 0) /* sorry, but loff_t says... */ goto out; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (error) goto out; - inode = path.dentry->d_inode; + inode = nd.path.dentry->d_inode; /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ error = -EISDIR; @@ -247,16 +247,16 @@ static long do_sys_truncate(const char __user *pathname, loff_t length) if (!S_ISREG(inode->i_mode)) goto dput_and_out; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (error) goto dput_and_out; - error = inode_permission(inode, MAY_WRITE); + error = vfs_permission(&nd, MAY_WRITE); if (error) goto mnt_drop_write_and_out; error = -EPERM; - if (IS_APPEND(inode)) + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) goto mnt_drop_write_and_out; error = get_write_access(inode); @@ -274,15 +274,15 @@ static long do_sys_truncate(const char __user *pathname, loff_t length) error = locks_verify_truncate(inode, NULL, length); if (!error) { DQUOT_INIT(inode); - error = do_truncate(path.dentry, length, 0, NULL); + error = do_truncate(nd.path.dentry, length, 0, NULL); } put_write_and_out: put_write_access(inode); mnt_drop_write_and_out: - mnt_drop_write(path.mnt); + mnt_drop_write(nd.path.mnt); dput_and_out: - path_put(&path); + path_put(&nd.path); out: return error; } @@ -425,8 +425,7 @@ asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len) */ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) { - struct path path; - struct inode *inode; + struct nameidata nd; int old_fsuid, old_fsgid; kernel_cap_t uninitialized_var(old_cap); /* !SECURE_NO_SETUID_FIXUP */ int res; @@ -449,7 +448,7 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) * FIXME: There is a race here against sys_capset. The * capabilities can change yet we will restore the old * value below. We should hold task_capabilities_lock, - * but we cannot because user_path_at can sleep. + * but we cannot because user_path_walk can sleep. */ #endif /* ndef CONFIG_SECURITY_FILE_CAPABILITIES */ if (current->uid) @@ -458,25 +457,14 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) old_cap = cap_set_effective(current->cap_permitted); } - res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); + res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); if (res) goto out; - inode = path.dentry->d_inode; - - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { - /* - * MAY_EXEC on regular files is denied if the fs is mounted - * with the "noexec" flag. - */ - res = -EACCES; - if (path.mnt->mnt_flags & MNT_NOEXEC) - goto out_path_release; - } - - res = inode_permission(inode, mode | MAY_ACCESS); + res = vfs_permission(&nd, mode); /* SuS v2 requires we report a read only fs too */ - if (res || !(mode & S_IWOTH) || special_file(inode->i_mode)) + if(res || !(mode & S_IWOTH) || + special_file(nd.path.dentry->d_inode->i_mode)) goto out_path_release; /* * This is a rare case where using __mnt_is_readonly() @@ -488,11 +476,11 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) * inherently racy and know that the fs may change * state before we even see this result. */ - if (__mnt_is_readonly(path.mnt)) + if (__mnt_is_readonly(nd.path.mnt)) res = -EROFS; out_path_release: - path_put(&path); + path_put(&nd.path); out: current->fsuid = old_fsuid; current->fsgid = old_fsgid; @@ -510,21 +498,22 @@ asmlinkage long sys_access(const char __user *filename, int mode) asmlinkage long sys_chdir(const char __user * filename) { - struct path path; + struct nameidata nd; int error; - error = user_path_dir(filename, &path); + error = __user_walk(filename, + LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd); if (error) goto out; - error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); + error = vfs_permission(&nd, MAY_EXEC); if (error) goto dput_and_out; - set_fs_pwd(current->fs, &path); + set_fs_pwd(current->fs, &nd.path); dput_and_out: - path_put(&path); + path_put(&nd.path); out: return error; } @@ -546,7 +535,7 @@ asmlinkage long sys_fchdir(unsigned int fd) if (!S_ISDIR(inode->i_mode)) goto out_putf; - error = inode_permission(inode, MAY_EXEC | MAY_ACCESS); + error = file_permission(file, MAY_EXEC); if (!error) set_fs_pwd(current->fs, &file->f_path); out_putf: @@ -557,14 +546,14 @@ asmlinkage long sys_fchdir(unsigned int fd) asmlinkage long sys_chroot(const char __user * filename) { - struct path path; + struct nameidata nd; int error; - error = user_path_dir(filename, &path); + error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); if (error) goto out; - error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); + error = vfs_permission(&nd, MAY_EXEC); if (error) goto dput_and_out; @@ -572,10 +561,11 @@ asmlinkage long sys_chroot(const char __user * filename) if (!capable(CAP_SYS_CHROOT)) goto dput_and_out; - set_fs_root(current->fs, &path); + set_fs_root(current->fs, &nd.path); + set_fs_altroot(); error = 0; dput_and_out: - path_put(&path); + path_put(&nd.path); out: return error; } @@ -600,6 +590,9 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) err = mnt_want_write(file->f_path.mnt); if (err) goto out_putf; + err = -EPERM; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + goto out_drop_write; mutex_lock(&inode->i_mutex); if (mode == (mode_t) -1) mode = inode->i_mode; @@ -607,6 +600,8 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; err = notify_change(dentry, &newattrs); mutex_unlock(&inode->i_mutex); + +out_drop_write: mnt_drop_write(file->f_path.mnt); out_putf: fput(file); @@ -617,29 +612,36 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) asmlinkage long sys_fchmodat(int dfd, const char __user *filename, mode_t mode) { - struct path path; - struct inode *inode; + struct nameidata nd; + struct inode * inode; int error; struct iattr newattrs; - error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); + error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); if (error) goto out; - inode = path.dentry->d_inode; + inode = nd.path.dentry->d_inode; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (error) goto dput_and_out; + + error = -EPERM; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + goto out_drop_write; + mutex_lock(&inode->i_mutex); if (mode == (mode_t) -1) mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - error = notify_change(path.dentry, &newattrs); + error = notify_change(nd.path.dentry, &newattrs); mutex_unlock(&inode->i_mutex); - mnt_drop_write(path.mnt); + +out_drop_write: + mnt_drop_write(nd.path.mnt); dput_and_out: - path_put(&path); + path_put(&nd.path); out: return error; } @@ -651,10 +653,18 @@ asmlinkage long sys_chmod(const char __user *filename, mode_t mode) static int chown_common(struct dentry * dentry, uid_t user, gid_t group) { - struct inode *inode = dentry->d_inode; + struct inode * inode; int error; struct iattr newattrs; + error = -ENOENT; + if (!(inode = dentry->d_inode)) { + printk(KERN_ERR "chown_common: NULL inode\n"); + goto out; + } + error = -EPERM; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + goto out; newattrs.ia_valid = ATTR_CTIME; if (user != (uid_t) -1) { newattrs.ia_valid |= ATTR_UID; @@ -670,25 +680,25 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group) mutex_lock(&inode->i_mutex); error = notify_change(dentry, &newattrs); mutex_unlock(&inode->i_mutex); - +out: return error; } asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) { - struct path path; + struct nameidata nd; int error; - error = user_path(filename, &path); + error = user_path_walk(filename, &nd); if (error) goto out; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); - mnt_drop_write(path.mnt); + error = chown_common(nd.path.dentry, user, group); + mnt_drop_write(nd.path.mnt); out_release: - path_put(&path); + path_put(&nd.path); out: return error; } @@ -696,7 +706,7 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, int flag) { - struct path path; + struct nameidata nd; int error = -EINVAL; int follow; @@ -704,35 +714,35 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, goto out; follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; - error = user_path_at(dfd, filename, follow, &path); + error = __user_walk_fd(dfd, filename, follow, &nd); if (error) goto out; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); - mnt_drop_write(path.mnt); + error = chown_common(nd.path.dentry, user, group); + mnt_drop_write(nd.path.mnt); out_release: - path_put(&path); + path_put(&nd.path); out: return error; } asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group) { - struct path path; + struct nameidata nd; int error; - error = user_lpath(filename, &path); + error = user_path_walk_link(filename, &nd); if (error) goto out; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); - mnt_drop_write(path.mnt); + error = chown_common(nd.path.dentry, user, group); + mnt_drop_write(nd.path.mnt); out_release: - path_put(&path); + path_put(&nd.path); out: return error; } @@ -972,6 +982,7 @@ int get_unused_fd_flags(int flags) int fd, error; struct fdtable *fdt; + error = -EMFILE; spin_lock(&files->file_lock); repeat: @@ -979,6 +990,13 @@ int get_unused_fd_flags(int flags) fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, files->next_fd); + /* + * N.B. For clone tasks sharing a files structure, this test + * will limit the total number of files that can be opened. + */ + if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) + goto out; + /* Do we need to expand the fd array or fd set? */ error = expand_files(files, fd); if (error < 0) @@ -989,6 +1007,7 @@ int get_unused_fd_flags(int flags) * If we needed to expand the fs array we * might have blocked - try again. */ + error = -EMFILE; goto repeat; } diff --git a/trunk/fs/openpromfs/inode.c b/trunk/fs/openpromfs/inode.c index 9f5b054f06b9..d17b4fd204e1 100644 --- a/trunk/fs/openpromfs/inode.c +++ b/trunk/fs/openpromfs/inode.c @@ -430,7 +430,7 @@ static struct file_system_type openprom_fs_type = { .kill_sb = kill_anon_super, }; -static void op_inode_init_once(void *data) +static void op_inode_init_once(struct kmem_cache * cachep, void *data) { struct op_inode_info *oi = (struct op_inode_info *) data; diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index fcba6542b8d0..10c4e9aa5c49 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -777,10 +777,45 @@ pipe_rdwr_open(struct inode *inode, struct file *filp) /* * The file_operations structs are not static because they * are also used in linux/fs/fifo.c to do operations on FIFOs. - * - * Pipes reuse fifos' file_operations structs. */ -const struct file_operations read_pipefifo_fops = { +const struct file_operations read_fifo_fops = { + .llseek = no_llseek, + .read = do_sync_read, + .aio_read = pipe_read, + .write = bad_pipe_w, + .poll = pipe_poll, + .unlocked_ioctl = pipe_ioctl, + .open = pipe_read_open, + .release = pipe_read_release, + .fasync = pipe_read_fasync, +}; + +const struct file_operations write_fifo_fops = { + .llseek = no_llseek, + .read = bad_pipe_r, + .write = do_sync_write, + .aio_write = pipe_write, + .poll = pipe_poll, + .unlocked_ioctl = pipe_ioctl, + .open = pipe_write_open, + .release = pipe_write_release, + .fasync = pipe_write_fasync, +}; + +const struct file_operations rdwr_fifo_fops = { + .llseek = no_llseek, + .read = do_sync_read, + .aio_read = pipe_read, + .write = do_sync_write, + .aio_write = pipe_write, + .poll = pipe_poll, + .unlocked_ioctl = pipe_ioctl, + .open = pipe_rdwr_open, + .release = pipe_rdwr_release, + .fasync = pipe_rdwr_fasync, +}; + +static const struct file_operations read_pipe_fops = { .llseek = no_llseek, .read = do_sync_read, .aio_read = pipe_read, @@ -792,7 +827,7 @@ const struct file_operations read_pipefifo_fops = { .fasync = pipe_read_fasync, }; -const struct file_operations write_pipefifo_fops = { +static const struct file_operations write_pipe_fops = { .llseek = no_llseek, .read = bad_pipe_r, .write = do_sync_write, @@ -804,7 +839,7 @@ const struct file_operations write_pipefifo_fops = { .fasync = pipe_write_fasync, }; -const struct file_operations rdwr_pipefifo_fops = { +static const struct file_operations rdwr_pipe_fops = { .llseek = no_llseek, .read = do_sync_read, .aio_read = pipe_read, @@ -892,7 +927,7 @@ static struct inode * get_pipe_inode(void) inode->i_pipe = pipe; pipe->readers = pipe->writers = 1; - inode->i_fop = &rdwr_pipefifo_fops; + inode->i_fop = &rdwr_pipe_fops; /* * Mark the inode dirty from the very beginning, @@ -943,7 +978,7 @@ struct file *create_write_pipe(int flags) d_instantiate(dentry, inode); err = -ENFILE; - f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipefifo_fops); + f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipe_fops); if (!f) goto err_dentry; f->f_mapping = inode->i_mapping; @@ -985,7 +1020,7 @@ struct file *create_read_pipe(struct file *wrf, int flags) f->f_pos = 0; f->f_flags = O_RDONLY | (flags & O_NONBLOCK); - f->f_op = &read_pipefifo_fops; + f->f_op = &read_pipe_fops; f->f_mode = FMODE_READ; f->f_version = 0; diff --git a/trunk/fs/proc/array.c b/trunk/fs/proc/array.c index 0d6eb33597c6..797d775e0354 100644 --- a/trunk/fs/proc/array.c +++ b/trunk/fs/proc/array.c @@ -80,7 +80,6 @@ #include #include #include -#include #include #include @@ -169,12 +168,8 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, rcu_read_lock(); ppid = pid_alive(p) ? task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; - tpid = 0; - if (pid_alive(p)) { - struct task_struct *tracer = tracehook_tracer_task(p); - if (tracer) - tpid = task_pid_nr_ns(tracer, ns); - } + tpid = pid_alive(p) && p->ptrace ? + task_pid_nr_ns(rcu_dereference(p->parent), ns) : 0; seq_printf(m, "State:\t%s\n" "Tgid:\t%d\n" diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 01ed610f9b87..a891fe4cb43b 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include @@ -70,7 +69,6 @@ #include #include #include -#include #include #include #include @@ -233,14 +231,10 @@ static int check_mem_permission(struct task_struct *task) * If current is actively ptrace'ing, and would also be * permitted to freshly attach with ptrace now, permit it. */ - if (task_is_stopped_or_traced(task)) { - int match; - rcu_read_lock(); - match = (tracehook_tracer_task(task) == current); - rcu_read_unlock(); - if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH)) - return 0; - } + if (task->parent == current && (task->ptrace & PT_PTRACED) && + task_is_stopped_or_traced(task) && + ptrace_may_access(task, PTRACE_MODE_ATTACH)) + return 0; /* * Noone else is allowed. @@ -510,26 +504,6 @@ static int proc_pid_limits(struct task_struct *task, char *buffer) return count; } -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK -static int proc_pid_syscall(struct task_struct *task, char *buffer) -{ - long nr; - unsigned long args[6], sp, pc; - - if (task_current_syscall(task, &nr, args, 6, &sp, &pc)) - return sprintf(buffer, "running\n"); - - if (nr < 0) - return sprintf(buffer, "%ld 0x%lx 0x%lx\n", nr, sp, pc); - - return sprintf(buffer, - "%ld 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", - nr, - args[0], args[1], args[2], args[3], args[4], args[5], - sp, pc); -} -#endif /* CONFIG_HAVE_ARCH_TRACEHOOK */ - /************************************************************************/ /* Here the fs part begins */ /************************************************************************/ @@ -1860,7 +1834,8 @@ static const struct file_operations proc_fd_operations = { * /proc/pid/fd needs a special permission handler so that a process can still * access /proc/self/fd after it has executed a setuid(). */ -static int proc_fd_permission(struct inode *inode, int mask) +static int proc_fd_permission(struct inode *inode, int mask, + struct nameidata *nd) { int rv; @@ -2403,18 +2378,53 @@ static int proc_base_fill_cache(struct file *filp, void *dirent, #ifdef CONFIG_TASK_IO_ACCOUNTING static int do_io_accounting(struct task_struct *task, char *buffer, int whole) { - struct task_io_accounting acct = task->ioac; - unsigned long flags; - - if (whole && lock_task_sighand(task, &flags)) { + u64 rchar, wchar, syscr, syscw; + struct task_io_accounting ioac; + + if (!whole) { + rchar = task->rchar; + wchar = task->wchar; + syscr = task->syscr; + syscw = task->syscw; + memcpy(&ioac, &task->ioac, sizeof(ioac)); + } else { + unsigned long flags; struct task_struct *t = task; + rchar = wchar = syscr = syscw = 0; + memset(&ioac, 0, sizeof(ioac)); + + rcu_read_lock(); + do { + rchar += t->rchar; + wchar += t->wchar; + syscr += t->syscr; + syscw += t->syscw; + + ioac.read_bytes += t->ioac.read_bytes; + ioac.write_bytes += t->ioac.write_bytes; + ioac.cancelled_write_bytes += + t->ioac.cancelled_write_bytes; + t = next_thread(t); + } while (t != task); + rcu_read_unlock(); + + if (lock_task_sighand(task, &flags)) { + struct signal_struct *sig = task->signal; - task_io_accounting_add(&acct, &task->signal->ioac); - while_each_thread(task, t) - task_io_accounting_add(&acct, &t->ioac); + rchar += sig->rchar; + wchar += sig->wchar; + syscr += sig->syscr; + syscw += sig->syscw; - unlock_task_sighand(task, &flags); + ioac.read_bytes += sig->ioac.read_bytes; + ioac.write_bytes += sig->ioac.write_bytes; + ioac.cancelled_write_bytes += + sig->ioac.cancelled_write_bytes; + + unlock_task_sighand(task, &flags); + } } + return sprintf(buffer, "rchar: %llu\n" "wchar: %llu\n" @@ -2423,10 +2433,13 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) "read_bytes: %llu\n" "write_bytes: %llu\n" "cancelled_write_bytes: %llu\n", - acct.rchar, acct.wchar, - acct.syscr, acct.syscw, - acct.read_bytes, acct.write_bytes, - acct.cancelled_write_bytes); + (unsigned long long)rchar, + (unsigned long long)wchar, + (unsigned long long)syscr, + (unsigned long long)syscw, + (unsigned long long)ioac.read_bytes, + (unsigned long long)ioac.write_bytes, + (unsigned long long)ioac.cancelled_write_bytes); } static int proc_tid_io_accounting(struct task_struct *task, char *buffer) @@ -2459,9 +2472,6 @@ static const struct pid_entry tgid_base_stuff[] = { INF("limits", S_IRUSR, pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, pid_sched), -#endif -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK - INF("syscall", S_IRUSR, pid_syscall), #endif INF("cmdline", S_IRUGO, pid_cmdline), ONE("stat", S_IRUGO, tgid_stat), @@ -2794,9 +2804,6 @@ static const struct pid_entry tid_base_stuff[] = { INF("limits", S_IRUSR, pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, pid_sched), -#endif -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK - INF("syscall", S_IRUSR, pid_syscall), #endif INF("cmdline", S_IRUGO, pid_cmdline), ONE("stat", S_IRUGO, tid_stat), diff --git a/trunk/fs/proc/generic.c b/trunk/fs/proc/generic.c index cb4096cc3fb7..bc0a0dd2d844 100644 --- a/trunk/fs/proc/generic.c +++ b/trunk/fs/proc/generic.c @@ -806,9 +806,12 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) if (S_ISDIR(de->mode)) parent->nlink--; de->nlink = 0; - WARN(de->subdir, KERN_WARNING "%s: removing non-empty directory " + if (de->subdir) { + printk(KERN_WARNING "%s: removing non-empty directory " "'%s/%s', leaking at least '%s'\n", __func__, de->parent->name, de->name, de->subdir->name); + WARN_ON(1); + } if (atomic_dec_and_test(&de->count)) free_proc_entry(de); } diff --git a/trunk/fs/proc/inode.c b/trunk/fs/proc/inode.c index 8bb03f056c28..02eca2ed9dd7 100644 --- a/trunk/fs/proc/inode.c +++ b/trunk/fs/proc/inode.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -66,8 +65,6 @@ static void proc_delete_inode(struct inode *inode) module_put(de->owner); de_put(de); } - if (PROC_I(inode)->sysctl) - sysctl_head_put(PROC_I(inode)->sysctl); clear_inode(inode); } @@ -87,8 +84,6 @@ static struct inode *proc_alloc_inode(struct super_block *sb) ei->fd = 0; ei->op.proc_get_link = NULL; ei->pde = NULL; - ei->sysctl = NULL; - ei->sysctl_entry = NULL; inode = &ei->vfs_inode; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; return inode; @@ -99,7 +94,7 @@ static void proc_destroy_inode(struct inode *inode) kmem_cache_free(proc_inode_cachep, PROC_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct proc_inode *ei = (struct proc_inode *) foo; diff --git a/trunk/fs/proc/proc_sysctl.c b/trunk/fs/proc/proc_sysctl.c index f9a8b892718f..5acc001d49f6 100644 --- a/trunk/fs/proc/proc_sysctl.c +++ b/trunk/fs/proc/proc_sysctl.c @@ -10,110 +10,149 @@ static struct dentry_operations proc_sys_dentry_operations; static const struct file_operations proc_sys_file_operations; static const struct inode_operations proc_sys_inode_operations; -static const struct file_operations proc_sys_dir_file_operations; -static const struct inode_operations proc_sys_dir_operations; -static struct inode *proc_sys_make_inode(struct super_block *sb, - struct ctl_table_header *head, struct ctl_table *table) +static void proc_sys_refresh_inode(struct inode *inode, struct ctl_table *table) +{ + /* Refresh the cached information bits in the inode */ + if (table) { + inode->i_uid = 0; + inode->i_gid = 0; + inode->i_mode = table->mode; + if (table->proc_handler) { + inode->i_mode |= S_IFREG; + inode->i_nlink = 1; + } else { + inode->i_mode |= S_IFDIR; + inode->i_nlink = 0; /* It is too hard to figure out */ + } + } +} + +static struct inode *proc_sys_make_inode(struct inode *dir, struct ctl_table *table) { struct inode *inode; - struct proc_inode *ei; + struct proc_inode *dir_ei, *ei; + int depth; - inode = new_inode(sb); + inode = new_inode(dir->i_sb); if (!inode) goto out; - sysctl_head_get(head); - ei = PROC_I(inode); - ei->sysctl = head; - ei->sysctl_entry = table; + /* A directory is always one deeper than it's parent */ + dir_ei = PROC_I(dir); + depth = dir_ei->fd + 1; + ei = PROC_I(inode); + ei->fd = depth; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_op = &proc_sys_inode_operations; + inode->i_fop = &proc_sys_file_operations; inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */ - inode->i_mode = table->mode; - if (!table->child) { - inode->i_mode |= S_IFREG; - inode->i_op = &proc_sys_inode_operations; - inode->i_fop = &proc_sys_file_operations; - } else { - inode->i_mode |= S_IFDIR; - inode->i_nlink = 0; - inode->i_op = &proc_sys_dir_operations; - inode->i_fop = &proc_sys_dir_file_operations; - } + proc_sys_refresh_inode(inode, table); out: return inode; } -static struct ctl_table *find_in_table(struct ctl_table *p, struct qstr *name) +static struct dentry *proc_sys_ancestor(struct dentry *dentry, int depth) +{ + for (;;) { + struct proc_inode *ei; + + ei = PROC_I(dentry->d_inode); + if (ei->fd == depth) + break; /* found */ + + dentry = dentry->d_parent; + } + return dentry; +} + +static struct ctl_table *proc_sys_lookup_table_one(struct ctl_table *table, + struct qstr *name) { int len; - for ( ; p->ctl_name || p->procname; p++) { + for ( ; table->ctl_name || table->procname; table++) { - if (!p->procname) + if (!table->procname) continue; - len = strlen(p->procname); + len = strlen(table->procname); if (len != name->len) continue; - if (memcmp(p->procname, name->name, len) != 0) + if (memcmp(table->procname, name->name, len) != 0) continue; /* I have a match */ - return p; + return table; } return NULL; } -struct ctl_table_header *grab_header(struct inode *inode) +static struct ctl_table *proc_sys_lookup_table(struct dentry *dentry, + struct ctl_table *table) { - if (PROC_I(inode)->sysctl) - return sysctl_head_grab(PROC_I(inode)->sysctl); - else - return sysctl_head_next(NULL); -} + struct dentry *ancestor; + struct proc_inode *ei; + int depth, i; -static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, - struct nameidata *nd) -{ - struct ctl_table_header *head = grab_header(dir); - struct ctl_table *table = PROC_I(dir)->sysctl_entry; - struct ctl_table_header *h = NULL; - struct qstr *name = &dentry->d_name; - struct ctl_table *p; - struct inode *inode; - struct dentry *err = ERR_PTR(-ENOENT); + ei = PROC_I(dentry->d_inode); + depth = ei->fd; - if (IS_ERR(head)) - return ERR_CAST(head); + if (depth == 0) + return table; - if (table && !table->child) { - WARN_ON(1); - goto out; + for (i = 1; table && (i <= depth); i++) { + ancestor = proc_sys_ancestor(dentry, i); + table = proc_sys_lookup_table_one(table, &ancestor->d_name); + if (table) + table = table->child; } + return table; + +} +static struct ctl_table *proc_sys_lookup_entry(struct dentry *dparent, + struct qstr *name, + struct ctl_table *table) +{ + table = proc_sys_lookup_table(dparent, table); + if (table) + table = proc_sys_lookup_table_one(table, name); + return table; +} - table = table ? table->child : head->ctl_table; +static struct ctl_table *do_proc_sys_lookup(struct dentry *parent, + struct qstr *name, + struct ctl_table_header **ptr) +{ + struct ctl_table_header *head; + struct ctl_table *table = NULL; - p = find_in_table(table, name); - if (!p) { - for (h = sysctl_head_next(NULL); h; h = sysctl_head_next(h)) { - if (h->attached_to != table) - continue; - p = find_in_table(h->attached_by, name); - if (p) - break; - } + for (head = sysctl_head_next(NULL); head; + head = sysctl_head_next(head)) { + table = proc_sys_lookup_entry(parent, name, head->ctl_table); + if (table) + break; } + *ptr = head; + return table; +} + +static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +{ + struct ctl_table_header *head; + struct inode *inode; + struct dentry *err; + struct ctl_table *table; - if (!p) + err = ERR_PTR(-ENOENT); + table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); + if (!table) goto out; err = ERR_PTR(-ENOMEM); - inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p); - if (h) - sysctl_head_finish(h); - + inode = proc_sys_make_inode(dir, table); if (!inode) goto out; @@ -129,14 +168,22 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, size_t count, loff_t *ppos, int write) { - struct inode *inode = filp->f_path.dentry->d_inode; - struct ctl_table_header *head = grab_header(inode); - struct ctl_table *table = PROC_I(inode)->sysctl_entry; + struct dentry *dentry = filp->f_dentry; + struct ctl_table_header *head; + struct ctl_table *table; ssize_t error; size_t res; - if (IS_ERR(head)) - return PTR_ERR(head); + table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); + /* Has the sysctl entry disappeared on us? */ + error = -ENOENT; + if (!table) + goto out; + + /* Has the sysctl entry been replaced by a directory? */ + error = -EISDIR; + if (!table->proc_handler) + goto out; /* * At this point we know that the sysctl was not unregistered @@ -146,11 +193,6 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, if (sysctl_perm(head->root, table, write ? MAY_WRITE : MAY_READ)) goto out; - /* if that can happen at all, it should be -EINVAL, not -EISDIR */ - error = -EINVAL; - if (!table->proc_handler) - goto out; - /* careful: calling conventions are nasty here */ res = count; error = table->proc_handler(table, write, filp, buf, &res, ppos); @@ -176,86 +218,82 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf, static int proc_sys_fill_cache(struct file *filp, void *dirent, - filldir_t filldir, - struct ctl_table_header *head, - struct ctl_table *table) + filldir_t filldir, struct ctl_table *table) { + struct ctl_table_header *head; + struct ctl_table *child_table = NULL; struct dentry *child, *dir = filp->f_path.dentry; struct inode *inode; struct qstr qname; ino_t ino = 0; unsigned type = DT_UNKNOWN; + int ret; qname.name = table->procname; qname.len = strlen(table->procname); qname.hash = full_name_hash(qname.name, qname.len); + /* Suppress duplicates. + * Only fill a directory entry if it is the value that + * an ordinary lookup of that name returns. Hide all + * others. + * + * If we ever cache this translation in the dcache + * I should do a dcache lookup first. But for now + * it is just simpler not to. + */ + ret = 0; + child_table = do_proc_sys_lookup(dir, &qname, &head); + sysctl_head_finish(head); + if (child_table != table) + return 0; + child = d_lookup(dir, &qname); if (!child) { - child = d_alloc(dir, &qname); - if (child) { - inode = proc_sys_make_inode(dir->d_sb, head, table); - if (!inode) { - dput(child); - return -ENOMEM; - } else { - child->d_op = &proc_sys_dentry_operations; - d_add(child, inode); + struct dentry *new; + new = d_alloc(dir, &qname); + if (new) { + inode = proc_sys_make_inode(dir->d_inode, table); + if (!inode) + child = ERR_PTR(-ENOMEM); + else { + new->d_op = &proc_sys_dentry_operations; + d_add(new, inode); } - } else { - return -ENOMEM; + if (child) + dput(new); + else + child = new; } } + if (!child || IS_ERR(child) || !child->d_inode) + goto end_instantiate; inode = child->d_inode; - ino = inode->i_ino; - type = inode->i_mode >> 12; - dput(child); - return !!filldir(dirent, qname.name, qname.len, filp->f_pos, ino, type); -} - -static int scan(struct ctl_table_header *head, ctl_table *table, - unsigned long *pos, struct file *file, - void *dirent, filldir_t filldir) -{ - - for (; table->ctl_name || table->procname; table++, (*pos)++) { - int res; - - /* Can't do anything without a proc name */ - if (!table->procname) - continue; - - if (*pos < file->f_pos) - continue; - - res = proc_sys_fill_cache(file, dirent, filldir, head, table); - if (res) - return res; - - file->f_pos = *pos + 1; + if (inode) { + ino = inode->i_ino; + type = inode->i_mode >> 12; } - return 0; + dput(child); +end_instantiate: + if (!ino) + ino= find_inode_number(dir, &qname); + if (!ino) + ino = 1; + return filldir(dirent, qname.name, qname.len, filp->f_pos, ino, type); } static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir) { - struct dentry *dentry = filp->f_path.dentry; + struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; - struct ctl_table_header *head = grab_header(inode); - struct ctl_table *table = PROC_I(inode)->sysctl_entry; - struct ctl_table_header *h = NULL; + struct ctl_table_header *head = NULL; + struct ctl_table *table; unsigned long pos; - int ret = -EINVAL; - - if (IS_ERR(head)) - return PTR_ERR(head); + int ret; - if (table && !table->child) { - WARN_ON(1); + ret = -ENOTDIR; + if (!S_ISDIR(inode->i_mode)) goto out; - } - - table = table ? table->child : head->ctl_table; ret = 0; /* Avoid a switch here: arm builds fail with missing __cmpdi2 */ @@ -273,17 +311,30 @@ static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir) } pos = 2; - ret = scan(head, table, &pos, filp, dirent, filldir); - if (ret) - goto out; + /* - Find each instance of the directory + * - Read all entries in each instance + * - Before returning an entry to user space lookup the entry + * by name and if I find a different entry don't return + * this one because it means it is a buried dup. + * For sysctl this should only happen for directory entries. + */ + for (head = sysctl_head_next(NULL); head; head = sysctl_head_next(head)) { + table = proc_sys_lookup_table(dentry, head->ctl_table); - for (h = sysctl_head_next(NULL); h; h = sysctl_head_next(h)) { - if (h->attached_to != table) + if (!table) continue; - ret = scan(h, h->attached_by, &pos, filp, dirent, filldir); - if (ret) { - sysctl_head_finish(h); - break; + + for (; table->ctl_name || table->procname; table++, pos++) { + /* Can't do anything without a proc name */ + if (!table->procname) + continue; + + if (pos < filp->f_pos) + continue; + + if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0) + goto out; + filp->f_pos = pos + 1; } } ret = 1; @@ -292,24 +343,53 @@ static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir) return ret; } -static int proc_sys_permission(struct inode *inode, int mask) +static int proc_sys_permission(struct inode *inode, int mask, struct nameidata *nd) { /* * sysctl entries that are not writeable, * are _NOT_ writeable, capabilities or not. */ - struct ctl_table_header *head = grab_header(inode); - struct ctl_table *table = PROC_I(inode)->sysctl_entry; + struct ctl_table_header *head; + struct ctl_table *table; + struct dentry *dentry; + int mode; + int depth; int error; - if (IS_ERR(head)) - return PTR_ERR(head); + head = NULL; + depth = PROC_I(inode)->fd; + + /* First check the cached permissions, in case we don't have + * enough information to lookup the sysctl table entry. + */ + error = -EACCES; + mode = inode->i_mode; + + if (current->euid == 0) + mode >>= 6; + else if (in_group_p(0)) + mode >>= 3; + + if ((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask) + error = 0; + + /* If we can't get a sysctl table entry the permission + * checks on the cached mode will have to be enough. + */ + if (!nd || !depth) + goto out; - if (!table) /* global root - r-xr-xr-x */ - error = mask & MAY_WRITE ? -EACCES : 0; - else /* Use the permissions on the sysctl table entry */ - error = sysctl_perm(head->root, table, mask); + dentry = nd->path.dentry; + table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); + /* If the entry does not exist deny permission */ + error = -EACCES; + if (!table) + goto out; + + /* Use the permissions on the sysctl table entry */ + error = sysctl_perm(head->root, table, mask); +out: sysctl_head_finish(head); return error; } @@ -329,70 +409,33 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr) return error; } -static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -{ - struct inode *inode = dentry->d_inode; - struct ctl_table_header *head = grab_header(inode); - struct ctl_table *table = PROC_I(inode)->sysctl_entry; - - if (IS_ERR(head)) - return PTR_ERR(head); - - generic_fillattr(inode, stat); - if (table) - stat->mode = (stat->mode & S_IFMT) | table->mode; - - sysctl_head_finish(head); - return 0; -} - +/* I'm lazy and don't distinguish between files and directories, + * until access time. + */ static const struct file_operations proc_sys_file_operations = { .read = proc_sys_read, .write = proc_sys_write, -}; - -static const struct file_operations proc_sys_dir_file_operations = { .readdir = proc_sys_readdir, }; static const struct inode_operations proc_sys_inode_operations = { - .permission = proc_sys_permission, - .setattr = proc_sys_setattr, - .getattr = proc_sys_getattr, -}; - -static const struct inode_operations proc_sys_dir_operations = { .lookup = proc_sys_lookup, .permission = proc_sys_permission, .setattr = proc_sys_setattr, - .getattr = proc_sys_getattr, }; static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) { - return !PROC_I(dentry->d_inode)->sysctl->unregistering; -} - -static int proc_sys_delete(struct dentry *dentry) -{ - return !!PROC_I(dentry->d_inode)->sysctl->unregistering; -} - -static int proc_sys_compare(struct dentry *dir, struct qstr *qstr, - struct qstr *name) -{ - struct dentry *dentry = container_of(qstr, struct dentry, d_name); - if (qstr->len != name->len) - return 1; - if (memcmp(qstr->name, name->name, name->len)) - return 1; - return !sysctl_is_seen(PROC_I(dentry->d_inode)->sysctl); + struct ctl_table_header *head; + struct ctl_table *table; + table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); + proc_sys_refresh_inode(dentry->d_inode, table); + sysctl_head_finish(head); + return !!table; } static struct dentry_operations proc_sys_dentry_operations = { .d_revalidate = proc_sys_revalidate, - .d_delete = proc_sys_delete, - .d_compare = proc_sys_compare, }; static struct proc_dir_entry *proc_sys_root; @@ -400,8 +443,8 @@ static struct proc_dir_entry *proc_sys_root; int proc_sys_init(void) { proc_sys_root = proc_mkdir("sys", NULL); - proc_sys_root->proc_iops = &proc_sys_dir_operations; - proc_sys_root->proc_fops = &proc_sys_dir_file_operations; + proc_sys_root->proc_iops = &proc_sys_inode_operations; + proc_sys_root->proc_fops = &proc_sys_file_operations; proc_sys_root->nlink = 0; return 0; } diff --git a/trunk/fs/qnx4/inode.c b/trunk/fs/qnx4/inode.c index 2aad1044b84c..b31ab78052b3 100644 --- a/trunk/fs/qnx4/inode.c +++ b/trunk/fs/qnx4/inode.c @@ -553,7 +553,7 @@ static void qnx4_destroy_inode(struct inode *inode) kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 879e54d35c2d..2ec748ba0bd3 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -521,7 +521,7 @@ static void reiserfs_destroy_inode(struct inode *inode) kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; diff --git a/trunk/fs/reiserfs/xattr.c b/trunk/fs/reiserfs/xattr.c index bb3cb5b7cdb2..d7c4935c1034 100644 --- a/trunk/fs/reiserfs/xattr.c +++ b/trunk/fs/reiserfs/xattr.c @@ -1250,7 +1250,7 @@ static int reiserfs_check_acl(struct inode *inode, int mask) return error; } -int reiserfs_permission(struct inode *inode, int mask) +int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) { /* * We don't do permission checks on the internal objects. diff --git a/trunk/fs/romfs/inode.c b/trunk/fs/romfs/inode.c index 8e51a2aaa977..3f13d491c7c7 100644 --- a/trunk/fs/romfs/inode.c +++ b/trunk/fs/romfs/inode.c @@ -577,7 +577,7 @@ static void romfs_destroy_inode(struct inode *inode) kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct romfs_inode_info *ei = foo; diff --git a/trunk/fs/smbfs/file.c b/trunk/fs/smbfs/file.c index e4f8d51a5553..2294783320cb 100644 --- a/trunk/fs/smbfs/file.c +++ b/trunk/fs/smbfs/file.c @@ -408,7 +408,7 @@ smb_file_release(struct inode *inode, struct file * file) * privileges, so we need our own check for this. */ static int -smb_file_permission(struct inode *inode, int mask) +smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) { int mode = inode->i_mode; int error = 0; @@ -417,7 +417,7 @@ smb_file_permission(struct inode *inode, int mask) /* Look at user permissions */ mode >>= 6; - if (mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC)) + if ((mode & 7 & mask) != mask) error = -EACCES; return error; } diff --git a/trunk/fs/smbfs/inode.c b/trunk/fs/smbfs/inode.c index 3528f40ffb0f..376ef3ee6ed7 100644 --- a/trunk/fs/smbfs/inode.c +++ b/trunk/fs/smbfs/inode.c @@ -67,7 +67,7 @@ static void smb_destroy_inode(struct inode *inode) kmem_cache_free(smb_inode_cachep, SMB_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct smb_inode_info *ei = (struct smb_inode_info *) foo; diff --git a/trunk/fs/splice.c b/trunk/fs/splice.c index b30311ba8af6..399442179d89 100644 --- a/trunk/fs/splice.c +++ b/trunk/fs/splice.c @@ -772,7 +772,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, ssize_t ret; int err; - err = file_remove_suid(out); + err = remove_suid(out->f_path.dentry); if (unlikely(err)) return err; @@ -830,7 +830,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, ssize_t ret; inode_double_lock(inode, pipe->inode); - ret = file_remove_suid(out); + ret = remove_suid(out->f_path.dentry); if (likely(!ret)) ret = __splice_from_pipe(pipe, &sd, pipe_to_file); inode_double_unlock(inode, pipe->inode); @@ -1160,6 +1160,36 @@ static long do_splice(struct file *in, loff_t __user *off_in, return -EINVAL; } +/* + * Do a copy-from-user while holding the mmap_semaphore for reading, in a + * manner safe from deadlocking with simultaneous mmap() (grabbing mmap_sem + * for writing) and page faulting on the user memory pointed to by src. + * This assumes that we will very rarely hit the partial != 0 path, or this + * will not be a win. + */ +static int copy_from_user_mmap_sem(void *dst, const void __user *src, size_t n) +{ + int partial; + + if (!access_ok(VERIFY_READ, src, n)) + return -EFAULT; + + pagefault_disable(); + partial = __copy_from_user_inatomic(dst, src, n); + pagefault_enable(); + + /* + * Didn't copy everything, drop the mmap_sem and do a faulting copy + */ + if (unlikely(partial)) { + up_read(¤t->mm->mmap_sem); + partial = copy_from_user(dst, src, n); + down_read(¤t->mm->mmap_sem); + } + + return partial; +} + /* * Map an iov into an array of pages and offset/length tupples. With the * partial_page structure, we can map several non-contiguous ranges into @@ -1173,6 +1203,8 @@ static int get_iovec_page_array(const struct iovec __user *iov, { int buffers = 0, error = 0; + down_read(¤t->mm->mmap_sem); + while (nr_vecs) { unsigned long off, npages; struct iovec entry; @@ -1181,7 +1213,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, int i; error = -EFAULT; - if (copy_from_user(&entry, iov, sizeof(entry))) + if (copy_from_user_mmap_sem(&entry, iov, sizeof(entry))) break; base = entry.iov_base; @@ -1215,8 +1247,9 @@ static int get_iovec_page_array(const struct iovec __user *iov, if (npages > PIPE_BUFFERS - buffers) npages = PIPE_BUFFERS - buffers; - error = get_user_pages_fast((unsigned long)base, npages, - 0, &pages[buffers]); + error = get_user_pages(current, current->mm, + (unsigned long) base, npages, 0, 0, + &pages[buffers], NULL); if (unlikely(error <= 0)) break; @@ -1255,6 +1288,8 @@ static int get_iovec_page_array(const struct iovec __user *iov, iov++; } + up_read(¤t->mm->mmap_sem); + if (buffers) return buffers; diff --git a/trunk/fs/stat.c b/trunk/fs/stat.c index 7c46fbeb8b76..9cf41f719d50 100644 --- a/trunk/fs/stat.c +++ b/trunk/fs/stat.c @@ -57,13 +57,13 @@ EXPORT_SYMBOL(vfs_getattr); int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) { - struct path path; + struct nameidata nd; int error; - error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path); + error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd); if (!error) { - error = vfs_getattr(path.mnt, path.dentry, stat); - path_put(&path); + error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); + path_put(&nd.path); } return error; } @@ -77,13 +77,13 @@ EXPORT_SYMBOL(vfs_stat); int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat) { - struct path path; + struct nameidata nd; int error; - error = user_path_at(dfd, name, 0, &path); + error = __user_walk_fd(dfd, name, 0, &nd); if (!error) { - error = vfs_getattr(path.mnt, path.dentry, stat); - path_put(&path); + error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); + path_put(&nd.path); } return error; } @@ -291,29 +291,29 @@ asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf) return error; } -asmlinkage long sys_readlinkat(int dfd, const char __user *pathname, +asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf, int bufsiz) { - struct path path; + struct nameidata nd; int error; if (bufsiz <= 0) return -EINVAL; - error = user_path_at(dfd, pathname, 0, &path); + error = __user_walk_fd(dfd, path, 0, &nd); if (!error) { - struct inode *inode = path.dentry->d_inode; + struct inode *inode = nd.path.dentry->d_inode; error = -EINVAL; if (inode->i_op && inode->i_op->readlink) { - error = security_inode_readlink(path.dentry); + error = security_inode_readlink(nd.path.dentry); if (!error) { - touch_atime(path.mnt, path.dentry); - error = inode->i_op->readlink(path.dentry, + touch_atime(nd.path.mnt, nd.path.dentry); + error = inode->i_op->readlink(nd.path.dentry, buf, bufsiz); } } - path_put(&path); + path_put(&nd.path); } return error; } diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index aedaeba82ae5..c1a7efb310bf 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -459,8 +459,11 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) int ret; ret = __sysfs_add_one(acxt, sd); - WARN(ret == -EEXIST, KERN_WARNING "sysfs: duplicate filename '%s' " + if (ret == -EEXIST) { + printk(KERN_WARNING "sysfs: duplicate filename '%s' " "can not be created\n", sd->s_name); + WARN_ON(1); + } return ret; } diff --git a/trunk/fs/sysfs/file.c b/trunk/fs/sysfs/file.c index c9e4e5091da1..3f07893ff896 100644 --- a/trunk/fs/sysfs/file.c +++ b/trunk/fs/sysfs/file.c @@ -337,8 +337,9 @@ static int sysfs_open_file(struct inode *inode, struct file *file) if (kobj->ktype && kobj->ktype->sysfs_ops) ops = kobj->ktype->sysfs_ops; else { - WARN(1, KERN_ERR "missing sysfs attribute operations for " + printk(KERN_ERR "missing sysfs attribute operations for " "kobject: %s\n", kobject_name(kobj)); + WARN_ON(1); goto err_out; } diff --git a/trunk/fs/sysfs/group.c b/trunk/fs/sysfs/group.c index fe611949a7f7..eeba38417b1d 100644 --- a/trunk/fs/sysfs/group.c +++ b/trunk/fs/sysfs/group.c @@ -134,8 +134,9 @@ void sysfs_remove_group(struct kobject * kobj, if (grp->name) { sd = sysfs_get_dirent(dir_sd, grp->name); if (!sd) { - WARN(!sd, KERN_WARNING "sysfs group %p not found for " + printk(KERN_WARNING "sysfs group %p not found for " "kobject '%s'\n", grp, kobject_name(kobj)); + WARN_ON(!sd); return; } } else diff --git a/trunk/fs/sysv/inode.c b/trunk/fs/sysv/inode.c index df0d435baa48..c5d60de0658f 100644 --- a/trunk/fs/sysv/inode.c +++ b/trunk/fs/sysv/inode.c @@ -326,7 +326,7 @@ static void sysv_destroy_inode(struct inode *inode) kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); } -static void init_once(void *p) +static void init_once(struct kmem_cache *cachep, void *p) { struct sysv_inode_info *si = (struct sysv_inode_info *)p; diff --git a/trunk/fs/ubifs/file.c b/trunk/fs/ubifs/file.c index 8565e586e533..005a3b854d96 100644 --- a/trunk/fs/ubifs/file.c +++ b/trunk/fs/ubifs/file.c @@ -53,7 +53,6 @@ #include "ubifs.h" #include -#include static int read_block(struct inode *inode, void *addr, unsigned int block, struct ubifs_data_node *dn) diff --git a/trunk/fs/ubifs/super.c b/trunk/fs/ubifs/super.c index ca1e2d4e03cc..00eb9c68ad03 100644 --- a/trunk/fs/ubifs/super.c +++ b/trunk/fs/ubifs/super.c @@ -1841,7 +1841,7 @@ static struct file_system_type ubifs_fs_type = { /* * Inode slab cache constructor. */ -static void inode_slab_ctor(void *obj) +static void inode_slab_ctor(struct kmem_cache *cachep, void *obj) { struct ubifs_inode *ui = obj; inode_init_once(&ui->vfs_inode); diff --git a/trunk/fs/udf/super.c b/trunk/fs/udf/super.c index 5698bbf83bbf..44cc702f96cc 100644 --- a/trunk/fs/udf/super.c +++ b/trunk/fs/udf/super.c @@ -148,7 +148,7 @@ static void udf_destroy_inode(struct inode *inode) kmem_cache_free(udf_inode_cachep, UDF_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct udf_inode_info *ei = (struct udf_inode_info *)foo; diff --git a/trunk/fs/ufs/super.c b/trunk/fs/ufs/super.c index 3e30e40aa24d..227c9d700040 100644 --- a/trunk/fs/ufs/super.c +++ b/trunk/fs/ufs/super.c @@ -1302,7 +1302,7 @@ static void ufs_destroy_inode(struct inode *inode) kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache * cachep, void *foo) { struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; diff --git a/trunk/fs/utimes.c b/trunk/fs/utimes.c index 6929e3e91d05..b6b664e7145e 100644 --- a/trunk/fs/utimes.c +++ b/trunk/fs/utimes.c @@ -48,22 +48,66 @@ static bool nsec_valid(long nsec) return nsec >= 0 && nsec <= 999999999; } -static int utimes_common(struct path *path, struct timespec *times) +/* If times==NULL, set access and modification to current time, + * must be owner or have write permission. + * Else, update from *times, must be owner or super user. + */ +long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags) { int error; + struct nameidata nd; + struct dentry *dentry; + struct inode *inode; struct iattr newattrs; - struct inode *inode = path->dentry->d_inode; + struct file *f = NULL; + struct vfsmount *mnt; - error = mnt_want_write(path->mnt); - if (error) + error = -EINVAL; + if (times && (!nsec_valid(times[0].tv_nsec) || + !nsec_valid(times[1].tv_nsec))) { goto out; + } + + if (flags & ~AT_SYMLINK_NOFOLLOW) + goto out; + + if (filename == NULL && dfd != AT_FDCWD) { + error = -EINVAL; + if (flags & AT_SYMLINK_NOFOLLOW) + goto out; + + error = -EBADF; + f = fget(dfd); + if (!f) + goto out; + dentry = f->f_path.dentry; + mnt = f->f_path.mnt; + } else { + error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); + if (error) + goto out; + + dentry = nd.path.dentry; + mnt = nd.path.mnt; + } + + inode = dentry->d_inode; + + error = mnt_want_write(mnt); + if (error) + goto dput_and_out; if (times && times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) times = NULL; + /* In most cases, the checks are done in inode_change_ok() */ newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; if (times) { + error = -EPERM; + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + goto mnt_drop_write_and_out; + if (times[0].tv_nsec == UTIME_OMIT) newattrs.ia_valid &= ~ATTR_ATIME; else if (times[0].tv_nsec != UTIME_NOW) { @@ -79,13 +123,21 @@ static int utimes_common(struct path *path, struct timespec *times) newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; newattrs.ia_valid |= ATTR_MTIME_SET; } + /* - * Tell inode_change_ok(), that this is an explicit time - * update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET - * were used. + * For the UTIME_OMIT/UTIME_NOW and UTIME_NOW/UTIME_OMIT + * cases, we need to make an extra check that is not done by + * inode_change_ok(). */ - newattrs.ia_valid |= ATTR_TIMES_SET; + if (((times[0].tv_nsec == UTIME_NOW && + times[1].tv_nsec == UTIME_OMIT) + || + (times[0].tv_nsec == UTIME_OMIT && + times[1].tv_nsec == UTIME_NOW)) + && !is_owner_or_cap(inode)) + goto mnt_drop_write_and_out; } else { + /* * If times is NULL (or both times are UTIME_NOW), * then we need to check permissions, because @@ -96,76 +148,21 @@ static int utimes_common(struct path *path, struct timespec *times) goto mnt_drop_write_and_out; if (!is_owner_or_cap(inode)) { - error = inode_permission(inode, MAY_WRITE); + error = permission(inode, MAY_WRITE, NULL); if (error) goto mnt_drop_write_and_out; } } mutex_lock(&inode->i_mutex); - error = notify_change(path->dentry, &newattrs); + error = notify_change(dentry, &newattrs); mutex_unlock(&inode->i_mutex); - mnt_drop_write_and_out: - mnt_drop_write(path->mnt); -out: - return error; -} - -/* - * do_utimes - change times on filename or file descriptor - * @dfd: open file descriptor, -1 or AT_FDCWD - * @filename: path name or NULL - * @times: new times or NULL - * @flags: zero or more flags (only AT_SYMLINK_NOFOLLOW for the moment) - * - * If filename is NULL and dfd refers to an open file, then operate on - * the file. Otherwise look up filename, possibly using dfd as a - * starting point. - * - * If times==NULL, set access and modification to current time, - * must be owner or have write permission. - * Else, update from *times, must be owner or super user. - */ -long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags) -{ - int error = -EINVAL; - - if (times && (!nsec_valid(times[0].tv_nsec) || - !nsec_valid(times[1].tv_nsec))) { - goto out; - } - - if (flags & ~AT_SYMLINK_NOFOLLOW) - goto out; - - if (filename == NULL && dfd != AT_FDCWD) { - struct file *file; - - if (flags & AT_SYMLINK_NOFOLLOW) - goto out; - - file = fget(dfd); - error = -EBADF; - if (!file) - goto out; - - error = utimes_common(&file->f_path, times); - fput(file); - } else { - struct path path; - int lookup_flags = 0; - - if (!(flags & AT_SYMLINK_NOFOLLOW)) - lookup_flags |= LOOKUP_FOLLOW; - - error = user_path_at(dfd, filename, lookup_flags, &path); - if (error) - goto out; - - error = utimes_common(&path, times); - path_put(&path); - } - + mnt_drop_write(mnt); +dput_and_out: + if (f) + fput(f); + else + path_put(&nd.path); out: return error; } diff --git a/trunk/fs/xattr.c b/trunk/fs/xattr.c index 468377e66531..4706a8b1f495 100644 --- a/trunk/fs/xattr.c +++ b/trunk/fs/xattr.c @@ -63,7 +63,7 @@ xattr_permission(struct inode *inode, const char *name, int mask) return -EPERM; } - return inode_permission(inode, mask); + return permission(inode, mask, NULL); } int @@ -252,40 +252,40 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, } asmlinkage long -sys_setxattr(const char __user *pathname, const char __user *name, +sys_setxattr(const char __user *path, const char __user *name, const void __user *value, size_t size, int flags) { - struct path path; + struct nameidata nd; int error; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (error) return error; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (!error) { - error = setxattr(path.dentry, name, value, size, flags); - mnt_drop_write(path.mnt); + error = setxattr(nd.path.dentry, name, value, size, flags); + mnt_drop_write(nd.path.mnt); } - path_put(&path); + path_put(&nd.path); return error; } asmlinkage long -sys_lsetxattr(const char __user *pathname, const char __user *name, +sys_lsetxattr(const char __user *path, const char __user *name, const void __user *value, size_t size, int flags) { - struct path path; + struct nameidata nd; int error; - error = user_lpath(pathname, &path); + error = user_path_walk_link(path, &nd); if (error) return error; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (!error) { - error = setxattr(path.dentry, name, value, size, flags); - mnt_drop_write(path.mnt); + error = setxattr(nd.path.dentry, name, value, size, flags); + mnt_drop_write(nd.path.mnt); } - path_put(&path); + path_put(&nd.path); return error; } @@ -350,32 +350,32 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, } asmlinkage ssize_t -sys_getxattr(const char __user *pathname, const char __user *name, +sys_getxattr(const char __user *path, const char __user *name, void __user *value, size_t size) { - struct path path; + struct nameidata nd; ssize_t error; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (error) return error; - error = getxattr(path.dentry, name, value, size); - path_put(&path); + error = getxattr(nd.path.dentry, name, value, size); + path_put(&nd.path); return error; } asmlinkage ssize_t -sys_lgetxattr(const char __user *pathname, const char __user *name, void __user *value, +sys_lgetxattr(const char __user *path, const char __user *name, void __user *value, size_t size) { - struct path path; + struct nameidata nd; ssize_t error; - error = user_lpath(pathname, &path); + error = user_path_walk_link(path, &nd); if (error) return error; - error = getxattr(path.dentry, name, value, size); - path_put(&path); + error = getxattr(nd.path.dentry, name, value, size); + path_put(&nd.path); return error; } @@ -425,30 +425,30 @@ listxattr(struct dentry *d, char __user *list, size_t size) } asmlinkage ssize_t -sys_listxattr(const char __user *pathname, char __user *list, size_t size) +sys_listxattr(const char __user *path, char __user *list, size_t size) { - struct path path; + struct nameidata nd; ssize_t error; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (error) return error; - error = listxattr(path.dentry, list, size); - path_put(&path); + error = listxattr(nd.path.dentry, list, size); + path_put(&nd.path); return error; } asmlinkage ssize_t -sys_llistxattr(const char __user *pathname, char __user *list, size_t size) +sys_llistxattr(const char __user *path, char __user *list, size_t size) { - struct path path; + struct nameidata nd; ssize_t error; - error = user_lpath(pathname, &path); + error = user_path_walk_link(path, &nd); if (error) return error; - error = listxattr(path.dentry, list, size); - path_put(&path); + error = listxattr(nd.path.dentry, list, size); + path_put(&nd.path); return error; } @@ -486,38 +486,38 @@ removexattr(struct dentry *d, const char __user *name) } asmlinkage long -sys_removexattr(const char __user *pathname, const char __user *name) +sys_removexattr(const char __user *path, const char __user *name) { - struct path path; + struct nameidata nd; int error; - error = user_path(pathname, &path); + error = user_path_walk(path, &nd); if (error) return error; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (!error) { - error = removexattr(path.dentry, name); - mnt_drop_write(path.mnt); + error = removexattr(nd.path.dentry, name); + mnt_drop_write(nd.path.mnt); } - path_put(&path); + path_put(&nd.path); return error; } asmlinkage long -sys_lremovexattr(const char __user *pathname, const char __user *name) +sys_lremovexattr(const char __user *path, const char __user *name) { - struct path path; + struct nameidata nd; int error; - error = user_lpath(pathname, &path); + error = user_path_walk_link(path, &nd); if (error) return error; - error = mnt_want_write(path.mnt); + error = mnt_want_write(nd.path.mnt); if (!error) { - error = removexattr(path.dentry, name); - mnt_drop_write(path.mnt); + error = removexattr(nd.path.dentry, name); + mnt_drop_write(nd.path.mnt); } - path_put(&path); + path_put(&nd.path); return error; } diff --git a/trunk/fs/xfs/linux-2.6/kmem.h b/trunk/fs/xfs/linux-2.6/kmem.h index a20683cf74dd..5e9564902976 100644 --- a/trunk/fs/xfs/linux-2.6/kmem.h +++ b/trunk/fs/xfs/linux-2.6/kmem.h @@ -79,7 +79,7 @@ kmem_zone_init(int size, char *zone_name) static inline kmem_zone_t * kmem_zone_init_flags(int size, char *zone_name, unsigned long flags, - void (*construct)(void *)) + void (*construct)(kmem_zone_t *, void *)) { return kmem_cache_create(zone_name, size, 0, flags, construct); } diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index 01939ba2d8de..a42ba9d71156 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -84,15 +84,17 @@ xfs_find_handle( switch (cmd) { case XFS_IOC_PATH_TO_FSHANDLE: case XFS_IOC_PATH_TO_HANDLE: { - struct path path; - int error = user_lpath((const char __user *)hreq.path, &path); + struct nameidata nd; + int error; + + error = user_path_walk_link((const char __user *)hreq.path, &nd); if (error) return error; - ASSERT(path.dentry); - ASSERT(path.dentry->d_inode); - inode = igrab(path.dentry->d_inode); - path_put(&path); + ASSERT(nd.path.dentry); + ASSERT(nd.path.dentry->d_inode); + inode = igrab(nd.path.dentry->d_inode); + path_put(&nd.path); break; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_iops.c b/trunk/fs/xfs/linux-2.6/xfs_iops.c index 5fc61c824bb9..2bf287ef5489 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_iops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_iops.c @@ -589,7 +589,8 @@ xfs_check_acl( STATIC int xfs_vn_permission( struct inode *inode, - int mask) + int mask, + struct nameidata *nd) { return generic_permission(inode, mask, xfs_check_acl); } diff --git a/trunk/fs/xfs/linux-2.6/xfs_lrw.c b/trunk/fs/xfs/linux-2.6/xfs_lrw.c index 82333b3e118e..5e3b57516ec7 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_lrw.c +++ b/trunk/fs/xfs/linux-2.6/xfs_lrw.c @@ -711,7 +711,7 @@ xfs_write( !capable(CAP_FSETID)) { error = xfs_write_clear_setuid(xip); if (likely(!error)) - error = -file_remove_suid(file); + error = -remove_suid(file->f_path.dentry); if (unlikely(error)) { goto out_unlock_internal; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c index 943381284e2e..742b2c7852c1 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_super.c +++ b/trunk/fs/xfs/linux-2.6/xfs_super.c @@ -843,6 +843,7 @@ xfs_fs_destroy_inode( STATIC void xfs_fs_inode_init_once( + kmem_zone_t *zonep, void *vnode) { inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); diff --git a/trunk/include/Kbuild b/trunk/include/Kbuild index d8c3e3cbf416..bdca155028ec 100644 --- a/trunk/include/Kbuild +++ b/trunk/include/Kbuild @@ -1,6 +1,3 @@ -# Top-level Makefile calls into asm-$(ARCH) -# List only non-arch directories below - header-y += asm-generic/ header-y += linux/ header-y += sound/ @@ -8,3 +5,5 @@ header-y += mtd/ header-y += rdma/ header-y += video/ header-y += drm/ + +header-y += asm-$(ARCH)/ diff --git a/trunk/include/asm-alpha/dma-mapping.h b/trunk/include/asm-alpha/dma-mapping.h index a5801ae02e4b..db351d1296f4 100644 --- a/trunk/include/asm-alpha/dma-mapping.h +++ b/trunk/include/asm-alpha/dma-mapping.h @@ -24,8 +24,8 @@ pci_unmap_sg(alpha_gendev_to_pci(dev), sg, nents, dir) #define dma_supported(dev, mask) \ pci_dma_supported(alpha_gendev_to_pci(dev), mask) -#define dma_mapping_error(dev, addr) \ - pci_dma_mapping_error(alpha_gendev_to_pci(dev), addr) +#define dma_mapping_error(addr) \ + pci_dma_mapping_error(addr) #else /* no PCI - no IOMMU. */ @@ -45,7 +45,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, #define dma_unmap_page(dev, addr, size, dir) ((void)0) #define dma_unmap_sg(dev, sg, nents, dir) ((void)0) -#define dma_mapping_error(dev, addr) (0) +#define dma_mapping_error(addr) (0) #endif /* !CONFIG_PCI */ diff --git a/trunk/include/asm-alpha/namei.h b/trunk/include/asm-alpha/namei.h new file mode 100644 index 000000000000..5cc9bb39499d --- /dev/null +++ b/trunk/include/asm-alpha/namei.h @@ -0,0 +1,17 @@ +/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $ + * linux/include/asm-alpha/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __ALPHA_NAMEI_H +#define __ALPHA_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __ALPHA_NAMEI_H */ diff --git a/trunk/include/asm-alpha/pci.h b/trunk/include/asm-alpha/pci.h index 2a14302c17a3..d31fd49ff79a 100644 --- a/trunk/include/asm-alpha/pci.h +++ b/trunk/include/asm-alpha/pci.h @@ -106,7 +106,7 @@ extern dma_addr_t pci_map_page(struct pci_dev *, struct page *, /* Test for pci_map_single or pci_map_page having generated an error. */ static inline int -pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) +pci_dma_mapping_error(dma_addr_t dma_addr) { return dma_addr == 0; } diff --git a/trunk/include/asm-arm/arch-at91/at91_ecc.h b/trunk/include/asm-arm/arch-at91/at91_ecc.h new file mode 100644 index 000000000000..1e5a8caca2d1 --- /dev/null +++ b/trunk/include/asm-arm/arch-at91/at91_ecc.h @@ -0,0 +1,38 @@ +/* + * include/asm-arm/arch-at91/at91_ecc.h + * + * Error Corrected Code Controller (ECC) - System peripherals regsters. + * Based on AT91SAM9260 datasheet revision B. + * + * 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 AT91_ECC_H +#define AT91_ECC_H + +#define AT91_ECC_CR 0x00 /* Control register */ +#define AT91_ECC_RST (1 << 0) /* Reset parity */ + +#define AT91_ECC_MR 0x04 /* Mode register */ +#define AT91_ECC_PAGESIZE (3 << 0) /* Page Size */ +#define AT91_ECC_PAGESIZE_528 (0) +#define AT91_ECC_PAGESIZE_1056 (1) +#define AT91_ECC_PAGESIZE_2112 (2) +#define AT91_ECC_PAGESIZE_4224 (3) + +#define AT91_ECC_SR 0x08 /* Status register */ +#define AT91_ECC_RECERR (1 << 0) /* Recoverable Error */ +#define AT91_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ +#define AT91_ECC_MULERR (1 << 2) /* Multiple Errors */ + +#define AT91_ECC_PR 0x0c /* Parity register */ +#define AT91_ECC_BITADDR (0xf << 0) /* Bit Error Address */ +#define AT91_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ + +#define AT91_ECC_NPR 0x10 /* NParity register */ +#define AT91_ECC_NPARITY (0xffff << 0) /* NParity */ + +#endif diff --git a/trunk/include/asm-arm/arch-at91/board.h b/trunk/include/asm-arm/arch-at91/board.h index 48bbd854f57d..94de788da76e 100644 --- a/trunk/include/asm-arm/arch-at91/board.h +++ b/trunk/include/asm-arm/arch-at91/board.h @@ -89,7 +89,7 @@ struct at91_usbh_data { extern void __init at91_add_device_usbh(struct at91_usbh_data *data); /* NAND / SmartMedia */ -struct atmel_nand_data { +struct at91_nand_data { u8 enable_pin; /* chip enable */ u8 det_pin; /* card detect */ u8 rdy_pin; /* ready/busy */ @@ -98,7 +98,7 @@ struct atmel_nand_data { u8 bus_width_16; /* buswidth is 16 bit */ struct mtd_partition* (*partition_info)(int, int*); }; -extern void __init at91_add_device_nand(struct atmel_nand_data *data); +extern void __init at91_add_device_nand(struct at91_nand_data *data); /* I2C*/ extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices); diff --git a/trunk/include/asm-arm/cacheflush.h b/trunk/include/asm-arm/cacheflush.h index 03cf1ee977b7..70b0fe724b62 100644 --- a/trunk/include/asm-arm/cacheflush.h +++ b/trunk/include/asm-arm/cacheflush.h @@ -424,9 +424,9 @@ static inline void flush_anon_page(struct vm_area_struct *vma, } #define flush_dcache_mmap_lock(mapping) \ - spin_lock_irq(&(mapping)->tree_lock) + write_lock_irq(&(mapping)->tree_lock) #define flush_dcache_mmap_unlock(mapping) \ - spin_unlock_irq(&(mapping)->tree_lock) + write_unlock_irq(&(mapping)->tree_lock) #define flush_icache_user_range(vma,page,addr,len) \ flush_dcache_page(page) diff --git a/trunk/include/asm-arm/dma-mapping.h b/trunk/include/asm-arm/dma-mapping.h index f41335ba6337..e99406a7bece 100644 --- a/trunk/include/asm-arm/dma-mapping.h +++ b/trunk/include/asm-arm/dma-mapping.h @@ -56,7 +56,7 @@ static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) /* * DMA errors are defined by all-bits-set in the DMA address. */ -static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +static inline int dma_mapping_error(dma_addr_t dma_addr) { return dma_addr == ~0; } diff --git a/trunk/include/asm-arm/namei.h b/trunk/include/asm-arm/namei.h new file mode 100644 index 000000000000..a402d3b9d0f7 --- /dev/null +++ b/trunk/include/asm-arm/namei.h @@ -0,0 +1,25 @@ +/* + * linux/include/asm-arm/namei.h + * + * Routines to handle famous /usr/gnemul + * Derived from the Sparc version of this file + * + * Included from linux/fs/namei.c + */ + +#ifndef __ASMARM_NAMEI_H +#define __ASMARM_NAMEI_H + +#define ARM_BSD_EMUL "usr/gnemul/bsd/" + +static inline char *__emul_prefix(void) +{ + switch (current->personality) { + case PER_BSD: + return ARM_BSD_EMUL; + default: + return NULL; + } +} + +#endif /* __ASMARM_NAMEI_H */ diff --git a/trunk/include/asm-avr32/arch-at32ap/board.h b/trunk/include/asm-avr32/arch-at32ap/board.h index e60e9076544d..a3783861cdd2 100644 --- a/trunk/include/asm-avr32/arch-at32ap/board.h +++ b/trunk/include/asm-avr32/arch-at32ap/board.h @@ -82,15 +82,7 @@ struct mci_platform_data; struct platform_device * at32_add_device_mci(unsigned int id, struct mci_platform_data *data); -struct ac97c_platform_data { - unsigned short dma_rx_periph_id; - unsigned short dma_tx_periph_id; - unsigned short dma_controller_id; - int reset_pin; -}; -struct platform_device * -at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data); - +struct platform_device *at32_add_device_ac97c(unsigned int id); struct platform_device *at32_add_device_abdac(unsigned int id); struct platform_device *at32_add_device_psif(unsigned int id); @@ -105,17 +97,4 @@ struct platform_device * at32_add_device_cf(unsigned int id, unsigned int extint, struct cf_platform_data *data); -/* NAND / SmartMedia */ -struct atmel_nand_data { - int enable_pin; /* chip enable */ - int det_pin; /* card detect */ - int rdy_pin; /* ready/busy */ - u8 ale; /* address line number connected to ALE */ - u8 cle; /* address line number connected to CLE */ - u8 bus_width_16; /* buswidth is 16 bit */ - struct mtd_partition *(*partition_info)(int size, int *num_partitions); -}; -struct platform_device * -at32_add_device_nand(unsigned int id, struct atmel_nand_data *data); - #endif /* __ASM_ARCH_BOARD_H */ diff --git a/trunk/include/asm-avr32/dma-mapping.h b/trunk/include/asm-avr32/dma-mapping.h index 0399359ab5d8..57dc672bab8e 100644 --- a/trunk/include/asm-avr32/dma-mapping.h +++ b/trunk/include/asm-avr32/dma-mapping.h @@ -35,7 +35,7 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) /* * dma_map_single can't fail as it is implemented now. */ -static inline int dma_mapping_error(struct device *dev, dma_addr_t addr) +static inline int dma_mapping_error(dma_addr_t addr) { return 0; } diff --git a/trunk/include/asm-avr32/namei.h b/trunk/include/asm-avr32/namei.h new file mode 100644 index 000000000000..f0a26de06cab --- /dev/null +++ b/trunk/include/asm-avr32/namei.h @@ -0,0 +1,7 @@ +#ifndef __ASM_AVR32_NAMEI_H +#define __ASM_AVR32_NAMEI_H + +/* This dummy routine may be changed to something useful */ +#define __emul_prefix() NULL + +#endif /* __ASM_AVR32_NAMEI_H */ diff --git a/trunk/include/asm-blackfin/bfin-global.h b/trunk/include/asm-blackfin/bfin-global.h index 320aa5e167e9..76033831eb35 100644 --- a/trunk/include/asm-blackfin/bfin-global.h +++ b/trunk/include/asm-blackfin/bfin-global.h @@ -92,20 +92,16 @@ extern void *l1_data_B_sram_alloc(size_t); extern void *l1_inst_sram_alloc(size_t); extern void *l1_data_sram_alloc(size_t); extern void *l1_data_sram_zalloc(size_t); -extern void *l2_sram_alloc(size_t); -extern void *l2_sram_zalloc(size_t); extern int l1_data_A_sram_free(const void*); extern int l1_data_B_sram_free(const void*); extern int l1_inst_sram_free(const void*); extern int l1_data_sram_free(const void*); -extern int l2_sram_free(const void *); extern int sram_free(const void*); #define L1_INST_SRAM 0x00000001 #define L1_DATA_A_SRAM 0x00000002 #define L1_DATA_B_SRAM 0x00000004 #define L1_DATA_SRAM 0x00000006 -#define L2_SRAM 0x00000008 extern void *sram_alloc_with_lsl(size_t, unsigned long); extern int sram_free_with_lsl(const void*); @@ -118,9 +114,7 @@ extern struct file_operations dpmc_fops; extern unsigned long _ramstart, _ramend, _rambase; extern unsigned long memory_start, memory_end, physical_mem_end; extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[], - _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[], - _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[], - _ebss_l2[], _l2_lma_start[]; + _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[]; #ifdef CONFIG_MTD_UCLINUX extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size; diff --git a/trunk/include/asm-blackfin/dma.h b/trunk/include/asm-blackfin/dma.h index 3cd4b522aa3f..c0d5259e315b 100644 --- a/trunk/include/asm-blackfin/dma.h +++ b/trunk/include/asm-blackfin/dma.h @@ -144,16 +144,8 @@ struct dma_channel { void *data; unsigned int dma_enable_flag; unsigned int loopback_flag; -#ifdef CONFIG_PM - unsigned short saved_peripheral_map; -#endif }; -#ifdef CONFIG_PM -int blackfin_dma_suspend(void); -void blackfin_dma_resume(void); -#endif - /******************************************************************************* * DMA API's *******************************************************************************/ diff --git a/trunk/include/asm-blackfin/dpmc.h b/trunk/include/asm-blackfin/dpmc.h index de28e6e018b3..7f34cd384f12 100644 --- a/trunk/include/asm-blackfin/dpmc.h +++ b/trunk/include/asm-blackfin/dpmc.h @@ -7,18 +7,63 @@ #ifndef _BLACKFIN_DPMC_H_ #define _BLACKFIN_DPMC_H_ +#define SLEEP_MODE 1 +#define DEEP_SLEEP_MODE 2 +#define ACTIVE_PLL_DISABLED 3 +#define FULLON_MODE 4 +#define ACTIVE_PLL_ENABLED 5 +#define HIBERNATE_MODE 6 + +#define IOCTL_FULL_ON_MODE _IO('s', 0xA0) +#define IOCTL_ACTIVE_MODE _IO('s', 0xA1) +#define IOCTL_SLEEP_MODE _IO('s', 0xA2) +#define IOCTL_DEEP_SLEEP_MODE _IO('s', 0xA3) +#define IOCTL_HIBERNATE_MODE _IO('s', 0xA4) +#define IOCTL_CHANGE_FREQUENCY _IOW('s', 0xA5, unsigned long) +#define IOCTL_CHANGE_VOLTAGE _IOW('s', 0xA6, unsigned long) +#define IOCTL_SET_CCLK _IOW('s', 0xA7, unsigned long) +#define IOCTL_SET_SCLK _IOW('s', 0xA8, unsigned long) +#define IOCTL_GET_PLLSTATUS _IOW('s', 0xA9, unsigned long) +#define IOCTL_GET_CORECLOCK _IOW('s', 0xAA, unsigned long) +#define IOCTL_GET_SYSTEMCLOCK _IOW('s', 0xAB, unsigned long) +#define IOCTL_GET_VCO _IOW('s', 0xAC, unsigned long) +#define IOCTL_DISABLE_WDOG_TIMER _IO('s', 0xAD) +#define IOCTL_UNMASK_WDOG_WAKEUP_EVENT _IO('s',0xAE) +#define IOCTL_PROGRAM_WDOG_TIMER _IOW('s',0xAF,unsigned long) +#define IOCTL_CLEAR_WDOG_WAKEUP_EVENT _IO('s',0xB0) +#define IOCTL_SLEEP_DEEPER_MODE _IO('s',0xB1) + +#define DPMC_MINOR 254 + +#define ON 0 +#define OFF 1 + #ifdef __KERNEL__ -#ifndef __ASSEMBLY__ +unsigned long calc_volt(void); +int calc_vlev(int vlt); +unsigned long change_voltage(unsigned long volt); +int calc_msel(int vco_hz); +unsigned long change_frequency(unsigned long vco_mhz); +int set_pll_div(unsigned short sel, unsigned char flag); +int get_vco(void); +unsigned long change_system_clock(unsigned long clock); +unsigned long change_core_clock(unsigned long clock); +unsigned long get_pll_status(void); +void change_baud(int baud); +void fullon_mode(void); +void active_mode(void); void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); void deep_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); void hibernate_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); void sleep_deeper(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); -void do_hibernate(int wakeup); -void set_dram_srfs(void); -void unset_dram_srfs(void); +void program_wdog_timer(unsigned long); +void unmask_wdog_wakeup_evt(void); +void clear_wdog_wakeup_evt(void); +void disable_wdog_timer(void); -#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16)) +extern unsigned long get_cclk(void); +extern unsigned long get_sclk(void); struct bfin_dpmc_platform_data { const unsigned int *tuple_tab; @@ -26,33 +71,8 @@ struct bfin_dpmc_platform_data { unsigned short vr_settling_time; /* in us */ }; -#else - -#define PM_PUSH(x) \ - R0 = [P0 + (x - SRAM_BASE_ADDRESS)];\ - [--SP] = R0;\ - -#define PM_POP(x) \ - R0 = [SP++];\ - [P0 + (x - SRAM_BASE_ADDRESS)] = R0;\ - -#define PM_SYS_PUSH(x) \ - R0 = [P0 + (x - PLL_CTL)];\ - [--SP] = R0;\ - -#define PM_SYS_POP(x) \ - R0 = [SP++];\ - [P0 + (x - PLL_CTL)] = R0;\ - -#define PM_SYS_PUSH16(x) \ - R0 = w[P0 + (x - PLL_CTL)];\ - [--SP] = R0;\ - -#define PM_SYS_POP16(x) \ - R0 = [SP++];\ - w[P0 + (x - PLL_CTL)] = R0;\ +#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16)) -#endif #endif /* __KERNEL__ */ #endif /*_BLACKFIN_DPMC_H_*/ diff --git a/trunk/include/asm-blackfin/elf.h b/trunk/include/asm-blackfin/elf.h index 67a03a8a353e..30303fc8292c 100644 --- a/trunk/include/asm-blackfin/elf.h +++ b/trunk/include/asm-blackfin/elf.h @@ -15,8 +15,6 @@ #define EF_BFIN_FDPIC 0x00000002 /* -mfdpic */ #define EF_BFIN_CODE_IN_L1 0x00000010 /* --code-in-l1 */ #define EF_BFIN_DATA_IN_L1 0x00000020 /* --data-in-l1 */ -#define EF_BFIN_CODE_IN_L2 0x00000040 /* --code-in-l2 */ -#define EF_BFIN_DATA_IN_L2 0x00000080 /* --data-in-l2 */ typedef unsigned long elf_greg_t; diff --git a/trunk/include/asm-blackfin/gpio.h b/trunk/include/asm-blackfin/gpio.h index 168f1251eb4d..ff95e9d88342 100644 --- a/trunk/include/asm-blackfin/gpio.h +++ b/trunk/include/asm-blackfin/gpio.h @@ -376,12 +376,8 @@ struct gpio_port_t { #endif #ifdef CONFIG_PM - -unsigned int bfin_pm_standby_setup(void); -void bfin_pm_standby_restore(void); - -void bfin_gpio_pm_hibernate_restore(void); -void bfin_gpio_pm_hibernate_suspend(void); +unsigned int bfin_pm_setup(void); +void bfin_pm_restore(void); #ifndef CONFIG_BF54x #define PM_WAKE_RISING 0x1 @@ -396,8 +392,17 @@ void gpio_pm_wakeup_free(unsigned gpio); struct gpio_port_s { unsigned short data; + unsigned short data_clear; + unsigned short data_set; + unsigned short toggle; unsigned short maska; + unsigned short maska_clear; + unsigned short maska_set; + unsigned short maska_toggle; unsigned short maskb; + unsigned short maskb_clear; + unsigned short maskb_set; + unsigned short maskb_toggle; unsigned short dir; unsigned short polar; unsigned short edge; @@ -406,10 +411,10 @@ struct gpio_port_s { unsigned short fer; unsigned short reserved; - unsigned short mux; }; #endif /*CONFIG_BF54x*/ #endif /*CONFIG_PM*/ + /*********************************************************** * * FUNCTIONS: Blackfin GPIO Driver diff --git a/trunk/include/asm-blackfin/mach-bf527/anomaly.h b/trunk/include/asm-blackfin/mach-bf527/anomaly.h index b7b166f4f064..4725268a5ada 100644 --- a/trunk/include/asm-blackfin/mach-bf527/anomaly.h +++ b/trunk/include/asm-blackfin/mach-bf527/anomaly.h @@ -23,8 +23,6 @@ #define ANOMALY_05000245 (1) /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ #define ANOMALY_05000265 (1) -/* New Feature: EMAC TX DMA Word Alignment */ -#define ANOMALY_05000285 (1) /* Errors when SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */ #define ANOMALY_05000312 (1) /* Incorrect Access of OTP_STATUS During otp_write() Function */ diff --git a/trunk/include/asm-blackfin/mach-bf527/bfin_sir.h b/trunk/include/asm-blackfin/mach-bf527/bfin_sir.h index cfd8ad4f1f2c..0612d0c9501c 100644 --- a/trunk/include/asm-blackfin/mach-bf527/bfin_sir.h +++ b/trunk/include/asm-blackfin/mach-bf527/bfin_sir.h @@ -118,25 +118,16 @@ static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port) #define DRIVER_NAME "bfin_sir" -static int bfin_sir_hw_init(void) +static void bfin_sir_hw_init(void) { - int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - ret = peripheral_request(P_UART0_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART0_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART0_TX, DRIVER_NAME); + peripheral_request(P_UART0_RX, DRIVER_NAME); #endif #ifdef CONFIG_BFIN_SIR1 - ret = peripheral_request(P_UART1_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART1_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART1_TX, DRIVER_NAME); + peripheral_request(P_UART1_RX, DRIVER_NAME); #endif - return ret; + SSYNC(); } diff --git a/trunk/include/asm-blackfin/mach-bf527/defBF527.h b/trunk/include/asm-blackfin/mach-bf527/defBF527.h index f1a70db70cb8..82134f578f32 100644 --- a/trunk/include/asm-blackfin/mach-bf527/defBF527.h +++ b/trunk/include/asm-blackfin/mach-bf527/defBF527.h @@ -302,7 +302,6 @@ #define PHYIE 0x00000001 /* PHY_INT Interrupt Enable */ #define RXDWA 0x00000002 /* Receive Frame DMA Word Alignment (Odd/Even*) */ #define RXCKS 0x00000004 /* Enable RX Frame TCP/UDP Checksum Computation */ -#define TXDWA 0x00000010 /* Transmit Frame DMA Word Alignment (Odd/Even*) */ #define MDCDIV 0x00003F00 /* SCLK:MDC Clock Divisor [MDC=SCLK/(2*(N+1))] */ #define SET_MDCDIV(x) (((x)&0x3F)<< 8) /* Set MDC Clock Divisor */ diff --git a/trunk/include/asm-blackfin/mach-bf527/mem_init.h b/trunk/include/asm-blackfin/mach-bf527/mem_init.h index cbe03f4a5698..008ca66719e2 100644 --- a/trunk/include/asm-blackfin/mach-bf527/mem_init.h +++ b/trunk/include/asm-blackfin/mach-bf527/mem_init.h @@ -146,6 +146,33 @@ #define SDRAM_CL CL_3 #endif +#if (CONFIG_MEM_SIZE == 128) +#define SDRAM_SIZE EBSZ_128 +#endif +#if (CONFIG_MEM_SIZE == 64) +#define SDRAM_SIZE EBSZ_64 +#endif +#if (CONFIG_MEM_SIZE == 32) +#define SDRAM_SIZE EBSZ_32 +#endif +#if (CONFIG_MEM_SIZE == 16) +#define SDRAM_SIZE EBSZ_16 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 11) +#define SDRAM_WIDTH EBCAW_11 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 10) +#define SDRAM_WIDTH EBCAW_10 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 9) +#define SDRAM_WIDTH EBCAW_9 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 8) +#define SDRAM_WIDTH EBCAW_8 +#endif + +#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE) + /* Equation from section 17 (p17-46) of BF533 HRM */ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) diff --git a/trunk/include/asm-blackfin/mach-bf533/bfin_sir.h b/trunk/include/asm-blackfin/mach-bf533/bfin_sir.h index 9bb87e9e2e9b..cefcf8bb505b 100644 --- a/trunk/include/asm-blackfin/mach-bf533/bfin_sir.h +++ b/trunk/include/asm-blackfin/mach-bf533/bfin_sir.h @@ -110,16 +110,11 @@ static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port) #define DRIVER_NAME "bfin_sir" -static int bfin_sir_hw_init(void) +static void bfin_sir_hw_init(void) { - int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - ret = peripheral_request(P_UART0_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART0_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART0_TX, DRIVER_NAME); + peripheral_request(P_UART0_RX, DRIVER_NAME); #endif - return ret; + SSYNC(); } diff --git a/trunk/include/asm-blackfin/mach-bf533/mem_init.h b/trunk/include/asm-blackfin/mach-bf533/mem_init.h index 995c06b2b1ef..f8f31901fca9 100644 --- a/trunk/include/asm-blackfin/mach-bf533/mem_init.h +++ b/trunk/include/asm-blackfin/mach-bf533/mem_init.h @@ -133,6 +133,33 @@ #define SDRAM_CL CL_3 #endif +#if (CONFIG_MEM_SIZE == 128) +#define SDRAM_SIZE EBSZ_128 +#endif +#if (CONFIG_MEM_SIZE == 64) +#define SDRAM_SIZE EBSZ_64 +#endif +#if (CONFIG_MEM_SIZE == 32) +#define SDRAM_SIZE EBSZ_32 +#endif +#if (CONFIG_MEM_SIZE == 16) +#define SDRAM_SIZE EBSZ_16 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 11) +#define SDRAM_WIDTH EBCAW_11 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 10) +#define SDRAM_WIDTH EBCAW_10 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 9) +#define SDRAM_WIDTH EBCAW_9 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 8) +#define SDRAM_WIDTH EBCAW_8 +#endif + +#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE) + /* Equation from section 17 (p17-46) of BF533 HRM */ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) diff --git a/trunk/include/asm-blackfin/mach-bf537/bfin_sir.h b/trunk/include/asm-blackfin/mach-bf537/bfin_sir.h index cfd8ad4f1f2c..0612d0c9501c 100644 --- a/trunk/include/asm-blackfin/mach-bf537/bfin_sir.h +++ b/trunk/include/asm-blackfin/mach-bf537/bfin_sir.h @@ -118,25 +118,16 @@ static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port) #define DRIVER_NAME "bfin_sir" -static int bfin_sir_hw_init(void) +static void bfin_sir_hw_init(void) { - int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - ret = peripheral_request(P_UART0_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART0_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART0_TX, DRIVER_NAME); + peripheral_request(P_UART0_RX, DRIVER_NAME); #endif #ifdef CONFIG_BFIN_SIR1 - ret = peripheral_request(P_UART1_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART1_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART1_TX, DRIVER_NAME); + peripheral_request(P_UART1_RX, DRIVER_NAME); #endif - return ret; + SSYNC(); } diff --git a/trunk/include/asm-blackfin/mach-bf537/defBF537.h b/trunk/include/asm-blackfin/mach-bf537/defBF537.h index abde24c6d3b1..3f455909c418 100644 --- a/trunk/include/asm-blackfin/mach-bf537/defBF537.h +++ b/trunk/include/asm-blackfin/mach-bf537/defBF537.h @@ -290,7 +290,6 @@ #define PHYIE 0x00000001 /* PHY_INT Interrupt Enable */ #define RXDWA 0x00000002 /* Receive Frame DMA Word Alignment (Odd/Even*) */ #define RXCKS 0x00000004 /* Enable RX Frame TCP/UDP Checksum Computation */ -#define TXDWA 0x00000010 /* Transmit Frame DMA Word Alignment (Odd/Even*) */ #define MDCDIV 0x00003F00 /* SCLK:MDC Clock Divisor [MDC=SCLK/(2*(N+1))] */ #define SET_MDCDIV(x) (((x)&0x3F)<< 8) /* Set MDC Clock Divisor */ diff --git a/trunk/include/asm-blackfin/mach-bf537/mem_init.h b/trunk/include/asm-blackfin/mach-bf537/mem_init.h index f67698f670ca..9ad979d416c6 100644 --- a/trunk/include/asm-blackfin/mach-bf537/mem_init.h +++ b/trunk/include/asm-blackfin/mach-bf537/mem_init.h @@ -139,6 +139,33 @@ #define SDRAM_CL CL_3 #endif +#if (CONFIG_MEM_SIZE == 128) +#define SDRAM_SIZE EBSZ_128 +#endif +#if (CONFIG_MEM_SIZE == 64) +#define SDRAM_SIZE EBSZ_64 +#endif +#if (CONFIG_MEM_SIZE == 32) +#define SDRAM_SIZE EBSZ_32 +#endif +#if (CONFIG_MEM_SIZE == 16) +#define SDRAM_SIZE EBSZ_16 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 11) +#define SDRAM_WIDTH EBCAW_11 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 10) +#define SDRAM_WIDTH EBCAW_10 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 9) +#define SDRAM_WIDTH EBCAW_9 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 8) +#define SDRAM_WIDTH EBCAW_8 +#endif + +#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE) + /* Equation from section 17 (p17-46) of BF533 HRM */ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) diff --git a/trunk/include/asm-blackfin/mach-bf548/bfin_sir.h b/trunk/include/asm-blackfin/mach-bf548/bfin_sir.h index c41f9cf00268..5e94271c7e3b 100644 --- a/trunk/include/asm-blackfin/mach-bf548/bfin_sir.h +++ b/trunk/include/asm-blackfin/mach-bf548/bfin_sir.h @@ -124,43 +124,26 @@ struct bfin_sir_self { #define DRIVER_NAME "bfin_sir" -static int bfin_sir_hw_init(void) +static void bfin_sir_hw_init(void) { - int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - ret = peripheral_request(P_UART0_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART0_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART0_TX, DRIVER_NAME); + peripheral_request(P_UART0_RX, DRIVER_NAME); #endif #ifdef CONFIG_BFIN_SIR1 - ret = peripheral_request(P_UART1_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART1_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART1_TX, DRIVER_NAME); + peripheral_request(P_UART1_RX, DRIVER_NAME); #endif #ifdef CONFIG_BFIN_SIR2 - ret = peripheral_request(P_UART2_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART2_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART2_TX, DRIVER_NAME); + peripheral_request(P_UART2_RX, DRIVER_NAME); #endif #ifdef CONFIG_BFIN_SIR3 - ret = peripheral_request(P_UART3_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART3_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART3_TX, DRIVER_NAME); + peripheral_request(P_UART3_RX, DRIVER_NAME); #endif - return ret; + SSYNC(); } diff --git a/trunk/include/asm-blackfin/mach-bf548/gpio.h b/trunk/include/asm-blackfin/mach-bf548/gpio.h index bba82dc75f16..cb8b0f15c9a6 100644 --- a/trunk/include/asm-blackfin/mach-bf548/gpio.h +++ b/trunk/include/asm-blackfin/mach-bf548/gpio.h @@ -209,11 +209,3 @@ struct gpio_port_t { unsigned short dummy7; unsigned int port_mux; }; - -struct gpio_port_s { - unsigned short fer; - unsigned short data; - unsigned short dir; - unsigned short inen; - unsigned int mux; -}; diff --git a/trunk/include/asm-blackfin/mach-bf561/bfin_sir.h b/trunk/include/asm-blackfin/mach-bf561/bfin_sir.h index 9bb87e9e2e9b..cefcf8bb505b 100644 --- a/trunk/include/asm-blackfin/mach-bf561/bfin_sir.h +++ b/trunk/include/asm-blackfin/mach-bf561/bfin_sir.h @@ -110,16 +110,11 @@ static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port) #define DRIVER_NAME "bfin_sir" -static int bfin_sir_hw_init(void) +static void bfin_sir_hw_init(void) { - int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - ret = peripheral_request(P_UART0_TX, DRIVER_NAME); - if (ret) - return ret; - ret = peripheral_request(P_UART0_RX, DRIVER_NAME); - if (ret) - return ret; + peripheral_request(P_UART0_TX, DRIVER_NAME); + peripheral_request(P_UART0_RX, DRIVER_NAME); #endif - return ret; + SSYNC(); } diff --git a/trunk/include/asm-blackfin/mach-bf561/mem_init.h b/trunk/include/asm-blackfin/mach-bf561/mem_init.h index e163260bca18..439a5895b346 100644 --- a/trunk/include/asm-blackfin/mach-bf561/mem_init.h +++ b/trunk/include/asm-blackfin/mach-bf561/mem_init.h @@ -131,6 +131,33 @@ #define SDRAM_CL CL_3 #endif +#if (CONFIG_MEM_SIZE == 128) +#define SDRAM_SIZE EB0_SZ_128 +#endif +#if (CONFIG_MEM_SIZE == 64) +#define SDRAM_SIZE EB0_SZ_64 +#endif +#if ( CONFIG_MEM_SIZE == 32) +#define SDRAM_SIZE EB0_SZ_32 +#endif +#if (CONFIG_MEM_SIZE == 16) +#define SDRAM_SIZE EB0_SZ_16 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 11) +#define SDRAM_WIDTH EB0_CAW_11 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 10) +#define SDRAM_WIDTH EB0_CAW_10 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 9) +#define SDRAM_WIDTH EB0_CAW_9 +#endif +#if (CONFIG_MEM_ADD_WIDTH == 8) +#define SDRAM_WIDTH EB0_CAW_8 +#endif + +#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EB0_E) + /* Equation from section 17 (p17-46) of BF533 HRM */ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) diff --git a/trunk/include/asm-blackfin/module.h b/trunk/include/asm-blackfin/module.h index e3128df139d6..3c7ce1644280 100644 --- a/trunk/include/asm-blackfin/module.h +++ b/trunk/include/asm-blackfin/module.h @@ -6,6 +6,8 @@ #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr +#define FLG_CODE_IN_L1 0x10 +#define FLG_DATA_IN_L1 0x20 struct mod_arch_specific { Elf_Shdr *text_l1; @@ -13,8 +15,5 @@ struct mod_arch_specific { Elf_Shdr *bss_a_l1; Elf_Shdr *data_b_l1; Elf_Shdr *bss_b_l1; - Elf_Shdr *text_l2; - Elf_Shdr *data_l2; - Elf_Shdr *bss_l2; }; #endif /* _ASM_BFIN_MODULE_H */ diff --git a/trunk/include/asm-blackfin/namei.h b/trunk/include/asm-blackfin/namei.h new file mode 100644 index 000000000000..8b89a2d65cb4 --- /dev/null +++ b/trunk/include/asm-blackfin/namei.h @@ -0,0 +1,19 @@ +/* + * linux/include/asm/namei.h + * + * Included from linux/fs/namei.c + * + * Changes made by Lineo Inc. May 2001 + */ + +#ifndef __BFIN_NAMEI_H +#define __BFIN_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif diff --git a/trunk/include/asm-blackfin/processor.h b/trunk/include/asm-blackfin/processor.h index 6f3995b119d8..1c0040724612 100644 --- a/trunk/include/asm-blackfin/processor.h +++ b/trunk/include/asm-blackfin/processor.h @@ -112,26 +112,7 @@ unsigned long get_wchan(struct task_struct *p); static inline uint32_t __pure bfin_revid(void) { /* stored in the upper 4 bits */ - uint32_t revid = bfin_read_CHIPID() >> 28; - -#ifdef CONFIG_BF52x - /* ANOMALY_05000357 - * Incorrect Revision Number in DSPID Register - */ - if (revid == 0) - switch (bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI)) { - case 0x0010: - revid = 0; - break; - case 0x2796: - revid = 1; - break; - default: - revid = 0xFFFF; - break; - } -#endif - return revid; + return bfin_read_CHIPID() >> 28; } static inline uint32_t __pure bfin_compiled_revid(void) diff --git a/trunk/include/asm-cris/dma-mapping.h b/trunk/include/asm-cris/dma-mapping.h index cb2fb25ff8d9..edc8d1bfaae2 100644 --- a/trunk/include/asm-cris/dma-mapping.h +++ b/trunk/include/asm-cris/dma-mapping.h @@ -120,7 +120,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, } static inline int -dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +dma_mapping_error(dma_addr_t dma_addr) { return 0; } diff --git a/trunk/include/asm-cris/namei.h b/trunk/include/asm-cris/namei.h new file mode 100644 index 000000000000..8a3be7a6d9f6 --- /dev/null +++ b/trunk/include/asm-cris/namei.h @@ -0,0 +1,17 @@ +/* $Id: namei.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ + * linux/include/asm-cris/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __CRIS_NAMEI_H +#define __CRIS_NAMEI_H + +/* used to find file-system prefixes for doing emulations + * see for example asm-sparc/namei.h + * we don't use it... + */ + +#define __emul_prefix() NULL + +#endif /* __CRIS_NAMEI_H */ diff --git a/trunk/include/asm-frv/dma-mapping.h b/trunk/include/asm-frv/dma-mapping.h index b2898877c07b..2e8966ca030d 100644 --- a/trunk/include/asm-frv/dma-mapping.h +++ b/trunk/include/asm-frv/dma-mapping.h @@ -126,7 +126,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele } static inline -int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +int dma_mapping_error(dma_addr_t dma_addr) { return 0; } diff --git a/trunk/include/asm-frv/namei.h b/trunk/include/asm-frv/namei.h new file mode 100644 index 000000000000..4ea57171d951 --- /dev/null +++ b/trunk/include/asm-frv/namei.h @@ -0,0 +1,18 @@ +/* + * include/asm-frv/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __ASM_NAMEI_H +#define __ASM_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif + diff --git a/trunk/include/asm-generic/dma-mapping-broken.h b/trunk/include/asm-generic/dma-mapping-broken.h index 82cd0cb1c3fe..e2468f894d2a 100644 --- a/trunk/include/asm-generic/dma-mapping-broken.h +++ b/trunk/include/asm-generic/dma-mapping-broken.h @@ -61,7 +61,7 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, #define dma_sync_sg_for_device dma_sync_sg_for_cpu extern int -dma_mapping_error(struct device *dev, dma_addr_t dma_addr); +dma_mapping_error(dma_addr_t dma_addr); extern int dma_supported(struct device *dev, u64 mask); diff --git a/trunk/include/asm-generic/dma-mapping.h b/trunk/include/asm-generic/dma-mapping.h index 189486c3f92e..783ab9944d70 100644 --- a/trunk/include/asm-generic/dma-mapping.h +++ b/trunk/include/asm-generic/dma-mapping.h @@ -144,9 +144,9 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, } static inline int -dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +dma_mapping_error(dma_addr_t dma_addr) { - return pci_dma_mapping_error(to_pci_dev(dev), dma_addr); + return pci_dma_mapping_error(dma_addr); } diff --git a/trunk/include/asm-generic/gpio.h b/trunk/include/asm-generic/gpio.h index c764a8fcb058..a3034d20ebd5 100644 --- a/trunk/include/asm-generic/gpio.h +++ b/trunk/include/asm-generic/gpio.h @@ -13,7 +13,7 @@ * * While the GPIO programming interface defines valid GPIO numbers * to be in the range 0..MAX_INT, this library restricts them to the - * smaller range 0..ARCH_NR_GPIOS-1. + * smaller range 0..ARCH_NR_GPIOS. */ #ifndef ARCH_NR_GPIOS diff --git a/trunk/include/asm-generic/pci-dma-compat.h b/trunk/include/asm-generic/pci-dma-compat.h index 37b3706226e7..25c10e96b2b7 100644 --- a/trunk/include/asm-generic/pci-dma-compat.h +++ b/trunk/include/asm-generic/pci-dma-compat.h @@ -99,9 +99,9 @@ pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, } static inline int -pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) +pci_dma_mapping_error(dma_addr_t dma_addr) { - return dma_mapping_error(&pdev->dev, dma_addr); + return dma_mapping_error(dma_addr); } #endif diff --git a/trunk/include/asm-generic/syscall.h b/trunk/include/asm-generic/syscall.h deleted file mode 100644 index abcf34c2fdc7..000000000000 --- a/trunk/include/asm-generic/syscall.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Access to user system call parameters and results - * - * Copyright (C) 2008 Red Hat, Inc. All rights reserved. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU General Public License v.2. - * - * This file is a stub providing documentation for what functions - * asm-ARCH/syscall.h files need to define. Most arch definitions - * will be simple inlines. - * - * All of these functions expect to be called with no locks, - * and only when the caller is sure that the task of interest - * cannot return to user mode while we are looking at it. - */ - -#ifndef _ASM_SYSCALL_H -#define _ASM_SYSCALL_H 1 - -struct task_struct; -struct pt_regs; - -/** - * syscall_get_nr - find what system call a task is executing - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * - * If @task is executing a system call or is at system call - * tracing about to attempt one, returns the system call number. - * If @task is not executing a system call, i.e. it's blocked - * inside the kernel for a fault or signal, returns -1. - * - * It's only valid to call this when @task is known to be blocked. - */ -long syscall_get_nr(struct task_struct *task, struct pt_regs *regs); - -/** - * syscall_rollback - roll back registers after an aborted system call - * @task: task of interest, must be in system call exit tracing - * @regs: task_pt_regs() of @task - * - * It's only valid to call this when @task is stopped for system - * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT), - * after tracehook_report_syscall_entry() returned nonzero to prevent - * the system call from taking place. - * - * This rolls back the register state in @regs so it's as if the - * system call instruction was a no-op. The registers containing - * the system call number and arguments are as they were before the - * system call instruction. This may not be the same as what the - * register state looked like at system call entry tracing. - */ -void syscall_rollback(struct task_struct *task, struct pt_regs *regs); - -/** - * syscall_get_error - check result of traced system call - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * - * Returns 0 if the system call succeeded, or -ERRORCODE if it failed. - * - * It's only valid to call this when @task is stopped for tracing on exit - * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - */ -long syscall_get_error(struct task_struct *task, struct pt_regs *regs); - -/** - * syscall_get_return_value - get the return value of a traced system call - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * - * Returns the return value of the successful system call. - * This value is meaningless if syscall_get_error() returned nonzero. - * - * It's only valid to call this when @task is stopped for tracing on exit - * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - */ -long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs); - -/** - * syscall_set_return_value - change the return value of a traced system call - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * @error: negative error code, or zero to indicate success - * @val: user return value if @error is zero - * - * This changes the results of the system call that user mode will see. - * If @error is zero, the user sees a successful system call with a - * return value of @val. If @error is nonzero, it's a negated errno - * code; the user sees a failed system call with this errno code. - * - * It's only valid to call this when @task is stopped for tracing on exit - * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - */ -void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, - int error, long val); - -/** - * syscall_get_arguments - extract system call parameter values - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * @i: argument index [0,5] - * @n: number of arguments; n+i must be [1,6]. - * @args: array filled with argument values - * - * Fetches @n arguments to the system call starting with the @i'th argument - * (from 0 through 5). Argument @i is stored in @args[0], and so on. - * An arch inline version is probably optimal when @i and @n are constants. - * - * It's only valid to call this when @task is stopped for tracing on - * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - * It's invalid to call this with @i + @n > 6; we only support system calls - * taking up to 6 arguments. - */ -void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, - unsigned int i, unsigned int n, unsigned long *args); - -/** - * syscall_set_arguments - change system call parameter value - * @task: task of interest, must be in system call entry tracing - * @regs: task_pt_regs() of @task - * @i: argument index [0,5] - * @n: number of arguments; n+i must be [1,6]. - * @args: array of argument values to store - * - * Changes @n arguments to the system call starting with the @i'th argument. - * @n'th argument to @val. Argument @i gets value @args[0], and so on. - * An arch inline version is probably optimal when @i and @n are constants. - * - * It's only valid to call this when @task is stopped for tracing on - * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - * It's invalid to call this with @i + @n > 6; we only support system calls - * taking up to 6 arguments. - */ -void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, - unsigned int i, unsigned int n, - const unsigned long *args); - -#endif /* _ASM_SYSCALL_H */ diff --git a/trunk/include/asm-generic/vmlinux.lds.h b/trunk/include/asm-generic/vmlinux.lds.h index 6d88a923c945..729f6b0a60e9 100644 --- a/trunk/include/asm-generic/vmlinux.lds.h +++ b/trunk/include/asm-generic/vmlinux.lds.h @@ -221,7 +221,6 @@ * during second ld run in second ld pass when generating System.map */ #define TEXT_TEXT \ ALIGN_FUNCTION(); \ - *(.text.hot) \ *(.text) \ *(.ref.text) \ *(.text.init.refok) \ @@ -231,8 +230,7 @@ CPU_KEEP(init.text) \ CPU_KEEP(exit.text) \ MEM_KEEP(init.text) \ - MEM_KEEP(exit.text) \ - *(.text.unlikely) + MEM_KEEP(exit.text) /* sched.text is aling to function alignment to secure we have same @@ -361,8 +359,6 @@ } #define INITCALLS \ - *(.initcallearly.init) \ - __early_initcall_end = .; \ *(.initcall0.init) \ *(.initcall0s.init) \ *(.initcall1.init) \ diff --git a/trunk/include/asm-h8300/namei.h b/trunk/include/asm-h8300/namei.h new file mode 100644 index 000000000000..ab6f196db6e0 --- /dev/null +++ b/trunk/include/asm-h8300/namei.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-h8300/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __H8300_NAMEI_H +#define __H8300_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif diff --git a/trunk/include/asm-ia64/machvec.h b/trunk/include/asm-ia64/machvec.h index a6d50c77b6bf..0721a5e8271e 100644 --- a/trunk/include/asm-ia64/machvec.h +++ b/trunk/include/asm-ia64/machvec.h @@ -54,7 +54,7 @@ typedef void ia64_mv_dma_sync_single_for_cpu (struct device *, dma_addr_t, size_ typedef void ia64_mv_dma_sync_sg_for_cpu (struct device *, struct scatterlist *, int, int); typedef void ia64_mv_dma_sync_single_for_device (struct device *, dma_addr_t, size_t, int); typedef void ia64_mv_dma_sync_sg_for_device (struct device *, struct scatterlist *, int, int); -typedef int ia64_mv_dma_mapping_error(struct device *, dma_addr_t dma_addr); +typedef int ia64_mv_dma_mapping_error (dma_addr_t dma_addr); typedef int ia64_mv_dma_supported (struct device *, u64); typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t, int, struct dma_attrs *); diff --git a/trunk/include/asm-ia64/namei.h b/trunk/include/asm-ia64/namei.h new file mode 100644 index 000000000000..78e768079083 --- /dev/null +++ b/trunk/include/asm-ia64/namei.h @@ -0,0 +1,25 @@ +#ifndef _ASM_IA64_NAMEI_H +#define _ASM_IA64_NAMEI_H + +/* + * Modified 1998, 1999, 2001 + * David Mosberger-Tang , Hewlett-Packard Co + */ + +#include +#include + +#define EMUL_PREFIX_LINUX_IA32 "/emul/ia32-linux/" + +static inline char * +__emul_prefix (void) +{ + switch (current->personality) { + case PER_LINUX32: + return EMUL_PREFIX_LINUX_IA32; + default: + return NULL; + } +} + +#endif /* _ASM_IA64_NAMEI_H */ diff --git a/trunk/include/asm-m32r/namei.h b/trunk/include/asm-m32r/namei.h new file mode 100644 index 000000000000..210f8056b805 --- /dev/null +++ b/trunk/include/asm-m32r/namei.h @@ -0,0 +1,17 @@ +#ifndef _ASM_M32R_NAMEI_H +#define _ASM_M32R_NAMEI_H + +/* + * linux/include/asm-m32r/namei.h + * + * Included from linux/fs/namei.c + */ + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* _ASM_M32R_NAMEI_H */ diff --git a/trunk/include/asm-m68k/dma-mapping.h b/trunk/include/asm-m68k/dma-mapping.h index 91f7944333d4..a26cdeb46a57 100644 --- a/trunk/include/asm-m68k/dma-mapping.h +++ b/trunk/include/asm-m68k/dma-mapping.h @@ -84,7 +84,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *s { } -static inline int dma_mapping_error(struct device *dev, dma_addr_t handle) +static inline int dma_mapping_error(dma_addr_t handle) { return 0; } diff --git a/trunk/include/asm-m68k/namei.h b/trunk/include/asm-m68k/namei.h new file mode 100644 index 000000000000..f33f243b644a --- /dev/null +++ b/trunk/include/asm-m68k/namei.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-m68k/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __M68K_NAMEI_H +#define __M68K_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif diff --git a/trunk/include/asm-m68knommu/namei.h b/trunk/include/asm-m68knommu/namei.h new file mode 100644 index 000000000000..31a85d27b931 --- /dev/null +++ b/trunk/include/asm-m68knommu/namei.h @@ -0,0 +1 @@ +#include diff --git a/trunk/include/asm-mips/dma-mapping.h b/trunk/include/asm-mips/dma-mapping.h index c64afb40cd06..230b3f1b69b1 100644 --- a/trunk/include/asm-mips/dma-mapping.h +++ b/trunk/include/asm-mips/dma-mapping.h @@ -42,7 +42,7 @@ extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); -extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr); +extern int dma_mapping_error(dma_addr_t dma_addr); extern int dma_supported(struct device *dev, u64 mask); static inline int diff --git a/trunk/include/asm-mips/namei.h b/trunk/include/asm-mips/namei.h new file mode 100644 index 000000000000..a6605a752469 --- /dev/null +++ b/trunk/include/asm-mips/namei.h @@ -0,0 +1,11 @@ +#ifndef _ASM_NAMEI_H +#define _ASM_NAMEI_H + +/* + * This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + */ + +#define __emul_prefix() NULL + +#endif /* _ASM_NAMEI_H */ diff --git a/trunk/include/asm-mn10300/dma-mapping.h b/trunk/include/asm-mn10300/dma-mapping.h index ccae8f6c6326..7c882fca9ec8 100644 --- a/trunk/include/asm-mn10300/dma-mapping.h +++ b/trunk/include/asm-mn10300/dma-mapping.h @@ -182,7 +182,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } static inline -int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +int dma_mapping_error(dma_addr_t dma_addr) { return 0; } diff --git a/trunk/include/asm-mn10300/namei.h b/trunk/include/asm-mn10300/namei.h new file mode 100644 index 000000000000..bd9ce94aeb65 --- /dev/null +++ b/trunk/include/asm-mn10300/namei.h @@ -0,0 +1,22 @@ +/* Emulation stuff + * + * Copyright (C) 2007 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 Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_NAMEI_H +#define _ASM_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* _ASM_NAMEI_H */ diff --git a/trunk/include/asm-parisc/cacheflush.h b/trunk/include/asm-parisc/cacheflush.h index b7ca6dc7fddc..2f1e1b05440a 100644 --- a/trunk/include/asm-parisc/cacheflush.h +++ b/trunk/include/asm-parisc/cacheflush.h @@ -45,9 +45,9 @@ void flush_cache_mm(struct mm_struct *mm); extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping) \ - spin_lock_irq(&(mapping)->tree_lock) + write_lock_irq(&(mapping)->tree_lock) #define flush_dcache_mmap_unlock(mapping) \ - spin_unlock_irq(&(mapping)->tree_lock) + write_unlock_irq(&(mapping)->tree_lock) #define flush_icache_page(vma,page) do { \ flush_kernel_dcache_page(page); \ diff --git a/trunk/include/asm-parisc/dma-mapping.h b/trunk/include/asm-parisc/dma-mapping.h index 53af696f23d2..c6c0e9ff6bde 100644 --- a/trunk/include/asm-parisc/dma-mapping.h +++ b/trunk/include/asm-parisc/dma-mapping.h @@ -248,6 +248,6 @@ void * sba_get_iommu(struct parisc_device *dev); #endif /* At the moment, we panic on error for IOMMU resource exaustion */ -#define dma_mapping_error(dev, x) 0 +#define dma_mapping_error(x) 0 #endif diff --git a/trunk/include/asm-parisc/namei.h b/trunk/include/asm-parisc/namei.h new file mode 100644 index 000000000000..8d29b3d9fb33 --- /dev/null +++ b/trunk/include/asm-parisc/namei.h @@ -0,0 +1,17 @@ +/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $ + * linux/include/asm-parisc/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __PARISC_NAMEI_H +#define __PARISC_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __PARISC_NAMEI_H */ diff --git a/trunk/include/asm-powerpc/dma-mapping.h b/trunk/include/asm-powerpc/dma-mapping.h index c7ca45f97dd2..74c549780987 100644 --- a/trunk/include/asm-powerpc/dma-mapping.h +++ b/trunk/include/asm-powerpc/dma-mapping.h @@ -415,7 +415,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); } -static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +static inline int dma_mapping_error(dma_addr_t dma_addr) { #ifdef CONFIG_PPC64 return (dma_addr == DMA_ERROR_CODE); diff --git a/trunk/include/asm-powerpc/kvm_ppc.h b/trunk/include/asm-powerpc/kvm_ppc.h index a8b068792260..5a21115228af 100644 --- a/trunk/include/asm-powerpc/kvm_ppc.h +++ b/trunk/include/asm-powerpc/kvm_ppc.h @@ -61,8 +61,7 @@ extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, u32 flags); -extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, - gva_t eend, u32 asid); +extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid); extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu); diff --git a/trunk/include/asm-powerpc/namei.h b/trunk/include/asm-powerpc/namei.h new file mode 100644 index 000000000000..657443474a6a --- /dev/null +++ b/trunk/include/asm-powerpc/namei.h @@ -0,0 +1,20 @@ +#ifndef _ASM_POWERPC_NAMEI_H +#define _ASM_POWERPC_NAMEI_H + +#ifdef __KERNEL__ + +/* + * Adapted from include/asm-alpha/namei.h + * + * Included from fs/namei.c + */ + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_NAMEI_H */ diff --git a/trunk/include/asm-s390/kvm_host.h b/trunk/include/asm-s390/kvm_host.h index 3c55e4107dcc..3234dd5b3511 100644 --- a/trunk/include/asm-s390/kvm_host.h +++ b/trunk/include/asm-s390/kvm_host.h @@ -111,7 +111,7 @@ struct kvm_vcpu_stat { u32 exit_validity; u32 exit_instruction; u32 instruction_lctl; - u32 instruction_lctlg; + u32 instruction_lctg; u32 exit_program_interruption; u32 exit_instr_and_program; u32 deliver_emergency_signal; @@ -231,5 +231,5 @@ struct kvm_arch{ struct kvm_s390_float_interrupt float_int; }; -extern int sie64a(struct kvm_s390_sie_block *, unsigned long *); +extern int sie64a(struct kvm_s390_sie_block *, __u64 *); #endif diff --git a/trunk/include/asm-s390/namei.h b/trunk/include/asm-s390/namei.h new file mode 100644 index 000000000000..3e286bdde4b0 --- /dev/null +++ b/trunk/include/asm-s390/namei.h @@ -0,0 +1,21 @@ +/* + * include/asm-s390/namei.h + * + * S390 version + * + * Derived from "include/asm-i386/namei.h" + * + * Included from linux/fs/namei.c + */ + +#ifndef __S390_NAMEI_H +#define __S390_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __S390_NAMEI_H */ diff --git a/trunk/include/asm-sh/dma-mapping.h b/trunk/include/asm-sh/dma-mapping.h index 6c0b8a2de143..22cc419389fe 100644 --- a/trunk/include/asm-sh/dma-mapping.h +++ b/trunk/include/asm-sh/dma-mapping.h @@ -171,7 +171,7 @@ static inline int dma_get_cache_alignment(void) return L1_CACHE_BYTES; } -static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +static inline int dma_mapping_error(dma_addr_t dma_addr) { return dma_addr == 0; } diff --git a/trunk/include/asm-sh/namei.h b/trunk/include/asm-sh/namei.h new file mode 100644 index 000000000000..338a5d947143 --- /dev/null +++ b/trunk/include/asm-sh/namei.h @@ -0,0 +1,17 @@ +/* $Id: namei.h,v 1.3 2000/07/04 06:24:49 gniibe Exp $ + * linux/include/asm-sh/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __ASM_SH_NAMEI_H +#define __ASM_SH_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __ASM_SH_NAMEI_H */ diff --git a/trunk/include/asm-sparc/dma-mapping_64.h b/trunk/include/asm-sparc/dma-mapping_64.h index bfa64f9702d5..38cbec76a33f 100644 --- a/trunk/include/asm-sparc/dma-mapping_64.h +++ b/trunk/include/asm-sparc/dma-mapping_64.h @@ -135,7 +135,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, /* No flushing needed to sync cpu writes to the device. */ } -static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +static inline int dma_mapping_error(dma_addr_t dma_addr) { return (dma_addr == DMA_ERROR_CODE); } diff --git a/trunk/include/asm-sparc/namei.h b/trunk/include/asm-sparc/namei.h new file mode 100644 index 000000000000..eff944b8e321 --- /dev/null +++ b/trunk/include/asm-sparc/namei.h @@ -0,0 +1,8 @@ +#ifndef ___ASM_SPARC_NAMEI_H +#define ___ASM_SPARC_NAMEI_H +#if defined(__sparc__) && defined(__arch64__) +#include +#else +#include +#endif +#endif diff --git a/trunk/include/asm-sparc/namei_32.h b/trunk/include/asm-sparc/namei_32.h new file mode 100644 index 000000000000..0646102fb020 --- /dev/null +++ b/trunk/include/asm-sparc/namei_32.h @@ -0,0 +1,13 @@ +/* + * linux/include/asm-sparc/namei.h + * + * Routines to handle famous /usr/gnemul/s*. + * Included from linux/fs/namei.c + */ + +#ifndef __SPARC_NAMEI_H +#define __SPARC_NAMEI_H + +#define __emul_prefix() NULL + +#endif /* __SPARC_NAMEI_H */ diff --git a/trunk/include/asm-sparc/namei_64.h b/trunk/include/asm-sparc/namei_64.h new file mode 100644 index 000000000000..cbc1b4c06891 --- /dev/null +++ b/trunk/include/asm-sparc/namei_64.h @@ -0,0 +1,13 @@ +/* + * linux/include/asm-sparc64/namei.h + * + * Routines to handle famous /usr/gnemul/s*. + * Included from linux/fs/namei.c + */ + +#ifndef __SPARC64_NAMEI_H +#define __SPARC64_NAMEI_H + +#define __emul_prefix() NULL + +#endif /* __SPARC64_NAMEI_H */ diff --git a/trunk/include/asm-sparc/pci_32.h b/trunk/include/asm-sparc/pci_32.h index 0ee949d220c0..b93b6c79e08f 100644 --- a/trunk/include/asm-sparc/pci_32.h +++ b/trunk/include/asm-sparc/pci_32.h @@ -154,8 +154,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, #define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0) -static inline int pci_dma_mapping_error(struct pci_dev *pdev, - dma_addr_t dma_addr) +static inline int pci_dma_mapping_error(dma_addr_t dma_addr) { return (dma_addr == PCI_DMA_ERROR_CODE); } diff --git a/trunk/include/asm-sparc/pci_64.h b/trunk/include/asm-sparc/pci_64.h index 4f79a54948f6..f59f2571295b 100644 --- a/trunk/include/asm-sparc/pci_64.h +++ b/trunk/include/asm-sparc/pci_64.h @@ -140,10 +140,9 @@ extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask); #define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) #define PCI64_ADDR_BASE 0xfffc000000000000UL -static inline int pci_dma_mapping_error(struct pci_dev *pdev, - dma_addr_t dma_addr) +static inline int pci_dma_mapping_error(dma_addr_t dma_addr) { - return dma_mapping_error(&pdev->dev, dma_addr); + return dma_mapping_error(dma_addr); } #ifdef CONFIG_PCI diff --git a/trunk/include/asm-sparc64/namei.h b/trunk/include/asm-sparc64/namei.h new file mode 100644 index 000000000000..1344a910ba2f --- /dev/null +++ b/trunk/include/asm-sparc64/namei.h @@ -0,0 +1 @@ +#include diff --git a/trunk/include/asm-um/namei.h b/trunk/include/asm-um/namei.h new file mode 100644 index 000000000000..002984d5bc85 --- /dev/null +++ b/trunk/include/asm-um/namei.h @@ -0,0 +1,6 @@ +#ifndef __UM_NAMEI_H +#define __UM_NAMEI_H + +#include "asm/arch/namei.h" + +#endif diff --git a/trunk/include/asm-v850/namei.h b/trunk/include/asm-v850/namei.h new file mode 100644 index 000000000000..ee8339b23843 --- /dev/null +++ b/trunk/include/asm-v850/namei.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-v850/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __V850_NAMEI_H__ +#define __V850_NAMEI_H__ + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __V850_NAMEI_H__ */ diff --git a/trunk/include/asm-x86/device.h b/trunk/include/asm-x86/device.h index 3c034f48fdb0..87a715367a1b 100644 --- a/trunk/include/asm-x86/device.h +++ b/trunk/include/asm-x86/device.h @@ -5,9 +5,6 @@ struct dev_archdata { #ifdef CONFIG_ACPI void *acpi_handle; #endif -#ifdef CONFIG_X86_64 -struct dma_mapping_ops *dma_ops; -#endif #ifdef CONFIG_DMAR void *iommu; /* hook for IOMMU specific extension */ #endif diff --git a/trunk/include/asm-x86/dma-mapping.h b/trunk/include/asm-x86/dma-mapping.h index 0eaa9bf6011f..c2ddd3d1b883 100644 --- a/trunk/include/asm-x86/dma-mapping.h +++ b/trunk/include/asm-x86/dma-mapping.h @@ -17,8 +17,7 @@ extern int panic_on_overflow; extern int force_iommu; struct dma_mapping_ops { - int (*mapping_error)(struct device *dev, - dma_addr_t dma_addr); + int (*mapping_error)(dma_addr_t dma_addr); void* (*alloc_coherent)(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp); void (*free_coherent)(struct device *dev, size_t size, @@ -57,32 +56,14 @@ struct dma_mapping_ops { int is_phys; }; -extern struct dma_mapping_ops *dma_ops; +extern const struct dma_mapping_ops *dma_ops; -static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) +static inline int dma_mapping_error(dma_addr_t dma_addr) { -#ifdef CONFIG_X86_32 - return dma_ops; -#else - if (unlikely(!dev) || !dev->archdata.dma_ops) - return dma_ops; - else - return dev->archdata.dma_ops; -#endif -} - -/* Make sure we keep the same behaviour */ -static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ -#ifdef CONFIG_X86_32 - return 0; -#else - struct dma_mapping_ops *ops = get_dma_ops(dev); - if (ops->mapping_error) - return ops->mapping_error(dev, dma_addr); + if (dma_ops->mapping_error) + return dma_ops->mapping_error(dma_addr); return (dma_addr == bad_dma_address); -#endif } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) @@ -102,53 +83,44 @@ static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - return ops->map_single(hwdev, virt_to_phys(ptr), size, direction); + return dma_ops->map_single(hwdev, virt_to_phys(ptr), size, direction); } static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(dev); - BUG_ON(!valid_dma_direction(direction)); - if (ops->unmap_single) - ops->unmap_single(dev, addr, size, direction); + if (dma_ops->unmap_single) + dma_ops->unmap_single(dev, addr, size, direction); } static inline int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - return ops->map_sg(hwdev, sg, nents, direction); + return dma_ops->map_sg(hwdev, sg, nents, direction); } static inline void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - if (ops->unmap_sg) - ops->unmap_sg(hwdev, sg, nents, direction); + if (dma_ops->unmap_sg) + dma_ops->unmap_sg(hwdev, sg, nents, direction); } static inline void dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - if (ops->sync_single_for_cpu) - ops->sync_single_for_cpu(hwdev, dma_handle, size, direction); + if (dma_ops->sync_single_for_cpu) + dma_ops->sync_single_for_cpu(hwdev, dma_handle, size, + direction); flush_write_buffers(); } @@ -156,11 +128,10 @@ static inline void dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - if (ops->sync_single_for_device) - ops->sync_single_for_device(hwdev, dma_handle, size, direction); + if (dma_ops->sync_single_for_device) + dma_ops->sync_single_for_device(hwdev, dma_handle, size, + direction); flush_write_buffers(); } @@ -168,12 +139,11 @@ static inline void dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - if (ops->sync_single_range_for_cpu) - ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, - size, direction); + if (dma_ops->sync_single_range_for_cpu) + dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, + size, direction); + flush_write_buffers(); } @@ -182,12 +152,11 @@ dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - if (ops->sync_single_range_for_device) - ops->sync_single_range_for_device(hwdev, dma_handle, - offset, size, direction); + if (dma_ops->sync_single_range_for_device) + dma_ops->sync_single_range_for_device(hwdev, dma_handle, + offset, size, direction); + flush_write_buffers(); } @@ -195,11 +164,9 @@ static inline void dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - if (ops->sync_sg_for_cpu) - ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); + if (dma_ops->sync_sg_for_cpu) + dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); flush_write_buffers(); } @@ -207,11 +174,9 @@ static inline void dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(direction)); - if (ops->sync_sg_for_device) - ops->sync_sg_for_device(hwdev, sg, nelems, direction); + if (dma_ops->sync_sg_for_device) + dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction); flush_write_buffers(); } @@ -220,11 +185,9 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, size_t offset, size_t size, int direction) { - struct dma_mapping_ops *ops = get_dma_ops(dev); - BUG_ON(!valid_dma_direction(direction)); - return ops->map_single(dev, page_to_phys(page) + offset, - size, direction); + return dma_ops->map_single(dev, page_to_phys(page)+offset, + size, direction); } static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, diff --git a/trunk/include/asm-x86/gpio.h b/trunk/include/asm-x86/gpio.h index c4c91b37c104..116e9147fe66 100644 --- a/trunk/include/asm-x86/gpio.h +++ b/trunk/include/asm-x86/gpio.h @@ -16,6 +16,10 @@ #ifndef _ASM_I386_GPIO_H #define _ASM_I386_GPIO_H +#ifdef CONFIG_X86_RDC321X +#include +#else /* CONFIG_X86_RDC321X */ + #include #ifdef CONFIG_GPIOLIB @@ -53,4 +57,6 @@ static inline int irq_to_gpio(unsigned int irq) #endif /* CONFIG_GPIOLIB */ +#endif /* CONFIG_X86_RDC321X */ + #endif /* _ASM_I386_GPIO_H */ diff --git a/trunk/include/asm-x86/iommu.h b/trunk/include/asm-x86/iommu.h index ecc8061904a9..d63166fb3ab7 100644 --- a/trunk/include/asm-x86/iommu.h +++ b/trunk/include/asm-x86/iommu.h @@ -3,7 +3,6 @@ extern void pci_iommu_shutdown(void); extern void no_iommu_init(void); -extern struct dma_mapping_ops nommu_dma_ops; extern int force_iommu, no_iommu; extern int iommu_detected; diff --git a/trunk/include/asm-x86/kexec.h b/trunk/include/asm-x86/kexec.h index c0e52a14fd4d..8f855a15f64d 100644 --- a/trunk/include/asm-x86/kexec.h +++ b/trunk/include/asm-x86/kexec.h @@ -10,15 +10,14 @@ # define VA_PTE_0 5 # define PA_PTE_1 6 # define VA_PTE_1 7 -# define PA_SWAP_PAGE 8 # ifdef CONFIG_X86_PAE -# define PA_PMD_0 9 -# define VA_PMD_0 10 -# define PA_PMD_1 11 -# define VA_PMD_1 12 -# define PAGES_NR 13 +# define PA_PMD_0 8 +# define VA_PMD_0 9 +# define PA_PMD_1 10 +# define VA_PMD_1 11 +# define PAGES_NR 12 # else -# define PAGES_NR 9 +# define PAGES_NR 8 # endif #else # define PA_CONTROL_PAGE 0 @@ -153,12 +152,11 @@ static inline void crash_setup_regs(struct pt_regs *newregs, } #ifdef CONFIG_X86_32 -asmlinkage unsigned long +asmlinkage NORET_TYPE void relocate_kernel(unsigned long indirection_page, unsigned long control_page, unsigned long start_address, - unsigned int has_pae, - unsigned int preserve_context); + unsigned int has_pae) ATTRIB_NORET; #else NORET_TYPE void relocate_kernel(unsigned long indirection_page, diff --git a/trunk/include/asm-x86/kvm_host.h b/trunk/include/asm-x86/kvm_host.h index bc34dc21f178..fdde0bedaa90 100644 --- a/trunk/include/asm-x86/kvm_host.h +++ b/trunk/include/asm-x86/kvm_host.h @@ -556,7 +556,6 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu); int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code); void kvm_enable_tdp(void); -void kvm_disable_tdp(void); int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); int complete_pio(struct kvm_vcpu *vcpu); diff --git a/trunk/include/asm-x86/mach-summit/mach_apic.h b/trunk/include/asm-x86/mach-summit/mach_apic.h index c47e2ab5c5ca..75d2c95005d7 100644 --- a/trunk/include/asm-x86/mach-summit/mach_apic.h +++ b/trunk/include/asm-x86/mach-summit/mach_apic.h @@ -122,7 +122,7 @@ static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_id_map) static inline physid_mask_t apicid_to_cpu_present(int apicid) { - return physid_mask_of_physid(apicid); + return physid_mask_of_physid(0); } static inline void setup_portio_remap(void) diff --git a/trunk/include/asm-x86/namei.h b/trunk/include/asm-x86/namei.h new file mode 100644 index 000000000000..415ef5d9550e --- /dev/null +++ b/trunk/include/asm-x86/namei.h @@ -0,0 +1,11 @@ +#ifndef _ASM_X86_NAMEI_H +#define _ASM_X86_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* _ASM_X86_NAMEI_H */ diff --git a/trunk/include/asm-x86/pgtable.h b/trunk/include/asm-x86/pgtable.h index 04caa2f544df..3e5dbc4195f4 100644 --- a/trunk/include/asm-x86/pgtable.h +++ b/trunk/include/asm-x86/pgtable.h @@ -18,7 +18,6 @@ #define _PAGE_BIT_UNUSED2 10 #define _PAGE_BIT_UNUSED3 11 #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ -#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ #define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT) @@ -35,8 +34,6 @@ #define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3) #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT) #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) -#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL) -#define __HAVE_ARCH_PTE_SPECIAL #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) @@ -57,7 +54,7 @@ /* Set of bits not changed in pte_modify */ #define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ - _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY) + _PAGE_ACCESSED | _PAGE_DIRTY) #define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) #define _PAGE_CACHE_WB (0) @@ -183,7 +180,7 @@ static inline int pte_exec(pte_t pte) static inline int pte_special(pte_t pte) { - return pte_val(pte) & _PAGE_SPECIAL; + return 0; } static inline int pmd_large(pmd_t pte) @@ -249,7 +246,7 @@ static inline pte_t pte_clrglobal(pte_t pte) static inline pte_t pte_mkspecial(pte_t pte) { - return __pte(pte_val(pte) | _PAGE_SPECIAL); + return pte; } extern pteval_t __supported_pte_mask; diff --git a/trunk/include/asm-x86/swiotlb.h b/trunk/include/asm-x86/swiotlb.h index 2730b351afcf..c706a7442633 100644 --- a/trunk/include/asm-x86/swiotlb.h +++ b/trunk/include/asm-x86/swiotlb.h @@ -35,7 +35,7 @@ extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction); -extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); +extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr); extern void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); extern int swiotlb_dma_supported(struct device *hwdev, u64 mask); diff --git a/trunk/include/asm-x86/uaccess.h b/trunk/include/asm-x86/uaccess.h index 5f702d1d5218..f6fa4d841bbc 100644 --- a/trunk/include/asm-x86/uaccess.h +++ b/trunk/include/asm-x86/uaccess.h @@ -451,4 +451,3 @@ extern struct movsl_mask { #endif #endif - diff --git a/trunk/include/asm-xtensa/dma-mapping.h b/trunk/include/asm-xtensa/dma-mapping.h index 51882ae3db4d..3c7d537dd15d 100644 --- a/trunk/include/asm-xtensa/dma-mapping.h +++ b/trunk/include/asm-xtensa/dma-mapping.h @@ -139,7 +139,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, consistent_sync(sg_virt(sg), sg->length, dir); } static inline int -dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +dma_mapping_error(dma_addr_t dma_addr) { return 0; } diff --git a/trunk/include/asm-xtensa/namei.h b/trunk/include/asm-xtensa/namei.h new file mode 100644 index 000000000000..3fdff039d27d --- /dev/null +++ b/trunk/include/asm-xtensa/namei.h @@ -0,0 +1,26 @@ +/* + * include/asm-xtensa/namei.h + * + * Included from linux/fs/namei.c + * + * 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) 2001 - 2005 Tensilica Inc. + */ + +#ifndef _XTENSA_NAMEI_H +#define _XTENSA_NAMEI_H + +#ifdef __KERNEL__ + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __KERNEL__ */ +#endif /* _XTENSA_NAMEI_H */ diff --git a/trunk/include/linux/aio.h b/trunk/include/linux/aio.h index 09b276c35227..b51ddd28444e 100644 --- a/trunk/include/linux/aio.h +++ b/trunk/include/linux/aio.h @@ -7,6 +7,7 @@ #include #include +#include #define AIO_MAXSEGS 4 #define AIO_KIOGRP_NR_ATOMIC 8 diff --git a/trunk/include/linux/coda_linux.h b/trunk/include/linux/coda_linux.h index dcc228aa335a..31b75311e2ca 100644 --- a/trunk/include/linux/coda_linux.h +++ b/trunk/include/linux/coda_linux.h @@ -37,7 +37,7 @@ extern const struct file_operations coda_ioctl_operations; /* operations shared over more than one file */ int coda_open(struct inode *i, struct file *f); int coda_release(struct inode *i, struct file *f); -int coda_permission(struct inode *inode, int mask); +int coda_permission(struct inode *inode, int mask, struct nameidata *nd); int coda_revalidate_inode(struct dentry *); int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); int coda_setattr(struct dentry *, struct iattr *); diff --git a/trunk/include/linux/crash_dump.h b/trunk/include/linux/crash_dump.h index 025e4f575103..6cd39a927e1f 100644 --- a/trunk/include/linux/crash_dump.h +++ b/trunk/include/linux/crash_dump.h @@ -8,13 +8,7 @@ #include #define ELFCORE_ADDR_MAX (-1ULL) - -#ifdef CONFIG_PROC_VMCORE extern unsigned long long elfcorehdr_addr; -#else -static const unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; -#endif - extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, unsigned long, int); extern const struct file_operations proc_vmcore_operations; diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 8252b045e624..49d8eb7a71be 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -60,8 +60,6 @@ extern int dir_notify_enable; #define MAY_WRITE 2 #define MAY_READ 4 #define MAY_APPEND 8 -#define MAY_ACCESS 16 -#define MAY_OPEN 32 #define FMODE_READ 1 #define FMODE_WRITE 2 @@ -279,7 +277,7 @@ extern int dir_notify_enable; #include #include #include -#include +#include #include #include #include @@ -320,23 +318,22 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, * Attribute flags. These should be or-ed together to figure out what * has been changed! */ -#define ATTR_MODE (1 << 0) -#define ATTR_UID (1 << 1) -#define ATTR_GID (1 << 2) -#define ATTR_SIZE (1 << 3) -#define ATTR_ATIME (1 << 4) -#define ATTR_MTIME (1 << 5) -#define ATTR_CTIME (1 << 6) -#define ATTR_ATIME_SET (1 << 7) -#define ATTR_MTIME_SET (1 << 8) -#define ATTR_FORCE (1 << 9) /* Not a change, but a change it */ -#define ATTR_ATTR_FLAG (1 << 10) -#define ATTR_KILL_SUID (1 << 11) -#define ATTR_KILL_SGID (1 << 12) -#define ATTR_FILE (1 << 13) -#define ATTR_KILL_PRIV (1 << 14) -#define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */ -#define ATTR_TIMES_SET (1 << 16) +#define ATTR_MODE 1 +#define ATTR_UID 2 +#define ATTR_GID 4 +#define ATTR_SIZE 8 +#define ATTR_ATIME 16 +#define ATTR_MTIME 32 +#define ATTR_CTIME 64 +#define ATTR_ATIME_SET 128 +#define ATTR_MTIME_SET 256 +#define ATTR_FORCE 512 /* Not a change, but a change it */ +#define ATTR_ATTR_FLAG 1024 +#define ATTR_KILL_SUID 2048 +#define ATTR_KILL_SGID 4096 +#define ATTR_FILE 8192 +#define ATTR_KILL_PRIV 16384 +#define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */ /* * This is the Inode Attributes structure, used for notify_change(). It @@ -502,7 +499,7 @@ struct backing_dev_info; struct address_space { struct inode *host; /* owner: inode, block_device */ struct radix_tree_root page_tree; /* radix tree of all pages */ - spinlock_t tree_lock; /* and lock protecting it */ + rwlock_t tree_lock; /* and rwlock protecting it */ unsigned int i_mmap_writable;/* count VM_SHARED mappings */ struct prio_tree_root i_mmap; /* tree of private and shared mappings */ struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ @@ -795,7 +792,7 @@ struct file { #define f_dentry f_path.dentry #define f_vfsmnt f_path.mnt const struct file_operations *f_op; - atomic_long_t f_count; + atomic_t f_count; unsigned int f_flags; mode_t f_mode; loff_t f_pos; @@ -824,8 +821,8 @@ extern spinlock_t files_lock; #define file_list_lock() spin_lock(&files_lock); #define file_list_unlock() spin_unlock(&files_lock); -#define get_file(x) atomic_long_inc(&(x)->f_count) -#define file_count(x) atomic_long_read(&(x)->f_count) +#define get_file(x) atomic_inc(&(x)->f_count) +#define file_count(x) atomic_read(&(x)->f_count) #ifdef CONFIG_DEBUG_WRITECOUNT static inline void file_take_write(struct file *f) @@ -1139,7 +1136,7 @@ extern int vfs_permission(struct nameidata *, int); extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); extern int vfs_mkdir(struct inode *, struct dentry *, int); extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); -extern int vfs_symlink(struct inode *, struct dentry *, const char *); +extern int vfs_symlink(struct inode *, struct dentry *, const char *, int); extern int vfs_link(struct dentry *, struct inode *, struct dentry *); extern int vfs_rmdir(struct inode *, struct dentry *); extern int vfs_unlink(struct inode *, struct dentry *); @@ -1275,7 +1272,7 @@ struct inode_operations { void * (*follow_link) (struct dentry *, struct nameidata *); void (*put_link) (struct dentry *, struct nameidata *, void *); void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); + int (*permission) (struct inode *, int, struct nameidata *); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); @@ -1699,9 +1696,9 @@ extern void init_special_inode(struct inode *, umode_t, dev_t); extern void make_bad_inode(struct inode *); extern int is_bad_inode(struct inode *); -extern const struct file_operations read_pipefifo_fops; -extern const struct file_operations write_pipefifo_fops; -extern const struct file_operations rdwr_pipefifo_fops; +extern const struct file_operations read_fifo_fops; +extern const struct file_operations write_fifo_fops; +extern const struct file_operations rdwr_fifo_fops; extern int fs_may_remount_ro(struct super_block *); @@ -1770,7 +1767,7 @@ extern int do_remount_sb(struct super_block *sb, int flags, extern sector_t bmap(struct inode *, sector_t); #endif extern int notify_change(struct dentry *, struct iattr *); -extern int inode_permission(struct inode *, int); +extern int permission(struct inode *, int, struct nameidata *); extern int generic_permission(struct inode *, int, int (*check_acl)(struct inode *, int)); @@ -1834,7 +1831,7 @@ extern void clear_inode(struct inode *); extern void destroy_inode(struct inode *); extern struct inode *new_inode(struct super_block *); extern int should_remove_suid(struct dentry *); -extern int file_remove_suid(struct file *); +extern int remove_suid(struct dentry *); extern void __insert_inode_hash(struct inode *, unsigned long hashval); extern void remove_inode_hash(struct inode *); diff --git a/trunk/include/linux/fs_struct.h b/trunk/include/linux/fs_struct.h index 9e5a06e78d02..282f54219129 100644 --- a/trunk/include/linux/fs_struct.h +++ b/trunk/include/linux/fs_struct.h @@ -7,7 +7,7 @@ struct fs_struct { atomic_t count; rwlock_t lock; int umask; - struct path root, pwd; + struct path root, pwd, altroot; }; #define INIT_FS { \ @@ -19,6 +19,7 @@ struct fs_struct { extern struct kmem_cache *fs_cachep; extern void exit_fs(struct task_struct *); +extern void set_fs_altroot(void); extern void set_fs_root(struct fs_struct *, struct path *); extern void set_fs_pwd(struct fs_struct *, struct path *); extern struct fs_struct *copy_fs_struct(struct fs_struct *); diff --git a/trunk/include/linux/hugetlb.h b/trunk/include/linux/hugetlb.h index 32e0ef0f6e1f..9a71d4cc88c8 100644 --- a/trunk/include/linux/hugetlb.h +++ b/trunk/include/linux/hugetlb.h @@ -273,10 +273,7 @@ struct hstate {}; #define huge_page_mask(h) PAGE_MASK #define huge_page_order(h) 0 #define huge_page_shift(h) PAGE_SHIFT -static inline unsigned int pages_per_huge_page(struct hstate *h) -{ - return 1; -} +#define pages_per_huge_page(h) 1 #endif #endif /* _LINUX_HUGETLB_H */ diff --git a/trunk/include/linux/i2o.h b/trunk/include/linux/i2o.h index 75ae6d8aba4f..7d51cbca49ab 100644 --- a/trunk/include/linux/i2o.h +++ b/trunk/include/linux/i2o.h @@ -758,7 +758,7 @@ static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, } dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction); - if (!dma_mapping_error(&c->pdev->dev, dma_addr)) { + if (!dma_mapping_error(dma_addr)) { #ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 if ((sizeof(dma_addr_t) > 4) && c->pae_support) { *mptr++ = cpu_to_le32(0x7C020002); diff --git a/trunk/include/linux/init.h b/trunk/include/linux/init.h index 11b84e106053..42ae95411a93 100644 --- a/trunk/include/linux/init.h +++ b/trunk/include/linux/init.h @@ -169,13 +169,6 @@ extern void (*late_time_init)(void); static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" level ".init"))) = fn -/* - * Early initcalls run before initializing SMP. - * - * Only for built-in code, not modules. - */ -#define early_initcall(fn) __define_initcall("early",fn,early) - /* * A "pure" initcall has no dependencies on anything else, and purely * initializes variables that couldn't be statically initialized. diff --git a/trunk/include/linux/jffs2.h b/trunk/include/linux/jffs2.h index da720bc3eb15..6b563cae23df 100644 --- a/trunk/include/linux/jffs2.h +++ b/trunk/include/linux/jffs2.h @@ -7,6 +7,9 @@ * * For licensing information, see the file 'LICENCE' in the * jffs2 directory. + * + * $Id: jffs2.h,v 1.38 2005/09/26 11:37:23 havasi Exp $ + * */ #ifndef __LINUX_JFFS2_H__ diff --git a/trunk/include/linux/kexec.h b/trunk/include/linux/kexec.h index 82f88a8a827b..3265968cd2cd 100644 --- a/trunk/include/linux/kexec.h +++ b/trunk/include/linux/kexec.h @@ -83,7 +83,6 @@ struct kimage { unsigned long start; struct page *control_code_page; - struct page *swap_page; unsigned long nr_segments; struct kexec_segment segment[KEXEC_SEGMENT_MAX]; @@ -99,20 +98,18 @@ struct kimage { unsigned int type : 1; #define KEXEC_TYPE_DEFAULT 0 #define KEXEC_TYPE_CRASH 1 - unsigned int preserve_context : 1; }; /* kexec interface functions */ -extern void machine_kexec(struct kimage *image); +extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET; extern int machine_kexec_prepare(struct kimage *image); extern void machine_kexec_cleanup(struct kimage *image); extern asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, struct kexec_segment __user *segments, unsigned long flags); -extern int kernel_kexec(void); #ifdef CONFIG_COMPAT extern asmlinkage long compat_sys_kexec_load(unsigned long entry, unsigned long nr_segments, @@ -159,9 +156,8 @@ extern struct kimage *kexec_crash_image; #define kexec_flush_icache_page(page) #endif -#define KEXEC_ON_CRASH 0x00000001 -#define KEXEC_PRESERVE_CONTEXT 0x00000002 -#define KEXEC_ARCH_MASK 0xffff0000 +#define KEXEC_ON_CRASH 0x00000001 +#define KEXEC_ARCH_MASK 0xffff0000 /* These values match the ELF architecture values. * Unless there is a good reason that should continue to be the case. @@ -178,12 +174,7 @@ extern struct kimage *kexec_crash_image; #define KEXEC_ARCH_MIPS_LE (10 << 16) #define KEXEC_ARCH_MIPS ( 8 << 16) -/* List of defined/legal kexec flags */ -#ifndef CONFIG_KEXEC_JUMP -#define KEXEC_FLAGS KEXEC_ON_CRASH -#else -#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT) -#endif +#define KEXEC_FLAGS (KEXEC_ON_CRASH) /* List of defined/legal kexec flags */ #define VMCOREINFO_BYTES (4096) #define VMCOREINFO_NOTE_NAME "VMCOREINFO" diff --git a/trunk/include/linux/mISDNdsp.h b/trunk/include/linux/mISDNdsp.h deleted file mode 100644 index 6b71d2dce508..000000000000 --- a/trunk/include/linux/mISDNdsp.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __mISDNdsp_H__ -#define __mISDNdsp_H__ - -struct mISDN_dsp_element_arg { - char *name; - char *def; - char *desc; -}; - -struct mISDN_dsp_element { - char *name; - void *(*new)(const char *arg); - void (*free)(void *p); - void (*process_tx)(void *p, unsigned char *data, int len); - void (*process_rx)(void *p, unsigned char *data, int len); - int num_args; - struct mISDN_dsp_element_arg - *args; -}; - -extern int mISDN_dsp_element_register(struct mISDN_dsp_element *elem); -extern void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem); - -struct dsp_features { - int hfc_id; /* unique id to identify the chip (or -1) */ - int hfc_dtmf; /* set if HFCmulti card supports dtmf */ - int hfc_loops; /* set if card supports tone loops */ - int hfc_echocanhw; /* set if card supports echocancelation*/ - int pcm_id; /* unique id to identify the pcm bus (or -1) */ - int pcm_slots; /* number of slots on the pcm bus */ - int pcm_banks; /* number of IO banks of pcm bus */ - int unclocked; /* data is not clocked (has jitter/loss) */ - int unordered; /* data is unordered (packets have index) */ -}; - -#endif - diff --git a/trunk/include/linux/mISDNhw.h b/trunk/include/linux/mISDNhw.h deleted file mode 100644 index e794dfb87504..000000000000 --- a/trunk/include/linux/mISDNhw.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Basic declarations for the mISDN HW channels - * - * Copyright 2008 by Karsten Keil - * - * 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. - * - */ - -#ifndef MISDNHW_H -#define MISDNHW_H -#include -#include - -/* - * HW DEBUG 0xHHHHGGGG - * H - hardware driver specific bits - * G - for all drivers - */ - -#define DEBUG_HW 0x00000001 -#define DEBUG_HW_OPEN 0x00000002 -#define DEBUG_HW_DCHANNEL 0x00000100 -#define DEBUG_HW_DFIFO 0x00000200 -#define DEBUG_HW_BCHANNEL 0x00001000 -#define DEBUG_HW_BFIFO 0x00002000 - -#define MAX_DFRAME_LEN_L1 300 -#define MAX_MON_FRAME 32 -#define MAX_LOG_SPACE 2048 -#define MISDN_COPY_SIZE 32 - -/* channel->Flags bit field */ -#define FLG_TX_BUSY 0 /* tx_buf in use */ -#define FLG_TX_NEXT 1 /* next_skb in use */ -#define FLG_L1_BUSY 2 /* L1 is permanent busy */ -#define FLG_L2_ACTIVATED 3 /* activated from L2 */ -#define FLG_OPEN 5 /* channel is in use */ -#define FLG_ACTIVE 6 /* channel is activated */ -#define FLG_BUSY_TIMER 7 -/* channel type */ -#define FLG_DCHANNEL 8 /* channel is D-channel */ -#define FLG_BCHANNEL 9 /* channel is B-channel */ -#define FLG_ECHANNEL 10 /* channel is E-channel */ -#define FLG_TRANSPARENT 12 /* channel use transparent data */ -#define FLG_HDLC 13 /* channel use hdlc data */ -#define FLG_L2DATA 14 /* channel use L2 DATA primitivs */ -#define FLG_ORIGIN 15 /* channel is on origin site */ -/* channel specific stuff */ -/* arcofi specific */ -#define FLG_ARCOFI_TIMER 16 -#define FLG_ARCOFI_ERROR 17 -/* isar specific */ -#define FLG_INITIALIZED 16 -#define FLG_DLEETX 17 -#define FLG_LASTDLE 18 -#define FLG_FIRST 19 -#define FLG_LASTDATA 20 -#define FLG_NMD_DATA 21 -#define FLG_FTI_RUN 22 -#define FLG_LL_OK 23 -#define FLG_LL_CONN 24 -#define FLG_DTMFSEND 25 - -/* workq events */ -#define FLG_RECVQUEUE 30 -#define FLG_PHCHANGE 31 - -#define schedule_event(s, ev) do { \ - test_and_set_bit(ev, &((s)->Flags)); \ - schedule_work(&((s)->workq)); \ - } while (0) - -struct dchannel { - struct mISDNdevice dev; - u_long Flags; - struct work_struct workq; - void (*phfunc) (struct dchannel *); - u_int state; - void *l1; - /* HW access */ - u_char (*read_reg) (void *, u_char); - void (*write_reg) (void *, u_char, u_char); - void (*read_fifo) (void *, u_char *, int); - void (*write_fifo) (void *, u_char *, int); - void *hw; - int slot; /* multiport card channel slot */ - struct timer_list timer; - /* receive data */ - struct sk_buff *rx_skb; - int maxlen; - /* send data */ - struct sk_buff_head squeue; - struct sk_buff_head rqueue; - struct sk_buff *tx_skb; - int tx_idx; - int debug; - /* statistics */ - int err_crc; - int err_tx; - int err_rx; -}; - -typedef int (dchannel_l1callback)(struct dchannel *, u_int); -extern int create_l1(struct dchannel *, dchannel_l1callback *); - -/* private L1 commands */ -#define INFO0 0x8002 -#define INFO1 0x8102 -#define INFO2 0x8202 -#define INFO3_P8 0x8302 -#define INFO3_P10 0x8402 -#define INFO4_P8 0x8502 -#define INFO4_P10 0x8602 -#define LOSTFRAMING 0x8702 -#define ANYSIGNAL 0x8802 -#define HW_POWERDOWN 0x8902 -#define HW_RESET_REQ 0x8a02 -#define HW_POWERUP_REQ 0x8b02 -#define HW_DEACT_REQ 0x8c02 -#define HW_ACTIVATE_REQ 0x8e02 -#define HW_D_NOBLOCKED 0x8f02 -#define HW_RESET_IND 0x9002 -#define HW_POWERUP_IND 0x9102 -#define HW_DEACT_IND 0x9202 -#define HW_ACTIVATE_IND 0x9302 -#define HW_DEACT_CNF 0x9402 -#define HW_TESTLOOP 0x9502 -#define HW_TESTRX_RAW 0x9602 -#define HW_TESTRX_HDLC 0x9702 -#define HW_TESTRX_OFF 0x9802 - -struct layer1; -extern int l1_event(struct layer1 *, u_int); - - -struct bchannel { - struct mISDNchannel ch; - int nr; - u_long Flags; - struct work_struct workq; - u_int state; - /* HW access */ - u_char (*read_reg) (void *, u_char); - void (*write_reg) (void *, u_char, u_char); - void (*read_fifo) (void *, u_char *, int); - void (*write_fifo) (void *, u_char *, int); - void *hw; - int slot; /* multiport card channel slot */ - struct timer_list timer; - /* receive data */ - struct sk_buff *rx_skb; - int maxlen; - /* send data */ - struct sk_buff *next_skb; - struct sk_buff *tx_skb; - struct sk_buff_head rqueue; - int rcount; - int tx_idx; - int debug; - /* statistics */ - int err_crc; - int err_tx; - int err_rx; -}; - -extern int mISDN_initdchannel(struct dchannel *, int, void *); -extern int mISDN_initbchannel(struct bchannel *, int); -extern int mISDN_freedchannel(struct dchannel *); -extern int mISDN_freebchannel(struct bchannel *); -extern void queue_ch_frame(struct mISDNchannel *, u_int, - int, struct sk_buff *); -extern int dchannel_senddata(struct dchannel *, struct sk_buff *); -extern int bchannel_senddata(struct bchannel *, struct sk_buff *); -extern void recv_Dchannel(struct dchannel *); -extern void recv_Bchannel(struct bchannel *); -extern void recv_Dchannel_skb(struct dchannel *, struct sk_buff *); -extern void recv_Bchannel_skb(struct bchannel *, struct sk_buff *); -extern void confirm_Bsend(struct bchannel *bch); -extern int get_next_bframe(struct bchannel *); -extern int get_next_dframe(struct dchannel *); - -#endif diff --git a/trunk/include/linux/mISDNif.h b/trunk/include/linux/mISDNif.h deleted file mode 100644 index 5c948f337817..000000000000 --- a/trunk/include/linux/mISDNif.h +++ /dev/null @@ -1,487 +0,0 @@ -/* - * - * Author Karsten Keil - * - * Copyright 2008 by Karsten Keil - * - * This code is free software; you can redistribute it and/or modify - * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE - * version 2.1 as published by the Free Software Foundation. - * - * This code 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. - * - */ - -#ifndef mISDNIF_H -#define mISDNIF_H - -#include -#include -#include -#include - -/* - * ABI Version 32 bit - * - * <8 bit> Major version - * - changed if any interface become backwards incompatible - * - * <8 bit> Minor version - * - changed if any interface is extended but backwards compatible - * - * <16 bit> Release number - * - should be incremented on every checkin - */ -#define MISDN_MAJOR_VERSION 1 -#define MISDN_MINOR_VERSION 0 -#define MISDN_RELEASE 18 - -/* primitives for information exchange - * generell format - * <16 bit 0 > - * <8 bit command> - * BIT 8 = 1 LAYER private - * BIT 7 = 1 answer - * BIT 6 = 1 DATA - * <8 bit target layer mask> - * - * Layer = 00 is reserved for general commands - Layer = 01 L2 -> HW - Layer = 02 HW -> L2 - Layer = 04 L3 -> L2 - Layer = 08 L2 -> L3 - * Layer = FF is reserved for broadcast commands - */ - -#define MISDN_CMDMASK 0xff00 -#define MISDN_LAYERMASK 0x00ff - -/* generell commands */ -#define OPEN_CHANNEL 0x0100 -#define CLOSE_CHANNEL 0x0200 -#define CONTROL_CHANNEL 0x0300 -#define CHECK_DATA 0x0400 - -/* layer 2 -> layer 1 */ -#define PH_ACTIVATE_REQ 0x0101 -#define PH_DEACTIVATE_REQ 0x0201 -#define PH_DATA_REQ 0x2001 -#define MPH_ACTIVATE_REQ 0x0501 -#define MPH_DEACTIVATE_REQ 0x0601 -#define MPH_INFORMATION_REQ 0x0701 -#define PH_CONTROL_REQ 0x0801 - -/* layer 1 -> layer 2 */ -#define PH_ACTIVATE_IND 0x0102 -#define PH_ACTIVATE_CNF 0x4102 -#define PH_DEACTIVATE_IND 0x0202 -#define PH_DEACTIVATE_CNF 0x4202 -#define PH_DATA_IND 0x2002 -#define MPH_ACTIVATE_IND 0x0502 -#define MPH_DEACTIVATE_IND 0x0602 -#define MPH_INFORMATION_IND 0x0702 -#define PH_DATA_CNF 0x6002 -#define PH_CONTROL_IND 0x0802 -#define PH_CONTROL_CNF 0x4802 - -/* layer 3 -> layer 2 */ -#define DL_ESTABLISH_REQ 0x1004 -#define DL_RELEASE_REQ 0x1104 -#define DL_DATA_REQ 0x3004 -#define DL_UNITDATA_REQ 0x3104 -#define DL_INFORMATION_REQ 0x0004 - -/* layer 2 -> layer 3 */ -#define DL_ESTABLISH_IND 0x1008 -#define DL_ESTABLISH_CNF 0x5008 -#define DL_RELEASE_IND 0x1108 -#define DL_RELEASE_CNF 0x5108 -#define DL_DATA_IND 0x3008 -#define DL_UNITDATA_IND 0x3108 -#define DL_INFORMATION_IND 0x0008 - -/* intern layer 2 managment */ -#define MDL_ASSIGN_REQ 0x1804 -#define MDL_ASSIGN_IND 0x1904 -#define MDL_REMOVE_REQ 0x1A04 -#define MDL_REMOVE_IND 0x1B04 -#define MDL_STATUS_UP_IND 0x1C04 -#define MDL_STATUS_DOWN_IND 0x1D04 -#define MDL_STATUS_UI_IND 0x1E04 -#define MDL_ERROR_IND 0x1F04 -#define MDL_ERROR_RSP 0x5F04 - -/* DL_INFORMATION_IND types */ -#define DL_INFO_L2_CONNECT 0x0001 -#define DL_INFO_L2_REMOVED 0x0002 - -/* PH_CONTROL types */ -/* TOUCH TONE IS 0x20XX XX "0"..."9", "A","B","C","D","*","#" */ -#define DTMF_TONE_VAL 0x2000 -#define DTMF_TONE_MASK 0x007F -#define DTMF_TONE_START 0x2100 -#define DTMF_TONE_STOP 0x2200 -#define DTMF_HFC_COEF 0x4000 -#define DSP_CONF_JOIN 0x2403 -#define DSP_CONF_SPLIT 0x2404 -#define DSP_RECEIVE_OFF 0x2405 -#define DSP_RECEIVE_ON 0x2406 -#define DSP_ECHO_ON 0x2407 -#define DSP_ECHO_OFF 0x2408 -#define DSP_MIX_ON 0x2409 -#define DSP_MIX_OFF 0x240a -#define DSP_DELAY 0x240b -#define DSP_JITTER 0x240c -#define DSP_TXDATA_ON 0x240d -#define DSP_TXDATA_OFF 0x240e -#define DSP_TX_DEJITTER 0x240f -#define DSP_TX_DEJ_OFF 0x2410 -#define DSP_TONE_PATT_ON 0x2411 -#define DSP_TONE_PATT_OFF 0x2412 -#define DSP_VOL_CHANGE_TX 0x2413 -#define DSP_VOL_CHANGE_RX 0x2414 -#define DSP_BF_ENABLE_KEY 0x2415 -#define DSP_BF_DISABLE 0x2416 -#define DSP_BF_ACCEPT 0x2416 -#define DSP_BF_REJECT 0x2417 -#define DSP_PIPELINE_CFG 0x2418 -#define HFC_VOL_CHANGE_TX 0x2601 -#define HFC_VOL_CHANGE_RX 0x2602 -#define HFC_SPL_LOOP_ON 0x2603 -#define HFC_SPL_LOOP_OFF 0x2604 - -/* DSP_TONE_PATT_ON parameter */ -#define TONE_OFF 0x0000 -#define TONE_GERMAN_DIALTONE 0x0001 -#define TONE_GERMAN_OLDDIALTONE 0x0002 -#define TONE_AMERICAN_DIALTONE 0x0003 -#define TONE_GERMAN_DIALPBX 0x0004 -#define TONE_GERMAN_OLDDIALPBX 0x0005 -#define TONE_AMERICAN_DIALPBX 0x0006 -#define TONE_GERMAN_RINGING 0x0007 -#define TONE_GERMAN_OLDRINGING 0x0008 -#define TONE_AMERICAN_RINGPBX 0x000b -#define TONE_GERMAN_RINGPBX 0x000c -#define TONE_GERMAN_OLDRINGPBX 0x000d -#define TONE_AMERICAN_RINGING 0x000e -#define TONE_GERMAN_BUSY 0x000f -#define TONE_GERMAN_OLDBUSY 0x0010 -#define TONE_AMERICAN_BUSY 0x0011 -#define TONE_GERMAN_HANGUP 0x0012 -#define TONE_GERMAN_OLDHANGUP 0x0013 -#define TONE_AMERICAN_HANGUP 0x0014 -#define TONE_SPECIAL_INFO 0x0015 -#define TONE_GERMAN_GASSENBESETZT 0x0016 -#define TONE_GERMAN_AUFSCHALTTON 0x0016 - -/* MPH_INFORMATION_IND */ -#define L1_SIGNAL_LOS_OFF 0x0010 -#define L1_SIGNAL_LOS_ON 0x0011 -#define L1_SIGNAL_AIS_OFF 0x0012 -#define L1_SIGNAL_AIS_ON 0x0013 -#define L1_SIGNAL_RDI_OFF 0x0014 -#define L1_SIGNAL_RDI_ON 0x0015 -#define L1_SIGNAL_SLIP_RX 0x0020 -#define L1_SIGNAL_SLIP_TX 0x0021 - -/* - * protocol ids - * D channel 1-31 - * B channel 33 - 63 - */ - -#define ISDN_P_NONE 0 -#define ISDN_P_BASE 0 -#define ISDN_P_TE_S0 0x01 -#define ISDN_P_NT_S0 0x02 -#define ISDN_P_TE_E1 0x03 -#define ISDN_P_NT_E1 0x04 -#define ISDN_P_LAPD_TE 0x10 -#define ISDN_P_LAPD_NT 0x11 - -#define ISDN_P_B_MASK 0x1f -#define ISDN_P_B_START 0x20 - -#define ISDN_P_B_RAW 0x21 -#define ISDN_P_B_HDLC 0x22 -#define ISDN_P_B_X75SLP 0x23 -#define ISDN_P_B_L2DTMF 0x24 -#define ISDN_P_B_L2DSP 0x25 -#define ISDN_P_B_L2DSPHDLC 0x26 - -#define OPTION_L2_PMX 1 -#define OPTION_L2_PTP 2 -#define OPTION_L2_FIXEDTEI 3 -#define OPTION_L2_CLEANUP 4 - -/* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */ -#define MISDN_MAX_IDLEN 20 - -struct mISDNhead { - unsigned int prim; - unsigned int id; -} __attribute__((packed)); - -#define MISDN_HEADER_LEN sizeof(struct mISDNhead) -#define MAX_DATA_SIZE 2048 -#define MAX_DATA_MEM (MAX_DATA_SIZE + MISDN_HEADER_LEN) -#define MAX_DFRAME_LEN 260 - -#define MISDN_ID_ADDR_MASK 0xFFFF -#define MISDN_ID_TEI_MASK 0xFF00 -#define MISDN_ID_SAPI_MASK 0x00FF -#define MISDN_ID_TEI_ANY 0x7F00 - -#define MISDN_ID_ANY 0xFFFF -#define MISDN_ID_NONE 0xFFFE - -#define GROUP_TEI 127 -#define TEI_SAPI 63 -#define CTRL_SAPI 0 - -#define MISDN_CHMAP_SIZE 4 - -#define SOL_MISDN 0 - -struct sockaddr_mISDN { - sa_family_t family; - unsigned char dev; - unsigned char channel; - unsigned char sapi; - unsigned char tei; -}; - -/* timer device ioctl */ -#define IMADDTIMER _IOR('I', 64, int) -#define IMDELTIMER _IOR('I', 65, int) -/* socket ioctls */ -#define IMGETVERSION _IOR('I', 66, int) -#define IMGETCOUNT _IOR('I', 67, int) -#define IMGETDEVINFO _IOR('I', 68, int) -#define IMCTRLREQ _IOR('I', 69, int) -#define IMCLEAR_L2 _IOR('I', 70, int) - -struct mISDNversion { - unsigned char major; - unsigned char minor; - unsigned short release; -}; - -struct mISDN_devinfo { - u_int id; - u_int Dprotocols; - u_int Bprotocols; - u_int protocol; - u_long channelmap[MISDN_CHMAP_SIZE]; - u_int nrbchan; - char name[MISDN_MAX_IDLEN]; -}; - -/* CONTROL_CHANNEL parameters */ -#define MISDN_CTRL_GETOP 0x0000 -#define MISDN_CTRL_LOOP 0x0001 -#define MISDN_CTRL_CONNECT 0x0002 -#define MISDN_CTRL_DISCONNECT 0x0004 -#define MISDN_CTRL_PCMCONNECT 0x0010 -#define MISDN_CTRL_PCMDISCONNECT 0x0020 -#define MISDN_CTRL_SETPEER 0x0040 -#define MISDN_CTRL_UNSETPEER 0x0080 -#define MISDN_CTRL_RX_OFF 0x0100 -#define MISDN_CTRL_HW_FEATURES_OP 0x2000 -#define MISDN_CTRL_HW_FEATURES 0x2001 -#define MISDN_CTRL_HFC_OP 0x4000 -#define MISDN_CTRL_HFC_PCM_CONN 0x4001 -#define MISDN_CTRL_HFC_PCM_DISC 0x4002 -#define MISDN_CTRL_HFC_CONF_JOIN 0x4003 -#define MISDN_CTRL_HFC_CONF_SPLIT 0x4004 -#define MISDN_CTRL_HFC_RECEIVE_OFF 0x4005 -#define MISDN_CTRL_HFC_RECEIVE_ON 0x4006 -#define MISDN_CTRL_HFC_ECHOCAN_ON 0x4007 -#define MISDN_CTRL_HFC_ECHOCAN_OFF 0x4008 - - -/* socket options */ -#define MISDN_TIME_STAMP 0x0001 - -struct mISDN_ctrl_req { - int op; - int channel; - int p1; - int p2; -}; - -/* muxer options */ -#define MISDN_OPT_ALL 1 -#define MISDN_OPT_TEIMGR 2 - -#ifdef __KERNEL__ -#include -#include -#include -#include -#include - -#define DEBUG_CORE 0x000000ff -#define DEBUG_CORE_FUNC 0x00000002 -#define DEBUG_SOCKET 0x00000004 -#define DEBUG_MANAGER 0x00000008 -#define DEBUG_SEND_ERR 0x00000010 -#define DEBUG_MSG_THREAD 0x00000020 -#define DEBUG_QUEUE_FUNC 0x00000040 -#define DEBUG_L1 0x0000ff00 -#define DEBUG_L1_FSM 0x00000200 -#define DEBUG_L2 0x00ff0000 -#define DEBUG_L2_FSM 0x00020000 -#define DEBUG_L2_CTRL 0x00040000 -#define DEBUG_L2_RECV 0x00080000 -#define DEBUG_L2_TEI 0x00100000 -#define DEBUG_L2_TEIFSM 0x00200000 -#define DEBUG_TIMER 0x01000000 - -#define mISDN_HEAD_P(s) ((struct mISDNhead *)&s->cb[0]) -#define mISDN_HEAD_PRIM(s) (((struct mISDNhead *)&s->cb[0])->prim) -#define mISDN_HEAD_ID(s) (((struct mISDNhead *)&s->cb[0])->id) - -/* socket states */ -#define MISDN_OPEN 1 -#define MISDN_BOUND 2 -#define MISDN_CLOSED 3 - -struct mISDNchannel; -struct mISDNdevice; -struct mISDNstack; - -struct channel_req { - u_int protocol; - struct sockaddr_mISDN adr; - struct mISDNchannel *ch; -}; - -typedef int (ctrl_func_t)(struct mISDNchannel *, u_int, void *); -typedef int (send_func_t)(struct mISDNchannel *, struct sk_buff *); -typedef int (create_func_t)(struct channel_req *); - -struct Bprotocol { - struct list_head list; - char *name; - u_int Bprotocols; - create_func_t *create; -}; - -struct mISDNchannel { - struct list_head list; - u_int protocol; - u_int nr; - u_long opt; - u_int addr; - struct mISDNstack *st; - struct mISDNchannel *peer; - send_func_t *send; - send_func_t *recv; - ctrl_func_t *ctrl; -}; - -struct mISDN_sock_list { - struct hlist_head head; - rwlock_t lock; -}; - -struct mISDN_sock { - struct sock sk; - struct mISDNchannel ch; - u_int cmask; - struct mISDNdevice *dev; -}; - - - -struct mISDNdevice { - struct mISDNchannel D; - u_int id; - char name[MISDN_MAX_IDLEN]; - u_int Dprotocols; - u_int Bprotocols; - u_int nrbchan; - u_long channelmap[MISDN_CHMAP_SIZE]; - struct list_head bchannels; - struct mISDNchannel *teimgr; - struct device dev; -}; - -struct mISDNstack { - u_long status; - struct mISDNdevice *dev; - struct task_struct *thread; - struct completion *notify; - wait_queue_head_t workq; - struct sk_buff_head msgq; - struct list_head layer2; - struct mISDNchannel *layer1; - struct mISDNchannel own; - struct mutex lmutex; /* protect lists */ - struct mISDN_sock_list l1sock; -#ifdef MISDN_MSG_STATS - u_int msg_cnt; - u_int sleep_cnt; - u_int stopped_cnt; -#endif -}; - -/* global alloc/queue dunctions */ - -static inline struct sk_buff * -mI_alloc_skb(unsigned int len, gfp_t gfp_mask) -{ - struct sk_buff *skb; - - skb = alloc_skb(len + MISDN_HEADER_LEN, gfp_mask); - if (likely(skb)) - skb_reserve(skb, MISDN_HEADER_LEN); - return skb; -} - -static inline struct sk_buff * -_alloc_mISDN_skb(u_int prim, u_int id, u_int len, void *dp, gfp_t gfp_mask) -{ - struct sk_buff *skb = mI_alloc_skb(len, gfp_mask); - struct mISDNhead *hh; - - if (!skb) - return NULL; - if (len) - memcpy(skb_put(skb, len), dp, len); - hh = mISDN_HEAD_P(skb); - hh->prim = prim; - hh->id = id; - return skb; -} - -static inline void -_queue_data(struct mISDNchannel *ch, u_int prim, - u_int id, u_int len, void *dp, gfp_t gfp_mask) -{ - struct sk_buff *skb; - - if (!ch->peer) - return; - skb = _alloc_mISDN_skb(prim, id, len, dp, gfp_mask); - if (!skb) - return; - if (ch->recv(ch->peer, skb)) - dev_kfree_skb(skb); -} - -/* global register/unregister functions */ - -extern int mISDN_register_device(struct mISDNdevice *, char *name); -extern void mISDN_unregister_device(struct mISDNdevice *); -extern int mISDN_register_Bprotocol(struct Bprotocol *); -extern void mISDN_unregister_Bprotocol(struct Bprotocol *); - -extern void set_channel_address(struct mISDNchannel *, u_int, u_int); - -#endif /* __KERNEL__ */ -#endif /* mISDNIF_H */ diff --git a/trunk/include/linux/memstick.h b/trunk/include/linux/memstick.h index a9f998a3f48b..37a5cdb03918 100644 --- a/trunk/include/linux/memstick.h +++ b/trunk/include/linux/memstick.h @@ -263,10 +263,6 @@ struct memstick_dev { /* Get next request from the media driver. */ int (*next_request)(struct memstick_dev *card, struct memstick_request **mrq); - /* Tell the media driver to stop doing things */ - void (*stop)(struct memstick_dev *card); - /* Allow the media driver to continue */ - void (*start)(struct memstick_dev *card); struct device dev; }; @@ -288,7 +284,7 @@ struct memstick_host { /* Notify the host that some requests are pending. */ void (*request)(struct memstick_host *host); /* Set host IO parameters (power, clock, etc). */ - int (*set_param)(struct memstick_host *host, + void (*set_param)(struct memstick_host *host, enum memstick_param param, int value); unsigned long private[0] ____cacheline_aligned; diff --git a/trunk/include/linux/mlx4/qp.h b/trunk/include/linux/mlx4/qp.h index bf8f11982dae..e27082cd650e 100644 --- a/trunk/include/linux/mlx4/qp.h +++ b/trunk/include/linux/mlx4/qp.h @@ -164,13 +164,11 @@ enum { MLX4_WQE_CTRL_SOLICITED = 1 << 1, MLX4_WQE_CTRL_IP_CSUM = 1 << 4, MLX4_WQE_CTRL_TCP_UDP_CSUM = 1 << 5, - MLX4_WQE_CTRL_INS_VLAN = 1 << 6, }; struct mlx4_wqe_ctrl_seg { __be32 owner_opcode; - __be16 vlan_tag; - u8 ins_vlan; + u8 reserved2[3]; u8 fence_size; /* * High 24 bits are SRC remote buffer; low 8 bits are flags: diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 6e695eaab4ce..d87a5a5fe87d 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -810,6 +810,7 @@ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void * int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int len, int write, int force, struct page **pages, struct vm_area_struct **vmas); +void print_bad_pte(struct vm_area_struct *, pte_t, unsigned long); extern int try_to_release_page(struct page * page, gfp_t gfp_mask); extern void do_invalidatepage(struct page *page, unsigned long offset); @@ -832,39 +833,6 @@ extern int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, unsigned long start, unsigned long end, unsigned long newflags); -#ifdef CONFIG_HAVE_GET_USER_PAGES_FAST -/* - * get_user_pages_fast provides equivalent functionality to get_user_pages, - * operating on current and current->mm (force=0 and doesn't return any vmas). - * - * get_user_pages_fast may take mmap_sem and page tables, so no assumptions - * can be made about locking. get_user_pages_fast is to be implemented in a - * way that is advantageous (vs get_user_pages()) when the user memory area is - * already faulted in and present in ptes. However if the pages have to be - * faulted in, it may turn out to be slightly slower). - */ -int get_user_pages_fast(unsigned long start, int nr_pages, int write, - struct page **pages); - -#else -/* - * Should probably be moved to asm-generic, and architectures can include it if - * they don't implement their own get_user_pages_fast. - */ -#define get_user_pages_fast(start, nr_pages, write, pages) \ -({ \ - struct mm_struct *mm = current->mm; \ - int ret; \ - \ - down_read(&mm->mmap_sem); \ - ret = get_user_pages(current, mm, start, nr_pages, \ - write, 0, pages, NULL); \ - up_read(&mm->mmap_sem); \ - \ - ret; \ -}) -#endif - /* * A callback you can register to apply pressure to ageable caches. * diff --git a/trunk/include/linux/mmc/card.h b/trunk/include/linux/mmc/card.h index ee6e822d5994..0d508ac17d64 100644 --- a/trunk/include/linux/mmc/card.h +++ b/trunk/include/linux/mmc/card.h @@ -111,8 +111,6 @@ struct mmc_card { unsigned num_info; /* number of info strings */ const char **info; /* info strings */ struct sdio_func_tuple *tuples; /* unknown common tuples */ - - struct dentry *debugfs_root; }; #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) diff --git a/trunk/include/linux/mmc/host.h b/trunk/include/linux/mmc/host.h index 9c288c909878..10a2080086ca 100644 --- a/trunk/include/linux/mmc/host.h +++ b/trunk/include/linux/mmc/host.h @@ -157,8 +157,6 @@ struct mmc_host { struct led_trigger *led; /* activity led */ #endif - struct dentry *debugfs_root; - unsigned long private[0] ____cacheline_aligned; }; diff --git a/trunk/include/linux/mount.h b/trunk/include/linux/mount.h index b5efaa2132ab..4374d1adeb4b 100644 --- a/trunk/include/linux/mount.h +++ b/trunk/include/linux/mount.h @@ -47,7 +47,7 @@ struct vfsmount { struct list_head mnt_child; /* and going through their mnt_child */ int mnt_flags; /* 4 bytes hole on 64bits arches */ - const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ + char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ struct list_head mnt_list; struct list_head mnt_expire; /* link in fs-specific expiry list */ struct list_head mnt_share; /* circular list of shared mounts */ diff --git a/trunk/include/linux/mtd/blktrans.h b/trunk/include/linux/mtd/blktrans.h index 310e61606415..9a6e2f953cba 100644 --- a/trunk/include/linux/mtd/blktrans.h +++ b/trunk/include/linux/mtd/blktrans.h @@ -1,4 +1,6 @@ /* + * $Id: blktrans.h,v 1.6 2005/11/07 11:14:54 gleixner Exp $ + * * (C) 2003 David Woodhouse * * Interface to Linux block layer for MTD 'translation layers'. diff --git a/trunk/include/linux/mtd/cfi.h b/trunk/include/linux/mtd/cfi.h index d6fb115f5a07..b0ddf4b25862 100644 --- a/trunk/include/linux/mtd/cfi.h +++ b/trunk/include/linux/mtd/cfi.h @@ -1,6 +1,7 @@ /* Common Flash Interface structures * See http://support.intel.com/design/flash/technote/index.htm + * $Id: cfi.h,v 1.57 2005/11/15 23:28:17 tpoynor Exp $ */ #ifndef __MTD_CFI_H__ diff --git a/trunk/include/linux/mtd/cfi_endian.h b/trunk/include/linux/mtd/cfi_endian.h index d802f7736be3..25724f7d3867 100644 --- a/trunk/include/linux/mtd/cfi_endian.h +++ b/trunk/include/linux/mtd/cfi_endian.h @@ -1,3 +1,8 @@ +/* + * $Id: cfi_endian.h,v 1.11 2002/01/30 23:20:48 awozniak Exp $ + * + */ + #include #ifndef CONFIG_MTD_CFI_ADV_OPTIONS diff --git a/trunk/include/linux/mtd/concat.h b/trunk/include/linux/mtd/concat.h index c02f3d264ecf..ed8dc6755219 100644 --- a/trunk/include/linux/mtd/concat.h +++ b/trunk/include/linux/mtd/concat.h @@ -4,6 +4,8 @@ * (C) 2002 Robert Kaiser * * This code is GPL + * + * $Id: concat.h,v 1.1 2002/03/08 16:34:36 rkaiser Exp $ */ #ifndef MTD_CONCAT_H diff --git a/trunk/include/linux/mtd/doc2000.h b/trunk/include/linux/mtd/doc2000.h index 0a6d516ab71d..9addd073bf15 100644 --- a/trunk/include/linux/mtd/doc2000.h +++ b/trunk/include/linux/mtd/doc2000.h @@ -6,6 +6,8 @@ * Copyright (C) 2002-2003 Greg Ungerer * Copyright (C) 2002-2003 SnapGear Inc * + * $Id: doc2000.h,v 1.25 2005/11/07 11:14:54 gleixner Exp $ + * * Released under GPL */ diff --git a/trunk/include/linux/mtd/flashchip.h b/trunk/include/linux/mtd/flashchip.h index 08dd131301c1..39e7d2a1be9a 100644 --- a/trunk/include/linux/mtd/flashchip.h +++ b/trunk/include/linux/mtd/flashchip.h @@ -5,6 +5,9 @@ * Contains information about the location and state of a given flash device * * (C) 2000 Red Hat. GPLd. + * + * $Id: flashchip.h,v 1.18 2005/11/07 11:14:54 gleixner Exp $ + * */ #ifndef __MTD_FLASHCHIP_H__ diff --git a/trunk/include/linux/mtd/ftl.h b/trunk/include/linux/mtd/ftl.h index 0be442f881dd..d99609113307 100644 --- a/trunk/include/linux/mtd/ftl.h +++ b/trunk/include/linux/mtd/ftl.h @@ -1,4 +1,6 @@ /* + * $Id: ftl.h,v 1.7 2005/11/07 11:14:54 gleixner Exp $ + * * Derived from (and probably identical to): * ftl.h 1.7 1999/10/25 20:23:17 * diff --git a/trunk/include/linux/mtd/gen_probe.h b/trunk/include/linux/mtd/gen_probe.h index df362ddf2949..256e7342ed1e 100644 --- a/trunk/include/linux/mtd/gen_probe.h +++ b/trunk/include/linux/mtd/gen_probe.h @@ -1,6 +1,7 @@ /* * (C) 2001, 2001 Red Hat, Inc. * GPL'd + * $Id: gen_probe.h,v 1.4 2005/11/07 11:14:54 gleixner Exp $ */ #ifndef __LINUX_MTD_GEN_PROBE_H__ diff --git a/trunk/include/linux/mtd/inftl.h b/trunk/include/linux/mtd/inftl.h index 64ee53ce95a9..85fd041d44ad 100644 --- a/trunk/include/linux/mtd/inftl.h +++ b/trunk/include/linux/mtd/inftl.h @@ -2,6 +2,8 @@ * inftl.h -- defines to support the Inverse NAND Flash Translation Layer * * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) + * + * $Id: inftl.h,v 1.7 2005/06/13 13:08:45 sean Exp $ */ #ifndef __MTD_INFTL_H__ @@ -50,6 +52,8 @@ struct INFTLrecord { int INFTL_mount(struct INFTLrecord *s); int INFTL_formatblock(struct INFTLrecord *s, int block); +extern char inftlmountrev[]; + void INFTL_dumptables(struct INFTLrecord *s); void INFTL_dumpVUchains(struct INFTLrecord *s); diff --git a/trunk/include/linux/mtd/map.h b/trunk/include/linux/mtd/map.h index aa30244492c6..9c1d95491f8b 100644 --- a/trunk/include/linux/mtd/map.h +++ b/trunk/include/linux/mtd/map.h @@ -1,5 +1,6 @@ /* Overhauled routines for dealing with different mmap regions of flash */ +/* $Id: map.h,v 1.54 2005/11/07 11:14:54 gleixner Exp $ */ #ifndef __LINUX_MTD_MAP_H__ #define __LINUX_MTD_MAP_H__ diff --git a/trunk/include/linux/mtd/mtd.h b/trunk/include/linux/mtd/mtd.h index 4ed40caff4e5..8b5d49133ec6 100644 --- a/trunk/include/linux/mtd/mtd.h +++ b/trunk/include/linux/mtd/mtd.h @@ -1,4 +1,6 @@ /* + * $Id: mtd.h,v 1.61 2005/11/07 11:14:54 gleixner Exp $ + * * Copyright (C) 1999-2003 David Woodhouse et al. * * Released under GPL diff --git a/trunk/include/linux/mtd/nand.h b/trunk/include/linux/mtd/nand.h index 83f678702dff..53ea3dc8b0e8 100644 --- a/trunk/include/linux/mtd/nand.h +++ b/trunk/include/linux/mtd/nand.h @@ -5,6 +5,8 @@ * Steven J. Hill * Thomas Gleixner * + * $Id: nand.h,v 1.74 2005/09/15 13:58:50 vwool Exp $ + * * 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. @@ -177,7 +179,6 @@ typedef enum { #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) -#define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT)) /* Mask to zero out the chip options, which come from the id table */ #define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) @@ -275,10 +276,6 @@ struct nand_ecc_ctrl { int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf); - int (*read_subpage)(struct mtd_info *mtd, - struct nand_chip *chip, - uint32_t offs, uint32_t len, - uint8_t *buf); void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf); diff --git a/trunk/include/linux/mtd/nand_ecc.h b/trunk/include/linux/mtd/nand_ecc.h index 090da505425d..12c5bc342ead 100644 --- a/trunk/include/linux/mtd/nand_ecc.h +++ b/trunk/include/linux/mtd/nand_ecc.h @@ -3,6 +3,8 @@ * * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * + * $Id: nand_ecc.h,v 1.4 2004/06/17 02:35:02 dbrown Exp $ + * * 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. diff --git a/trunk/include/linux/mtd/nftl.h b/trunk/include/linux/mtd/nftl.h index dcaf611ed748..001eec50cac6 100644 --- a/trunk/include/linux/mtd/nftl.h +++ b/trunk/include/linux/mtd/nftl.h @@ -1,4 +1,6 @@ /* + * $Id: nftl.h,v 1.16 2004/06/30 14:49:00 dbrown Exp $ + * * (C) 1999-2003 David Woodhouse */ diff --git a/trunk/include/linux/mtd/partitions.h b/trunk/include/linux/mtd/partitions.h index 5014f7a9f5df..7c37d7e55abc 100644 --- a/trunk/include/linux/mtd/partitions.h +++ b/trunk/include/linux/mtd/partitions.h @@ -4,6 +4,8 @@ * (C) 2000 Nicolas Pitre * * This code is GPL + * + * $Id: partitions.h,v 1.17 2005/11/07 11:14:55 gleixner Exp $ */ #ifndef MTD_PARTITIONS_H diff --git a/trunk/include/linux/mtd/physmap.h b/trunk/include/linux/mtd/physmap.h index c8e63a5ee72e..0dc07d5f3354 100644 --- a/trunk/include/linux/mtd/physmap.h +++ b/trunk/include/linux/mtd/physmap.h @@ -2,6 +2,8 @@ * For boards with physically mapped flash and using * drivers/mtd/maps/physmap.c mapping driver. * + * $Id: physmap.h,v 1.4 2005/11/07 11:14:55 gleixner Exp $ + * * Copyright (C) 2003 MontaVista Software Inc. * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net * diff --git a/trunk/include/linux/mtd/plat-ram.h b/trunk/include/linux/mtd/plat-ram.h index e07890aff1cf..0e37ad07bce2 100644 --- a/trunk/include/linux/mtd/plat-ram.h +++ b/trunk/include/linux/mtd/plat-ram.h @@ -6,6 +6,8 @@ * * Generic platform device based RAM map * + * $Id: plat-ram.h,v 1.2 2005/01/24 00:37:40 bjd Exp $ + * * 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. diff --git a/trunk/include/linux/mtd/pmc551.h b/trunk/include/linux/mtd/pmc551.h index 27ad40aed19f..5cc070c24d88 100644 --- a/trunk/include/linux/mtd/pmc551.h +++ b/trunk/include/linux/mtd/pmc551.h @@ -1,4 +1,6 @@ /* + * $Id: pmc551.h,v 1.6 2005/11/07 11:14:55 gleixner Exp $ + * * PMC551 PCI Mezzanine Ram Device * * Author: @@ -15,7 +17,7 @@ #include -#define PMC551_VERSION \ +#define PMC551_VERSION "$Id: pmc551.h,v 1.6 2005/11/07 11:14:55 gleixner Exp $\n"\ "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" /* diff --git a/trunk/include/linux/mtd/xip.h b/trunk/include/linux/mtd/xip.h index 36efcba15ecd..e9d40bdde48c 100644 --- a/trunk/include/linux/mtd/xip.h +++ b/trunk/include/linux/mtd/xip.h @@ -11,6 +11,8 @@ * 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. + * + * $Id: xip.h,v 1.5 2005/11/07 11:14:55 gleixner Exp $ */ #ifndef __LINUX_MTD_XIP_H__ diff --git a/trunk/include/linux/namei.h b/trunk/include/linux/namei.h index 68f8c3203c89..24d88e98a626 100644 --- a/trunk/include/linux/namei.h +++ b/trunk/include/linux/namei.h @@ -47,24 +47,27 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; #define LOOKUP_DIRECTORY 2 #define LOOKUP_CONTINUE 4 #define LOOKUP_PARENT 16 +#define LOOKUP_NOALT 32 #define LOOKUP_REVAL 64 /* * Intent data */ #define LOOKUP_OPEN (0x0100) #define LOOKUP_CREATE (0x0200) - -extern int user_path_at(int, const char __user *, unsigned, struct path *); - -#define user_path(name, path) user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW, path) -#define user_lpath(name, path) user_path_at(AT_FDCWD, name, 0, path) -#define user_path_dir(name, path) \ - user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path) - +#define LOOKUP_ACCESS (0x0400) +#define LOOKUP_CHDIR (0x0800) + +extern int __user_walk(const char __user *, unsigned, struct nameidata *); +extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *); +#define user_path_walk(name,nd) \ + __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd) +#define user_path_walk_link(name,nd) \ + __user_walk_fd(AT_FDCWD, name, 0, nd) extern int path_lookup(const char *, unsigned, struct nameidata *); extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct nameidata *); +extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags); extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags); extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, int (*open)(struct inode *, struct file *)); diff --git a/trunk/include/linux/nfs_fs.h b/trunk/include/linux/nfs_fs.h index 78a5922a2f11..29d261918734 100644 --- a/trunk/include/linux/nfs_fs.h +++ b/trunk/include/linux/nfs_fs.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -331,7 +332,7 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); -extern int nfs_permission(struct inode *, int); +extern int nfs_permission(struct inode *, int, struct nameidata *); extern int nfs_open(struct inode *, struct file *); extern int nfs_release(struct inode *, struct file *); extern int nfs_attribute_timeout(struct inode *inode); diff --git a/trunk/include/linux/pagemap.h b/trunk/include/linux/pagemap.h index a81d81890422..ee1ec2c7723c 100644 --- a/trunk/include/linux/pagemap.h +++ b/trunk/include/linux/pagemap.h @@ -12,7 +12,6 @@ #include #include #include -#include /* for in_interrupt() */ /* * Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page @@ -63,98 +62,6 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask) #define page_cache_release(page) put_page(page) void release_pages(struct page **pages, int nr, int cold); -/* - * speculatively take a reference to a page. - * If the page is free (_count == 0), then _count is untouched, and 0 - * is returned. Otherwise, _count is incremented by 1 and 1 is returned. - * - * This function must be called inside the same rcu_read_lock() section as has - * been used to lookup the page in the pagecache radix-tree (or page table): - * this allows allocators to use a synchronize_rcu() to stabilize _count. - * - * Unless an RCU grace period has passed, the count of all pages coming out - * of the allocator must be considered unstable. page_count may return higher - * than expected, and put_page must be able to do the right thing when the - * page has been finished with, no matter what it is subsequently allocated - * for (because put_page is what is used here to drop an invalid speculative - * reference). - * - * This is the interesting part of the lockless pagecache (and lockless - * get_user_pages) locking protocol, where the lookup-side (eg. find_get_page) - * has the following pattern: - * 1. find page in radix tree - * 2. conditionally increment refcount - * 3. check the page is still in pagecache (if no, goto 1) - * - * Remove-side that cares about stability of _count (eg. reclaim) has the - * following (with tree_lock held for write): - * A. atomically check refcount is correct and set it to 0 (atomic_cmpxchg) - * B. remove page from pagecache - * C. free the page - * - * There are 2 critical interleavings that matter: - * - 2 runs before A: in this case, A sees elevated refcount and bails out - * - A runs before 2: in this case, 2 sees zero refcount and retries; - * subsequently, B will complete and 1 will find no page, causing the - * lookup to return NULL. - * - * It is possible that between 1 and 2, the page is removed then the exact same - * page is inserted into the same position in pagecache. That's OK: the - * old find_get_page using tree_lock could equally have run before or after - * such a re-insertion, depending on order that locks are granted. - * - * Lookups racing against pagecache insertion isn't a big problem: either 1 - * will find the page or it will not. Likewise, the old find_get_page could run - * either before the insertion or afterwards, depending on timing. - */ -static inline int page_cache_get_speculative(struct page *page) -{ - VM_BUG_ON(in_interrupt()); - -#if !defined(CONFIG_SMP) && defined(CONFIG_CLASSIC_RCU) -# ifdef CONFIG_PREEMPT - VM_BUG_ON(!in_atomic()); -# endif - /* - * Preempt must be disabled here - we rely on rcu_read_lock doing - * this for us. - * - * Pagecache won't be truncated from interrupt context, so if we have - * found a page in the radix tree here, we have pinned its refcount by - * disabling preempt, and hence no need for the "speculative get" that - * SMP requires. - */ - VM_BUG_ON(page_count(page) == 0); - atomic_inc(&page->_count); - -#else - if (unlikely(!get_page_unless_zero(page))) { - /* - * Either the page has been freed, or will be freed. - * In either case, retry here and the caller should - * do the right thing (see comments above). - */ - return 0; - } -#endif - VM_BUG_ON(PageTail(page)); - - return 1; -} - -static inline int page_freeze_refs(struct page *page, int count) -{ - return likely(atomic_cmpxchg(&page->_count, count, 0) == count); -} - -static inline void page_unfreeze_refs(struct page *page, int count) -{ - VM_BUG_ON(page_count(page) != 0); - VM_BUG_ON(count == 0); - - atomic_set(&page->_count, count); -} - #ifdef CONFIG_NUMA extern struct page *__page_cache_alloc(gfp_t gfp); #else @@ -226,29 +133,13 @@ static inline struct page *read_mapping_page(struct address_space *mapping, return read_cache_page(mapping, index, filler, data); } -int add_to_page_cache_locked(struct page *page, struct address_space *mapping, +int add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t index, gfp_t gfp_mask); int add_to_page_cache_lru(struct page *page, struct address_space *mapping, pgoff_t index, gfp_t gfp_mask); extern void remove_from_page_cache(struct page *page); extern void __remove_from_page_cache(struct page *page); -/* - * Like add_to_page_cache_locked, but used to add newly allocated pages: - * the page is new, so we can just run SetPageLocked() against it. - */ -static inline int add_to_page_cache(struct page *page, - struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) -{ - int error; - - SetPageLocked(page); - error = add_to_page_cache_locked(page, mapping, offset, gfp_mask); - if (unlikely(error)) - ClearPageLocked(page); - return error; -} - /* * Return byte-offset into filesystem object for page. */ diff --git a/trunk/include/linux/parport.h b/trunk/include/linux/parport.h index 6a0d7cdb5774..dcb9e01a69ca 100644 --- a/trunk/include/linux/parport.h +++ b/trunk/include/linux/parport.h @@ -560,8 +560,5 @@ extern int parport_device_proc_unregister(struct pardevice *device); #endif /* !CONFIG_PARPORT_NOT_PC */ -extern unsigned long parport_default_timeslice; -extern int parport_default_spintime; - #endif /* __KERNEL__ */ #endif /* _PARPORT_H_ */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 35a78415accc..c3b1761aba26 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -748,7 +748,6 @@ #define PCI_VENDOR_ID_TI 0x104c #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 #define PCI_DEVICE_ID_TI_4450 0x8011 -#define PCI_DEVICE_ID_TI_TSB43AB22 0x8023 #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 #define PCI_DEVICE_ID_TI_XX21_XX11_FM 0x8033 #define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034 @@ -1833,13 +1832,7 @@ #define PCI_DEVICE_ID_MOXA_C320 0x3200 #define PCI_VENDOR_ID_CCD 0x1397 -#define PCI_DEVICE_ID_CCD_HFC4S 0x08B4 -#define PCI_SUBDEVICE_ID_CCD_PMX2S 0x1234 -#define PCI_DEVICE_ID_CCD_HFC8S 0x16B8 #define PCI_DEVICE_ID_CCD_2BD0 0x2bd0 -#define PCI_DEVICE_ID_CCD_HFCE1 0x30B1 -#define PCI_SUBDEVICE_ID_CCD_SPD4S 0x3136 -#define PCI_SUBDEVICE_ID_CCD_SPDE1 0x3137 #define PCI_DEVICE_ID_CCD_B000 0xb000 #define PCI_DEVICE_ID_CCD_B006 0xb006 #define PCI_DEVICE_ID_CCD_B007 0xb007 @@ -1849,32 +1842,8 @@ #define PCI_DEVICE_ID_CCD_B00B 0xb00b #define PCI_DEVICE_ID_CCD_B00C 0xb00c #define PCI_DEVICE_ID_CCD_B100 0xb100 -#define PCI_SUBDEVICE_ID_CCD_IOB4ST 0xB520 -#define PCI_SUBDEVICE_ID_CCD_IOB8STR 0xB521 -#define PCI_SUBDEVICE_ID_CCD_IOB8ST 0xB522 -#define PCI_SUBDEVICE_ID_CCD_IOB1E1 0xB523 -#define PCI_SUBDEVICE_ID_CCD_SWYX4S 0xB540 -#define PCI_SUBDEVICE_ID_CCD_JH4S20 0xB550 -#define PCI_SUBDEVICE_ID_CCD_IOB8ST_1 0xB552 -#define PCI_SUBDEVICE_ID_CCD_BN4S 0xB560 -#define PCI_SUBDEVICE_ID_CCD_BN8S 0xB562 -#define PCI_SUBDEVICE_ID_CCD_BNE1 0xB563 -#define PCI_SUBDEVICE_ID_CCD_BNE1D 0xB564 -#define PCI_SUBDEVICE_ID_CCD_BNE1DP 0xB565 -#define PCI_SUBDEVICE_ID_CCD_BN2S 0xB566 -#define PCI_SUBDEVICE_ID_CCD_BN1SM 0xB567 -#define PCI_SUBDEVICE_ID_CCD_BN4SM 0xB568 -#define PCI_SUBDEVICE_ID_CCD_BN2SM 0xB569 -#define PCI_SUBDEVICE_ID_CCD_BNE1M 0xB56A -#define PCI_SUBDEVICE_ID_CCD_BN8SP 0xB56B -#define PCI_SUBDEVICE_ID_CCD_HFC4S 0xB620 -#define PCI_SUBDEVICE_ID_CCD_HFC8S 0xB622 #define PCI_DEVICE_ID_CCD_B700 0xb700 #define PCI_DEVICE_ID_CCD_B701 0xb701 -#define PCI_SUBDEVICE_ID_CCD_HFCE1 0xC523 -#define PCI_SUBDEVICE_ID_CCD_OV2S 0xE884 -#define PCI_SUBDEVICE_ID_CCD_OV4S 0xE888 -#define PCI_SUBDEVICE_ID_CCD_OV8S 0xE998 #define PCI_VENDOR_ID_EXAR 0x13a8 #define PCI_DEVICE_ID_EXAR_XR17C152 0x0152 @@ -2554,9 +2523,6 @@ #define PCI_VENDOR_ID_3COM_2 0xa727 -#define PCI_VENDOR_ID_DIGIUM 0xd161 -#define PCI_DEVICE_ID_DIGIUM_HFC4S 0xb410 - #define PCI_SUBVENDOR_ID_EXSYS 0xd84d #define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014 #define PCI_SUBDEVICE_ID_EXSYS_4055 0x4055 diff --git a/trunk/include/linux/percpu.h b/trunk/include/linux/percpu.h index fac3337547eb..4cdd393e71e1 100644 --- a/trunk/include/linux/percpu.h +++ b/trunk/include/linux/percpu.h @@ -74,6 +74,11 @@ struct percpu_data { (__typeof__(ptr))__p->ptrs[(cpu)]; \ }) +extern void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu); +extern void percpu_depopulate(void *__pdata, int cpu); +extern int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, + cpumask_t *mask); +extern void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask); extern void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask); extern void percpu_free(void *__pdata); @@ -81,6 +86,26 @@ extern void percpu_free(void *__pdata); #define percpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) +static inline void percpu_depopulate(void *__pdata, int cpu) +{ +} + +static inline void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask) +{ +} + +static inline void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, + int cpu) +{ + return percpu_ptr(__pdata, cpu); +} + +static inline int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, + cpumask_t *mask) +{ + return 0; +} + static __always_inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) { return kzalloc(size, gfp); @@ -93,6 +118,10 @@ static inline void percpu_free(void *__pdata) #endif /* CONFIG_SMP */ +#define percpu_populate_mask(__pdata, size, gfp, mask) \ + __percpu_populate_mask((__pdata), (size), (gfp), &(mask)) +#define percpu_depopulate_mask(__pdata, mask) \ + __percpu_depopulate_mask((__pdata), &(mask)) #define percpu_alloc_mask(size, gfp, mask) \ __percpu_alloc_mask((size), (gfp), &(mask)) diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index fb61850d1cfc..f560d1705afe 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -282,16 +282,11 @@ union proc_op { struct task_struct *task); }; -struct ctl_table_header; -struct ctl_table; - struct proc_inode { struct pid *pid; int fd; union proc_op op; struct proc_dir_entry *pde; - struct ctl_table_header *sysctl; - struct ctl_table *sysctl_entry; struct inode vfs_inode; }; diff --git a/trunk/include/linux/ptrace.h b/trunk/include/linux/ptrace.h index fd31756e1a00..c6f5f9dd0cee 100644 --- a/trunk/include/linux/ptrace.h +++ b/trunk/include/linux/ptrace.h @@ -121,74 +121,6 @@ static inline void ptrace_unlink(struct task_struct *child) int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data); int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data); -/** - * task_ptrace - return %PT_* flags that apply to a task - * @task: pointer to &task_struct in question - * - * Returns the %PT_* flags that apply to @task. - */ -static inline int task_ptrace(struct task_struct *task) -{ - return task->ptrace; -} - -/** - * ptrace_event - possibly stop for a ptrace event notification - * @mask: %PT_* bit to check in @current->ptrace - * @event: %PTRACE_EVENT_* value to report if @mask is set - * @message: value for %PTRACE_GETEVENTMSG to return - * - * This checks the @mask bit to see if ptrace wants stops for this event. - * If so we stop, reporting @event and @message to the ptrace parent. - * - * Returns nonzero if we did a ptrace notification, zero if not. - * - * Called without locks. - */ -static inline int ptrace_event(int mask, int event, unsigned long message) -{ - if (mask && likely(!(current->ptrace & mask))) - return 0; - current->ptrace_message = message; - ptrace_notify((event << 8) | SIGTRAP); - return 1; -} - -/** - * ptrace_init_task - initialize ptrace state for a new child - * @child: new child task - * @ptrace: true if child should be ptrace'd by parent's tracer - * - * This is called immediately after adding @child to its parent's children - * list. @ptrace is false in the normal case, and true to ptrace @child. - * - * Called with current's siglock and write_lock_irq(&tasklist_lock) held. - */ -static inline void ptrace_init_task(struct task_struct *child, bool ptrace) -{ - INIT_LIST_HEAD(&child->ptrace_entry); - INIT_LIST_HEAD(&child->ptraced); - child->parent = child->real_parent; - child->ptrace = 0; - if (unlikely(ptrace)) { - child->ptrace = current->ptrace; - __ptrace_link(child, current->parent); - } -} - -/** - * ptrace_release_task - final ptrace-related cleanup of a zombie being reaped - * @task: task in %EXIT_DEAD state - * - * Called with write_lock(&tasklist_lock) held. - */ -static inline void ptrace_release_task(struct task_struct *task) -{ - BUG_ON(!list_empty(&task->ptraced)); - ptrace_unlink(task); - BUG_ON(!list_empty(&task->ptrace_entry)); -} - #ifndef force_successful_syscall_return /* * System call handlers that, upon successful completion, need to return a @@ -314,10 +246,6 @@ static inline void user_enable_block_step(struct task_struct *task) #define arch_ptrace_stop(code, info) do { } while (0) #endif -extern int task_current_syscall(struct task_struct *target, long *callno, - unsigned long args[6], unsigned int maxargs, - unsigned long *sp, unsigned long *pc); - #endif #endif diff --git a/trunk/include/linux/radix-tree.h b/trunk/include/linux/radix-tree.h index a916c6660dfa..b8ce2b444bb5 100644 --- a/trunk/include/linux/radix-tree.h +++ b/trunk/include/linux/radix-tree.h @@ -99,15 +99,12 @@ do { \ * * The notable exceptions to this rule are the following functions: * radix_tree_lookup - * radix_tree_lookup_slot * radix_tree_tag_get * radix_tree_gang_lookup - * radix_tree_gang_lookup_slot * radix_tree_gang_lookup_tag - * radix_tree_gang_lookup_tag_slot * radix_tree_tagged * - * The first 7 functions are able to be called locklessly, using RCU. The + * The first 4 functions are able to be called locklessly, using RCU. The * caller must ensure calls to these functions are made within rcu_read_lock() * regions. Other readers (lock-free or otherwise) and modifications may be * running concurrently. @@ -162,9 +159,6 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long); unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items); -unsigned int -radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, - unsigned long first_index, unsigned int max_items); unsigned long radix_tree_next_hole(struct radix_tree_root *root, unsigned long index, unsigned long max_scan); int radix_tree_preload(gfp_t gfp_mask); @@ -179,10 +173,6 @@ unsigned int radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items, unsigned int tag); -unsigned int -radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, - unsigned long first_index, unsigned int max_items, - unsigned int tag); int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag); static inline void radix_tree_preload_end(void) diff --git a/trunk/include/linux/reiserfs_xattr.h b/trunk/include/linux/reiserfs_xattr.h index af135ae895db..66a96814d614 100644 --- a/trunk/include/linux/reiserfs_xattr.h +++ b/trunk/include/linux/reiserfs_xattr.h @@ -55,7 +55,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name); int reiserfs_delete_xattrs(struct inode *inode); int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); int reiserfs_xattr_init(struct super_block *sb, int mount_flags); -int reiserfs_permission(struct inode *inode, int mask); +int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd); int reiserfs_xattr_del(struct inode *, const char *); int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t); diff --git a/trunk/include/linux/relay.h b/trunk/include/linux/relay.h index 953fc055e875..6cd8c4425fc7 100644 --- a/trunk/include/linux/relay.h +++ b/trunk/include/linux/relay.h @@ -48,7 +48,6 @@ struct rchan_buf size_t *padding; /* padding counts per sub-buffer */ size_t prev_padding; /* temporary variable */ size_t bytes_consumed; /* bytes consumed in cur read subbuf */ - size_t early_bytes; /* bytes consumed before VFS inited */ unsigned int cpu; /* this buf's cpu */ } ____cacheline_aligned; @@ -69,7 +68,6 @@ struct rchan int is_global; /* One global buffer ? */ struct list_head list; /* for channel list */ struct dentry *parent; /* parent dentry passed to open */ - int has_base_filename; /* has a filename associated? */ char base_filename[NAME_MAX]; /* saved base filename */ }; @@ -171,9 +169,6 @@ struct rchan *relay_open(const char *base_filename, size_t n_subbufs, struct rchan_callbacks *cb, void *private_data); -extern int relay_late_setup_files(struct rchan *chan, - const char *base_filename, - struct dentry *parent); extern void relay_close(struct rchan *chan); extern void relay_flush(struct rchan *chan); extern void relay_subbufs_consumed(struct rchan *chan, diff --git a/trunk/include/linux/rtc.h b/trunk/include/linux/rtc.h index 91f597ad6acc..b01fe004cb5e 100644 --- a/trunk/include/linux/rtc.h +++ b/trunk/include/linux/rtc.h @@ -225,6 +225,8 @@ typedef struct rtc_task { 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); #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/rtnetlink.h b/trunk/include/linux/rtnetlink.h index ca643b13b026..f4d386c191f5 100644 --- a/trunk/include/linux/rtnetlink.h +++ b/trunk/include/linux/rtnetlink.h @@ -755,6 +755,13 @@ extern void __rtnl_unlock(void); } \ } while(0) +#define BUG_TRAP(x) do { \ + if (unlikely(!(x))) { \ + printk(KERN_ERR "KERNEL: assertion (%s) failed at %s (%d)\n", \ + #x, __FILE__ , __LINE__); \ + } \ +} while(0) + static inline u32 rtm_get_table(struct rtattr **rta, u8 table) { return RTA_GET_U32(rta[RTA_TABLE-1]); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 5270d449ff9d..42036ffe6b00 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -292,6 +292,7 @@ extern void sched_show_task(struct task_struct *p); #ifdef CONFIG_DETECT_SOFTLOCKUP extern void softlockup_tick(void); +extern void spawn_softlockup_task(void); extern void touch_softlockup_watchdog(void); extern void touch_all_softlockup_watchdogs(void); extern unsigned int softlockup_panic; @@ -505,6 +506,9 @@ struct signal_struct { unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; unsigned long inblock, oublock, cinblock, coublock; +#ifdef CONFIG_TASK_XACCT + u64 rchar, wchar, syscr, syscw; +#endif struct task_io_accounting ioac; /* @@ -1253,6 +1257,10 @@ struct task_struct { unsigned long ptrace_message; siginfo_t *last_siginfo; /* For ptrace use. */ +#ifdef CONFIG_TASK_XACCT +/* i/o counters(bytes read/written, #syscalls */ + u64 rchar, wchar, syscr, syscw; +#endif struct task_io_accounting ioac; #if defined(CONFIG_TASK_XACCT) u64 acct_rss_mem1; /* accumulated rss usage */ @@ -1789,7 +1797,7 @@ extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_ extern int kill_pgrp(struct pid *pid, int sig, int priv); extern int kill_pid(struct pid *pid, int sig, int priv); extern int kill_proc_info(int, struct siginfo *, pid_t); -extern int do_notify_parent(struct task_struct *, int); +extern void do_notify_parent(struct task_struct *, int); extern void force_sig(int, struct task_struct *); extern void force_sig_specific(int, struct task_struct *); extern int send_sig(int, struct task_struct *, int); @@ -1875,13 +1883,9 @@ extern void set_task_comm(struct task_struct *tsk, char *from); extern char *get_task_comm(char *to, struct task_struct *tsk); #ifdef CONFIG_SMP -extern unsigned long wait_task_inactive(struct task_struct *, long match_state); +extern void wait_task_inactive(struct task_struct * p); #else -static inline unsigned long wait_task_inactive(struct task_struct *p, - long match_state) -{ - return 1; -} +#define wait_task_inactive(p) do { } while (0) #endif #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) @@ -2135,7 +2139,16 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) #endif /* CONFIG_SMP */ +#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT extern void arch_pick_mmap_layout(struct mm_struct *mm); +#else +static inline void arch_pick_mmap_layout(struct mm_struct *mm) +{ + mm->mmap_base = TASK_UNMAPPED_BASE; + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; +} +#endif #ifdef CONFIG_TRACING extern void @@ -2183,22 +2196,22 @@ extern long sched_group_rt_period(struct task_group *tg); #ifdef CONFIG_TASK_XACCT static inline void add_rchar(struct task_struct *tsk, ssize_t amt) { - tsk->ioac.rchar += amt; + tsk->rchar += amt; } static inline void add_wchar(struct task_struct *tsk, ssize_t amt) { - tsk->ioac.wchar += amt; + tsk->wchar += amt; } static inline void inc_syscr(struct task_struct *tsk) { - tsk->ioac.syscr++; + tsk->syscr++; } static inline void inc_syscw(struct task_struct *tsk) { - tsk->ioac.syscw++; + tsk->syscw++; } #else static inline void add_rchar(struct task_struct *tsk, ssize_t amt) @@ -2218,6 +2231,14 @@ static inline void inc_syscw(struct task_struct *tsk) } #endif +#ifdef CONFIG_SMP +void migration_init(void); +#else +static inline void migration_init(void) +{ +} +#endif + #ifndef TASK_SIZE_OF #define TASK_SIZE_OF(tsk) TASK_SIZE #endif diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index fd96e7f8a6f9..f0e9adb22ac2 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -1362,7 +1362,7 @@ struct security_operations { struct inode *new_dir, struct dentry *new_dentry); int (*inode_readlink) (struct dentry *dentry); int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); - int (*inode_permission) (struct inode *inode, int mask); + int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); void (*inode_delete) (struct inode *inode); @@ -1628,7 +1628,7 @@ int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); int security_inode_readlink(struct dentry *dentry); int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd); -int security_inode_permission(struct inode *inode, int mask); +int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd); int security_inode_setattr(struct dentry *dentry, struct iattr *attr); int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry); void security_inode_delete(struct inode *inode); @@ -2021,7 +2021,8 @@ static inline int security_inode_follow_link(struct dentry *dentry, return 0; } -static inline int security_inode_permission(struct inode *inode, int mask) +static inline int security_inode_permission(struct inode *inode, int mask, + struct nameidata *nd) { return 0; } diff --git a/trunk/include/linux/shmem_fs.h b/trunk/include/linux/shmem_fs.h index fd83f2584b15..f2d12d5a21b8 100644 --- a/trunk/include/linux/shmem_fs.h +++ b/trunk/include/linux/shmem_fs.h @@ -43,7 +43,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) } #ifdef CONFIG_TMPFS_POSIX_ACL -int shmem_permission(struct inode *, int); +int shmem_permission(struct inode *, int, struct nameidata *); int shmem_acl_init(struct inode *, struct inode *); void shmem_acl_destroy_inode(struct inode *); diff --git a/trunk/include/linux/slab.h b/trunk/include/linux/slab.h index 5ff9676c1e2c..41103910f8a2 100644 --- a/trunk/include/linux/slab.h +++ b/trunk/include/linux/slab.h @@ -58,7 +58,7 @@ int slab_is_available(void); struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, unsigned long, - void (*)(void *)); + void (*)(struct kmem_cache *, void *)); void kmem_cache_destroy(struct kmem_cache *); int kmem_cache_shrink(struct kmem_cache *); void kmem_cache_free(struct kmem_cache *, void *); @@ -96,7 +96,6 @@ int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); /* * Common kmalloc functions provided by all allocators */ -void * __must_check __krealloc(const void *, size_t, gfp_t); void * __must_check krealloc(const void *, size_t, gfp_t); void kfree(const void *); size_t ksize(const void *); diff --git a/trunk/include/linux/slub_def.h b/trunk/include/linux/slub_def.h index 5bad61a93f65..d117ea2825a9 100644 --- a/trunk/include/linux/slub_def.h +++ b/trunk/include/linux/slub_def.h @@ -85,7 +85,7 @@ struct kmem_cache { struct kmem_cache_order_objects min; gfp_t allocflags; /* gfp flags to use on each alloc */ int refcount; /* Refcount for slab cache destroy */ - void (*ctor)(void *); + void (*ctor)(struct kmem_cache *, void *); int inuse; /* Offset to metadata */ int align; /* Alignment */ const char *name; /* Name (only for display!) */ diff --git a/trunk/include/linux/smp.h b/trunk/include/linux/smp.h index 66484d4a8459..48262f86c969 100644 --- a/trunk/include/linux/smp.h +++ b/trunk/include/linux/smp.h @@ -74,10 +74,15 @@ void __smp_call_function_single(int cpuid, struct call_single_data *data); #ifdef CONFIG_USE_GENERIC_SMP_HELPERS void generic_smp_call_function_single_interrupt(void); void generic_smp_call_function_interrupt(void); +void init_call_single_data(void); void ipi_call_lock(void); void ipi_call_unlock(void); void ipi_call_lock_irq(void); void ipi_call_unlock_irq(void); +#else +static inline void init_call_single_data(void) +{ +} #endif /* diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index dc5086fe7736..950af631e7fb 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -189,8 +189,7 @@ struct ucred { #define AF_BLUETOOTH 31 /* Bluetooth sockets */ #define AF_IUCV 32 /* IUCV sockets */ #define AF_RXRPC 33 /* RxRPC sockets */ -#define AF_ISDN 34 /* mISDN sockets */ -#define AF_MAX 35 /* For now.. */ +#define AF_MAX 34 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -226,7 +225,6 @@ struct ucred { #define PF_BLUETOOTH AF_BLUETOOTH #define PF_IUCV AF_IUCV #define PF_RXRPC AF_RXRPC -#define PF_ISDN AF_ISDN #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ diff --git a/trunk/include/linux/ssb/ssb.h b/trunk/include/linux/ssb/ssb.h index e530026eedf7..4bf8cade9dbc 100644 --- a/trunk/include/linux/ssb/ssb.h +++ b/trunk/include/linux/ssb/ssb.h @@ -427,9 +427,9 @@ static inline int ssb_dma_mapping_error(struct ssb_device *dev, dma_addr_t addr) { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: - return pci_dma_mapping_error(dev->bus->host_pci, addr); + return pci_dma_mapping_error(addr); case SSB_BUSTYPE_SSB: - return dma_mapping_error(dev->dev, addr); + return dma_mapping_error(addr); default: __ssb_dma_not_implemented(dev); } diff --git a/trunk/include/linux/suspend.h b/trunk/include/linux/suspend.h index c63435095970..e8e69159af71 100644 --- a/trunk/include/linux/suspend.h +++ b/trunk/include/linux/suspend.h @@ -278,6 +278,4 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e) } #endif -extern struct mutex pm_mutex; - #endif /* _LINUX_SUSPEND_H */ diff --git a/trunk/include/linux/swap.h b/trunk/include/linux/swap.h index de40f169a4e4..0b3377650c85 100644 --- a/trunk/include/linux/swap.h +++ b/trunk/include/linux/swap.h @@ -237,6 +237,7 @@ extern struct page *swapin_readahead(swp_entry_t, gfp_t, /* linux/mm/swapfile.c */ extern long total_swap_pages; +extern unsigned int nr_swapfiles; extern void si_swapinfo(struct sysinfo *); extern swp_entry_t get_swap_page(void); extern swp_entry_t get_swap_page_of_type(int); @@ -253,6 +254,8 @@ extern int can_share_swap_page(struct page *); extern int remove_exclusive_swap_page(struct page *); struct backing_dev_info; +extern spinlock_t swap_lock; + /* linux/mm/thrash.c */ extern struct mm_struct * swap_token_mm; extern void grab_swap_token(void); diff --git a/trunk/include/linux/sysctl.h b/trunk/include/linux/sysctl.h index d0437f36921f..24141b4d1a11 100644 --- a/trunk/include/linux/sysctl.h +++ b/trunk/include/linux/sysctl.h @@ -947,22 +947,6 @@ struct ctl_table; struct nsproxy; struct ctl_table_root; -struct ctl_table_set { - struct list_head list; - struct ctl_table_set *parent; - int (*is_seen)(struct ctl_table_set *); -}; - -extern void setup_sysctl_set(struct ctl_table_set *p, - struct ctl_table_set *parent, - int (*is_seen)(struct ctl_table_set *)); - -struct ctl_table_header; - -extern void sysctl_head_get(struct ctl_table_header *); -extern void sysctl_head_put(struct ctl_table_header *); -extern int sysctl_is_seen(struct ctl_table_header *); -extern struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *); extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev); extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, struct ctl_table_header *prev); @@ -1065,8 +1049,8 @@ struct ctl_table struct ctl_table_root { struct list_head root_list; - struct ctl_table_set default_set; - struct ctl_table_set *(*lookup)(struct ctl_table_root *root, + struct list_head header_list; + struct list_head *(*lookup)(struct ctl_table_root *root, struct nsproxy *namespaces); int (*permissions)(struct ctl_table_root *root, struct nsproxy *namespaces, struct ctl_table *table); @@ -1079,14 +1063,9 @@ struct ctl_table_header struct ctl_table *ctl_table; struct list_head ctl_entry; int used; - int count; struct completion *unregistering; struct ctl_table *ctl_table_arg; struct ctl_table_root *root; - struct ctl_table_set *set; - struct ctl_table *attached_by; - struct ctl_table *attached_to; - struct ctl_table_header *parent; }; /* struct ctl_path describes where in the hierarchy a table is added */ diff --git a/trunk/include/linux/task_io_accounting.h b/trunk/include/linux/task_io_accounting.h index 5e88afc9a2fb..44d00e9cceea 100644 --- a/trunk/include/linux/task_io_accounting.h +++ b/trunk/include/linux/task_io_accounting.h @@ -8,19 +8,8 @@ * Blame akpm@osdl.org for all this. */ -struct task_io_accounting { -#ifdef CONFIG_TASK_XACCT - /* bytes read */ - u64 rchar; - /* bytes written */ - u64 wchar; - /* # of read syscalls */ - u64 syscr; - /* # of write syscalls */ - u64 syscw; -#endif /* CONFIG_TASK_XACCT */ - #ifdef CONFIG_TASK_IO_ACCOUNTING +struct task_io_accounting { /* * The number of bytes which this task has caused to be read from * storage. @@ -41,5 +30,8 @@ struct task_io_accounting { * information loss in doing that. */ u64 cancelled_write_bytes; -#endif /* CONFIG_TASK_IO_ACCOUNTING */ }; +#else +struct task_io_accounting { +}; +#endif diff --git a/trunk/include/linux/task_io_accounting_ops.h b/trunk/include/linux/task_io_accounting_ops.h index 4d090f9ee608..ff46c6fad79d 100644 --- a/trunk/include/linux/task_io_accounting_ops.h +++ b/trunk/include/linux/task_io_accounting_ops.h @@ -40,17 +40,9 @@ static inline void task_io_account_cancelled_write(size_t bytes) current->ioac.cancelled_write_bytes += bytes; } -static inline void task_io_accounting_init(struct task_io_accounting *ioac) +static inline void task_io_accounting_init(struct task_struct *tsk) { - memset(ioac, 0, sizeof(*ioac)); -} - -static inline void task_blk_io_accounting_add(struct task_io_accounting *dst, - struct task_io_accounting *src) -{ - dst->read_bytes += src->read_bytes; - dst->write_bytes += src->write_bytes; - dst->cancelled_write_bytes += src->cancelled_write_bytes; + memset(&tsk->ioac, 0, sizeof(tsk->ioac)); } #else @@ -77,37 +69,9 @@ static inline void task_io_account_cancelled_write(size_t bytes) { } -static inline void task_io_accounting_init(struct task_io_accounting *ioac) -{ -} - -static inline void task_blk_io_accounting_add(struct task_io_accounting *dst, - struct task_io_accounting *src) +static inline void task_io_accounting_init(struct task_struct *tsk) { } -#endif /* CONFIG_TASK_IO_ACCOUNTING */ - -#ifdef CONFIG_TASK_XACCT -static inline void task_chr_io_accounting_add(struct task_io_accounting *dst, - struct task_io_accounting *src) -{ - dst->rchar += src->rchar; - dst->wchar += src->wchar; - dst->syscr += src->syscr; - dst->syscw += src->syscw; -} -#else -static inline void task_chr_io_accounting_add(struct task_io_accounting *dst, - struct task_io_accounting *src) -{ -} -#endif /* CONFIG_TASK_XACCT */ - -static inline void task_io_accounting_add(struct task_io_accounting *dst, - struct task_io_accounting *src) -{ - task_chr_io_accounting_add(dst, src); - task_blk_io_accounting_add(dst, src); -} -#endif /* __TASK_IO_ACCOUNTING_OPS_INCLUDED */ +#endif /* CONFIG_TASK_IO_ACCOUNTING */ +#endif /* __TASK_IO_ACCOUNTING_OPS_INCLUDED */ diff --git a/trunk/include/linux/tracehook.h b/trunk/include/linux/tracehook.h deleted file mode 100644 index b1875582c1a1..000000000000 --- a/trunk/include/linux/tracehook.h +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Tracing hooks - * - * Copyright (C) 2008 Red Hat, Inc. All rights reserved. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU General Public License v.2. - * - * This file defines hook entry points called by core code where - * user tracing/debugging support might need to do something. These - * entry points are called tracehook_*(). Each hook declared below - * has a detailed kerneldoc comment giving the context (locking et - * al) from which it is called, and the meaning of its return value. - * - * Each function here typically has only one call site, so it is ok - * to have some nontrivial tracehook_*() inlines. In all cases, the - * fast path when no tracing is enabled should be very short. - * - * The purpose of this file and the tracehook_* layer is to consolidate - * the interface that the kernel core and arch code uses to enable any - * user debugging or tracing facility (such as ptrace). The interfaces - * here are carefully documented so that maintainers of core and arch - * code do not need to think about the implementation details of the - * tracing facilities. Likewise, maintainers of the tracing code do not - * need to understand all the calling core or arch code in detail, just - * documented circumstances of each call, such as locking conditions. - * - * If the calling core code changes so that locking is different, then - * it is ok to change the interface documented here. The maintainer of - * core code changing should notify the maintainers of the tracing code - * that they need to work out the change. - * - * Some tracehook_*() inlines take arguments that the current tracing - * implementations might not necessarily use. These function signatures - * are chosen to pass in all the information that is on hand in the - * caller and might conceivably be relevant to a tracer, so that the - * core code won't have to be updated when tracing adds more features. - * If a call site changes so that some of those parameters are no longer - * already on hand without extra work, then the tracehook_* interface - * can change so there is no make-work burden on the core code. The - * maintainer of core code changing should notify the maintainers of the - * tracing code that they need to work out the change. - */ - -#ifndef _LINUX_TRACEHOOK_H -#define _LINUX_TRACEHOOK_H 1 - -#include -#include -#include -struct linux_binprm; - -/** - * tracehook_expect_breakpoints - guess if task memory might be touched - * @task: current task, making a new mapping - * - * Return nonzero if @task is expected to want breakpoint insertion in - * its memory at some point. A zero return is no guarantee it won't - * be done, but this is a hint that it's known to be likely. - * - * May be called with @task->mm->mmap_sem held for writing. - */ -static inline int tracehook_expect_breakpoints(struct task_struct *task) -{ - return (task_ptrace(task) & PT_PTRACED) != 0; -} - -/* - * ptrace report for syscall entry and exit looks identical. - */ -static inline void ptrace_report_syscall(struct pt_regs *regs) -{ - int ptrace = task_ptrace(current); - - if (!(ptrace & PT_PTRACED)) - return; - - ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} - -/** - * tracehook_report_syscall_entry - task is about to attempt a system call - * @regs: user register state of current task - * - * This will be called if %TIF_SYSCALL_TRACE has been set, when the - * current task has just entered the kernel for a system call. - * Full user register state is available here. Changing the values - * in @regs can affect the system call number and arguments to be tried. - * It is safe to block here, preventing the system call from beginning. - * - * Returns zero normally, or nonzero if the calling arch code should abort - * the system call. That must prevent normal entry so no system call is - * made. If @task ever returns to user mode after this, its register state - * is unspecified, but should be something harmless like an %ENOSYS error - * return. It should preserve enough information so that syscall_rollback() - * can work (see asm-generic/syscall.h). - * - * Called without locks, just after entering kernel mode. - */ -static inline __must_check int tracehook_report_syscall_entry( - struct pt_regs *regs) -{ - ptrace_report_syscall(regs); - return 0; -} - -/** - * tracehook_report_syscall_exit - task has just finished a system call - * @regs: user register state of current task - * @step: nonzero if simulating single-step or block-step - * - * This will be called if %TIF_SYSCALL_TRACE has been set, when the - * current task has just finished an attempted system call. Full - * user register state is available here. It is safe to block here, - * preventing signals from being processed. - * - * If @step is nonzero, this report is also in lieu of the normal - * trap that would follow the system call instruction because - * user_enable_block_step() or user_enable_single_step() was used. - * In this case, %TIF_SYSCALL_TRACE might not be set. - * - * Called without locks, just before checking for pending signals. - */ -static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) -{ - ptrace_report_syscall(regs); -} - -/** - * tracehook_unsafe_exec - check for exec declared unsafe due to tracing - * @task: current task doing exec - * - * Return %LSM_UNSAFE_* bits applied to an exec because of tracing. - * - * Called with task_lock() held on @task. - */ -static inline int tracehook_unsafe_exec(struct task_struct *task) -{ - int unsafe = 0; - int ptrace = task_ptrace(task); - if (ptrace & PT_PTRACED) { - if (ptrace & PT_PTRACE_CAP) - unsafe |= LSM_UNSAFE_PTRACE_CAP; - else - unsafe |= LSM_UNSAFE_PTRACE; - } - return unsafe; -} - -/** - * tracehook_tracer_task - return the task that is tracing the given task - * @tsk: task to consider - * - * Returns NULL if noone is tracing @task, or the &struct task_struct - * pointer to its tracer. - * - * Must called under rcu_read_lock(). The pointer returned might be kept - * live only by RCU. During exec, this may be called with task_lock() - * held on @task, still held from when tracehook_unsafe_exec() was called. - */ -static inline struct task_struct *tracehook_tracer_task(struct task_struct *tsk) -{ - if (task_ptrace(tsk) & PT_PTRACED) - return rcu_dereference(tsk->parent); - return NULL; -} - -/** - * tracehook_report_exec - a successful exec was completed - * @fmt: &struct linux_binfmt that performed the exec - * @bprm: &struct linux_binprm containing exec details - * @regs: user-mode register state - * - * An exec just completed, we are shortly going to return to user mode. - * The freshly initialized register state can be seen and changed in @regs. - * The name, file and other pointers in @bprm are still on hand to be - * inspected, but will be freed as soon as this returns. - * - * Called with no locks, but with some kernel resources held live - * and a reference on @fmt->module. - */ -static inline void tracehook_report_exec(struct linux_binfmt *fmt, - struct linux_binprm *bprm, - struct pt_regs *regs) -{ - if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) && - unlikely(task_ptrace(current) & PT_PTRACED)) - send_sig(SIGTRAP, current, 0); -} - -/** - * tracehook_report_exit - task has begun to exit - * @exit_code: pointer to value destined for @current->exit_code - * - * @exit_code points to the value passed to do_exit(), which tracing - * might change here. This is almost the first thing in do_exit(), - * before freeing any resources or setting the %PF_EXITING flag. - * - * Called with no locks held. - */ -static inline void tracehook_report_exit(long *exit_code) -{ - ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code); -} - -/** - * tracehook_prepare_clone - prepare for new child to be cloned - * @clone_flags: %CLONE_* flags from clone/fork/vfork system call - * - * This is called before a new user task is to be cloned. - * Its return value will be passed to tracehook_finish_clone(). - * - * Called with no locks held. - */ -static inline int tracehook_prepare_clone(unsigned clone_flags) -{ - if (clone_flags & CLONE_UNTRACED) - return 0; - - if (clone_flags & CLONE_VFORK) { - if (current->ptrace & PT_TRACE_VFORK) - return PTRACE_EVENT_VFORK; - } else if ((clone_flags & CSIGNAL) != SIGCHLD) { - if (current->ptrace & PT_TRACE_CLONE) - return PTRACE_EVENT_CLONE; - } else if (current->ptrace & PT_TRACE_FORK) - return PTRACE_EVENT_FORK; - - return 0; -} - -/** - * tracehook_finish_clone - new child created and being attached - * @child: new child task - * @clone_flags: %CLONE_* flags from clone/fork/vfork system call - * @trace: return value from tracehook_prepare_clone() - * - * This is called immediately after adding @child to its parent's children list. - * The @trace value is that returned by tracehook_prepare_clone(). - * - * Called with current's siglock and write_lock_irq(&tasklist_lock) held. - */ -static inline void tracehook_finish_clone(struct task_struct *child, - unsigned long clone_flags, int trace) -{ - ptrace_init_task(child, (clone_flags & CLONE_PTRACE) || trace); -} - -/** - * tracehook_report_clone - in parent, new child is about to start running - * @trace: return value from tracehook_prepare_clone() - * @regs: parent's user register state - * @clone_flags: flags from parent's system call - * @pid: new child's PID in the parent's namespace - * @child: new child task - * - * Called after a child is set up, but before it has been started - * running. @trace is the value returned by tracehook_prepare_clone(). - * This is not a good place to block, because the child has not started - * yet. Suspend the child here if desired, and then block in - * tracehook_report_clone_complete(). This must prevent the child from - * self-reaping if tracehook_report_clone_complete() uses the @child - * pointer; otherwise it might have died and been released by the time - * tracehook_report_report_clone_complete() is called. - * - * Called with no locks held, but the child cannot run until this returns. - */ -static inline void tracehook_report_clone(int trace, struct pt_regs *regs, - unsigned long clone_flags, - pid_t pid, struct task_struct *child) -{ - if (unlikely(trace)) { - /* - * The child starts up with an immediate SIGSTOP. - */ - sigaddset(&child->pending.signal, SIGSTOP); - set_tsk_thread_flag(child, TIF_SIGPENDING); - } -} - -/** - * tracehook_report_clone_complete - new child is running - * @trace: return value from tracehook_prepare_clone() - * @regs: parent's user register state - * @clone_flags: flags from parent's system call - * @pid: new child's PID in the parent's namespace - * @child: child task, already running - * - * This is called just after the child has started running. This is - * just before the clone/fork syscall returns, or blocks for vfork - * child completion if @clone_flags has the %CLONE_VFORK bit set. - * The @child pointer may be invalid if a self-reaping child died and - * tracehook_report_clone() took no action to prevent it from self-reaping. - * - * Called with no locks held. - */ -static inline void tracehook_report_clone_complete(int trace, - struct pt_regs *regs, - unsigned long clone_flags, - pid_t pid, - struct task_struct *child) -{ - if (unlikely(trace)) - ptrace_event(0, trace, pid); -} - -/** - * tracehook_report_vfork_done - vfork parent's child has exited or exec'd - * @child: child task, already running - * @pid: new child's PID in the parent's namespace - * - * Called after a %CLONE_VFORK parent has waited for the child to complete. - * The clone/vfork system call will return immediately after this. - * The @child pointer may be invalid if a self-reaping child died and - * tracehook_report_clone() took no action to prevent it from self-reaping. - * - * Called with no locks held. - */ -static inline void tracehook_report_vfork_done(struct task_struct *child, - pid_t pid) -{ - ptrace_event(PT_TRACE_VFORK_DONE, PTRACE_EVENT_VFORK_DONE, pid); -} - -/** - * tracehook_prepare_release_task - task is being reaped, clean up tracing - * @task: task in %EXIT_DEAD state - * - * This is called in release_task() just before @task gets finally reaped - * and freed. This would be the ideal place to remove and clean up any - * tracing-related state for @task. - * - * Called with no locks held. - */ -static inline void tracehook_prepare_release_task(struct task_struct *task) -{ -} - -/** - * tracehook_finish_release_task - final tracing clean-up - * @task: task in %EXIT_DEAD state - * - * This is called in release_task() when @task is being in the middle of - * being reaped. After this, there must be no tracing entanglements. - * - * Called with write_lock_irq(&tasklist_lock) held. - */ -static inline void tracehook_finish_release_task(struct task_struct *task) -{ - ptrace_release_task(task); -} - -/** - * tracehook_signal_handler - signal handler setup is complete - * @sig: number of signal being delivered - * @info: siginfo_t of signal being delivered - * @ka: sigaction setting that chose the handler - * @regs: user register state - * @stepping: nonzero if debugger single-step or block-step in use - * - * Called by the arch code after a signal handler has been set up. - * Register and stack state reflects the user handler about to run. - * Signal mask changes have already been made. - * - * Called without locks, shortly before returning to user mode - * (or handling more signals). - */ -static inline void tracehook_signal_handler(int sig, siginfo_t *info, - const struct k_sigaction *ka, - struct pt_regs *regs, int stepping) -{ - if (stepping) - ptrace_notify(SIGTRAP); -} - -/** - * tracehook_consider_ignored_signal - suppress short-circuit of ignored signal - * @task: task receiving the signal - * @sig: signal number being sent - * @handler: %SIG_IGN or %SIG_DFL - * - * Return zero iff tracing doesn't care to examine this ignored signal, - * so it can short-circuit normal delivery and never even get queued. - * Either @handler is %SIG_DFL and @sig's default is ignore, or it's %SIG_IGN. - * - * Called with @task->sighand->siglock held. - */ -static inline int tracehook_consider_ignored_signal(struct task_struct *task, - int sig, - void __user *handler) -{ - return (task_ptrace(task) & PT_PTRACED) != 0; -} - -/** - * tracehook_consider_fatal_signal - suppress special handling of fatal signal - * @task: task receiving the signal - * @sig: signal number being sent - * @handler: %SIG_DFL or %SIG_IGN - * - * Return nonzero to prevent special handling of this termination signal. - * Normally @handler is %SIG_DFL. It can be %SIG_IGN if @sig is ignored, - * in which case force_sig() is about to reset it to %SIG_DFL. - * When this returns zero, this signal might cause a quick termination - * that does not give the debugger a chance to intercept the signal. - * - * Called with or without @task->sighand->siglock held. - */ -static inline int tracehook_consider_fatal_signal(struct task_struct *task, - int sig, - void __user *handler) -{ - return (task_ptrace(task) & PT_PTRACED) != 0; -} - -/** - * tracehook_force_sigpending - let tracing force signal_pending(current) on - * - * Called when recomputing our signal_pending() flag. Return nonzero - * to force the signal_pending() flag on, so that tracehook_get_signal() - * will be called before the next return to user mode. - * - * Called with @current->sighand->siglock held. - */ -static inline int tracehook_force_sigpending(void) -{ - return 0; -} - -/** - * tracehook_get_signal - deliver synthetic signal to traced task - * @task: @current - * @regs: task_pt_regs(@current) - * @info: details of synthetic signal - * @return_ka: sigaction for synthetic signal - * - * Return zero to check for a real pending signal normally. - * Return -1 after releasing the siglock to repeat the check. - * Return a signal number to induce an artifical signal delivery, - * setting *@info and *@return_ka to specify its details and behavior. - * - * The @return_ka->sa_handler value controls the disposition of the - * signal, no matter the signal number. For %SIG_DFL, the return value - * is a representative signal to indicate the behavior (e.g. %SIGTERM - * for death, %SIGQUIT for core dump, %SIGSTOP for job control stop, - * %SIGTSTP for stop unless in an orphaned pgrp), but the signal number - * reported will be @info->si_signo instead. - * - * Called with @task->sighand->siglock held, before dequeuing pending signals. - */ -static inline int tracehook_get_signal(struct task_struct *task, - struct pt_regs *regs, - siginfo_t *info, - struct k_sigaction *return_ka) -{ - return 0; -} - -/** - * tracehook_notify_jctl - report about job control stop/continue - * @notify: nonzero if this is the last thread in the group to stop - * @why: %CLD_STOPPED or %CLD_CONTINUED - * - * This is called when we might call do_notify_parent_cldstop(). - * It's called when about to stop for job control; we are already in - * %TASK_STOPPED state, about to call schedule(). It's also called when - * a delayed %CLD_STOPPED or %CLD_CONTINUED report is ready to be made. - * - * Return nonzero to generate a %SIGCHLD with @why, which is - * normal if @notify is nonzero. - * - * Called with no locks held. - */ -static inline int tracehook_notify_jctl(int notify, int why) -{ - return notify || (current->ptrace & PT_PTRACED); -} - -/** - * tracehook_notify_death - task is dead, ready to notify parent - * @task: @current task now exiting - * @death_cookie: value to pass to tracehook_report_death() - * @group_dead: nonzero if this was the last thread in the group to die - * - * Return the signal number to send our parent with do_notify_parent(), or - * zero to send no signal and leave a zombie, or -1 to self-reap right now. - * - * Called with write_lock_irq(&tasklist_lock) held. - */ -static inline int tracehook_notify_death(struct task_struct *task, - void **death_cookie, int group_dead) -{ - if (task->exit_signal == -1) - return task->ptrace ? SIGCHLD : -1; - - /* - * If something other than our normal parent is ptracing us, then - * send it a SIGCHLD instead of honoring exit_signal. exit_signal - * only has special meaning to our real parent. - */ - if (thread_group_empty(task) && !ptrace_reparented(task)) - return task->exit_signal; - - return task->ptrace ? SIGCHLD : 0; -} - -/** - * tracehook_report_death - task is dead and ready to be reaped - * @task: @current task now exiting - * @signal: signal number sent to parent, or 0 or -1 - * @death_cookie: value passed back from tracehook_notify_death() - * @group_dead: nonzero if this was the last thread in the group to die - * - * Thread has just become a zombie or is about to self-reap. If positive, - * @signal is the signal number just sent to the parent (usually %SIGCHLD). - * If @signal is -1, this thread will self-reap. If @signal is 0, this is - * a delayed_group_leader() zombie. The @death_cookie was passed back by - * tracehook_notify_death(). - * - * If normal reaping is not inhibited, @task->exit_state might be changing - * in parallel. - * - * Called without locks. - */ -static inline void tracehook_report_death(struct task_struct *task, - int signal, void *death_cookie, - int group_dead) -{ -} - -#ifdef TIF_NOTIFY_RESUME -/** - * set_notify_resume - cause tracehook_notify_resume() to be called - * @task: task that will call tracehook_notify_resume() - * - * Calling this arranges that @task will call tracehook_notify_resume() - * before returning to user mode. If it's already running in user mode, - * it will enter the kernel and call tracehook_notify_resume() soon. - * If it's blocked, it will not be woken. - */ -static inline void set_notify_resume(struct task_struct *task) -{ - if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME)) - kick_process(task); -} - -/** - * tracehook_notify_resume - report when about to return to user mode - * @regs: user-mode registers of @current task - * - * This is called when %TIF_NOTIFY_RESUME has been set. Now we are - * about to return to user mode, and the user state in @regs can be - * inspected or adjusted. The caller in arch code has cleared - * %TIF_NOTIFY_RESUME before the call. If the flag gets set again - * asynchronously, this will be called again before we return to - * user mode. - * - * Called without locks. - */ -static inline void tracehook_notify_resume(struct pt_regs *regs) -{ -} -#endif /* TIF_NOTIFY_RESUME */ - -#endif /* */ diff --git a/trunk/include/mtd/inftl-user.h b/trunk/include/mtd/inftl-user.h index e17eda302b2d..9b1e2526b45e 100644 --- a/trunk/include/mtd/inftl-user.h +++ b/trunk/include/mtd/inftl-user.h @@ -1,4 +1,6 @@ /* + * $Id: inftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $ + * * Parts of INFTL headers shared with userspace * */ diff --git a/trunk/include/mtd/jffs2-user.h b/trunk/include/mtd/jffs2-user.h index 001685d7fa88..d508ef0ae091 100644 --- a/trunk/include/mtd/jffs2-user.h +++ b/trunk/include/mtd/jffs2-user.h @@ -1,4 +1,6 @@ /* + * $Id: jffs2-user.h,v 1.1 2004/05/05 11:57:54 dwmw2 Exp $ + * * JFFS2 definitions for use in user space only */ diff --git a/trunk/include/mtd/mtd-abi.h b/trunk/include/mtd/mtd-abi.h index c6c61cd5a254..615072c4da04 100644 --- a/trunk/include/mtd/mtd-abi.h +++ b/trunk/include/mtd/mtd-abi.h @@ -1,4 +1,6 @@ /* + * $Id: mtd-abi.h,v 1.13 2005/11/07 11:14:56 gleixner Exp $ + * * Portions of MTD ABI definition which are shared by kernel and user space */ diff --git a/trunk/include/mtd/mtd-user.h b/trunk/include/mtd/mtd-user.h index 170ceca3b2d0..713f34d3e62e 100644 --- a/trunk/include/mtd/mtd-user.h +++ b/trunk/include/mtd/mtd-user.h @@ -1,4 +1,6 @@ /* + * $Id: mtd-user.h,v 1.2 2004/05/05 14:44:57 dwmw2 Exp $ + * * MTD ABI header for use by user space only. */ diff --git a/trunk/include/mtd/nftl-user.h b/trunk/include/mtd/nftl-user.h index 390d21c080aa..b2bca18e7311 100644 --- a/trunk/include/mtd/nftl-user.h +++ b/trunk/include/mtd/nftl-user.h @@ -1,4 +1,6 @@ /* + * $Id: nftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $ + * * Parts of NFTL headers shared with userspace * */ diff --git a/trunk/include/net/af_unix.h b/trunk/include/net/af_unix.h index 7dd29b7e461d..2dfa96b0575e 100644 --- a/trunk/include/net/af_unix.h +++ b/trunk/include/net/af_unix.h @@ -51,7 +51,7 @@ struct unix_sock { struct sock *peer; struct sock *other; struct list_head link; - atomic_long_t inflight; + atomic_t inflight; spinlock_t lock; unsigned int gc_candidate : 1; wait_queue_head_t peer_wait; diff --git a/trunk/include/net/ip.h b/trunk/include/net/ip.h index 250e6ef025a4..b5862b975207 100644 --- a/trunk/include/net/ip.h +++ b/trunk/include/net/ip.h @@ -188,8 +188,6 @@ extern int sysctl_ip_dynaddr; extern void ipfrag_init(void); -extern void ip_static_sysctl_init(void); - #ifdef CONFIG_INET #include diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index 113028fb8f66..2d5c18514a2d 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -608,8 +608,6 @@ extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net); extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); extern int ipv6_sysctl_register(void); extern void ipv6_sysctl_unregister(void); -extern int ipv6_static_sysctl_register(void); -extern void ipv6_static_sysctl_unregister(void); #endif #endif /* __KERNEL__ */ diff --git a/trunk/include/net/net_namespace.h b/trunk/include/net/net_namespace.h index a8eb43cf0c7e..3855620b78a9 100644 --- a/trunk/include/net/net_namespace.h +++ b/trunk/include/net/net_namespace.h @@ -38,9 +38,7 @@ struct net { struct proc_dir_entry *proc_net; struct proc_dir_entry *proc_net_stat; -#ifdef CONFIG_SYSCTL - struct ctl_table_set sysctls; -#endif + struct list_head sysctl_table_headers; struct net_device *loopback_dev; /* The loopback */ diff --git a/trunk/include/net/request_sock.h b/trunk/include/net/request_sock.h index 8d6e991ef4df..0c96e7bed5db 100644 --- a/trunk/include/net/request_sock.h +++ b/trunk/include/net/request_sock.h @@ -18,7 +18,6 @@ #include #include #include -#include #include @@ -171,7 +170,7 @@ static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue { struct request_sock *req = queue->rskq_accept_head; - WARN_ON(req == NULL); + BUG_TRAP(req != NULL); queue->rskq_accept_head = req->dl_next; if (queue->rskq_accept_head == NULL) @@ -186,7 +185,7 @@ static inline struct sock *reqsk_queue_get_child(struct request_sock_queue *queu struct request_sock *req = reqsk_queue_remove(queue); struct sock *child = req->sk; - WARN_ON(child == NULL); + BUG_TRAP(child != NULL); sk_acceptq_removed(parent); __reqsk_free(req); diff --git a/trunk/include/net/route.h b/trunk/include/net/route.h index 4f0d8c14736c..3140cc500854 100644 --- a/trunk/include/net/route.h +++ b/trunk/include/net/route.h @@ -204,4 +204,6 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt) return rt->peer; } +extern ctl_table ipv4_route_table[]; + #endif /* _ROUTE_H */ diff --git a/trunk/include/rdma/ib_verbs.h b/trunk/include/rdma/ib_verbs.h index 936e333e7ce5..90b529f7a154 100644 --- a/trunk/include/rdma/ib_verbs.h +++ b/trunk/include/rdma/ib_verbs.h @@ -1590,7 +1590,7 @@ static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr) { if (dev->dma_ops) return dev->dma_ops->mapping_error(dev, dma_addr); - return dma_mapping_error(dev->dma_device, dma_addr); + return dma_mapping_error(dma_addr); } /** diff --git a/trunk/include/scsi/scsi.h b/trunk/include/scsi/scsi.h index 5c40cc537d4c..00137a7769ee 100644 --- a/trunk/include/scsi/scsi.h +++ b/trunk/include/scsi/scsi.h @@ -106,7 +106,6 @@ #define VARIABLE_LENGTH_CMD 0x7f #define REPORT_LUNS 0xa0 #define MAINTENANCE_IN 0xa3 -#define MAINTENANCE_OUT 0xa4 #define MOVE_MEDIUM 0xa5 #define EXCHANGE_MEDIUM 0xa6 #define READ_12 0xa8 @@ -126,8 +125,6 @@ #define SAI_READ_CAPACITY_16 0x10 /* values for maintenance in */ #define MI_REPORT_TARGET_PGS 0x0a -/* values for maintenance out */ -#define MO_SET_TARGET_PGS 0x0a /* Values for T10/04-262r7 */ #define ATA_16 0x85 /* 16-byte pass-thru */ diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h index f9f6e793575c..66c944849d6b 100644 --- a/trunk/include/scsi/scsi_cmnd.h +++ b/trunk/include/scsi/scsi_cmnd.h @@ -77,9 +77,6 @@ struct scsi_cmnd { int allowed; int timeout_per_command; - unsigned char prot_op; - unsigned char prot_type; - unsigned short cmd_len; enum dma_data_direction sc_data_direction; @@ -90,8 +87,6 @@ struct scsi_cmnd { /* These elements define the operation we ultimately want to perform */ struct scsi_data_buffer sdb; - struct scsi_data_buffer *prot_sdb; - unsigned underflow; /* Return error if less than this amount is transferred */ @@ -213,85 +208,4 @@ static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, buf, buflen); } -/* - * The operations below are hints that tell the controller driver how - * to handle I/Os with DIF or similar types of protection information. - */ -enum scsi_prot_operations { - /* Normal I/O */ - SCSI_PROT_NORMAL = 0, - - /* OS-HBA: Protected, HBA-Target: Unprotected */ - SCSI_PROT_READ_INSERT, - SCSI_PROT_WRITE_STRIP, - - /* OS-HBA: Unprotected, HBA-Target: Protected */ - SCSI_PROT_READ_STRIP, - SCSI_PROT_WRITE_INSERT, - - /* OS-HBA: Protected, HBA-Target: Protected */ - SCSI_PROT_READ_PASS, - SCSI_PROT_WRITE_PASS, - - /* OS-HBA: Protected, HBA-Target: Protected, checksum conversion */ - SCSI_PROT_READ_CONVERT, - SCSI_PROT_WRITE_CONVERT, -}; - -static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op) -{ - scmd->prot_op = op; -} - -static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd) -{ - return scmd->prot_op; -} - -/* - * The controller usually does not know anything about the target it - * is communicating with. However, when DIX is enabled the controller - * must be know target type so it can verify the protection - * information passed along with the I/O. - */ -enum scsi_prot_target_type { - SCSI_PROT_DIF_TYPE0 = 0, - SCSI_PROT_DIF_TYPE1, - SCSI_PROT_DIF_TYPE2, - SCSI_PROT_DIF_TYPE3, -}; - -static inline void scsi_set_prot_type(struct scsi_cmnd *scmd, unsigned char type) -{ - scmd->prot_type = type; -} - -static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd) -{ - return scmd->prot_type; -} - -static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) -{ - return scmd->request->sector; -} - -static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd) -{ - return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0; -} - -static inline struct scatterlist *scsi_prot_sglist(struct scsi_cmnd *cmd) -{ - return cmd->prot_sdb ? cmd->prot_sdb->table.sgl : NULL; -} - -static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd) -{ - return cmd->prot_sdb; -} - -#define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \ - for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i) - #endif /* _SCSI_SCSI_CMND_H */ diff --git a/trunk/include/scsi/scsi_device.h b/trunk/include/scsi/scsi_device.h index 291d56a19167..6467f78b191f 100644 --- a/trunk/include/scsi/scsi_device.h +++ b/trunk/include/scsi/scsi_device.h @@ -140,8 +140,7 @@ struct scsi_device { unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ - unsigned last_sector_bug:1; /* do not use multisector accesses on - SD_LAST_BUGGY_SECTORS */ + unsigned last_sector_bug:1; /* Always read last sector in a 1 sector read */ DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ struct list_head event_list; /* asserted events */ @@ -168,22 +167,15 @@ struct scsi_device { unsigned long sdev_data[0]; } __attribute__((aligned(sizeof(unsigned long)))); -struct scsi_dh_devlist { - char *vendor; - char *model; -}; - struct scsi_device_handler { /* Used by the infrastructure */ struct list_head list; /* list of scsi_device_handlers */ + struct notifier_block nb; /* Filled by the hardware handler */ struct module *module; const char *name; - const struct scsi_dh_devlist *devlist; int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); - int (*attach)(struct scsi_device *); - void (*detach)(struct scsi_device *); int (*activate)(struct scsi_device *); int (*prep_fn)(struct scsi_device *, struct request *); }; @@ -424,11 +416,6 @@ static inline int scsi_device_enclosure(struct scsi_device *sdev) return sdev->inquiry[6] & (1<<6); } -static inline int scsi_device_protection(struct scsi_device *sdev) -{ - return sdev->inquiry[5] & (1<<0); -} - #define MODULE_ALIAS_SCSI_DEVICE(type) \ MODULE_ALIAS("scsi:t-" __stringify(type) "*") #define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" diff --git a/trunk/include/scsi/scsi_dh.h b/trunk/include/scsi/scsi_dh.h index 33efce20c26c..3ad2303d1a16 100644 --- a/trunk/include/scsi/scsi_dh.h +++ b/trunk/include/scsi/scsi_dh.h @@ -32,7 +32,6 @@ enum { */ SCSI_DH_DEV_FAILED, /* generic device error */ SCSI_DH_DEV_TEMP_BUSY, - SCSI_DH_DEV_UNSUPP, /* device handler not supported */ SCSI_DH_DEVICE_MAX, /* max device blkerr definition */ /* @@ -58,8 +57,6 @@ enum { #if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) extern int scsi_dh_activate(struct request_queue *); extern int scsi_dh_handler_exist(const char *); -extern int scsi_dh_attach(struct request_queue *, const char *); -extern void scsi_dh_detach(struct request_queue *); #else static inline int scsi_dh_activate(struct request_queue *req) { @@ -69,12 +66,4 @@ static inline int scsi_dh_handler_exist(const char *name) { return 0; } -static inline int scsi_dh_attach(struct request_queue *req, const char *name) -{ - return SCSI_DH_NOSYS; -} -static inline void scsi_dh_detach(struct request_queue *q) -{ - return; -} #endif diff --git a/trunk/include/scsi/scsi_eh.h b/trunk/include/scsi/scsi_eh.h index 06a8790893ef..2a9add21267d 100644 --- a/trunk/include/scsi/scsi_eh.h +++ b/trunk/include/scsi/scsi_eh.h @@ -74,9 +74,7 @@ struct scsi_eh_save { /* saved state */ int result; enum dma_data_direction data_direction; - unsigned underflow; unsigned char cmd_len; - unsigned char prot_op; unsigned char *cmnd; struct scsi_data_buffer sdb; struct request *next_rq; diff --git a/trunk/include/scsi/scsi_host.h b/trunk/include/scsi/scsi_host.h index 44a55d1bf530..a594bac4a77d 100644 --- a/trunk/include/scsi/scsi_host.h +++ b/trunk/include/scsi/scsi_host.h @@ -547,7 +547,7 @@ struct Scsi_Host { unsigned int host_failed; /* commands that failed. */ unsigned int host_eh_scheduled; /* EH scheduled without command */ - unsigned int host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ + unsigned short host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ int resetting; /* if set, it means that last_reset is a valid value */ unsigned long last_reset; @@ -636,10 +636,6 @@ struct Scsi_Host { */ unsigned int max_host_blocked; - /* Protection Information */ - unsigned int prot_capabilities; - unsigned char prot_guard_type; - /* * q used for scsi_tgt msgs, async events or any other requests that * need to be processed in userspace @@ -760,86 +756,6 @@ extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, extern void scsi_free_host_dev(struct scsi_device *); extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); -/* - * DIF defines the exchange of protection information between - * initiator and SBC block device. - * - * DIX defines the exchange of protection information between OS and - * initiator. - */ -enum scsi_host_prot_capabilities { - SHOST_DIF_TYPE1_PROTECTION = 1 << 0, /* T10 DIF Type 1 */ - SHOST_DIF_TYPE2_PROTECTION = 1 << 1, /* T10 DIF Type 2 */ - SHOST_DIF_TYPE3_PROTECTION = 1 << 2, /* T10 DIF Type 3 */ - - SHOST_DIX_TYPE0_PROTECTION = 1 << 3, /* DIX between OS and HBA only */ - SHOST_DIX_TYPE1_PROTECTION = 1 << 4, /* DIX with DIF Type 1 */ - SHOST_DIX_TYPE2_PROTECTION = 1 << 5, /* DIX with DIF Type 2 */ - SHOST_DIX_TYPE3_PROTECTION = 1 << 6, /* DIX with DIF Type 3 */ -}; - -/* - * SCSI hosts which support the Data Integrity Extensions must - * indicate their capabilities by setting the prot_capabilities using - * this call. - */ -static inline void scsi_host_set_prot(struct Scsi_Host *shost, unsigned int mask) -{ - shost->prot_capabilities = mask; -} - -static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost) -{ - return shost->prot_capabilities; -} - -static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) -{ - switch (target_type) { - case 1: return shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION; - case 2: return shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION; - case 3: return shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION; - } - - return 0; -} - -static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) -{ - switch (target_type) { - case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION; - case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION; - case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION; - case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION; - } - - return 0; -} - -/* - * All DIX-capable initiators must support the T10-mandated CRC - * checksum. Controllers can optionally implement the IP checksum - * scheme which has much lower impact on system performance. Note - * that the main rationale for the checksum is to match integrity - * metadata with data. Detecting bit errors are a job for ECC memory - * and buses. - */ - -enum scsi_host_guard_type { - SHOST_DIX_GUARD_CRC = 1 << 0, - SHOST_DIX_GUARD_IP = 1 << 1, -}; - -static inline void scsi_host_set_guard(struct Scsi_Host *shost, unsigned char type) -{ - shost->prot_guard_type = type; -} - -static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost) -{ - return shost->prot_guard_type; -} - /* legacy interfaces */ extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); extern void scsi_unregister(struct Scsi_Host *); diff --git a/trunk/include/video/atmel_lcdc.h b/trunk/include/video/atmel_lcdc.h index 613173b5db69..1ccf462b433a 100644 --- a/trunk/include/video/atmel_lcdc.h +++ b/trunk/include/video/atmel_lcdc.h @@ -22,7 +22,6 @@ #ifndef __ATMEL_LCDC_H__ #define __ATMEL_LCDC_H__ -#include /* Way LCD wires are connected to the chip: * Some Atmel chips use BGR color mode (instead of standard RGB) diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index 43d6989c275f..a50bdfed2df7 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -171,7 +171,7 @@ config BSD_PROCESS_ACCT_V3 process and it's parent. Note that this file format is incompatible with previous v0/v1/v2 file formats, so you will need updated tools for processing it. A preliminary version of these tools is available - at . + at . config TASKSTATS bool "Export task/process statistics through netlink (EXPERIMENTAL)" @@ -486,7 +486,7 @@ config PID_NS default n depends on NAMESPACES && EXPERIMENTAL help - Support process id namespaces. This allows having multiple + Suport process id namespaces. This allows having multiple process with the same pid as long as they are in different pid namespaces. This is a building block of containers. diff --git a/trunk/init/do_mounts.c b/trunk/init/do_mounts.c index 3715feb8446d..f769fac4f4c0 100644 --- a/trunk/init/do_mounts.c +++ b/trunk/init/do_mounts.c @@ -23,7 +23,7 @@ int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ int root_mountflags = MS_RDONLY | MS_SILENT; -static char * __initdata root_device_name; +char * __initdata root_device_name; static char __initdata saved_root_name[64]; static int __initdata root_wait; diff --git a/trunk/init/do_mounts.h b/trunk/init/do_mounts.h index 9aa968d54329..735705d137ff 100644 --- a/trunk/init/do_mounts.h +++ b/trunk/init/do_mounts.h @@ -11,6 +11,7 @@ void change_floppy(char *fmt, ...); void mount_block_root(char *name, int flags); void mount_root(void); extern int root_mountflags; +extern char *root_device_name; static inline int create_dev(char *name, dev_t dev) { diff --git a/trunk/init/main.c b/trunk/init/main.c index 20fdc9884b77..0604cbcaf1e4 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -743,13 +743,13 @@ static void __init do_one_initcall(initcall_t fn) } -extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; +extern initcall_t __initcall_start[], __initcall_end[]; static void __init do_initcalls(void) { initcall_t *call; - for (call = __early_initcall_end; call < __initcall_end; call++) + for (call = __initcall_start; call < __initcall_end; call++) do_one_initcall(*call); /* Make sure there is no pending stuff from the initcall sequence */ @@ -774,12 +774,24 @@ static void __init do_basic_setup(void) do_initcalls(); } +static int __initdata nosoftlockup; + +static int __init nosoftlockup_setup(char *str) +{ + nosoftlockup = 1; + return 1; +} +__setup("nosoftlockup", nosoftlockup_setup); + static void __init do_pre_smp_initcalls(void) { - initcall_t *call; + extern int spawn_ksoftirqd(void); - for (call = __initcall_start; call < __early_initcall_end; call++) - do_one_initcall(*call); + init_call_single_data(); + migration_init(); + spawn_ksoftirqd(); + if (!nosoftlockup) + spawn_softlockup_task(); } static void run_init_process(char *init_filename) diff --git a/trunk/ipc/mqueue.c b/trunk/ipc/mqueue.c index 96fb36cd9874..1fdc2eb2f6d8 100644 --- a/trunk/ipc/mqueue.c +++ b/trunk/ipc/mqueue.c @@ -207,7 +207,7 @@ static int mqueue_get_sb(struct file_system_type *fs_type, return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; @@ -638,7 +638,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, return ERR_PTR(-EINVAL); } - if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { + if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) { dput(dentry); mntput(mqueue_mnt); return ERR_PTR(-EACCES); diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c index 657f8f8d93a5..66ec9fd21e0c 100644 --- a/trunk/kernel/cgroup.c +++ b/trunk/kernel/cgroup.c @@ -45,7 +45,6 @@ #include #include #include -#include #include @@ -1530,7 +1529,7 @@ static int cgroup_seqfile_show(struct seq_file *m, void *arg) return cft->read_seq_string(state->cgroup, cft, m); } -static int cgroup_seqfile_release(struct inode *inode, struct file *file) +int cgroup_seqfile_release(struct inode *inode, struct file *file) { struct seq_file *seq = file->private_data; kfree(seq->private); diff --git a/trunk/kernel/exec_domain.c b/trunk/kernel/exec_domain.c index 0d407e886735..c1ef192aa655 100644 --- a/trunk/kernel/exec_domain.c +++ b/trunk/kernel/exec_domain.c @@ -168,6 +168,7 @@ __set_personality(u_long personality) current->personality = personality; oep = current_thread_info()->exec_domain; current_thread_info()->exec_domain = ep; + set_fs_altroot(); module_put(oep->module); return 0; diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index eb4d6470d1d0..ad933bb29ec7 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -121,7 +120,18 @@ static void __exit_signal(struct task_struct *tsk) sig->nivcsw += tsk->nivcsw; sig->inblock += task_io_get_inblock(tsk); sig->oublock += task_io_get_oublock(tsk); - task_io_accounting_add(&sig->ioac, &tsk->ioac); +#ifdef CONFIG_TASK_XACCT + sig->rchar += tsk->rchar; + sig->wchar += tsk->wchar; + sig->syscr += tsk->syscr; + sig->syscw += tsk->syscw; +#endif /* CONFIG_TASK_XACCT */ +#ifdef CONFIG_TASK_IO_ACCOUNTING + sig->ioac.read_bytes += tsk->ioac.read_bytes; + sig->ioac.write_bytes += tsk->ioac.write_bytes; + sig->ioac.cancelled_write_bytes += + tsk->ioac.cancelled_write_bytes; +#endif /* CONFIG_TASK_IO_ACCOUNTING */ sig->sum_sched_runtime += tsk->se.sum_exec_runtime; sig = NULL; /* Marker for below. */ } @@ -152,17 +162,27 @@ static void delayed_put_task_struct(struct rcu_head *rhp) put_task_struct(container_of(rhp, struct task_struct, rcu)); } +/* + * Do final ptrace-related cleanup of a zombie being reaped. + * + * Called with write_lock(&tasklist_lock) held. + */ +static void ptrace_release_task(struct task_struct *p) +{ + BUG_ON(!list_empty(&p->ptraced)); + ptrace_unlink(p); + BUG_ON(!list_empty(&p->ptrace_entry)); +} void release_task(struct task_struct * p) { struct task_struct *leader; int zap_leader; repeat: - tracehook_prepare_release_task(p); atomic_dec(&p->user->processes); proc_flush_task(p); write_lock_irq(&tasklist_lock); - tracehook_finish_release_task(p); + ptrace_release_task(p); __exit_signal(p); /* @@ -184,13 +204,6 @@ void release_task(struct task_struct * p) * that case. */ zap_leader = task_detached(leader); - - /* - * This maintains the invariant that release_task() - * only runs on a task in EXIT_DEAD, just for sanity. - */ - if (zap_leader) - leader->exit_state = EXIT_DEAD; } write_unlock_irq(&tasklist_lock); @@ -554,6 +567,8 @@ void put_fs_struct(struct fs_struct *fs) if (atomic_dec_and_test(&fs->count)) { path_put(&fs->root); path_put(&fs->pwd); + if (fs->altroot.dentry) + path_put(&fs->altroot); kmem_cache_free(fs_cachep, fs); } } @@ -872,8 +887,7 @@ static void forget_original_parent(struct task_struct *father) */ static void exit_notify(struct task_struct *tsk, int group_dead) { - int signal; - void *cookie; + int state; /* * This does two things: @@ -910,11 +924,22 @@ static void exit_notify(struct task_struct *tsk, int group_dead) !capable(CAP_KILL)) tsk->exit_signal = SIGCHLD; - signal = tracehook_notify_death(tsk, &cookie, group_dead); - if (signal > 0) - signal = do_notify_parent(tsk, signal); + /* If something other than our normal parent is ptracing us, then + * send it a SIGCHLD instead of honoring exit_signal. exit_signal + * only has special meaning to our real parent. + */ + if (!task_detached(tsk) && thread_group_empty(tsk)) { + int signal = ptrace_reparented(tsk) ? + SIGCHLD : tsk->exit_signal; + do_notify_parent(tsk, signal); + } else if (tsk->ptrace) { + do_notify_parent(tsk, SIGCHLD); + } - tsk->exit_state = signal < 0 ? EXIT_DEAD : EXIT_ZOMBIE; + state = EXIT_ZOMBIE; + if (task_detached(tsk) && likely(!tsk->ptrace)) + state = EXIT_DEAD; + tsk->exit_state = state; /* mt-exec, de_thread() is waiting for us */ if (thread_group_leader(tsk) && @@ -924,10 +949,8 @@ static void exit_notify(struct task_struct *tsk, int group_dead) write_unlock_irq(&tasklist_lock); - tracehook_report_death(tsk, signal, cookie, group_dead); - /* If the process is dead, release it - nobody will wait for it */ - if (signal < 0) + if (state == EXIT_DEAD) release_task(tsk); } @@ -1006,7 +1029,10 @@ NORET_TYPE void do_exit(long code) if (unlikely(!tsk->pid)) panic("Attempted to kill the idle task!"); - tracehook_report_exit(&code); + if (unlikely(current->ptrace & PT_TRACE_EXIT)) { + current->ptrace_message = code; + ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP); + } /* * We're taking recursive faults here in do_exit. Safest is to just @@ -1352,8 +1378,21 @@ static int wait_task_zombie(struct task_struct *p, int options, psig->coublock += task_io_get_oublock(p) + sig->oublock + sig->coublock; - task_io_accounting_add(&psig->ioac, &p->ioac); - task_io_accounting_add(&psig->ioac, &sig->ioac); +#ifdef CONFIG_TASK_XACCT + psig->rchar += p->rchar + sig->rchar; + psig->wchar += p->wchar + sig->wchar; + psig->syscr += p->syscr + sig->syscr; + psig->syscw += p->syscw + sig->syscw; +#endif /* CONFIG_TASK_XACCT */ +#ifdef CONFIG_TASK_IO_ACCOUNTING + psig->ioac.read_bytes += + p->ioac.read_bytes + sig->ioac.read_bytes; + psig->ioac.write_bytes += + p->ioac.write_bytes + sig->ioac.write_bytes; + psig->ioac.cancelled_write_bytes += + p->ioac.cancelled_write_bytes + + sig->ioac.cancelled_write_bytes; +#endif /* CONFIG_TASK_IO_ACCOUNTING */ spin_unlock_irq(&p->parent->sighand->siglock); } diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 8214ba7c8bb1..b99d73e971a4 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -657,6 +656,13 @@ static struct fs_struct *__copy_fs_struct(struct fs_struct *old) path_get(&old->root); fs->pwd = old->pwd; path_get(&old->pwd); + if (old->altroot.dentry) { + fs->altroot = old->altroot; + path_get(&old->altroot); + } else { + fs->altroot.mnt = NULL; + fs->altroot.dentry = NULL; + } read_unlock(&old->lock); } return fs; @@ -806,7 +812,12 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; - task_io_accounting_init(&sig->ioac); +#ifdef CONFIG_TASK_XACCT + sig->rchar = sig->wchar = sig->syscr = sig->syscw = 0; +#endif +#ifdef CONFIG_TASK_IO_ACCOUNTING + memset(&sig->ioac, 0, sizeof(sig->ioac)); +#endif sig->sum_sched_runtime = 0; INIT_LIST_HEAD(&sig->cpu_timers[0]); INIT_LIST_HEAD(&sig->cpu_timers[1]); @@ -854,7 +865,8 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) new_flags &= ~PF_SUPERPRIV; new_flags |= PF_FORKNOEXEC; - new_flags |= PF_STARTING; + if (!(clone_flags & CLONE_PTRACE)) + p->ptrace = 0; p->flags = new_flags; clear_freeze_flag(p); } @@ -895,8 +907,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, struct pt_regs *regs, unsigned long stack_size, int __user *child_tidptr, - struct pid *pid, - int trace) + struct pid *pid) { int retval; struct task_struct *p; @@ -989,7 +1000,13 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->last_switch_timestamp = 0; #endif - task_io_accounting_init(&p->ioac); +#ifdef CONFIG_TASK_XACCT + p->rchar = 0; /* I/O counter: bytes read */ + p->wchar = 0; /* I/O counter: bytes written */ + p->syscr = 0; /* I/O counter: read syscalls */ + p->syscw = 0; /* I/O counter: write syscalls */ +#endif + task_io_accounting_init(p); acct_clear_integrals(p); p->it_virt_expires = cputime_zero; @@ -1146,6 +1163,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, */ p->group_leader = p; INIT_LIST_HEAD(&p->thread_group); + INIT_LIST_HEAD(&p->ptrace_entry); + INIT_LIST_HEAD(&p->ptraced); /* Now that the task is set up, run cgroup callbacks if * necessary. We need to run them before the task is visible @@ -1176,6 +1195,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->real_parent = current->real_parent; else p->real_parent = current; + p->parent = p->real_parent; spin_lock(¤t->sighand->siglock); @@ -1217,7 +1237,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, if (likely(p->pid)) { list_add_tail(&p->sibling, &p->real_parent->children); - tracehook_finish_clone(p, clone_flags, trace); + if (unlikely(p->ptrace & PT_PTRACED)) + __ptrace_link(p, current->parent); if (thread_group_leader(p)) { if (clone_flags & CLONE_NEWPID) @@ -1302,13 +1323,29 @@ struct task_struct * __cpuinit fork_idle(int cpu) struct pt_regs regs; task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, - &init_struct_pid, 0); + &init_struct_pid); if (!IS_ERR(task)) init_idle(task, cpu); return task; } +static int fork_traceflag(unsigned clone_flags) +{ + if (clone_flags & CLONE_UNTRACED) + return 0; + else if (clone_flags & CLONE_VFORK) { + if (current->ptrace & PT_TRACE_VFORK) + return PTRACE_EVENT_VFORK; + } else if ((clone_flags & CSIGNAL) != SIGCHLD) { + if (current->ptrace & PT_TRACE_CLONE) + return PTRACE_EVENT_CLONE; + } else if (current->ptrace & PT_TRACE_FORK) + return PTRACE_EVENT_FORK; + + return 0; +} + /* * Ok, this is the main fork-routine. * @@ -1343,14 +1380,14 @@ long do_fork(unsigned long clone_flags, } } - /* - * When called from kernel_thread, don't do user tracing stuff. - */ - if (likely(user_mode(regs))) - trace = tracehook_prepare_clone(clone_flags); + if (unlikely(current->ptrace)) { + trace = fork_traceflag (clone_flags); + if (trace) + clone_flags |= CLONE_PTRACE; + } p = copy_process(clone_flags, stack_start, regs, stack_size, - child_tidptr, NULL, trace); + child_tidptr, NULL); /* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. @@ -1368,35 +1405,32 @@ long do_fork(unsigned long clone_flags, init_completion(&vfork); } - tracehook_report_clone(trace, regs, clone_flags, nr, p); - - /* - * We set PF_STARTING at creation in case tracing wants to - * use this to distinguish a fully live task from one that - * hasn't gotten to tracehook_report_clone() yet. Now we - * clear it and set the child going. - */ - p->flags &= ~PF_STARTING; - - if (unlikely(clone_flags & CLONE_STOPPED)) { + if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) { /* * We'll start up with an immediate SIGSTOP. */ sigaddset(&p->pending.signal, SIGSTOP); set_tsk_thread_flag(p, TIF_SIGPENDING); - __set_task_state(p, TASK_STOPPED); - } else { - wake_up_new_task(p, clone_flags); } - tracehook_report_clone_complete(trace, regs, - clone_flags, nr, p); + if (!(clone_flags & CLONE_STOPPED)) + wake_up_new_task(p, clone_flags); + else + __set_task_state(p, TASK_STOPPED); + + if (unlikely (trace)) { + current->ptrace_message = nr; + ptrace_notify ((trace << 8) | SIGTRAP); + } if (clone_flags & CLONE_VFORK) { freezer_do_not_count(); wait_for_completion(&vfork); freezer_count(); - tracehook_report_vfork_done(p, nr); + if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) { + current->ptrace_message = nr; + ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP); + } } } else { nr = PTR_ERR(p); @@ -1408,7 +1442,7 @@ long do_fork(unsigned long clone_flags, #define ARCH_MIN_MMSTRUCT_ALIGN 0 #endif -static void sighand_ctor(void *data) +static void sighand_ctor(struct kmem_cache *cachep, void *data) { struct sighand_struct *sighand = data; diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index 3cd441ebf5d2..964964baefa2 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -28,7 +28,8 @@ void dynamic_irq_init(unsigned int irq) unsigned long flags; if (irq >= NR_IRQS) { - WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); + printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); + WARN_ON(1); return; } @@ -61,7 +62,8 @@ void dynamic_irq_cleanup(unsigned int irq) unsigned long flags; if (irq >= NR_IRQS) { - WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); + printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); + WARN_ON(1); return; } @@ -69,8 +71,9 @@ void dynamic_irq_cleanup(unsigned int irq) spin_lock_irqsave(&desc->lock, flags); if (desc->action) { spin_unlock_irqrestore(&desc->lock, flags); - WARN(1, KERN_ERR "Destroying IRQ%d without calling free_irq\n", + printk(KERN_ERR "Destroying IRQ%d without calling free_irq\n", irq); + WARN_ON(1); return; } desc->msi_desc = NULL; @@ -93,7 +96,8 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip) unsigned long flags; if (irq >= NR_IRQS) { - WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq); + printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq); + WARN_ON(1); return -EINVAL; } diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 152abfd3589f..f8914b92b664 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -177,7 +177,8 @@ static void __enable_irq(struct irq_desc *desc, unsigned int irq) { switch (desc->depth) { case 0: - WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); + printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); + WARN_ON(1); break; case 1: { unsigned int status = desc->status & ~IRQ_DISABLED; diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index c8a4370e2a34..1c5fcacbcf33 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -24,12 +24,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include @@ -248,12 +242,6 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, goto out; } - image->swap_page = kimage_alloc_control_pages(image, 0); - if (!image->swap_page) { - printk(KERN_ERR "Could not allocate swap buffer\n"); - goto out; - } - result = 0; out: if (result == 0) @@ -601,12 +589,14 @@ static void kimage_free_extra_pages(struct kimage *image) kimage_free_page_list(&image->unuseable_pages); } -static void kimage_terminate(struct kimage *image) +static int kimage_terminate(struct kimage *image) { if (*image->entry != 0) image->entry++; *image->entry = IND_DONE; + + return 0; } #define for_each_kimage_entry(image, ptr, entry) \ @@ -998,8 +988,6 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, if (result) goto out; - if (flags & KEXEC_PRESERVE_CONTEXT) - image->preserve_context = 1; result = machine_kexec_prepare(image); if (result) goto out; @@ -1009,7 +997,9 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, if (result) goto out; } - kimage_terminate(image); + result = kimage_terminate(image); + if (result) + goto out; } /* Install the new kernel, and Uninstall the old */ image = xchg(dest_image, image); @@ -1425,85 +1415,3 @@ static int __init crash_save_vmcoreinfo_init(void) } module_init(crash_save_vmcoreinfo_init) - -/** - * kernel_kexec - reboot the system - * - * Move into place and start executing a preloaded standalone - * executable. If nothing was preloaded return an error. - */ -int kernel_kexec(void) -{ - int error = 0; - - if (xchg(&kexec_lock, 1)) - return -EBUSY; - if (!kexec_image) { - error = -EINVAL; - goto Unlock; - } - - if (kexec_image->preserve_context) { -#ifdef CONFIG_KEXEC_JUMP - mutex_lock(&pm_mutex); - pm_prepare_console(); - error = freeze_processes(); - if (error) { - error = -EBUSY; - goto Restore_console; - } - suspend_console(); - error = device_suspend(PMSG_FREEZE); - if (error) - goto Resume_console; - error = disable_nonboot_cpus(); - if (error) - goto Resume_devices; - local_irq_disable(); - /* At this point, device_suspend() has been called, - * but *not* device_power_down(). We *must* - * device_power_down() now. Otherwise, drivers for - * some devices (e.g. interrupt controllers) become - * desynchronized with the actual state of the - * hardware at resume time, and evil weirdness ensues. - */ - error = device_power_down(PMSG_FREEZE); - if (error) - goto Enable_irqs; - save_processor_state(); -#endif - } else { - blocking_notifier_call_chain(&reboot_notifier_list, - SYS_RESTART, NULL); - system_state = SYSTEM_RESTART; - device_shutdown(); - sysdev_shutdown(); - printk(KERN_EMERG "Starting new kernel\n"); - machine_shutdown(); - } - - machine_kexec(kexec_image); - - if (kexec_image->preserve_context) { -#ifdef CONFIG_KEXEC_JUMP - restore_processor_state(); - device_power_up(PMSG_RESTORE); - Enable_irqs: - local_irq_enable(); - enable_nonboot_cpus(); - Resume_devices: - device_resume(PMSG_RESTORE); - Resume_console: - resume_console(); - thaw_processes(); - Restore_console: - pm_restore_console(); - mutex_unlock(&pm_mutex); -#endif - } - - Unlock: - xchg(&kexec_lock, 0); - - return error; -} diff --git a/trunk/kernel/kthread.c b/trunk/kernel/kthread.c index 96cff2f8710b..6111c27491b1 100644 --- a/trunk/kernel/kthread.c +++ b/trunk/kernel/kthread.c @@ -176,7 +176,7 @@ void kthread_bind(struct task_struct *k, unsigned int cpu) return; } /* Must have done schedule() in kthread() before we set_task_cpu */ - wait_task_inactive(k, 0); + wait_task_inactive(k); set_task_cpu(k, cpu); k->cpus_allowed = cpumask_of_cpu(cpu); k->rt.nr_cpus_allowed = 1; diff --git a/trunk/kernel/power/main.c b/trunk/kernel/power/main.c index 0b7476f5d2a6..95bff23ecdaa 100644 --- a/trunk/kernel/power/main.c +++ b/trunk/kernel/power/main.c @@ -635,13 +635,6 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state) } if (status < 0) printk(err_suspend, status); - - /* Some platforms can't detect that the alarm triggered the - * wakeup, or (accordingly) disable it after it afterwards. - * It's supposed to give oneshot behavior; cope. - */ - alm.enabled = false; - rtc_set_alarm(rtc, &alm); } static int __init has_wakealarm(struct device *dev, void *name_ptr) diff --git a/trunk/kernel/power/power.h b/trunk/kernel/power/power.h index acc0c101dbd5..700f44ec8406 100644 --- a/trunk/kernel/power/power.h +++ b/trunk/kernel/power/power.h @@ -53,6 +53,8 @@ extern int hibernation_platform_enter(void); extern int pfn_is_nosave(unsigned long); +extern struct mutex pm_mutex; + #define power_attr(_name) \ static struct kobj_attribute _name##_attr = { \ .attr = { \ diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 082b3fcb32a0..8392a9da6450 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -107,7 +107,7 @@ int ptrace_check_attach(struct task_struct *child, int kill) read_unlock(&tasklist_lock); if (!ret && !kill) - ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH; + wait_task_inactive(child); /* All systems go.. */ return ret; diff --git a/trunk/kernel/relay.c b/trunk/kernel/relay.c index 04006ef970b8..7de644cdec43 100644 --- a/trunk/kernel/relay.c +++ b/trunk/kernel/relay.c @@ -407,35 +407,6 @@ void relay_reset(struct rchan *chan) } EXPORT_SYMBOL_GPL(relay_reset); -static inline void relay_set_buf_dentry(struct rchan_buf *buf, - struct dentry *dentry) -{ - buf->dentry = dentry; - buf->dentry->d_inode->i_size = buf->early_bytes; -} - -static struct dentry *relay_create_buf_file(struct rchan *chan, - struct rchan_buf *buf, - unsigned int cpu) -{ - struct dentry *dentry; - char *tmpname; - - tmpname = kzalloc(NAME_MAX + 1, GFP_KERNEL); - if (!tmpname) - return NULL; - snprintf(tmpname, NAME_MAX, "%s%d", chan->base_filename, cpu); - - /* Create file in fs */ - dentry = chan->cb->create_buf_file(tmpname, chan->parent, - S_IRUSR, buf, - &chan->is_global); - - kfree(tmpname); - - return dentry; -} - /* * relay_open_buf - create a new relay channel buffer * @@ -445,34 +416,45 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu) { struct rchan_buf *buf = NULL; struct dentry *dentry; + char *tmpname; if (chan->is_global) return chan->buf[0]; + tmpname = kzalloc(NAME_MAX + 1, GFP_KERNEL); + if (!tmpname) + goto end; + snprintf(tmpname, NAME_MAX, "%s%d", chan->base_filename, cpu); + buf = relay_create_buf(chan); if (!buf) - return NULL; - - if (chan->has_base_filename) { - dentry = relay_create_buf_file(chan, buf, cpu); - if (!dentry) - goto free_buf; - relay_set_buf_dentry(buf, dentry); - } + goto free_name; buf->cpu = cpu; __relay_reset(buf, 1); + /* Create file in fs */ + dentry = chan->cb->create_buf_file(tmpname, chan->parent, S_IRUSR, + buf, &chan->is_global); + if (!dentry) + goto free_buf; + + buf->dentry = dentry; + if(chan->is_global) { chan->buf[0] = buf; buf->cpu = 0; } - return buf; + goto free_name; free_buf: relay_destroy_buf(buf); - return NULL; + buf = NULL; +free_name: + kfree(tmpname); +end: + return buf; } /** @@ -555,8 +537,8 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb, /** * relay_open - create a new relay channel - * @base_filename: base name of files to create, %NULL for buffering only - * @parent: dentry of parent directory, %NULL for root directory or buffer + * @base_filename: base name of files to create + * @parent: dentry of parent directory, %NULL for root directory * @subbuf_size: size of sub-buffers * @n_subbufs: number of sub-buffers * @cb: client callback functions @@ -578,6 +560,8 @@ struct rchan *relay_open(const char *base_filename, { unsigned int i; struct rchan *chan; + if (!base_filename) + return NULL; if (!(subbuf_size && n_subbufs)) return NULL; @@ -592,10 +576,7 @@ struct rchan *relay_open(const char *base_filename, chan->alloc_size = FIX_SIZE(subbuf_size * n_subbufs); chan->parent = parent; chan->private_data = private_data; - if (base_filename) { - chan->has_base_filename = 1; - strlcpy(chan->base_filename, base_filename, NAME_MAX); - } + strlcpy(chan->base_filename, base_filename, NAME_MAX); setup_callbacks(chan, cb); kref_init(&chan->kref); @@ -623,94 +604,6 @@ struct rchan *relay_open(const char *base_filename, } EXPORT_SYMBOL_GPL(relay_open); -struct rchan_percpu_buf_dispatcher { - struct rchan_buf *buf; - struct dentry *dentry; -}; - -/* Called in atomic context. */ -static void __relay_set_buf_dentry(void *info) -{ - struct rchan_percpu_buf_dispatcher *p = info; - - relay_set_buf_dentry(p->buf, p->dentry); -} - -/** - * relay_late_setup_files - triggers file creation - * @chan: channel to operate on - * @base_filename: base name of files to create - * @parent: dentry of parent directory, %NULL for root directory - * - * Returns 0 if successful, non-zero otherwise. - * - * Use to setup files for a previously buffer-only channel. - * Useful to do early tracing in kernel, before VFS is up, for example. - */ -int relay_late_setup_files(struct rchan *chan, - const char *base_filename, - struct dentry *parent) -{ - int err = 0; - unsigned int i, curr_cpu; - unsigned long flags; - struct dentry *dentry; - struct rchan_percpu_buf_dispatcher disp; - - if (!chan || !base_filename) - return -EINVAL; - - strlcpy(chan->base_filename, base_filename, NAME_MAX); - - mutex_lock(&relay_channels_mutex); - /* Is chan already set up? */ - if (unlikely(chan->has_base_filename)) - return -EEXIST; - chan->has_base_filename = 1; - chan->parent = parent; - curr_cpu = get_cpu(); - /* - * The CPU hotplug notifier ran before us and created buffers with - * no files associated. So it's safe to call relay_setup_buf_file() - * on all currently online CPUs. - */ - for_each_online_cpu(i) { - if (unlikely(!chan->buf[i])) { - printk(KERN_ERR "relay_late_setup_files: CPU %u " - "has no buffer, it must have!\n", i); - BUG(); - err = -EINVAL; - break; - } - - dentry = relay_create_buf_file(chan, chan->buf[i], i); - if (unlikely(!dentry)) { - err = -EINVAL; - break; - } - - if (curr_cpu == i) { - local_irq_save(flags); - relay_set_buf_dentry(chan->buf[i], dentry); - local_irq_restore(flags); - } else { - disp.buf = chan->buf[i]; - disp.dentry = dentry; - smp_mb(); - /* relay_channels_mutex must be held, so wait. */ - err = smp_call_function_single(i, - __relay_set_buf_dentry, - &disp, 1); - } - if (unlikely(err)) - break; - } - put_cpu(); - mutex_unlock(&relay_channels_mutex); - - return err; -} - /** * relay_switch_subbuf - switch to a new sub-buffer * @buf: channel buffer @@ -734,13 +627,8 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length) old_subbuf = buf->subbufs_produced % buf->chan->n_subbufs; buf->padding[old_subbuf] = buf->prev_padding; buf->subbufs_produced++; - if (buf->dentry) - buf->dentry->d_inode->i_size += - buf->chan->subbuf_size - - buf->padding[old_subbuf]; - else - buf->early_bytes += buf->chan->subbuf_size - - buf->padding[old_subbuf]; + buf->dentry->d_inode->i_size += buf->chan->subbuf_size - + buf->padding[old_subbuf]; smp_mb(); if (waitqueue_active(&buf->read_wait)) /* @@ -1349,4 +1237,4 @@ static __init int relay_init(void) return 0; } -early_initcall(relay_init); +module_init(relay_init); diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 0236958addcb..0047bd9b96aa 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -1867,24 +1867,16 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req) /* * wait_task_inactive - wait for a thread to unschedule. * - * If @match_state is nonzero, it's the @p->state value just checked and - * not expected to change. If it changes, i.e. @p might have woken up, - * then return zero. When we succeed in waiting for @p to be off its CPU, - * we return a positive number (its total switch count). If a second call - * a short while later returns the same number, the caller can be sure that - * @p has remained unscheduled the whole time. - * * The caller must ensure that the task *will* unschedule sometime soon, * else this function might spin for a *long* time. This function can't * be called with interrupts off, or it may introduce deadlock with * smp_call_function() if an IPI is sent by the same process we are * waiting to become inactive. */ -unsigned long wait_task_inactive(struct task_struct *p, long match_state) +void wait_task_inactive(struct task_struct *p) { unsigned long flags; int running, on_rq; - unsigned long ncsw; struct rq *rq; for (;;) { @@ -1907,11 +1899,8 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) * return false if the runqueue has changed and p * is actually now running somewhere else! */ - while (task_running(rq, p)) { - if (match_state && unlikely(p->state != match_state)) - return 0; + while (task_running(rq, p)) cpu_relax(); - } /* * Ok, time to look more closely! We need the rq @@ -1921,20 +1910,8 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) rq = task_rq_lock(p, &flags); running = task_running(rq, p); on_rq = p->se.on_rq; - ncsw = 0; - if (!match_state || p->state == match_state) { - ncsw = p->nivcsw + p->nvcsw; - if (unlikely(!ncsw)) - ncsw = 1; - } task_rq_unlock(rq, &flags); - /* - * If it changed from the expected state, bail out now. - */ - if (unlikely(!ncsw)) - break; - /* * Was it really running after all now that we * checked with the proper locks actually held? @@ -1967,8 +1944,6 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) */ break; } - - return ncsw; } /*** @@ -6414,7 +6389,7 @@ static struct notifier_block __cpuinitdata migration_notifier = { .priority = 10 }; -static int __init migration_init(void) +void __init migration_init(void) { void *cpu = (void *)(long)smp_processor_id(); int err; @@ -6424,10 +6399,7 @@ static int __init migration_init(void) BUG_ON(err == NOTIFY_BAD); migration_call(&migration_notifier, CPU_ONLINE, cpu); register_cpu_notifier(&migration_notifier); - - return err; } -early_initcall(migration_init); #endif #ifdef CONFIG_SMP diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 954f77d7e3bc..82c3545596c5 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -40,21 +39,24 @@ static struct kmem_cache *sigqueue_cachep; -static void __user *sig_handler(struct task_struct *t, int sig) +static int __sig_ignored(struct task_struct *t, int sig) { - return t->sighand->action[sig - 1].sa.sa_handler; -} + void __user *handler; -static int sig_handler_ignored(void __user *handler, int sig) -{ /* Is it explicitly or implicitly ignored? */ + + handler = t->sighand->action[sig - 1].sa.sa_handler; return handler == SIG_IGN || (handler == SIG_DFL && sig_kernel_ignore(sig)); } static int sig_ignored(struct task_struct *t, int sig) { - void __user *handler; + /* + * Tracers always want to know about signals.. + */ + if (t->ptrace & PT_PTRACED) + return 0; /* * Blocked signals are never ignored, since the @@ -64,14 +66,7 @@ static int sig_ignored(struct task_struct *t, int sig) if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) return 0; - handler = sig_handler(t, sig); - if (!sig_handler_ignored(handler, sig)) - return 0; - - /* - * Tracers may want to know about even ignored signals. - */ - return !tracehook_consider_ignored_signal(t, sig, handler); + return __sig_ignored(t, sig); } /* @@ -134,9 +129,7 @@ void recalc_sigpending_and_wake(struct task_struct *t) void recalc_sigpending(void) { - if (unlikely(tracehook_force_sigpending())) - set_thread_flag(TIF_SIGPENDING); - else if (!recalc_sigpending_tsk(current) && !freezing(current)) + if (!recalc_sigpending_tsk(current) && !freezing(current)) clear_thread_flag(TIF_SIGPENDING); } @@ -302,12 +295,12 @@ flush_signal_handlers(struct task_struct *t, int force_default) int unhandled_signal(struct task_struct *tsk, int sig) { - void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler; if (is_global_init(tsk)) return 1; - if (handler != SIG_IGN && handler != SIG_DFL) + if (tsk->ptrace & PT_PTRACED) return 0; - return !tracehook_consider_fatal_signal(tsk, sig, handler); + return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || + (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); } @@ -598,6 +591,9 @@ static int check_kill_permission(int sig, struct siginfo *info, return security_task_kill(t, info, sig, 0); } +/* forward decl */ +static void do_notify_parent_cldstop(struct task_struct *tsk, int why); + /* * Handle magic process-wide effects of stop/continue signals. Unlike * the signal actions, these happen immediately at signal-generation @@ -760,8 +756,7 @@ static void complete_signal(int sig, struct task_struct *p, int group) if (sig_fatal(p, sig) && !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && !sigismember(&t->real_blocked, sig) && - (sig == SIGKILL || - !tracehook_consider_fatal_signal(t, sig, SIG_DFL))) { + (sig == SIGKILL || !(t->ptrace & PT_PTRACED))) { /* * This signal will be fatal to the whole group. */ @@ -1328,11 +1323,9 @@ static inline void __wake_up_parent(struct task_struct *p, /* * Let a parent know about the death of a child. * For a stopped/continued status change, use do_notify_parent_cldstop instead. - * - * Returns -1 if our parent ignored us and so we've switched to - * self-reaping, or else @sig. */ -int do_notify_parent(struct task_struct *tsk, int sig) + +void do_notify_parent(struct task_struct *tsk, int sig) { struct siginfo info; unsigned long flags; @@ -1403,14 +1396,12 @@ int do_notify_parent(struct task_struct *tsk, int sig) */ tsk->exit_signal = -1; if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) - sig = -1; + sig = 0; } if (valid_signal(sig) && sig > 0) __group_send_sig_info(sig, &info, tsk->parent); __wake_up_parent(tsk, tsk->parent); spin_unlock_irqrestore(&psig->siglock, flags); - - return sig; } static void do_notify_parent_cldstop(struct task_struct *tsk, int why) @@ -1608,7 +1599,7 @@ finish_stop(int stop_count) * a group stop in progress and we are the last to stop, * report to the parent. When ptraced, every thread reports itself. */ - if (tracehook_notify_jctl(stop_count == 0, CLD_STOPPED)) { + if (stop_count == 0 || (current->ptrace & PT_PTRACED)) { read_lock(&tasklist_lock); do_notify_parent_cldstop(current, CLD_STOPPED); read_unlock(&tasklist_lock); @@ -1744,9 +1735,6 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, signal->flags &= ~SIGNAL_CLD_MASK; spin_unlock_irq(&sighand->siglock); - if (unlikely(!tracehook_notify_jctl(1, why))) - goto relock; - read_lock(&tasklist_lock); do_notify_parent_cldstop(current->group_leader, why); read_unlock(&tasklist_lock); @@ -1760,33 +1748,17 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, do_signal_stop(0)) goto relock; - /* - * Tracing can induce an artifical signal and choose sigaction. - * The return value in @signr determines the default action, - * but @info->si_signo is the signal number we will report. - */ - signr = tracehook_get_signal(current, regs, info, return_ka); - if (unlikely(signr < 0)) - goto relock; - if (unlikely(signr != 0)) - ka = return_ka; - else { - signr = dequeue_signal(current, ¤t->blocked, - info); + signr = dequeue_signal(current, ¤t->blocked, info); + if (!signr) + break; /* will return 0 */ + if (signr != SIGKILL) { + signr = ptrace_signal(signr, info, regs, cookie); if (!signr) - break; /* will return 0 */ - - if (signr != SIGKILL) { - signr = ptrace_signal(signr, info, - regs, cookie); - if (!signr) - continue; - } - - ka = &sighand->action[signr-1]; + continue; } + ka = &sighand->action[signr-1]; if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ continue; if (ka->sa.sa_handler != SIG_DFL) { @@ -1834,7 +1806,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, spin_lock_irq(&sighand->siglock); } - if (likely(do_signal_stop(info->si_signo))) { + if (likely(do_signal_stop(signr))) { /* It released the siglock. */ goto relock; } @@ -1855,7 +1827,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, if (sig_kernel_coredump(signr)) { if (print_fatal_signals) - print_fatal_signal(regs, info->si_signo); + print_fatal_signal(regs, signr); /* * If it was able to dump core, this kills all * other threads in the group and synchronizes with @@ -1864,13 +1836,13 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, * first and our do_group_exit call below will use * that value and ignore the one we pass it. */ - do_coredump(info->si_signo, info->si_signo, regs); + do_coredump((long)signr, signr, regs); } /* * Death signals, no core dump. */ - do_group_exit(info->si_signo); + do_group_exit(signr); /* NOTREACHED */ } spin_unlock_irq(&sighand->siglock); @@ -1912,7 +1884,7 @@ void exit_signals(struct task_struct *tsk) out: spin_unlock_irq(&tsk->sighand->siglock); - if (unlikely(group_stop) && tracehook_notify_jctl(1, CLD_STOPPED)) { + if (unlikely(group_stop)) { read_lock(&tasklist_lock); do_notify_parent_cldstop(tsk, CLD_STOPPED); read_unlock(&tasklist_lock); @@ -1923,6 +1895,7 @@ EXPORT_SYMBOL(recalc_sigpending); EXPORT_SYMBOL_GPL(dequeue_signal); EXPORT_SYMBOL(flush_signals); EXPORT_SYMBOL(force_sig); +EXPORT_SYMBOL(ptrace_notify); EXPORT_SYMBOL(send_sig); EXPORT_SYMBOL(send_sig_info); EXPORT_SYMBOL(sigprocmask); @@ -2326,7 +2299,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) * (for example, SIGCHLD), shall cause the pending signal to * be discarded, whether or not it is blocked" */ - if (sig_handler_ignored(sig_handler(t, sig), sig)) { + if (__sig_ignored(t, sig)) { sigemptyset(&mask); sigaddset(&mask, sig); rm_from_queue_full(&mask, &t->signal->shared_pending); diff --git a/trunk/kernel/smp.c b/trunk/kernel/smp.c index 96fc7c0edc59..462c785ca1ee 100644 --- a/trunk/kernel/smp.c +++ b/trunk/kernel/smp.c @@ -33,7 +33,7 @@ struct call_single_queue { spinlock_t lock; }; -static int __cpuinit init_call_single_data(void) +void __cpuinit init_call_single_data(void) { int i; @@ -43,9 +43,7 @@ static int __cpuinit init_call_single_data(void) spin_lock_init(&q->lock); INIT_LIST_HEAD(&q->list); } - return 0; } -early_initcall(init_call_single_data); static void csd_flag_wait(struct call_single_data *data) { diff --git a/trunk/kernel/softirq.c b/trunk/kernel/softirq.c index c506f266a6b9..f6b03d56c2bf 100644 --- a/trunk/kernel/softirq.c +++ b/trunk/kernel/softirq.c @@ -630,7 +630,7 @@ static struct notifier_block __cpuinitdata cpu_nfb = { .notifier_call = cpu_callback }; -static __init int spawn_ksoftirqd(void) +__init int spawn_ksoftirqd(void) { void *cpu = (void *)(long)smp_processor_id(); int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); @@ -640,7 +640,6 @@ static __init int spawn_ksoftirqd(void) register_cpu_notifier(&cpu_nfb); return 0; } -early_initcall(spawn_ksoftirqd); #ifdef CONFIG_SMP /* diff --git a/trunk/kernel/softlockup.c b/trunk/kernel/softlockup.c index b75b492fbfcf..7bd8d1aadd5d 100644 --- a/trunk/kernel/softlockup.c +++ b/trunk/kernel/softlockup.c @@ -338,33 +338,14 @@ static struct notifier_block __cpuinitdata cpu_nfb = { .notifier_call = cpu_callback }; -static int __initdata nosoftlockup; - -static int __init nosoftlockup_setup(char *str) -{ - nosoftlockup = 1; - return 1; -} -__setup("nosoftlockup", nosoftlockup_setup); - -static int __init spawn_softlockup_task(void) +__init void spawn_softlockup_task(void) { void *cpu = (void *)(long)smp_processor_id(); - int err; + int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); - if (nosoftlockup) - return 0; - - err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); - if (err == NOTIFY_BAD) { - BUG(); - return 1; - } + BUG_ON(err == NOTIFY_BAD); cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); register_cpu_notifier(&cpu_nfb); atomic_notifier_chain_register(&panic_notifier_list, &panic_block); - - return 0; } -early_initcall(spawn_softlockup_task); diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index c01858090a98..0c9d3fa1f5ff 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -301,6 +301,26 @@ void kernel_restart(char *cmd) } EXPORT_SYMBOL_GPL(kernel_restart); +/** + * kernel_kexec - reboot the system + * + * Move into place and start executing a preloaded standalone + * executable. If nothing was preloaded return an error. + */ +static void kernel_kexec(void) +{ +#ifdef CONFIG_KEXEC + struct kimage *image; + image = xchg(&kexec_image, NULL); + if (!image) + return; + kernel_restart_prepare(NULL); + printk(KERN_EMERG "Starting new kernel\n"); + machine_shutdown(); + machine_kexec(image); +#endif +} + static void kernel_shutdown_prepare(enum system_states state) { blocking_notifier_call_chain(&reboot_notifier_list, @@ -405,15 +425,10 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user kernel_restart(buffer); break; -#ifdef CONFIG_KEXEC case LINUX_REBOOT_CMD_KEXEC: - { - int ret; - ret = kernel_kexec(); - unlock_kernel(); - return ret; - } -#endif + kernel_kexec(); + unlock_kernel(); + return -EINVAL; #ifdef CONFIG_HIBERNATION case LINUX_REBOOT_CMD_SW_SUSPEND: diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index fe4713347275..35a50db9b6ce 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -160,13 +160,12 @@ static struct ctl_table root_table[]; static struct ctl_table_root sysctl_table_root; static struct ctl_table_header root_table_header = { .ctl_table = root_table, - .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list), + .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.header_list), .root = &sysctl_table_root, - .set = &sysctl_table_root.default_set, }; static struct ctl_table_root sysctl_table_root = { .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list), - .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry), + .header_list = LIST_HEAD_INIT(root_table_header.ctl_entry), }; static struct ctl_table kern_table[]; @@ -1387,9 +1386,6 @@ static void start_unregistering(struct ctl_table_header *p) spin_unlock(&sysctl_lock); wait_for_completion(&wait); spin_lock(&sysctl_lock); - } else { - /* anything non-NULL; we'll never dereference it */ - p->unregistering = ERR_PTR(-EINVAL); } /* * do not remove from the list until nobody holds it; walking the @@ -1398,32 +1394,6 @@ static void start_unregistering(struct ctl_table_header *p) list_del_init(&p->ctl_entry); } -void sysctl_head_get(struct ctl_table_header *head) -{ - spin_lock(&sysctl_lock); - head->count++; - spin_unlock(&sysctl_lock); -} - -void sysctl_head_put(struct ctl_table_header *head) -{ - spin_lock(&sysctl_lock); - if (!--head->count) - kfree(head); - spin_unlock(&sysctl_lock); -} - -struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head) -{ - if (!head) - BUG(); - spin_lock(&sysctl_lock); - if (!use_table(head)) - head = ERR_PTR(-ENOENT); - spin_unlock(&sysctl_lock); - return head; -} - void sysctl_head_finish(struct ctl_table_header *head) { if (!head) @@ -1433,20 +1403,14 @@ void sysctl_head_finish(struct ctl_table_header *head) spin_unlock(&sysctl_lock); } -static struct ctl_table_set * -lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces) -{ - struct ctl_table_set *set = &root->default_set; - if (root->lookup) - set = root->lookup(root, namespaces); - return set; -} - static struct list_head * lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces) { - struct ctl_table_set *set = lookup_header_set(root, namespaces); - return &set->list; + struct list_head *header_list; + header_list = &root->header_list; + if (root->lookup) + header_list = root->lookup(root, namespaces); + return header_list; } struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, @@ -1516,9 +1480,9 @@ static int do_sysctl_strategy(struct ctl_table_root *root, int op = 0, rc; if (oldval) - op |= MAY_READ; + op |= 004; if (newval) - op |= MAY_WRITE; + op |= 002; if (sysctl_perm(root, table, op)) return -EPERM; @@ -1560,7 +1524,7 @@ static int parse_table(int __user *name, int nlen, if (n == table->ctl_name) { int error; if (table->child) { - if (sysctl_perm(root, table, MAY_EXEC)) + if (sysctl_perm(root, table, 001)) return -EPERM; name++; nlen--; @@ -1635,7 +1599,7 @@ static int test_perm(int mode, int op) mode >>= 6; else if (in_egroup_p(0)) mode >>= 3; - if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0) + if ((mode & op & 0007) == op) return 0; return -EACCES; } @@ -1645,7 +1609,7 @@ int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) int error; int mode; - error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC)); + error = security_sysctl(table, op); if (error) return error; @@ -1680,54 +1644,6 @@ static __init int sysctl_init(void) core_initcall(sysctl_init); -static struct ctl_table *is_branch_in(struct ctl_table *branch, - struct ctl_table *table) -{ - struct ctl_table *p; - const char *s = branch->procname; - - /* branch should have named subdirectory as its first element */ - if (!s || !branch->child) - return NULL; - - /* ... and nothing else */ - if (branch[1].procname || branch[1].ctl_name) - return NULL; - - /* table should contain subdirectory with the same name */ - for (p = table; p->procname || p->ctl_name; p++) { - if (!p->child) - continue; - if (p->procname && strcmp(p->procname, s) == 0) - return p; - } - return NULL; -} - -/* see if attaching q to p would be an improvement */ -static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q) -{ - struct ctl_table *to = p->ctl_table, *by = q->ctl_table; - struct ctl_table *next; - int is_better = 0; - int not_in_parent = !p->attached_by; - - while ((next = is_branch_in(by, to)) != NULL) { - if (by == q->attached_by) - is_better = 1; - if (to == p->attached_by) - not_in_parent = 1; - by = by->child; - to = next->child; - } - - if (is_better && not_in_parent) { - q->attached_by = by; - q->attached_to = to; - q->parent = p; - } -} - /** * __register_sysctl_paths - register a sysctl hierarchy * @root: List of sysctl headers to register on @@ -1804,10 +1720,10 @@ struct ctl_table_header *__register_sysctl_paths( struct nsproxy *namespaces, const struct ctl_path *path, struct ctl_table *table) { + struct list_head *header_list; struct ctl_table_header *header; struct ctl_table *new, **prevp; unsigned int n, npath; - struct ctl_table_set *set; /* Count the path components */ for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath) @@ -1849,7 +1765,6 @@ struct ctl_table_header *__register_sysctl_paths( header->unregistering = NULL; header->root = root; sysctl_set_parent(NULL, header->ctl_table); - header->count = 1; #ifdef CONFIG_SYSCTL_SYSCALL_CHECK if (sysctl_check_table(namespaces, header->ctl_table)) { kfree(header); @@ -1857,20 +1772,8 @@ struct ctl_table_header *__register_sysctl_paths( } #endif spin_lock(&sysctl_lock); - header->set = lookup_header_set(root, namespaces); - header->attached_by = header->ctl_table; - header->attached_to = root_table; - header->parent = &root_table_header; - for (set = header->set; set; set = set->parent) { - struct ctl_table_header *p; - list_for_each_entry(p, &set->list, ctl_entry) { - if (p->unregistering) - continue; - try_attach(p, header); - } - } - header->parent->count++; - list_add_tail(&header->ctl_entry, &header->set->list); + header_list = lookup_header_list(root, namespaces); + list_add_tail(&header->ctl_entry, header_list); spin_unlock(&sysctl_lock); return header; @@ -1925,37 +1828,8 @@ void unregister_sysctl_table(struct ctl_table_header * header) spin_lock(&sysctl_lock); start_unregistering(header); - if (!--header->parent->count) { - WARN_ON(1); - kfree(header->parent); - } - if (!--header->count) - kfree(header); spin_unlock(&sysctl_lock); -} - -int sysctl_is_seen(struct ctl_table_header *p) -{ - struct ctl_table_set *set = p->set; - int res; - spin_lock(&sysctl_lock); - if (p->unregistering) - res = 0; - else if (!set->is_seen) - res = 1; - else - res = set->is_seen(set); - spin_unlock(&sysctl_lock); - return res; -} - -void setup_sysctl_set(struct ctl_table_set *p, - struct ctl_table_set *parent, - int (*is_seen)(struct ctl_table_set *)) -{ - INIT_LIST_HEAD(&p->list); - p->parent = parent ? parent : &sysctl_table_root.default_set; - p->is_seen = is_seen; + kfree(header); } #else /* !CONFIG_SYSCTL */ @@ -1974,16 +1848,6 @@ void unregister_sysctl_table(struct ctl_table_header * table) { } -void setup_sysctl_set(struct ctl_table_set *p, - struct ctl_table_set *parent, - int (*is_seen)(struct ctl_table_set *)) -{ -} - -void sysctl_head_put(struct ctl_table_header *head) -{ -} - #endif /* CONFIG_SYSCTL */ /* diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 8f3fb3db61c3..868e121c8e38 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -1183,6 +1183,7 @@ static void *find_next_entry_inc(struct trace_iterator *iter) static void *s_next(struct seq_file *m, void *v, loff_t *pos) { struct trace_iterator *iter = m->private; + void *last_ent = iter->ent; int i = (int)*pos; void *ent; @@ -1202,6 +1203,9 @@ static void *s_next(struct seq_file *m, void *v, loff_t *pos) iter->pos = *pos; + if (last_ent && !ent) + seq_puts(m, "\n\nvim:ft=help\n"); + return ent; } diff --git a/trunk/kernel/trace/trace_irqsoff.c b/trunk/kernel/trace/trace_irqsoff.c index ece6cfb649fa..421d6fe3650e 100644 --- a/trunk/kernel/trace/trace_irqsoff.c +++ b/trunk/kernel/trace/trace_irqsoff.c @@ -253,14 +253,12 @@ void start_critical_timings(void) if (preempt_trace() || irq_trace()) start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } -EXPORT_SYMBOL_GPL(start_critical_timings); void stop_critical_timings(void) { if (preempt_trace() || irq_trace()) stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } -EXPORT_SYMBOL_GPL(stop_critical_timings); #ifdef CONFIG_IRQSOFF_TRACER #ifdef CONFIG_PROVE_LOCKING @@ -339,14 +337,12 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller); #ifdef CONFIG_PREEMPT_TRACER void trace_preempt_on(unsigned long a0, unsigned long a1) { - if (preempt_trace()) - stop_critical_timing(a0, a1); + stop_critical_timing(a0, a1); } void trace_preempt_off(unsigned long a0, unsigned long a1) { - if (preempt_trace()) - start_critical_timing(a0, a1); + start_critical_timing(a0, a1); } #endif /* CONFIG_PREEMPT_TRACER */ diff --git a/trunk/kernel/trace/trace_sched_wakeup.c b/trunk/kernel/trace/trace_sched_wakeup.c index e303ccb62cdf..3c8d61df4474 100644 --- a/trunk/kernel/trace/trace_sched_wakeup.c +++ b/trunk/kernel/trace/trace_sched_wakeup.c @@ -26,8 +26,7 @@ static struct task_struct *wakeup_task; static int wakeup_cpu; static unsigned wakeup_prio = -1; -static raw_spinlock_t wakeup_lock = - (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(wakeup_lock); static void __wakeup_reset(struct trace_array *tr); @@ -57,8 +56,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip) if (unlikely(disabled != 1)) goto out; - local_irq_save(flags); - __raw_spin_lock(&wakeup_lock); + spin_lock_irqsave(&wakeup_lock, flags); if (unlikely(!wakeup_task)) goto unlock; @@ -73,8 +71,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip) trace_function(tr, data, ip, parent_ip, flags); unlock: - __raw_spin_unlock(&wakeup_lock); - local_irq_restore(flags); + spin_unlock_irqrestore(&wakeup_lock, flags); out: atomic_dec(&data->disabled); @@ -148,8 +145,7 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev, if (likely(disabled != 1)) goto out; - local_irq_save(flags); - __raw_spin_lock(&wakeup_lock); + spin_lock_irqsave(&wakeup_lock, flags); /* We could race with grabbing wakeup_lock */ if (unlikely(!tracer_enabled || next != wakeup_task)) @@ -178,8 +174,7 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev, out_unlock: __wakeup_reset(tr); - __raw_spin_unlock(&wakeup_lock); - local_irq_restore(flags); + spin_unlock_irqrestore(&wakeup_lock, flags); out: atomic_dec(&tr->data[cpu]->disabled); } @@ -214,6 +209,8 @@ static void __wakeup_reset(struct trace_array *tr) struct trace_array_cpu *data; int cpu; + assert_spin_locked(&wakeup_lock); + for_each_possible_cpu(cpu) { data = tr->data[cpu]; tracing_reset(data); @@ -232,11 +229,9 @@ static void wakeup_reset(struct trace_array *tr) { unsigned long flags; - local_irq_save(flags); - __raw_spin_lock(&wakeup_lock); + spin_lock_irqsave(&wakeup_lock, flags); __wakeup_reset(tr); - __raw_spin_unlock(&wakeup_lock); - local_irq_restore(flags); + spin_unlock_irqrestore(&wakeup_lock, flags); } static void @@ -257,7 +252,7 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p, goto out; /* interrupts should be off from try_to_wake_up */ - __raw_spin_lock(&wakeup_lock); + spin_lock(&wakeup_lock); /* check for races. */ if (!tracer_enabled || p->prio >= wakeup_prio) @@ -279,7 +274,7 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p, CALLER_ADDR1, CALLER_ADDR2, flags); out_locked: - __raw_spin_unlock(&wakeup_lock); + spin_unlock(&wakeup_lock); out: atomic_dec(&tr->data[cpu]->disabled); } diff --git a/trunk/kernel/tsacct.c b/trunk/kernel/tsacct.c index 8ebcd8532dfb..3da47ccdc5e5 100644 --- a/trunk/kernel/tsacct.c +++ b/trunk/kernel/tsacct.c @@ -94,10 +94,10 @@ void xacct_add_tsk(struct taskstats *stats, struct task_struct *p) stats->hiwater_vm = mm->hiwater_vm * PAGE_SIZE / KB; mmput(mm); } - stats->read_char = p->ioac.rchar; - stats->write_char = p->ioac.wchar; - stats->read_syscalls = p->ioac.syscr; - stats->write_syscalls = p->ioac.syscw; + stats->read_char = p->rchar; + stats->write_char = p->wchar; + stats->read_syscalls = p->syscr; + stats->write_syscalls = p->syscw; #ifdef CONFIG_TASK_IO_ACCOUNTING stats->read_bytes = p->ioac.read_bytes; stats->write_bytes = p->ioac.write_bytes; diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index 3b1f94bbe9de..9085ad6fa53d 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -11,7 +11,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o \ idr.o int_sqrt.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ - proportions.o prio_heap.o ratelimit.o show_mem.o + proportions.o prio_heap.o ratelimit.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o @@ -78,8 +78,6 @@ lib-$(CONFIG_GENERIC_BUG) += bug.o obj-$(CONFIG_HAVE_LMB) += lmb.o -obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o - hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/trunk/lib/debugobjects.c b/trunk/lib/debugobjects.c index 45a6bde762d1..f86196390cfd 100644 --- a/trunk/lib/debugobjects.c +++ b/trunk/lib/debugobjects.c @@ -205,8 +205,9 @@ static void debug_print_object(struct debug_obj *obj, char *msg) if (limit < 5 && obj->descr != descr_test) { limit++; - WARN(1, KERN_ERR "ODEBUG: %s %s object type: %s\n", msg, + printk(KERN_ERR "ODEBUG: %s %s object type: %s\n", msg, obj_states[obj->state], obj->descr->name); + WARN_ON(1); } debug_objects_warnings++; } @@ -732,22 +733,26 @@ check_results(void *addr, enum debug_obj_state state, int fixups, int warnings) obj = lookup_object(addr, db); if (!obj && state != ODEBUG_STATE_NONE) { - WARN(1, KERN_ERR "ODEBUG: selftest object not found\n"); + printk(KERN_ERR "ODEBUG: selftest object not found\n"); + WARN_ON(1); goto out; } if (obj && obj->state != state) { - WARN(1, KERN_ERR "ODEBUG: selftest wrong state: %d != %d\n", + printk(KERN_ERR "ODEBUG: selftest wrong state: %d != %d\n", obj->state, state); + WARN_ON(1); goto out; } if (fixups != debug_objects_fixups) { - WARN(1, KERN_ERR "ODEBUG: selftest fixups failed %d != %d\n", + printk(KERN_ERR "ODEBUG: selftest fixups failed %d != %d\n", fixups, debug_objects_fixups); + WARN_ON(1); goto out; } if (warnings != debug_objects_warnings) { - WARN(1, KERN_ERR "ODEBUG: selftest warnings failed %d != %d\n", + printk(KERN_ERR "ODEBUG: selftest warnings failed %d != %d\n", warnings, debug_objects_warnings); + WARN_ON(1); goto out; } res = 0; diff --git a/trunk/lib/idr.c b/trunk/lib/idr.c index e728c7fccc4d..3476f8203e97 100644 --- a/trunk/lib/idr.c +++ b/trunk/lib/idr.c @@ -607,7 +607,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id) } EXPORT_SYMBOL(idr_replace); -static void idr_cache_ctor(void *idr_layer) +static void idr_cache_ctor(struct kmem_cache *idr_layer_cache, void *idr_layer) { memset(idr_layer, 0, sizeof(struct idr_layer)); } diff --git a/trunk/lib/iomap.c b/trunk/lib/iomap.c index d32229385151..37a3ea4cac9f 100644 --- a/trunk/lib/iomap.c +++ b/trunk/lib/iomap.c @@ -40,7 +40,8 @@ static void bad_io_access(unsigned long port, const char *access) static int count = 10; if (count) { count--; - WARN(1, KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access); + printk(KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access); + WARN_ON(1); } } diff --git a/trunk/lib/kobject_uevent.c b/trunk/lib/kobject_uevent.c index 3f914725bda8..9f8d599459d1 100644 --- a/trunk/lib/kobject_uevent.c +++ b/trunk/lib/kobject_uevent.c @@ -285,7 +285,8 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) int len; if (env->envp_idx >= ARRAY_SIZE(env->envp)) { - WARN(1, KERN_ERR "add_uevent_var: too many keys\n"); + printk(KERN_ERR "add_uevent_var: too many keys\n"); + WARN_ON(1); return -ENOMEM; } @@ -296,7 +297,8 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) va_end(args); if (len >= (sizeof(env->buf) - env->buflen)) { - WARN(1, KERN_ERR "add_uevent_var: buffer size too small\n"); + printk(KERN_ERR "add_uevent_var: buffer size too small\n"); + WARN_ON(1); return -ENOMEM; } diff --git a/trunk/lib/plist.c b/trunk/lib/plist.c index d6c64a824e1d..3074a02272f3 100644 --- a/trunk/lib/plist.c +++ b/trunk/lib/plist.c @@ -31,13 +31,12 @@ static void plist_check_prev_next(struct list_head *t, struct list_head *p, struct list_head *n) { - WARN(n->prev != p || p->next != n, - "top: %p, n: %p, p: %p\n" - "prev: %p, n: %p, p: %p\n" - "next: %p, n: %p, p: %p\n", - t, t->next, t->prev, - p, p->next, p->prev, - n, n->next, n->prev); + if (n->prev != p || p->next != n) { + printk("top: %p, n: %p, p: %p\n", t, t->next, t->prev); + printk("prev: %p, n: %p, p: %p\n", p, p->next, p->prev); + printk("next: %p, n: %p, p: %p\n", n, n->next, n->prev); + WARN_ON(1); + } } static void plist_check_list(struct list_head *top) diff --git a/trunk/lib/radix-tree.c b/trunk/lib/radix-tree.c index be86b32bc874..56ec21a7f73d 100644 --- a/trunk/lib/radix-tree.c +++ b/trunk/lib/radix-tree.c @@ -359,17 +359,18 @@ EXPORT_SYMBOL(radix_tree_insert); * Returns: the slot corresponding to the position @index in the * radix tree @root. This is useful for update-if-exists operations. * - * This function can be called under rcu_read_lock iff the slot is not - * modified by radix_tree_replace_slot, otherwise it must be called - * exclusive from other writers. Any dereference of the slot must be done - * using radix_tree_deref_slot. + * This function cannot be called under rcu_read_lock, it must be + * excluded from writers, as must the returned slot for subsequent + * use by radix_tree_deref_slot() and radix_tree_replace slot. + * Caller must hold tree write locked across slot lookup and + * replace. */ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) { unsigned int height, shift; struct radix_tree_node *node, **slot; - node = rcu_dereference(root->rnode); + node = root->rnode; if (node == NULL) return NULL; @@ -389,7 +390,7 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) do { slot = (struct radix_tree_node **) (node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK)); - node = rcu_dereference(*slot); + node = *slot; if (node == NULL) return NULL; @@ -666,7 +667,7 @@ unsigned long radix_tree_next_hole(struct radix_tree_root *root, EXPORT_SYMBOL(radix_tree_next_hole); static unsigned int -__lookup(struct radix_tree_node *slot, void ***results, unsigned long index, +__lookup(struct radix_tree_node *slot, void **results, unsigned long index, unsigned int max_items, unsigned long *next_index) { unsigned int nr_found = 0; @@ -700,9 +701,11 @@ __lookup(struct radix_tree_node *slot, void ***results, unsigned long index, /* Bottom level: grab some items */ for (i = index & RADIX_TREE_MAP_MASK; i < RADIX_TREE_MAP_SIZE; i++) { + struct radix_tree_node *node; index++; - if (slot->slots[i]) { - results[nr_found++] = &(slot->slots[i]); + node = slot->slots[i]; + if (node) { + results[nr_found++] = rcu_dereference(node); if (nr_found == max_items) goto out; } @@ -756,22 +759,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, ret = 0; while (ret < max_items) { - unsigned int nr_found, slots_found, i; + unsigned int nr_found; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; - slots_found = __lookup(node, (void ***)results + ret, cur_index, + nr_found = __lookup(node, results + ret, cur_index, max_items - ret, &next_index); - nr_found = 0; - for (i = 0; i < slots_found; i++) { - struct radix_tree_node *slot; - slot = *(((void ***)results)[ret + i]); - if (!slot) - continue; - results[ret + nr_found] = rcu_dereference(slot); - nr_found++; - } ret += nr_found; if (next_index == 0) break; @@ -782,71 +776,12 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, } EXPORT_SYMBOL(radix_tree_gang_lookup); -/** - * radix_tree_gang_lookup_slot - perform multiple slot lookup on radix tree - * @root: radix tree root - * @results: where the results of the lookup are placed - * @first_index: start the lookup from this key - * @max_items: place up to this many items at *results - * - * Performs an index-ascending scan of the tree for present items. Places - * their slots at *@results and returns the number of items which were - * placed at *@results. - * - * The implementation is naive. - * - * Like radix_tree_gang_lookup as far as RCU and locking goes. Slots must - * be dereferenced with radix_tree_deref_slot, and if using only RCU - * protection, radix_tree_deref_slot may fail requiring a retry. - */ -unsigned int -radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, - unsigned long first_index, unsigned int max_items) -{ - unsigned long max_index; - struct radix_tree_node *node; - unsigned long cur_index = first_index; - unsigned int ret; - - node = rcu_dereference(root->rnode); - if (!node) - return 0; - - if (!radix_tree_is_indirect_ptr(node)) { - if (first_index > 0) - return 0; - results[0] = (void **)&root->rnode; - return 1; - } - node = radix_tree_indirect_to_ptr(node); - - max_index = radix_tree_maxindex(node->height); - - ret = 0; - while (ret < max_items) { - unsigned int slots_found; - unsigned long next_index; /* Index of next search */ - - if (cur_index > max_index) - break; - slots_found = __lookup(node, results + ret, cur_index, - max_items - ret, &next_index); - ret += slots_found; - if (next_index == 0) - break; - cur_index = next_index; - } - - return ret; -} -EXPORT_SYMBOL(radix_tree_gang_lookup_slot); - /* * FIXME: the two tag_get()s here should use find_next_bit() instead of * open-coding the search. */ static unsigned int -__lookup_tag(struct radix_tree_node *slot, void ***results, unsigned long index, +__lookup_tag(struct radix_tree_node *slot, void **results, unsigned long index, unsigned int max_items, unsigned long *next_index, unsigned int tag) { unsigned int nr_found = 0; @@ -876,9 +811,11 @@ __lookup_tag(struct radix_tree_node *slot, void ***results, unsigned long index, unsigned long j = index & RADIX_TREE_MAP_MASK; for ( ; j < RADIX_TREE_MAP_SIZE; j++) { + struct radix_tree_node *node; index++; if (!tag_get(slot, tag, j)) continue; + node = slot->slots[j]; /* * Even though the tag was found set, we need to * recheck that we have a non-NULL node, because @@ -889,8 +826,9 @@ __lookup_tag(struct radix_tree_node *slot, void ***results, unsigned long index, * lookup ->slots[x] without a lock (ie. can't * rely on its value remaining the same). */ - if (slot->slots[j]) { - results[nr_found++] = &(slot->slots[j]); + if (node) { + node = rcu_dereference(node); + results[nr_found++] = node; if (nr_found == max_items) goto out; } @@ -949,22 +887,13 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, ret = 0; while (ret < max_items) { - unsigned int nr_found, slots_found, i; + unsigned int nr_found; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; - slots_found = __lookup_tag(node, (void ***)results + ret, - cur_index, max_items - ret, &next_index, tag); - nr_found = 0; - for (i = 0; i < slots_found; i++) { - struct radix_tree_node *slot; - slot = *(((void ***)results)[ret + i]); - if (!slot) - continue; - results[ret + nr_found] = rcu_dereference(slot); - nr_found++; - } + nr_found = __lookup_tag(node, results + ret, cur_index, + max_items - ret, &next_index, tag); ret += nr_found; if (next_index == 0) break; @@ -975,67 +904,6 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, } EXPORT_SYMBOL(radix_tree_gang_lookup_tag); -/** - * radix_tree_gang_lookup_tag_slot - perform multiple slot lookup on a - * radix tree based on a tag - * @root: radix tree root - * @results: where the results of the lookup are placed - * @first_index: start the lookup from this key - * @max_items: place up to this many items at *results - * @tag: the tag index (< RADIX_TREE_MAX_TAGS) - * - * Performs an index-ascending scan of the tree for present items which - * have the tag indexed by @tag set. Places the slots at *@results and - * returns the number of slots which were placed at *@results. - */ -unsigned int -radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, - unsigned long first_index, unsigned int max_items, - unsigned int tag) -{ - struct radix_tree_node *node; - unsigned long max_index; - unsigned long cur_index = first_index; - unsigned int ret; - - /* check the root's tag bit */ - if (!root_tag_get(root, tag)) - return 0; - - node = rcu_dereference(root->rnode); - if (!node) - return 0; - - if (!radix_tree_is_indirect_ptr(node)) { - if (first_index > 0) - return 0; - results[0] = (void **)&root->rnode; - return 1; - } - node = radix_tree_indirect_to_ptr(node); - - max_index = radix_tree_maxindex(node->height); - - ret = 0; - while (ret < max_items) { - unsigned int slots_found; - unsigned long next_index; /* Index of next search */ - - if (cur_index > max_index) - break; - slots_found = __lookup_tag(node, results + ret, - cur_index, max_items - ret, &next_index, tag); - ret += slots_found; - if (next_index == 0) - break; - cur_index = next_index; - } - - return ret; -} -EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot); - - /** * radix_tree_shrink - shrink height of a radix tree to minimal * @root radix tree root @@ -1183,7 +1051,7 @@ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag) EXPORT_SYMBOL(radix_tree_tagged); static void -radix_tree_node_ctor(void *node) +radix_tree_node_ctor(struct kmem_cache *cachep, void *node) { memset(node, 0, sizeof(struct radix_tree_node)); } diff --git a/trunk/lib/show_mem.c b/trunk/lib/show_mem.c deleted file mode 100644 index 238e72a18ce1..000000000000 --- a/trunk/lib/show_mem.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Generic show_mem() implementation - * - * Copyright (C) 2008 Johannes Weiner - * All code subject to the GPL version 2. - */ - -#include -#include -#include - -void show_mem(void) -{ - pg_data_t *pgdat; - unsigned long total = 0, reserved = 0, shared = 0, - nonshared = 0, highmem = 0; - - printk(KERN_INFO "Mem-Info:\n"); - show_free_areas(); - - for_each_online_pgdat(pgdat) { - unsigned long i, flags; - - pgdat_resize_lock(pgdat, &flags); - for (i = 0; i < pgdat->node_spanned_pages; i++) { - struct page *page; - unsigned long pfn = pgdat->node_start_pfn + i; - - if (unlikely(!(i % MAX_ORDER_NR_PAGES))) - touch_nmi_watchdog(); - - if (!pfn_valid(pfn)) - continue; - - page = pfn_to_page(pfn); - - if (PageHighMem(page)) - highmem++; - - if (PageReserved(page)) - reserved++; - else if (page_count(page) == 1) - nonshared++; - else if (page_count(page) > 1) - shared += page_count(page) - 1; - - total++; - } - pgdat_resize_unlock(pgdat, &flags); - } - - printk(KERN_INFO "%lu pages RAM\n", total); -#ifdef CONFIG_HIGHMEM - printk(KERN_INFO "%lu pages HighMem\n", highmem); -#endif - printk(KERN_INFO "%lu pages reserved\n", reserved); - printk(KERN_INFO "%lu pages shared\n", shared); - printk(KERN_INFO "%lu pages non-shared\n", nonshared); -#ifdef CONFIG_QUICKLIST - printk(KERN_INFO "%lu pages in pagetable cache\n", - quicklist_total_size()); -#endif -} diff --git a/trunk/lib/swiotlb.c b/trunk/lib/swiotlb.c index 977edbdbc1de..d568894df8cc 100644 --- a/trunk/lib/swiotlb.c +++ b/trunk/lib/swiotlb.c @@ -492,7 +492,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, */ dma_addr_t handle; handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE); - if (swiotlb_dma_mapping_error(hwdev, handle)) + if (swiotlb_dma_mapping_error(handle)) return NULL; ret = bus_to_virt(handle); @@ -824,7 +824,7 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, } int -swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) +swiotlb_dma_mapping_error(dma_addr_t dma_addr) { return (dma_addr == virt_to_bus(io_tlb_overflow_buffer)); } diff --git a/trunk/lib/syscall.c b/trunk/lib/syscall.c deleted file mode 100644 index a4f7067f72fa..000000000000 --- a/trunk/lib/syscall.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include - -static int collect_syscall(struct task_struct *target, long *callno, - unsigned long args[6], unsigned int maxargs, - unsigned long *sp, unsigned long *pc) -{ - struct pt_regs *regs = task_pt_regs(target); - if (unlikely(!regs)) - return -EAGAIN; - - *sp = user_stack_pointer(regs); - *pc = instruction_pointer(regs); - - *callno = syscall_get_nr(target, regs); - if (*callno != -1L && maxargs > 0) - syscall_get_arguments(target, regs, 0, maxargs, args); - - return 0; -} - -/** - * task_current_syscall - Discover what a blocked task is doing. - * @target: thread to examine - * @callno: filled with system call number or -1 - * @args: filled with @maxargs system call arguments - * @maxargs: number of elements in @args to fill - * @sp: filled with user stack pointer - * @pc: filled with user PC - * - * If @target is blocked in a system call, returns zero with *@callno - * set to the the call's number and @args filled in with its arguments. - * Registers not used for system call arguments may not be available and - * it is not kosher to use &struct user_regset calls while the system - * call is still in progress. Note we may get this result if @target - * has finished its system call but not yet returned to user mode, such - * as when it's stopped for signal handling or syscall exit tracing. - * - * If @target is blocked in the kernel during a fault or exception, - * returns zero with *@callno set to -1 and does not fill in @args. - * If so, it's now safe to examine @target using &struct user_regset - * get() calls as long as we're sure @target won't return to user mode. - * - * Returns -%EAGAIN if @target does not remain blocked. - * - * Returns -%EINVAL if @maxargs is too large (maximum is six). - */ -int task_current_syscall(struct task_struct *target, long *callno, - unsigned long args[6], unsigned int maxargs, - unsigned long *sp, unsigned long *pc) -{ - long state; - unsigned long ncsw; - - if (unlikely(maxargs > 6)) - return -EINVAL; - - if (target == current) - return collect_syscall(target, callno, args, maxargs, sp, pc); - - state = target->state; - if (unlikely(!state)) - return -EAGAIN; - - ncsw = wait_task_inactive(target, state); - if (unlikely(!ncsw) || - unlikely(collect_syscall(target, callno, args, maxargs, sp, pc)) || - unlikely(wait_task_inactive(target, state) != ncsw)) - return -EAGAIN; - - return 0; -} -EXPORT_SYMBOL_GPL(task_current_syscall); diff --git a/trunk/mm/Kconfig b/trunk/mm/Kconfig index efee5d379df4..aa799007a11b 100644 --- a/trunk/mm/Kconfig +++ b/trunk/mm/Kconfig @@ -77,9 +77,6 @@ config FLAT_NODE_MEM_MAP def_bool y depends on !SPARSEMEM -config HAVE_GET_USER_PAGES_FAST - bool - # # Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's # to represent different areas of memory. This variable allows diff --git a/trunk/mm/allocpercpu.c b/trunk/mm/allocpercpu.c index 4297bc41bfd2..843364594e23 100644 --- a/trunk/mm/allocpercpu.c +++ b/trunk/mm/allocpercpu.c @@ -18,28 +18,27 @@ * Depopulating per-cpu data for a cpu going offline would be a typical * use case. You need to register a cpu hotplug handler for that purpose. */ -static void percpu_depopulate(void *__pdata, int cpu) +void percpu_depopulate(void *__pdata, int cpu) { struct percpu_data *pdata = __percpu_disguise(__pdata); kfree(pdata->ptrs[cpu]); pdata->ptrs[cpu] = NULL; } +EXPORT_SYMBOL_GPL(percpu_depopulate); /** * percpu_depopulate_mask - depopulate per-cpu data for some cpu's * @__pdata: per-cpu data to depopulate * @mask: depopulate per-cpu data for cpu's selected through mask bits */ -static void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask) +void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask) { int cpu; for_each_cpu_mask_nr(cpu, *mask) percpu_depopulate(__pdata, cpu); } - -#define percpu_depopulate_mask(__pdata, mask) \ - __percpu_depopulate_mask((__pdata), &(mask)) +EXPORT_SYMBOL_GPL(__percpu_depopulate_mask); /** * percpu_populate - populate per-cpu data for given cpu @@ -52,7 +51,7 @@ static void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask) * use case. You need to register a cpu hotplug handler for that purpose. * Per-cpu object is populated with zeroed buffer. */ -static void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) +void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) { struct percpu_data *pdata = __percpu_disguise(__pdata); int node = cpu_to_node(cpu); @@ -69,6 +68,7 @@ static void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) pdata->ptrs[cpu] = kzalloc(size, gfp); return pdata->ptrs[cpu]; } +EXPORT_SYMBOL_GPL(percpu_populate); /** * percpu_populate_mask - populate per-cpu data for more cpu's @@ -79,8 +79,8 @@ static void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) * * Per-cpu objects are populated with zeroed buffers. */ -static int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, - cpumask_t *mask) +int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, + cpumask_t *mask) { cpumask_t populated; int cpu; @@ -94,9 +94,7 @@ static int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, cpu_set(cpu, populated); return 0; } - -#define percpu_populate_mask(__pdata, size, gfp, mask) \ - __percpu_populate_mask((__pdata), (size), (gfp), &(mask)) +EXPORT_SYMBOL_GPL(__percpu_populate_mask); /** * percpu_alloc_mask - initial setup of per-cpu data diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index 5de7633e1dbe..2d3ec1ffc66e 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -109,7 +109,7 @@ /* * Remove a page from the page cache and free it. Caller has to make * sure the page is locked and that nobody else uses it - or that usage - * is safe. The caller must hold the mapping's tree_lock. + * is safe. The caller must hold a write_lock on the mapping's tree_lock. */ void __remove_from_page_cache(struct page *page) { @@ -141,9 +141,9 @@ void remove_from_page_cache(struct page *page) BUG_ON(!PageLocked(page)); - spin_lock_irq(&mapping->tree_lock); + write_lock_irq(&mapping->tree_lock); __remove_from_page_cache(page); - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); } static int sync_page(void *word) @@ -442,52 +442,48 @@ int filemap_write_and_wait_range(struct address_space *mapping, } /** - * add_to_page_cache_locked - add a locked page to the pagecache + * add_to_page_cache - add newly allocated pagecache pages * @page: page to add * @mapping: the page's address_space * @offset: page index * @gfp_mask: page allocation mode * - * This function is used to add a page to the pagecache. It must be locked. + * This function is used to add newly allocated pagecache pages; + * the page is new, so we can just run SetPageLocked() against it. + * The other page state flags were set by rmqueue(). + * * This function does not add the page to the LRU. The caller must do that. */ -int add_to_page_cache_locked(struct page *page, struct address_space *mapping, +int add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) { - int error; - - VM_BUG_ON(!PageLocked(page)); - - error = mem_cgroup_cache_charge(page, current->mm, + int error = mem_cgroup_cache_charge(page, current->mm, gfp_mask & ~__GFP_HIGHMEM); if (error) goto out; error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM); if (error == 0) { - page_cache_get(page); - page->mapping = mapping; - page->index = offset; - - spin_lock_irq(&mapping->tree_lock); + write_lock_irq(&mapping->tree_lock); error = radix_tree_insert(&mapping->page_tree, offset, page); - if (likely(!error)) { + if (!error) { + page_cache_get(page); + SetPageLocked(page); + page->mapping = mapping; + page->index = offset; mapping->nrpages++; __inc_zone_page_state(page, NR_FILE_PAGES); - } else { - page->mapping = NULL; + } else mem_cgroup_uncharge_cache_page(page); - page_cache_release(page); - } - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); radix_tree_preload_end(); } else mem_cgroup_uncharge_cache_page(page); out: return error; } -EXPORT_SYMBOL(add_to_page_cache_locked); +EXPORT_SYMBOL(add_to_page_cache); int add_to_page_cache_lru(struct page *page, struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) @@ -637,35 +633,15 @@ void __lock_page_nosync(struct page *page) * Is there a pagecache struct page at the given (mapping, offset) tuple? * If yes, increment its refcount and return it; if no, return NULL. */ -struct page *find_get_page(struct address_space *mapping, pgoff_t offset) +struct page * find_get_page(struct address_space *mapping, pgoff_t offset) { - void **pagep; struct page *page; - rcu_read_lock(); -repeat: - page = NULL; - pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); - if (pagep) { - page = radix_tree_deref_slot(pagep); - if (unlikely(!page || page == RADIX_TREE_RETRY)) - goto repeat; - - if (!page_cache_get_speculative(page)) - goto repeat; - - /* - * Has the page moved? - * This is part of the lockless pagecache protocol. See - * include/linux/pagemap.h for details. - */ - if (unlikely(page != *pagep)) { - page_cache_release(page); - goto repeat; - } - } - rcu_read_unlock(); - + read_lock_irq(&mapping->tree_lock); + page = radix_tree_lookup(&mapping->page_tree, offset); + if (page) + page_cache_get(page); + read_unlock_irq(&mapping->tree_lock); return page; } EXPORT_SYMBOL(find_get_page); @@ -680,22 +656,32 @@ EXPORT_SYMBOL(find_get_page); * * Returns zero if the page was not present. find_lock_page() may sleep. */ -struct page *find_lock_page(struct address_space *mapping, pgoff_t offset) +struct page *find_lock_page(struct address_space *mapping, + pgoff_t offset) { struct page *page; repeat: - page = find_get_page(mapping, offset); + read_lock_irq(&mapping->tree_lock); + page = radix_tree_lookup(&mapping->page_tree, offset); if (page) { - lock_page(page); - /* Has the page been truncated? */ - if (unlikely(page->mapping != mapping)) { - unlock_page(page); - page_cache_release(page); - goto repeat; + page_cache_get(page); + if (TestSetPageLocked(page)) { + read_unlock_irq(&mapping->tree_lock); + __lock_page(page); + + /* Has the page been truncated while we slept? */ + if (unlikely(page->mapping != mapping)) { + unlock_page(page); + page_cache_release(page); + goto repeat; + } + VM_BUG_ON(page->index != offset); + goto out; } - VM_BUG_ON(page->index != offset); } + read_unlock_irq(&mapping->tree_lock); +out: return page; } EXPORT_SYMBOL(find_lock_page); @@ -761,39 +747,13 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, { unsigned int i; unsigned int ret; - unsigned int nr_found; - - rcu_read_lock(); -restart: - nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree, - (void ***)pages, start, nr_pages); - ret = 0; - for (i = 0; i < nr_found; i++) { - struct page *page; -repeat: - page = radix_tree_deref_slot((void **)pages[i]); - if (unlikely(!page)) - continue; - /* - * this can only trigger if nr_found == 1, making livelock - * a non issue. - */ - if (unlikely(page == RADIX_TREE_RETRY)) - goto restart; - if (!page_cache_get_speculative(page)) - goto repeat; - - /* Has the page moved? */ - if (unlikely(page != *((void **)pages[i]))) { - page_cache_release(page); - goto repeat; - } - - pages[ret] = page; - ret++; - } - rcu_read_unlock(); + read_lock_irq(&mapping->tree_lock); + ret = radix_tree_gang_lookup(&mapping->page_tree, + (void **)pages, start, nr_pages); + for (i = 0; i < ret; i++) + page_cache_get(pages[i]); + read_unlock_irq(&mapping->tree_lock); return ret; } @@ -814,44 +774,19 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index, { unsigned int i; unsigned int ret; - unsigned int nr_found; - - rcu_read_lock(); -restart: - nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree, - (void ***)pages, index, nr_pages); - ret = 0; - for (i = 0; i < nr_found; i++) { - struct page *page; -repeat: - page = radix_tree_deref_slot((void **)pages[i]); - if (unlikely(!page)) - continue; - /* - * this can only trigger if nr_found == 1, making livelock - * a non issue. - */ - if (unlikely(page == RADIX_TREE_RETRY)) - goto restart; - if (page->mapping == NULL || page->index != index) + read_lock_irq(&mapping->tree_lock); + ret = radix_tree_gang_lookup(&mapping->page_tree, + (void **)pages, index, nr_pages); + for (i = 0; i < ret; i++) { + if (pages[i]->mapping == NULL || pages[i]->index != index) break; - if (!page_cache_get_speculative(page)) - goto repeat; - - /* Has the page moved? */ - if (unlikely(page != *((void **)pages[i]))) { - page_cache_release(page); - goto repeat; - } - - pages[ret] = page; - ret++; + page_cache_get(pages[i]); index++; } - rcu_read_unlock(); - return ret; + read_unlock_irq(&mapping->tree_lock); + return i; } EXPORT_SYMBOL(find_get_pages_contig); @@ -871,43 +806,15 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, { unsigned int i; unsigned int ret; - unsigned int nr_found; - - rcu_read_lock(); -restart: - nr_found = radix_tree_gang_lookup_tag_slot(&mapping->page_tree, - (void ***)pages, *index, nr_pages, tag); - ret = 0; - for (i = 0; i < nr_found; i++) { - struct page *page; -repeat: - page = radix_tree_deref_slot((void **)pages[i]); - if (unlikely(!page)) - continue; - /* - * this can only trigger if nr_found == 1, making livelock - * a non issue. - */ - if (unlikely(page == RADIX_TREE_RETRY)) - goto restart; - - if (!page_cache_get_speculative(page)) - goto repeat; - - /* Has the page moved? */ - if (unlikely(page != *((void **)pages[i]))) { - page_cache_release(page); - goto repeat; - } - - pages[ret] = page; - ret++; - } - rcu_read_unlock(); + read_lock_irq(&mapping->tree_lock); + ret = radix_tree_gang_lookup_tag(&mapping->page_tree, + (void **)pages, *index, nr_pages, tag); + for (i = 0; i < ret; i++) + page_cache_get(pages[i]); if (ret) *index = pages[ret - 1]->index + 1; - + read_unlock_irq(&mapping->tree_lock); return ret; } EXPORT_SYMBOL(find_get_pages_tag); @@ -1758,9 +1665,8 @@ static int __remove_suid(struct dentry *dentry, int kill) return notify_change(dentry, &newattrs); } -int file_remove_suid(struct file *file) +int remove_suid(struct dentry *dentry) { - struct dentry *dentry = file->f_path.dentry; int killsuid = should_remove_suid(dentry); int killpriv = security_inode_need_killpriv(dentry); int error = 0; @@ -1774,7 +1680,7 @@ int file_remove_suid(struct file *file) return error; } -EXPORT_SYMBOL(file_remove_suid); +EXPORT_SYMBOL(remove_suid); static size_t __iovec_copy_from_user_inatomic(char *vaddr, const struct iovec *iov, size_t base, size_t bytes) @@ -2530,7 +2436,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, if (count == 0) goto out; - err = file_remove_suid(file); + err = remove_suid(file->f_path.dentry); if (err) goto out; diff --git a/trunk/mm/filemap_xip.c b/trunk/mm/filemap_xip.c index 98a3f31ccd6a..3e744abcce9d 100644 --- a/trunk/mm/filemap_xip.c +++ b/trunk/mm/filemap_xip.c @@ -380,7 +380,7 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len, if (count == 0) goto out_backing; - ret = file_remove_suid(filp); + ret = remove_suid(filp->f_path.dentry); if (ret) goto out_backing; diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 3be79dc18c5c..a8bf4ab01f86 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -1026,6 +1026,18 @@ static void __init report_hugepages(void) } } +static unsigned int cpuset_mems_nr(unsigned int *array) +{ + int node; + unsigned int nr = 0; + + for_each_node_mask(node, cpuset_current_mems_allowed) + nr += array[node]; + + return nr; +} + +#ifdef CONFIG_SYSCTL #ifdef CONFIG_HIGHMEM static void try_to_free_low(struct hstate *h, unsigned long count) { @@ -1374,18 +1386,6 @@ static int __init hugetlb_default_setup(char *s) } __setup("default_hugepagesz=", hugetlb_default_setup); -static unsigned int cpuset_mems_nr(unsigned int *array) -{ - int node; - unsigned int nr = 0; - - for_each_node_mask(node, cpuset_current_mems_allowed) - nr += array[node]; - - return nr; -} - -#ifdef CONFIG_SYSCTL int hugetlb_sysctl_handler(struct ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, loff_t *ppos) diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index a8ca04faaea6..262e3eb6601a 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -374,8 +374,7 @@ static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss) * * The calling function must still handle the error. */ -static void print_bad_pte(struct vm_area_struct *vma, pte_t pte, - unsigned long vaddr) +void print_bad_pte(struct vm_area_struct *vma, pte_t pte, unsigned long vaddr) { printk(KERN_ERR "Bad pte = %08llx, process = %s, " "vm_flags = %lx, vaddr = %lx\n", diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index 153572fb60b8..d8c65a65c61d 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -285,15 +285,7 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, page = migration_entry_to_page(entry); - /* - * Once radix-tree replacement of page migration started, page_count - * *must* be zero. And, we don't want to call wait_on_page_locked() - * against a page without get_page(). - * So, we use get_page_unless_zero(), here. Even failed, page fault - * will occur again. - */ - if (!get_page_unless_zero(page)) - goto out; + get_page(page); pte_unmap_unlock(ptep, ptl); wait_on_page_locked(page); put_page(page); @@ -313,7 +305,6 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, static int migrate_page_move_mapping(struct address_space *mapping, struct page *newpage, struct page *page) { - int expected_count; void **pslot; if (!mapping) { @@ -323,20 +314,14 @@ static int migrate_page_move_mapping(struct address_space *mapping, return 0; } - spin_lock_irq(&mapping->tree_lock); + write_lock_irq(&mapping->tree_lock); pslot = radix_tree_lookup_slot(&mapping->page_tree, page_index(page)); - expected_count = 2 + !!PagePrivate(page); - if (page_count(page) != expected_count || + if (page_count(page) != 2 + !!PagePrivate(page) || (struct page *)radix_tree_deref_slot(pslot) != page) { - spin_unlock_irq(&mapping->tree_lock); - return -EAGAIN; - } - - if (!page_freeze_refs(page, expected_count)) { - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); return -EAGAIN; } @@ -353,7 +338,6 @@ static int migrate_page_move_mapping(struct address_space *mapping, radix_tree_replace_slot(pslot, newpage); - page_unfreeze_refs(page, expected_count); /* * Drop cache reference from old page. * We know this isn't the last reference. @@ -373,9 +357,10 @@ static int migrate_page_move_mapping(struct address_space *mapping, __dec_zone_page_state(page, NR_FILE_PAGES); __inc_zone_page_state(newpage, NR_FILE_PAGES); - spin_unlock_irq(&mapping->tree_lock); - if (!PageSwapCache(newpage)) + write_unlock_irq(&mapping->tree_lock); + if (!PageSwapCache(newpage)) { mem_cgroup_uncharge_cache_page(page); + } return 0; } diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index 5edccd9c9218..4462b6a3fcb9 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -745,7 +745,7 @@ static unsigned long determine_vm_flags(struct file *file, * it's being traced - otherwise breakpoints set in it may interfere * with another untraced process */ - if ((flags & MAP_PRIVATE) && tracehook_expect_breakpoints(current)) + if ((flags & MAP_PRIVATE) && (current->ptrace & PT_PTRACED)) vm_flags &= ~VM_MAYSHARE; return vm_flags; diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 24de8b65fdbd..94c6d8988ab3 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -1088,7 +1088,7 @@ int __set_page_dirty_nobuffers(struct page *page) if (!mapping) return 1; - spin_lock_irq(&mapping->tree_lock); + write_lock_irq(&mapping->tree_lock); mapping2 = page_mapping(page); if (mapping2) { /* Race with truncate? */ BUG_ON(mapping2 != mapping); @@ -1102,7 +1102,7 @@ int __set_page_dirty_nobuffers(struct page *page) radix_tree_tag_set(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); } - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); if (mapping->host) { /* !PageAnon && !swapper_space */ __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); @@ -1258,7 +1258,7 @@ int test_clear_page_writeback(struct page *page) struct backing_dev_info *bdi = mapping->backing_dev_info; unsigned long flags; - spin_lock_irqsave(&mapping->tree_lock, flags); + write_lock_irqsave(&mapping->tree_lock, flags); ret = TestClearPageWriteback(page); if (ret) { radix_tree_tag_clear(&mapping->page_tree, @@ -1269,7 +1269,7 @@ int test_clear_page_writeback(struct page *page) __bdi_writeout_inc(bdi); } } - spin_unlock_irqrestore(&mapping->tree_lock, flags); + write_unlock_irqrestore(&mapping->tree_lock, flags); } else { ret = TestClearPageWriteback(page); } @@ -1287,7 +1287,7 @@ int test_set_page_writeback(struct page *page) struct backing_dev_info *bdi = mapping->backing_dev_info; unsigned long flags; - spin_lock_irqsave(&mapping->tree_lock, flags); + write_lock_irqsave(&mapping->tree_lock, flags); ret = TestSetPageWriteback(page); if (!ret) { radix_tree_tag_set(&mapping->page_tree, @@ -1300,7 +1300,7 @@ int test_set_page_writeback(struct page *page) radix_tree_tag_clear(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); - spin_unlock_irqrestore(&mapping->tree_lock, flags); + write_unlock_irqrestore(&mapping->tree_lock, flags); } else { ret = TestSetPageWriteback(page); } diff --git a/trunk/mm/readahead.c b/trunk/mm/readahead.c index 77e8ddf945e9..d8723a5f6496 100644 --- a/trunk/mm/readahead.c +++ b/trunk/mm/readahead.c @@ -382,9 +382,9 @@ ondemand_readahead(struct address_space *mapping, if (hit_readahead_marker) { pgoff_t start; - rcu_read_lock(); - start = radix_tree_next_hole(&mapping->page_tree, offset,max+1); - rcu_read_unlock(); + read_lock_irq(&mapping->tree_lock); + start = radix_tree_next_hole(&mapping->page_tree, offset, max+1); + read_unlock_irq(&mapping->tree_lock); if (!start || start - offset > max) return 0; diff --git a/trunk/mm/rmap.c b/trunk/mm/rmap.c index 39ae5a9bf382..abbd29f7c43f 100644 --- a/trunk/mm/rmap.c +++ b/trunk/mm/rmap.c @@ -138,7 +138,7 @@ void anon_vma_unlink(struct vm_area_struct *vma) anon_vma_free(anon_vma); } -static void anon_vma_ctor(void *data) +static void anon_vma_ctor(struct kmem_cache *cachep, void *data) { struct anon_vma *anon_vma = data; diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 952d361774bb..f92fea94d037 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -936,7 +936,7 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s spin_lock(&info->lock); ptr = shmem_swp_entry(info, idx, NULL); if (ptr && ptr->val == entry.val) { - error = add_to_page_cache_locked(page, inode->i_mapping, + error = add_to_page_cache(page, inode->i_mapping, idx, GFP_NOWAIT); /* does mem_cgroup_uncharge_cache_page on error */ } else /* we must compensate for our precharge above */ @@ -1301,8 +1301,8 @@ static int shmem_getpage(struct inode *inode, unsigned long idx, SetPageUptodate(filepage); set_page_dirty(filepage); swap_free(swap); - } else if (!(error = add_to_page_cache_locked(swappage, mapping, - idx, GFP_NOWAIT))) { + } else if (!(error = add_to_page_cache( + swappage, mapping, idx, GFP_NOWAIT))) { info->flags |= SHMEM_PAGEIN; shmem_swp_set(info, entry, 0); shmem_swp_unmap(entry); @@ -2352,7 +2352,7 @@ static void shmem_destroy_inode(struct inode *inode) kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct shmem_inode_info *p = (struct shmem_inode_info *) foo; diff --git a/trunk/mm/shmem_acl.c b/trunk/mm/shmem_acl.c index 8e5aadd7dcd6..f5664c5b9eb1 100644 --- a/trunk/mm/shmem_acl.c +++ b/trunk/mm/shmem_acl.c @@ -191,7 +191,7 @@ shmem_check_acl(struct inode *inode, int mask) * shmem_permission - permission() inode operation */ int -shmem_permission(struct inode *inode, int mask) +shmem_permission(struct inode *inode, int mask, struct nameidata *nd) { return generic_permission(inode, mask, shmem_check_acl); } diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 918f04f7fef1..052e7d64537e 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -406,7 +406,7 @@ struct kmem_cache { unsigned int dflags; /* dynamic flags */ /* constructor func */ - void (*ctor)(void *obj); + void (*ctor)(struct kmem_cache *, void *); /* 5) cache creation/removal */ const char *name; @@ -2137,7 +2137,8 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep) */ struct kmem_cache * kmem_cache_create (const char *name, size_t size, size_t align, - unsigned long flags, void (*ctor)(void *)) + unsigned long flags, + void (*ctor)(struct kmem_cache *, void *)) { size_t left_over, slab_size, ralign; struct kmem_cache *cachep = NULL, *pc; @@ -2652,7 +2653,7 @@ static void cache_init_objs(struct kmem_cache *cachep, * They must also be threaded. */ if (cachep->ctor && !(cachep->flags & SLAB_POISON)) - cachep->ctor(objp + obj_offset(cachep)); + cachep->ctor(cachep, objp + obj_offset(cachep)); if (cachep->flags & SLAB_RED_ZONE) { if (*dbg_redzone2(cachep, objp) != RED_INACTIVE) @@ -2668,7 +2669,7 @@ static void cache_init_objs(struct kmem_cache *cachep, cachep->buffer_size / PAGE_SIZE, 0); #else if (cachep->ctor) - cachep->ctor(objp); + cachep->ctor(cachep, objp); #endif slab_bufctl(slabp)[i] = i + 1; } @@ -3092,7 +3093,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep, #endif objp += obj_offset(cachep); if (cachep->ctor && cachep->flags & SLAB_POISON) - cachep->ctor(objp); + cachep->ctor(cachep, objp); #if ARCH_SLAB_MINALIGN if ((u32)objp & (ARCH_SLAB_MINALIGN-1)) { printk(KERN_ERR "0x%p: not aligned to ARCH_SLAB_MINALIGN=%d\n", diff --git a/trunk/mm/slob.c b/trunk/mm/slob.c index d8fbd4d1bfa7..de268eb7ac70 100644 --- a/trunk/mm/slob.c +++ b/trunk/mm/slob.c @@ -525,11 +525,12 @@ struct kmem_cache { unsigned int size, align; unsigned long flags; const char *name; - void (*ctor)(void *); + void (*ctor)(struct kmem_cache *, void *); }; struct kmem_cache *kmem_cache_create(const char *name, size_t size, - size_t align, unsigned long flags, void (*ctor)(void *)) + size_t align, unsigned long flags, + void (*ctor)(struct kmem_cache *, void *)) { struct kmem_cache *c; @@ -574,7 +575,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node) b = slob_new_page(flags, get_order(c->size), node); if (c->ctor) - c->ctor(b); + c->ctor(c, b); return b; } diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index b7e2cd5d82db..77c21cf53ff9 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -1012,7 +1012,7 @@ __setup("slub_debug", setup_slub_debug); static unsigned long kmem_cache_flags(unsigned long objsize, unsigned long flags, const char *name, - void (*ctor)(void *)) + void (*ctor)(struct kmem_cache *, void *)) { /* * Enable debugging if selected on the kernel commandline. @@ -1040,7 +1040,7 @@ static inline int check_object(struct kmem_cache *s, struct page *page, static inline void add_full(struct kmem_cache_node *n, struct page *page) {} static inline unsigned long kmem_cache_flags(unsigned long objsize, unsigned long flags, const char *name, - void (*ctor)(void *)) + void (*ctor)(struct kmem_cache *, void *)) { return flags; } @@ -1103,7 +1103,7 @@ static void setup_object(struct kmem_cache *s, struct page *page, { setup_object_debug(s, page, object); if (unlikely(s->ctor)) - s->ctor(object); + s->ctor(s, object); } static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) @@ -2286,7 +2286,7 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order) static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags, const char *name, size_t size, size_t align, unsigned long flags, - void (*ctor)(void *)) + void (*ctor)(struct kmem_cache *, void *)) { memset(s, 0, kmem_size); s->name = name; @@ -3042,7 +3042,7 @@ static int slab_unmergeable(struct kmem_cache *s) static struct kmem_cache *find_mergeable(size_t size, size_t align, unsigned long flags, const char *name, - void (*ctor)(void *)) + void (*ctor)(struct kmem_cache *, void *)) { struct kmem_cache *s; @@ -3082,7 +3082,8 @@ static struct kmem_cache *find_mergeable(size_t size, } struct kmem_cache *kmem_cache_create(const char *name, size_t size, - size_t align, unsigned long flags, void (*ctor)(void *)) + size_t align, unsigned long flags, + void (*ctor)(struct kmem_cache *, void *)) { struct kmem_cache *s; diff --git a/trunk/mm/sparse.c b/trunk/mm/sparse.c index 5d9dbbb9d39e..8ffc08990008 100644 --- a/trunk/mm/sparse.c +++ b/trunk/mm/sparse.c @@ -377,7 +377,7 @@ struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid) } #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ -static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) +struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) { struct page *map; struct mem_section *ms = __nr_to_section(pnum); diff --git a/trunk/mm/swap_state.c b/trunk/mm/swap_state.c index b8035b055129..d8aadaf2a0ba 100644 --- a/trunk/mm/swap_state.c +++ b/trunk/mm/swap_state.c @@ -39,7 +39,7 @@ static struct backing_dev_info swap_backing_dev_info = { struct address_space swapper_space = { .page_tree = RADIX_TREE_INIT(GFP_ATOMIC|__GFP_NOWARN), - .tree_lock = __SPIN_LOCK_UNLOCKED(swapper_space.tree_lock), + .tree_lock = __RW_LOCK_UNLOCKED(swapper_space.tree_lock), .a_ops = &swap_aops, .i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear), .backing_dev_info = &swap_backing_dev_info, @@ -56,8 +56,7 @@ static struct { void show_swap_cache_info(void) { - printk("%lu pages in swap cache\n", total_swapcache_pages); - printk("Swap cache stats: add %lu, delete %lu, find %lu/%lu\n", + printk("Swap cache: add %lu, delete %lu, find %lu/%lu\n", swap_cache_info.add_total, swap_cache_info.del_total, swap_cache_info.find_success, swap_cache_info.find_total); printk("Free swap = %lukB\n", nr_swap_pages << (PAGE_SHIFT - 10)); @@ -65,7 +64,7 @@ void show_swap_cache_info(void) } /* - * add_to_swap_cache resembles add_to_page_cache_locked on swapper_space, + * add_to_swap_cache resembles add_to_page_cache on swapper_space, * but sets SwapCache flag and private instead of mapping and index. */ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) @@ -77,26 +76,19 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) BUG_ON(PagePrivate(page)); error = radix_tree_preload(gfp_mask); if (!error) { - page_cache_get(page); - SetPageSwapCache(page); - set_page_private(page, entry.val); - - spin_lock_irq(&swapper_space.tree_lock); + write_lock_irq(&swapper_space.tree_lock); error = radix_tree_insert(&swapper_space.page_tree, entry.val, page); - if (likely(!error)) { + if (!error) { + page_cache_get(page); + SetPageSwapCache(page); + set_page_private(page, entry.val); total_swapcache_pages++; __inc_zone_page_state(page, NR_FILE_PAGES); INC_CACHE_INFO(add_total); } - spin_unlock_irq(&swapper_space.tree_lock); + write_unlock_irq(&swapper_space.tree_lock); radix_tree_preload_end(); - - if (unlikely(error)) { - set_page_private(page, 0UL); - ClearPageSwapCache(page); - page_cache_release(page); - } } return error; } @@ -183,9 +175,9 @@ void delete_from_swap_cache(struct page *page) entry.val = page_private(page); - spin_lock_irq(&swapper_space.tree_lock); + write_lock_irq(&swapper_space.tree_lock); __delete_from_swap_cache(page); - spin_unlock_irq(&swapper_space.tree_lock); + write_unlock_irq(&swapper_space.tree_lock); swap_free(entry); page_cache_release(page); diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index 6beb6251e99d..2f33edb8bee9 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -33,8 +33,8 @@ #include #include -static DEFINE_SPINLOCK(swap_lock); -static unsigned int nr_swapfiles; +DEFINE_SPINLOCK(swap_lock); +unsigned int nr_swapfiles; long total_swap_pages; static int swap_overflow; static int least_priority; @@ -44,7 +44,7 @@ static const char Unused_file[] = "Unused swap file entry "; static const char Bad_offset[] = "Bad swap offset entry "; static const char Unused_offset[] = "Unused swap offset entry "; -static struct swap_list_t swap_list = {-1, -1}; +struct swap_list_t swap_list = {-1, -1}; static struct swap_info_struct swap_info[MAX_SWAPFILES]; @@ -369,13 +369,13 @@ int remove_exclusive_swap_page(struct page *page) retval = 0; if (p->swap_map[swp_offset(entry)] == 1) { /* Recheck the page count with the swapcache lock held.. */ - spin_lock_irq(&swapper_space.tree_lock); + write_lock_irq(&swapper_space.tree_lock); if ((page_count(page) == 2) && !PageWriteback(page)) { __delete_from_swap_cache(page); SetPageDirty(page); retval = 1; } - spin_unlock_irq(&swapper_space.tree_lock); + write_unlock_irq(&swapper_space.tree_lock); } spin_unlock(&swap_lock); diff --git a/trunk/mm/truncate.c b/trunk/mm/truncate.c index e68443d74567..b8961cb63414 100644 --- a/trunk/mm/truncate.c +++ b/trunk/mm/truncate.c @@ -349,18 +349,18 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL)) return 0; - spin_lock_irq(&mapping->tree_lock); + write_lock_irq(&mapping->tree_lock); if (PageDirty(page)) goto failed; BUG_ON(PagePrivate(page)); __remove_from_page_cache(page); - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); ClearPageUptodate(page); page_cache_release(page); /* pagecache ref */ return 1; failed: - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); return 0; } diff --git a/trunk/mm/util.c b/trunk/mm/util.c index 9341ca77bd88..8f18683825bc 100644 --- a/trunk/mm/util.c +++ b/trunk/mm/util.c @@ -1,9 +1,7 @@ -#include #include #include #include #include -#include #include /** @@ -70,22 +68,25 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp) EXPORT_SYMBOL(kmemdup); /** - * __krealloc - like krealloc() but don't free @p. + * krealloc - reallocate memory. The contents will remain unchanged. * @p: object to reallocate memory for. * @new_size: how many bytes of memory are required. * @flags: the type of memory to allocate. * - * This function is like krealloc() except it never frees the originally - * allocated buffer. Use this if you don't want to free the buffer immediately - * like, for example, with RCU. + * The contents of the object pointed to are preserved up to the + * lesser of the new and old sizes. If @p is %NULL, krealloc() + * behaves exactly like kmalloc(). If @size is 0 and @p is not a + * %NULL pointer, the object pointed to is freed. */ -void *__krealloc(const void *p, size_t new_size, gfp_t flags) +void *krealloc(const void *p, size_t new_size, gfp_t flags) { void *ret; size_t ks = 0; - if (unlikely(!new_size)) + if (unlikely(!new_size)) { + kfree(p); return ZERO_SIZE_PTR; + } if (p) ks = ksize(p); @@ -94,37 +95,10 @@ void *__krealloc(const void *p, size_t new_size, gfp_t flags) return (void *)p; ret = kmalloc_track_caller(new_size, flags); - if (ret && p) + if (ret && p) { memcpy(ret, p, ks); - - return ret; -} -EXPORT_SYMBOL(__krealloc); - -/** - * krealloc - reallocate memory. The contents will remain unchanged. - * @p: object to reallocate memory for. - * @new_size: how many bytes of memory are required. - * @flags: the type of memory to allocate. - * - * The contents of the object pointed to are preserved up to the - * lesser of the new and old sizes. If @p is %NULL, krealloc() - * behaves exactly like kmalloc(). If @size is 0 and @p is not a - * %NULL pointer, the object pointed to is freed. - */ -void *krealloc(const void *p, size_t new_size, gfp_t flags) -{ - void *ret; - - if (unlikely(!new_size)) { kfree(p); - return ZERO_SIZE_PTR; } - - ret = __krealloc(p, new_size, flags); - if (ret && p != ret) - kfree(p); - return ret; } EXPORT_SYMBOL(krealloc); @@ -162,12 +136,3 @@ char *strndup_user(const char __user *s, long n) return p; } EXPORT_SYMBOL(strndup_user); - -#ifndef HAVE_ARCH_PICK_MMAP_LAYOUT -void arch_pick_mmap_layout(struct mm_struct *mm) -{ - mm->mmap_base = TASK_UNMAPPED_BASE; - mm->get_unmapped_area = arch_get_unmapped_area; - mm->unmap_area = arch_unmap_area; -} -#endif diff --git a/trunk/mm/vmalloc.c b/trunk/mm/vmalloc.c index 85b9a0d2c877..35f293816294 100644 --- a/trunk/mm/vmalloc.c +++ b/trunk/mm/vmalloc.c @@ -381,14 +381,16 @@ static void __vunmap(const void *addr, int deallocate_pages) return; if ((PAGE_SIZE-1) & (unsigned long)addr) { - WARN(1, KERN_ERR "Trying to vfree() bad address (%p)\n", addr); + printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr); + WARN_ON(1); return; } area = remove_vm_area(addr); if (unlikely(!area)) { - WARN(1, KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", + printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr); + WARN_ON(1); return; } diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 8f71761bc4b7..26672c6cd3ce 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -391,15 +391,17 @@ static pageout_t pageout(struct page *page, struct address_space *mapping, } /* - * Same as remove_mapping, but if the page is removed from the mapping, it - * gets returned with a refcount of 0. + * 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. */ -static int __remove_mapping(struct address_space *mapping, struct page *page) +int remove_mapping(struct address_space *mapping, struct page *page) { BUG_ON(!PageLocked(page)); BUG_ON(mapping != page_mapping(page)); - spin_lock_irq(&mapping->tree_lock); + write_lock_irq(&mapping->tree_lock); /* * The non racy check for a busy page. * @@ -425,48 +427,28 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) * Note that if SetPageDirty is always performed via set_page_dirty, * and thus under tree_lock, then this ordering is not required. */ - if (!page_freeze_refs(page, 2)) + if (unlikely(page_count(page) != 2)) goto cannot_free; - /* note: atomic_cmpxchg in page_freeze_refs provides the smp_rmb */ - if (unlikely(PageDirty(page))) { - page_unfreeze_refs(page, 2); + smp_rmb(); + if (unlikely(PageDirty(page))) goto cannot_free; - } if (PageSwapCache(page)) { swp_entry_t swap = { .val = page_private(page) }; __delete_from_swap_cache(page); - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); swap_free(swap); - } else { - __remove_from_page_cache(page); - spin_unlock_irq(&mapping->tree_lock); + __put_page(page); /* The pagecache ref */ + return 1; } + __remove_from_page_cache(page); + write_unlock_irq(&mapping->tree_lock); + __put_page(page); return 1; cannot_free: - spin_unlock_irq(&mapping->tree_lock); - return 0; -} - -/* - * 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) -{ - if (__remove_mapping(mapping, page)) { - /* - * Unfreezing the refcount with 1 rather than 2 effectively - * drops the pagecache ref for us without requiring another - * atomic operation. - */ - page_unfreeze_refs(page, 1); - return 1; - } + write_unlock_irq(&mapping->tree_lock); return 0; } @@ -616,34 +598,18 @@ static unsigned long shrink_page_list(struct list_head *page_list, if (PagePrivate(page)) { if (!try_to_release_page(page, sc->gfp_mask)) goto activate_locked; - if (!mapping && page_count(page) == 1) { - unlock_page(page); - if (put_page_testzero(page)) - goto free_it; - else { - /* - * rare race with speculative reference. - * the speculative reference will free - * this page shortly, so we may - * increment nr_reclaimed here (and - * leave it off the LRU). - */ - nr_reclaimed++; - continue; - } - } + if (!mapping && page_count(page) == 1) + goto free_it; } - if (!mapping || !__remove_mapping(mapping, page)) + if (!mapping || !remove_mapping(mapping, page)) goto keep_locked; - unlock_page(page); free_it: + unlock_page(page); nr_reclaimed++; - if (!pagevec_add(&freed_pvec, page)) { - __pagevec_free(&freed_pvec); - pagevec_reinit(&freed_pvec); - } + if (!pagevec_add(&freed_pvec, page)) + __pagevec_release_nonlru(&freed_pvec); continue; activate_locked: @@ -657,7 +623,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, } list_splice(&ret_pages, page_list); if (pagevec_count(&freed_pvec)) - __pagevec_free(&freed_pvec); + __pagevec_release_nonlru(&freed_pvec); count_vm_events(PGACTIVATE, pgactivate); return nr_reclaimed; } diff --git a/trunk/net/appletalk/ddp.c b/trunk/net/appletalk/ddp.c index 0c850427a85b..07b5b82c5eab 100644 --- a/trunk/net/appletalk/ddp.c +++ b/trunk/net/appletalk/ddp.c @@ -959,7 +959,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -986,7 +986,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, for (; list; list = list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { diff --git a/trunk/net/bridge/netfilter/ebtable_filter.c b/trunk/net/bridge/netfilter/ebtable_filter.c index 1a58af51a2e2..690bc3ab186c 100644 --- a/trunk/net/bridge/netfilter/ebtable_filter.c +++ b/trunk/net/bridge/netfilter/ebtable_filter.c @@ -93,20 +93,28 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { static int __init ebtable_filter_init(void) { - int ret; + int i, j, ret; ret = ebt_register_table(&frame_filter); if (ret < 0) return ret; - ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); - if (ret < 0) - ebt_unregister_table(&frame_filter); + for (i = 0; i < ARRAY_SIZE(ebt_ops_filter); i++) + if ((ret = nf_register_hook(&ebt_ops_filter[i])) < 0) + goto cleanup; + return ret; +cleanup: + for (j = 0; j < i; j++) + nf_unregister_hook(&ebt_ops_filter[j]); + ebt_unregister_table(&frame_filter); return ret; } static void __exit ebtable_filter_fini(void) { - nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); + int i; + + for (i = 0; i < ARRAY_SIZE(ebt_ops_filter); i++) + nf_unregister_hook(&ebt_ops_filter[i]); ebt_unregister_table(&frame_filter); } diff --git a/trunk/net/bridge/netfilter/ebtable_nat.c b/trunk/net/bridge/netfilter/ebtable_nat.c index f60c1e78e575..5b495fe2d0b6 100644 --- a/trunk/net/bridge/netfilter/ebtable_nat.c +++ b/trunk/net/bridge/netfilter/ebtable_nat.c @@ -100,20 +100,28 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { static int __init ebtable_nat_init(void) { - int ret; + int i, ret, j; ret = ebt_register_table(&frame_nat); if (ret < 0) return ret; - ret = nf_register_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat)); - if (ret < 0) - ebt_unregister_table(&frame_nat); + for (i = 0; i < ARRAY_SIZE(ebt_ops_nat); i++) + if ((ret = nf_register_hook(&ebt_ops_nat[i])) < 0) + goto cleanup; + return ret; +cleanup: + for (j = 0; j < i; j++) + nf_unregister_hook(&ebt_ops_nat[j]); + ebt_unregister_table(&frame_nat); return ret; } static void __exit ebtable_nat_fini(void) { - nf_unregister_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat)); + int i; + + for (i = 0; i < ARRAY_SIZE(ebt_ops_nat); i++) + nf_unregister_hook(&ebt_ops_nat[i]); ebt_unregister_table(&frame_nat); } diff --git a/trunk/net/core/datagram.c b/trunk/net/core/datagram.c index dd61dcad6019..8a28fc93b724 100644 --- a/trunk/net/core/datagram.c +++ b/trunk/net/core/datagram.c @@ -285,7 +285,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -315,7 +315,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, for (; list; list = list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -366,7 +366,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -402,7 +402,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, for (; list; list=list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 8d13a9b9f1df..53af7841018a 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1973,7 +1973,7 @@ static void net_tx_action(struct softirq_action *h) struct sk_buff *skb = clist; clist = clist->next; - WARN_ON(atomic_read(&skb->users)); + BUG_TRAP(!atomic_read(&skb->users)); __kfree_skb(skb); } } @@ -3847,7 +3847,7 @@ static void rollback_registered(struct net_device *dev) dev->uninit(dev); /* Notifier chain MUST detach us from master device. */ - WARN_ON(dev->master); + BUG_TRAP(!dev->master); /* Remove entries from kobject tree */ netdev_unregister_kobject(dev); @@ -4169,9 +4169,9 @@ void netdev_run_todo(void) /* paranoia */ BUG_ON(atomic_read(&dev->refcnt)); - WARN_ON(dev->ip_ptr); - WARN_ON(dev->ip6_ptr); - WARN_ON(dev->dn_ptr); + BUG_TRAP(!dev->ip_ptr); + BUG_TRAP(!dev->ip6_ptr); + BUG_TRAP(!dev->dn_ptr); if (dev->destructor) dev->destructor(dev); diff --git a/trunk/net/core/request_sock.c b/trunk/net/core/request_sock.c index 7552495aff7a..2d3035d3abd7 100644 --- a/trunk/net/core/request_sock.c +++ b/trunk/net/core/request_sock.c @@ -123,7 +123,7 @@ void reqsk_queue_destroy(struct request_sock_queue *queue) } } - WARN_ON(lopt->qlen != 0); + BUG_TRAP(lopt->qlen == 0); if (lopt_size > PAGE_SIZE) vfree(lopt); else diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 4e0c92274189..e4115672b6cf 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -1200,7 +1200,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -1229,7 +1229,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) for (; list; list = list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -1475,7 +1475,7 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + frag->size; if ((copy = end - offset) > 0) { @@ -1503,7 +1503,7 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) for (; list; list = list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -1552,7 +1552,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -1581,7 +1581,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, for (; list; list = list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -1629,7 +1629,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -1662,7 +1662,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, __wsum csum2; int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -2373,7 +2373,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -2397,7 +2397,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) for (; list; list = list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { diff --git a/trunk/net/core/stream.c b/trunk/net/core/stream.c index a6b3437ff082..4a0ad152c9c4 100644 --- a/trunk/net/core/stream.c +++ b/trunk/net/core/stream.c @@ -192,13 +192,13 @@ void sk_stream_kill_queues(struct sock *sk) __skb_queue_purge(&sk->sk_error_queue); /* Next, the write queue. */ - WARN_ON(!skb_queue_empty(&sk->sk_write_queue)); + BUG_TRAP(skb_queue_empty(&sk->sk_write_queue)); /* Account for returned memory. */ sk_mem_reclaim(sk); - WARN_ON(sk->sk_wmem_queued); - WARN_ON(sk->sk_forward_alloc); + BUG_TRAP(!sk->sk_wmem_queued); + BUG_TRAP(!sk->sk_forward_alloc); /* It is _impossible_ for the backlog to contain anything * when we get here. All user references to this socket diff --git a/trunk/net/core/user_dma.c b/trunk/net/core/user_dma.c index 164b090d5ac3..8c6b706963ff 100644 --- a/trunk/net/core/user_dma.c +++ b/trunk/net/core/user_dma.c @@ -27,6 +27,7 @@ #include #include +#include /* for BUG_TRAP */ #include #include @@ -71,7 +72,7 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; copy = end - offset; @@ -100,7 +101,7 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, for (; list; list = list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; copy = end - offset; diff --git a/trunk/net/dccp/dccp.h b/trunk/net/dccp/dccp.h index 743d85fcd651..32617e0576cb 100644 --- a/trunk/net/dccp/dccp.h +++ b/trunk/net/dccp/dccp.h @@ -164,7 +164,7 @@ static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp) { s64 delta = dccp_delta_seqno(s1, s2); - WARN_ON(delta < 0); + BUG_TRAP(delta >= 0); return (u64)delta <= ndp + 1; } diff --git a/trunk/net/dccp/input.c b/trunk/net/dccp/input.c index df2f110df94a..08392ed86c25 100644 --- a/trunk/net/dccp/input.c +++ b/trunk/net/dccp/input.c @@ -413,7 +413,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, /* Stop the REQUEST timer */ inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); - WARN_ON(sk->sk_send_head == NULL); + BUG_TRAP(sk->sk_send_head != NULL); __kfree_skb(sk->sk_send_head); sk->sk_send_head = NULL; diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index a835b88237cb..2622ace17c46 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -283,7 +283,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) * ICMPs are not backlogged, hence we cannot get an established * socket here. */ - WARN_ON(req->sk); + BUG_TRAP(!req->sk); if (seq != dccp_rsk(req)->dreq_iss) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index da509127e00c..b74e8b2cbe55 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -186,7 +186,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, * ICMPs are not backlogged, hence we cannot get an established * socket here. */ - WARN_ON(req->sk != NULL); + BUG_TRAP(req->sk == NULL); if (seq != dccp_rsk(req)->dreq_iss) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index b622d9744856..a0b56009611f 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -327,7 +327,7 @@ int dccp_disconnect(struct sock *sk, int flags) inet_csk_delack_init(sk); __sk_dst_reset(sk); - WARN_ON(inet->num && !icsk->icsk_bind_hash); + BUG_TRAP(!inet->num || icsk->icsk_bind_hash); sk->sk_error_report(sk); return err; @@ -981,7 +981,7 @@ void dccp_close(struct sock *sk, long timeout) */ local_bh_disable(); bh_lock_sock(sk); - WARN_ON(sock_owned_by_user(sk)); + BUG_TRAP(!sock_owned_by_user(sk)); /* Have we already been destroyed by a softirq or backlog? */ if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED) diff --git a/trunk/net/dccp/timer.c b/trunk/net/dccp/timer.c index 6a5b961b6f5c..3608d5342ca2 100644 --- a/trunk/net/dccp/timer.c +++ b/trunk/net/dccp/timer.c @@ -106,7 +106,7 @@ static void dccp_retransmit_timer(struct sock *sk) * -- Acks in client-PARTOPEN state (sec. 8.1.5) * -- CloseReq in server-CLOSEREQ state (sec. 8.3) * -- Close in node-CLOSING state (sec. 8.3) */ - WARN_ON(sk->sk_send_head == NULL); + BUG_TRAP(sk->sk_send_head != NULL); /* * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was diff --git a/trunk/net/ipv4/af_inet.c b/trunk/net/ipv4/af_inet.c index 8a3ac1fa71a9..f440a9f54924 100644 --- a/trunk/net/ipv4/af_inet.c +++ b/trunk/net/ipv4/af_inet.c @@ -148,10 +148,10 @@ void inet_sock_destruct(struct sock *sk) return; } - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(atomic_read(&sk->sk_wmem_alloc)); - WARN_ON(sk->sk_wmem_queued); - WARN_ON(sk->sk_forward_alloc); + BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); + BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); + BUG_TRAP(!sk->sk_wmem_queued); + BUG_TRAP(!sk->sk_forward_alloc); kfree(inet->opt); dst_release(sk->sk_dst_cache); @@ -338,7 +338,7 @@ static int inet_create(struct net *net, struct socket *sock, int protocol) answer_flags = answer->flags; rcu_read_unlock(); - WARN_ON(answer_prot->slab == NULL); + BUG_TRAP(answer_prot->slab != NULL); err = -ENOBUFS; sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot); @@ -658,8 +658,8 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags) lock_sock(sk2); - WARN_ON(!((1 << sk2->sk_state) & - (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE))); + BUG_TRAP((1 << sk2->sk_state) & + (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE)); sock_graft(sk2, newsock); @@ -1439,10 +1439,6 @@ static int __init inet_init(void) (void)sock_register(&inet_family_ops); -#ifdef CONFIG_SYSCTL - ip_static_sysctl_init(); -#endif - /* * Add all the base protocols. */ diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index 91d3d96805d0..2e667e2f90df 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -138,8 +138,8 @@ void in_dev_finish_destroy(struct in_device *idev) { struct net_device *dev = idev->dev; - WARN_ON(idev->ifa_list); - WARN_ON(idev->mc_list); + BUG_TRAP(!idev->ifa_list); + BUG_TRAP(!idev->mc_list); #ifdef NET_REFCNT_DEBUG printk(KERN_DEBUG "in_dev_finish_destroy: %p=%s\n", idev, dev ? dev->name : "NIL"); @@ -399,7 +399,7 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) } ipv4_devconf_setall(in_dev); if (ifa->ifa_dev != in_dev) { - WARN_ON(ifa->ifa_dev); + BUG_TRAP(!ifa->ifa_dev); in_dev_hold(in_dev); ifa->ifa_dev = in_dev; } diff --git a/trunk/net/ipv4/inet_connection_sock.c b/trunk/net/ipv4/inet_connection_sock.c index 0c1ae68ee84b..bb81c958b744 100644 --- a/trunk/net/ipv4/inet_connection_sock.c +++ b/trunk/net/ipv4/inet_connection_sock.c @@ -167,7 +167,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) success: if (!inet_csk(sk)->icsk_bind_hash) inet_bind_hash(sk, tb, snum); - WARN_ON(inet_csk(sk)->icsk_bind_hash != tb); + BUG_TRAP(inet_csk(sk)->icsk_bind_hash == tb); ret = 0; fail_unlock: @@ -260,7 +260,7 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err) } newsk = reqsk_queue_get_child(&icsk->icsk_accept_queue, sk); - WARN_ON(newsk->sk_state == TCP_SYN_RECV); + BUG_TRAP(newsk->sk_state != TCP_SYN_RECV); out: release_sock(sk); return newsk; @@ -386,7 +386,7 @@ struct request_sock *inet_csk_search_req(const struct sock *sk, ireq->rmt_addr == raddr && ireq->loc_addr == laddr && AF_INET_FAMILY(req->rsk_ops->family)) { - WARN_ON(req->sk); + BUG_TRAP(!req->sk); *prevp = prev; break; } @@ -539,14 +539,14 @@ EXPORT_SYMBOL_GPL(inet_csk_clone); */ void inet_csk_destroy_sock(struct sock *sk) { - WARN_ON(sk->sk_state != TCP_CLOSE); - WARN_ON(!sock_flag(sk, SOCK_DEAD)); + BUG_TRAP(sk->sk_state == TCP_CLOSE); + BUG_TRAP(sock_flag(sk, SOCK_DEAD)); /* It cannot be in hash table! */ - WARN_ON(!sk_unhashed(sk)); + BUG_TRAP(sk_unhashed(sk)); /* If it has not 0 inet_sk(sk)->num, it must be bound */ - WARN_ON(inet_sk(sk)->num && !inet_csk(sk)->icsk_bind_hash); + BUG_TRAP(!inet_sk(sk)->num || inet_csk(sk)->icsk_bind_hash); sk->sk_prot->destroy(sk); @@ -629,7 +629,7 @@ void inet_csk_listen_stop(struct sock *sk) local_bh_disable(); bh_lock_sock(child); - WARN_ON(sock_owned_by_user(child)); + BUG_TRAP(!sock_owned_by_user(child)); sock_hold(child); sk->sk_prot->disconnect(child, O_NONBLOCK); @@ -647,7 +647,7 @@ void inet_csk_listen_stop(struct sock *sk) sk_acceptq_removed(sk); __reqsk_free(req); } - WARN_ON(sk->sk_ack_backlog); + BUG_TRAP(!sk->sk_ack_backlog); } EXPORT_SYMBOL_GPL(inet_csk_listen_stop); diff --git a/trunk/net/ipv4/inet_fragment.c b/trunk/net/ipv4/inet_fragment.c index 6c52e08f786e..0546a0bc97ea 100644 --- a/trunk/net/ipv4/inet_fragment.c +++ b/trunk/net/ipv4/inet_fragment.c @@ -134,8 +134,8 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f, struct sk_buff *fp; struct netns_frags *nf; - WARN_ON(!(q->last_in & INET_FRAG_COMPLETE)); - WARN_ON(del_timer(&q->timer) != 0); + BUG_TRAP(q->last_in & INET_FRAG_COMPLETE); + BUG_TRAP(del_timer(&q->timer) == 0); /* Release all fragment data. */ fp = q->fragments; diff --git a/trunk/net/ipv4/inet_hashtables.c b/trunk/net/ipv4/inet_hashtables.c index 44981906fb91..115f53722d20 100644 --- a/trunk/net/ipv4/inet_hashtables.c +++ b/trunk/net/ipv4/inet_hashtables.c @@ -305,7 +305,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, inet->num = lport; inet->sport = htons(lport); sk->sk_hash = hash; - WARN_ON(!sk_unhashed(sk)); + BUG_TRAP(sk_unhashed(sk)); __sk_add_node(sk, &head->chain); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); write_unlock(lock); @@ -342,7 +342,7 @@ void __inet_hash_nolisten(struct sock *sk) rwlock_t *lock; struct inet_ehash_bucket *head; - WARN_ON(!sk_unhashed(sk)); + BUG_TRAP(sk_unhashed(sk)); sk->sk_hash = inet_sk_ehashfn(sk); head = inet_ehash_bucket(hashinfo, sk->sk_hash); @@ -367,7 +367,7 @@ static void __inet_hash(struct sock *sk) return; } - WARN_ON(!sk_unhashed(sk)); + BUG_TRAP(sk_unhashed(sk)); list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; lock = &hashinfo->lhash_lock; @@ -450,7 +450,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, */ inet_bind_bucket_for_each(tb, node, &head->chain) { if (tb->ib_net == net && tb->port == port) { - WARN_ON(hlist_empty(&tb->owners)); + BUG_TRAP(!hlist_empty(&tb->owners)); if (tb->fastreuse >= 0) goto next_port; if (!check_established(death_row, sk, diff --git a/trunk/net/ipv4/inet_timewait_sock.c b/trunk/net/ipv4/inet_timewait_sock.c index d985bd613d25..75c2def8f9a0 100644 --- a/trunk/net/ipv4/inet_timewait_sock.c +++ b/trunk/net/ipv4/inet_timewait_sock.c @@ -86,7 +86,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, hashinfo->bhash_size)]; spin_lock(&bhead->lock); tw->tw_tb = icsk->icsk_bind_hash; - WARN_ON(!icsk->icsk_bind_hash); + BUG_TRAP(icsk->icsk_bind_hash); inet_twsk_add_bind_node(tw, &tw->tw_tb->owners); spin_unlock(&bhead->lock); diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 2152d222b954..38d38f058018 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -488,8 +488,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, qp->q.fragments = head; } - WARN_ON(head == NULL); - WARN_ON(FRAG_CB(head)->offset != 0); + BUG_TRAP(head != NULL); + BUG_TRAP(FRAG_CB(head)->offset == 0); /* Allocate a new buffer for the datagram. */ ihlen = ip_hdrlen(head); diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index d533a89e08de..465544f6281a 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -118,7 +118,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) __skb_pull(newskb, skb_network_offset(newskb)); newskb->pkt_type = PACKET_LOOPBACK; newskb->ip_summed = CHECKSUM_UNNECESSARY; - WARN_ON(!newskb->dst); + BUG_TRAP(newskb->dst); netif_rx(newskb); return 0; } diff --git a/trunk/net/ipv4/netfilter/arptable_filter.c b/trunk/net/ipv4/netfilter/arptable_filter.c index 082f5dd3156c..3be4d07e7ed9 100644 --- a/trunk/net/ipv4/netfilter/arptable_filter.c +++ b/trunk/net/ipv4/netfilter/arptable_filter.c @@ -55,53 +55,32 @@ static struct xt_table packet_filter = { }; /* The work comes in here from netfilter.c */ -static unsigned int arpt_in_hook(unsigned int hook, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) +static unsigned int arpt_hook(unsigned int hook, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) { - return arpt_do_table(skb, hook, in, out, - dev_net(in)->ipv4.arptable_filter); -} - -static unsigned int arpt_out_hook(unsigned int hook, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -{ - return arpt_do_table(skb, hook, in, out, - dev_net(out)->ipv4.arptable_filter); -} - -static unsigned int arpt_forward_hook(unsigned int hook, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -{ - return arpt_do_table(skb, hook, in, out, - dev_net(in)->ipv4.arptable_filter); + return arpt_do_table(skb, hook, in, out, init_net.ipv4.arptable_filter); } static struct nf_hook_ops arpt_ops[] __read_mostly = { { - .hook = arpt_in_hook, + .hook = arpt_hook, .owner = THIS_MODULE, .pf = NF_ARP, .hooknum = NF_ARP_IN, .priority = NF_IP_PRI_FILTER, }, { - .hook = arpt_out_hook, + .hook = arpt_hook, .owner = THIS_MODULE, .pf = NF_ARP, .hooknum = NF_ARP_OUT, .priority = NF_IP_PRI_FILTER, }, { - .hook = arpt_forward_hook, + .hook = arpt_hook, .owner = THIS_MODULE, .pf = NF_ARP, .hooknum = NF_ARP_FORWARD, diff --git a/trunk/net/ipv4/netfilter/iptable_security.c b/trunk/net/ipv4/netfilter/iptable_security.c index db6d312128e1..2b472ac2263a 100644 --- a/trunk/net/ipv4/netfilter/iptable_security.c +++ b/trunk/net/ipv4/netfilter/iptable_security.c @@ -32,7 +32,7 @@ static struct struct ipt_replace repl; struct ipt_standard entries[3]; struct ipt_error term; -} initial_table __net_initdata = { +} initial_table __initdata = { .repl = { .name = "security", .valid_hooks = SECURITY_VALID_HOOKS, diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 380d6474cf66..e4ab0ac94f92 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -1502,7 +1502,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, rth->fl.iif != 0 || dst_metric_locked(&rth->u.dst, RTAX_MTU) || !net_eq(dev_net(rth->u.dst.dev), net) || - rt_is_expired(rth)) + !rt_is_expired(rth)) continue; if (new_mtu < 68 || new_mtu >= old_mtu) { @@ -2914,7 +2914,7 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, return 0; } -static ctl_table ipv4_route_table[] = { +ctl_table ipv4_route_table[] = { { .ctl_name = NET_IPV4_ROUTE_GC_THRESH, .procname = "gc_thresh", @@ -3216,15 +3216,6 @@ int __init ip_rt_init(void) return rc; } -/* - * We really need to sanitize the damn ipv4 init order, then all - * this nonsense will go away. - */ -void __init ip_static_sysctl_init(void) -{ - register_sysctl_paths(ipv4_route_path, ipv4_route_table); -} - EXPORT_SYMBOL(__ip_select_ident); EXPORT_SYMBOL(ip_route_input); EXPORT_SYMBOL(ip_route_output_key); diff --git a/trunk/net/ipv4/syncookies.c b/trunk/net/ipv4/syncookies.c index 9d38005abbac..51bc24d3b8a7 100644 --- a/trunk/net/ipv4/syncookies.c +++ b/trunk/net/ipv4/syncookies.c @@ -299,7 +299,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ireq->rmt_port = th->source; ireq->loc_addr = ip_hdr(skb)->daddr; ireq->rmt_addr = ip_hdr(skb)->saddr; - ireq->ecn_ok = 0; ireq->snd_wscale = tcp_opt.snd_wscale; ireq->rcv_wscale = tcp_opt.rcv_wscale; ireq->sack_ok = tcp_opt.sack_ok; diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index 770d827f5ab8..14ef202a2254 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -401,6 +401,13 @@ static struct ctl_table ipv4_table[] = { .proc_handler = &ipv4_local_port_range, .strategy = &ipv4_sysctl_local_port_range, }, + { + .ctl_name = NET_IPV4_ROUTE, + .procname = "route", + .maxlen = 0, + .mode = 0555, + .child = ipv4_route_table + }, #ifdef CONFIG_IP_MULTICAST { .ctl_name = NET_IPV4_IGMP_MAX_MEMBERSHIPS, diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 1ab341e5d3e0..0b491bf03db4 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -1096,7 +1096,7 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) #if TCP_DEBUG struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); - WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); + BUG_TRAP(!skb || before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); #endif if (inet_csk_ack_scheduled(sk)) { @@ -1358,7 +1358,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto found_ok_skb; if (tcp_hdr(skb)->fin) goto found_fin_ok; - WARN_ON(!(flags & MSG_PEEK)); + BUG_TRAP(flags & MSG_PEEK); skb = skb->next; } while (skb != (struct sk_buff *)&sk->sk_receive_queue); @@ -1421,8 +1421,8 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, tp->ucopy.len = len; - WARN_ON(tp->copied_seq != tp->rcv_nxt && - !(flags & (MSG_PEEK | MSG_TRUNC))); + BUG_TRAP(tp->copied_seq == tp->rcv_nxt || + (flags & (MSG_PEEK | MSG_TRUNC))); /* Ugly... If prequeue is not empty, we have to * process it before releasing socket, otherwise @@ -1844,7 +1844,7 @@ void tcp_close(struct sock *sk, long timeout) */ local_bh_disable(); bh_lock_sock(sk); - WARN_ON(sock_owned_by_user(sk)); + BUG_TRAP(!sock_owned_by_user(sk)); /* Have we already been destroyed by a softirq or backlog? */ if (state != TCP_CLOSE && sk->sk_state == TCP_CLOSE) @@ -1973,7 +1973,7 @@ int tcp_disconnect(struct sock *sk, int flags) memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); __sk_dst_reset(sk); - WARN_ON(inet->num && !icsk->icsk_bind_hash); + BUG_TRAP(!inet->num || icsk->icsk_bind_hash); sk->sk_error_report(sk); return err; diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 67ccce2a96bd..75efd244f2af 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -1629,10 +1629,10 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, out: #if FASTRETRANS_DEBUG > 0 - WARN_ON((int)tp->sacked_out < 0); - WARN_ON((int)tp->lost_out < 0); - WARN_ON((int)tp->retrans_out < 0); - WARN_ON((int)tcp_packets_in_flight(tp) < 0); + BUG_TRAP((int)tp->sacked_out >= 0); + BUG_TRAP((int)tp->lost_out >= 0); + BUG_TRAP((int)tp->retrans_out >= 0); + BUG_TRAP((int)tcp_packets_in_flight(tp) >= 0); #endif return flag; } @@ -2181,7 +2181,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) int err; unsigned int mss; - WARN_ON(packets > tp->packets_out); + BUG_TRAP(packets <= tp->packets_out); if (tp->lost_skb_hint) { skb = tp->lost_skb_hint; cnt = tp->lost_cnt_hint; @@ -2610,7 +2610,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) /* E. Check state exit conditions. State can be terminated * when high_seq is ACKed. */ if (icsk->icsk_ca_state == TCP_CA_Open) { - WARN_ON(tp->retrans_out != 0); + BUG_TRAP(tp->retrans_out == 0); tp->retrans_stamp = 0; } else if (!before(tp->snd_una, tp->high_seq)) { switch (icsk->icsk_ca_state) { @@ -2972,9 +2972,9 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets) } #if FASTRETRANS_DEBUG > 0 - WARN_ON((int)tp->sacked_out < 0); - WARN_ON((int)tp->lost_out < 0); - WARN_ON((int)tp->retrans_out < 0); + BUG_TRAP((int)tp->sacked_out >= 0); + BUG_TRAP((int)tp->lost_out >= 0); + BUG_TRAP((int)tp->retrans_out >= 0); if (!tp->packets_out && tcp_is_sack(tp)) { icsk = inet_csk(sk); if (tp->lost_out) { @@ -3877,7 +3877,7 @@ static void tcp_sack_remove(struct tcp_sock *tp) int i; /* RCV.NXT must cover all the block! */ - WARN_ON(before(tp->rcv_nxt, sp->end_seq)); + BUG_TRAP(!before(tp->rcv_nxt, sp->end_seq)); /* Zap this SACK, by moving forward any other SACKS. */ for (i=this_sack+1; i < num_sacks; i++) diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index a2b06d0cc26b..a82df6307567 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -418,7 +418,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) /* ICMPs are not backlogged, hence we cannot get an established socket here. */ - WARN_ON(req->sk); + BUG_TRAP(!req->sk); if (seq != tcp_rsk(req)->snt_isn) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); diff --git a/trunk/net/ipv4/tcp_timer.c b/trunk/net/ipv4/tcp_timer.c index 5ab6ba19c3ce..328e0cf42b3c 100644 --- a/trunk/net/ipv4/tcp_timer.c +++ b/trunk/net/ipv4/tcp_timer.c @@ -287,7 +287,7 @@ static void tcp_retransmit_timer(struct sock *sk) if (!tp->packets_out) goto out; - WARN_ON(tcp_write_queue_empty(sk)); + BUG_TRAP(!tcp_write_queue_empty(sk)); if (!tp->snd_wnd && !sock_flag(sk, SOCK_DEAD) && !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) { diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index a7842c54f58a..74d543d504a1 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -313,10 +313,8 @@ static void in6_dev_finish_destroy_rcu(struct rcu_head *head) void in6_dev_finish_destroy(struct inet6_dev *idev) { struct net_device *dev = idev->dev; - - WARN_ON(idev->addr_list != NULL); - WARN_ON(idev->mc_list != NULL); - + BUG_TRAP(idev->addr_list==NULL); + BUG_TRAP(idev->mc_list==NULL); #ifdef NET_REFCNT_DEBUG printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL"); #endif @@ -519,9 +517,8 @@ static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) { - WARN_ON(ifp->if_next != NULL); - WARN_ON(ifp->lst_next != NULL); - + BUG_TRAP(ifp->if_next==NULL); + BUG_TRAP(ifp->lst_next==NULL); #ifdef NET_REFCNT_DEBUG printk(KERN_DEBUG "inet6_ifa_finish_destroy\n"); #endif diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index 95055f8c3f35..60461ad7fa6f 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -150,7 +150,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol) answer_flags = answer->flags; rcu_read_unlock(); - WARN_ON(answer_prot->slab == NULL); + BUG_TRAP(answer_prot->slab != NULL); err = -ENOBUFS; sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot); @@ -934,11 +934,6 @@ static int __init inet6_init(void) if (err) goto out_unregister_sock; -#ifdef CONFIG_SYSCTL - err = ipv6_static_sysctl_register(); - if (err) - goto static_sysctl_fail; -#endif /* * ipngwg API draft makes clear that the correct semantics * for TCP and UDP is to consider one TCP and UDP instance @@ -1063,10 +1058,6 @@ static int __init inet6_init(void) icmp_fail: unregister_pernet_subsys(&inet6_net_ops); register_pernet_fail: -#ifdef CONFIG_SYSCTL - ipv6_static_sysctl_unregister(); -static_sysctl_fail: -#endif cleanup_ipv6_mibs(); out_unregister_sock: sock_unregister(PF_INET6); @@ -1122,9 +1113,6 @@ static void __exit inet6_exit(void) rawv6_exit(); unregister_pernet_subsys(&inet6_net_ops); -#ifdef CONFIG_SYSCTL - ipv6_static_sysctl_unregister(); -#endif cleanup_ipv6_mibs(); proto_unregister(&rawv6_prot); proto_unregister(&udplitev6_prot); diff --git a/trunk/net/ipv6/inet6_connection_sock.c b/trunk/net/ipv6/inet6_connection_sock.c index 16d43f20b32f..87801cc1b2f8 100644 --- a/trunk/net/ipv6/inet6_connection_sock.c +++ b/trunk/net/ipv6/inet6_connection_sock.c @@ -98,7 +98,7 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk, ipv6_addr_equal(&treq->rmt_addr, raddr) && ipv6_addr_equal(&treq->loc_addr, laddr) && (!treq->iif || treq->iif == iif)) { - WARN_ON(req->sk != NULL); + BUG_TRAP(req->sk == NULL); *prevp = prev; return req; } diff --git a/trunk/net/ipv6/inet6_hashtables.c b/trunk/net/ipv6/inet6_hashtables.c index 1646a5658255..00a8a5f9380c 100644 --- a/trunk/net/ipv6/inet6_hashtables.c +++ b/trunk/net/ipv6/inet6_hashtables.c @@ -28,7 +28,7 @@ void __inet6_hash(struct sock *sk) struct hlist_head *list; rwlock_t *lock; - WARN_ON(!sk_unhashed(sk)); + BUG_TRAP(sk_unhashed(sk)); if (sk->sk_state == TCP_LISTEN) { list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; @@ -202,7 +202,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, * in hash table socket with a funny identity. */ inet->num = lport; inet->sport = htons(lport); - WARN_ON(!sk_unhashed(sk)); + BUG_TRAP(sk_unhashed(sk)); __sk_add_node(sk, &head->chain); sk->sk_hash = hash; sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index 52dddc25d3e6..08ea2de28d63 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -287,7 +287,7 @@ static int fib6_dump_node(struct fib6_walker_t *w) w->leaf = rt; return 1; } - WARN_ON(res == 0); + BUG_TRAP(res!=0); } w->leaf = NULL; return 0; @@ -778,7 +778,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info) pn->leaf = fib6_find_prefix(info->nl_net, pn); #if RT6_DEBUG >= 2 if (!pn->leaf) { - WARN_ON(pn->leaf == NULL); + BUG_TRAP(pn->leaf != NULL); pn->leaf = info->nl_net->ipv6.ip6_null_entry; } #endif @@ -942,7 +942,7 @@ struct fib6_node * fib6_locate(struct fib6_node *root, #ifdef CONFIG_IPV6_SUBTREES if (src_len) { - WARN_ON(saddr == NULL); + BUG_TRAP(saddr!=NULL); if (fn && fn->subtree) fn = fib6_locate_1(fn->subtree, saddr, src_len, offsetof(struct rt6_info, rt6i_src)); @@ -996,9 +996,9 @@ static struct fib6_node *fib6_repair_tree(struct net *net, RT6_TRACE("fixing tree: plen=%d iter=%d\n", fn->fn_bit, iter); iter++; - WARN_ON(fn->fn_flags & RTN_RTINFO); - WARN_ON(fn->fn_flags & RTN_TL_ROOT); - WARN_ON(fn->leaf != NULL); + BUG_TRAP(!(fn->fn_flags&RTN_RTINFO)); + BUG_TRAP(!(fn->fn_flags&RTN_TL_ROOT)); + BUG_TRAP(fn->leaf==NULL); children = 0; child = NULL; @@ -1014,7 +1014,7 @@ static struct fib6_node *fib6_repair_tree(struct net *net, fn->leaf = fib6_find_prefix(net, fn); #if RT6_DEBUG >= 2 if (fn->leaf==NULL) { - WARN_ON(!fn->leaf); + BUG_TRAP(fn->leaf); fn->leaf = net->ipv6.ip6_null_entry; } #endif @@ -1025,17 +1025,16 @@ static struct fib6_node *fib6_repair_tree(struct net *net, pn = fn->parent; #ifdef CONFIG_IPV6_SUBTREES if (FIB6_SUBTREE(pn) == fn) { - WARN_ON(!(fn->fn_flags & RTN_ROOT)); + BUG_TRAP(fn->fn_flags&RTN_ROOT); FIB6_SUBTREE(pn) = NULL; nstate = FWS_L; } else { - WARN_ON(fn->fn_flags & RTN_ROOT); + BUG_TRAP(!(fn->fn_flags&RTN_ROOT)); #endif if (pn->right == fn) pn->right = child; else if (pn->left == fn) pn->left = child; #if RT6_DEBUG >= 2 - else - WARN_ON(1); + else BUG_TRAP(0); #endif if (child) child->parent = pn; @@ -1155,14 +1154,14 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info) #if RT6_DEBUG >= 2 if (rt->u.dst.obsolete>0) { - WARN_ON(fn != NULL); + BUG_TRAP(fn==NULL); return -ENOENT; } #endif if (fn == NULL || rt == net->ipv6.ip6_null_entry) return -ENOENT; - WARN_ON(!(fn->fn_flags & RTN_RTINFO)); + BUG_TRAP(fn->fn_flags&RTN_RTINFO); if (!(rt->rt6i_flags&RTF_CACHE)) { struct fib6_node *pn = fn; @@ -1267,7 +1266,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) w->node = pn; #ifdef CONFIG_IPV6_SUBTREES if (FIB6_SUBTREE(pn) == fn) { - WARN_ON(!(fn->fn_flags & RTN_ROOT)); + BUG_TRAP(fn->fn_flags&RTN_ROOT); w->state = FWS_L; continue; } @@ -1282,7 +1281,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) continue; } #if RT6_DEBUG >= 2 - WARN_ON(1); + BUG_TRAP(0); #endif } } @@ -1324,7 +1323,7 @@ static int fib6_clean_node(struct fib6_walker_t *w) } return 0; } - WARN_ON(res != 0); + BUG_TRAP(res==0); } w->leaf = rt; return 0; diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 6811901e6b1e..6407c64ea4a5 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -116,7 +116,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) __skb_pull(newskb, skb_network_offset(newskb)); newskb->pkt_type = PACKET_LOOPBACK; newskb->ip_summed = CHECKSUM_UNNECESSARY; - WARN_ON(!newskb->dst); + BUG_TRAP(newskb->dst); netif_rx(newskb); return 0; diff --git a/trunk/net/ipv6/mip6.c b/trunk/net/ipv6/mip6.c index 31295c8f6196..ad1cc5bbf977 100644 --- a/trunk/net/ipv6/mip6.c +++ b/trunk/net/ipv6/mip6.c @@ -164,8 +164,8 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) calc_padlen(sizeof(*dstopt), 6)); hao->type = IPV6_TLV_HAO; - BUILD_BUG_ON(sizeof(*hao) != 18); hao->length = sizeof(*hao) - 2; + BUG_TRAP(hao->length == 16); len = ((char *)hao - (char *)dstopt) + sizeof(*hao); @@ -174,7 +174,7 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr)); spin_unlock_bh(&x->lock); - WARN_ON(len != x->props.header_len); + BUG_TRAP(len == x->props.header_len); dstopt->hdrlen = (x->props.header_len >> 3) - 1; return 0; @@ -317,7 +317,7 @@ static int mip6_destopt_init_state(struct xfrm_state *x) x->props.header_len = sizeof(struct ipv6_destopt_hdr) + calc_padlen(sizeof(struct ipv6_destopt_hdr), 6) + sizeof(struct ipv6_destopt_hao); - WARN_ON(x->props.header_len != 24); + BUG_TRAP(x->props.header_len == 24); return 0; } @@ -380,7 +380,7 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb) rt2->rt_hdr.segments_left = 1; memset(&rt2->reserved, 0, sizeof(rt2->reserved)); - WARN_ON(rt2->rt_hdr.hdrlen != 2); + BUG_TRAP(rt2->rt_hdr.hdrlen == 2); memcpy(&rt2->addr, &iph->daddr, sizeof(rt2->addr)); spin_lock_bh(&x->lock); diff --git a/trunk/net/ipv6/netfilter/ip6table_security.c b/trunk/net/ipv6/netfilter/ip6table_security.c index 6e7131036bc6..a07abee30497 100644 --- a/trunk/net/ipv6/netfilter/ip6table_security.c +++ b/trunk/net/ipv6/netfilter/ip6table_security.c @@ -31,7 +31,7 @@ static struct struct ip6t_replace repl; struct ip6t_standard entries[3]; struct ip6t_error term; -} initial_table __net_initdata = { +} initial_table __initdata = { .repl = { .name = "security", .valid_hooks = SECURITY_VALID_HOOKS, diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 52d06dd4b817..cf20bc4fd60d 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -416,8 +416,8 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) fq_kill(fq); - WARN_ON(head == NULL); - WARN_ON(NFCT_FRAG6_CB(head)->offset != 0); + BUG_TRAP(head != NULL); + BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0); /* Unfragmented part is taken from the first segment. */ payload_len = ((head->data - skb_network_header(head)) - diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index 89184b576e23..6ab957ec2dd6 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -473,8 +473,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, fq->q.fragments = head; } - WARN_ON(head == NULL); - WARN_ON(FRAG6_CB(head)->offset != 0); + BUG_TRAP(head != NULL); + BUG_TRAP(FRAG6_CB(head)->offset == 0); /* Unfragmented part is taken from the first segment. */ payload_len = ((head->data - skb_network_header(head)) - diff --git a/trunk/net/ipv6/syncookies.c b/trunk/net/ipv6/syncookies.c index a46badd1082d..6a68eeb7bbf8 100644 --- a/trunk/net/ipv6/syncookies.c +++ b/trunk/net/ipv6/syncookies.c @@ -223,7 +223,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) req->expires = 0UL; req->retrans = 0; - ireq->ecn_ok = 0; ireq->snd_wscale = tcp_opt.snd_wscale; ireq->rcv_wscale = tcp_opt.rcv_wscale; ireq->sack_ok = tcp_opt.sack_ok; diff --git a/trunk/net/ipv6/sysctl_net_ipv6.c b/trunk/net/ipv6/sysctl_net_ipv6.c index e6dfaeac6be3..5c99274558bf 100644 --- a/trunk/net/ipv6/sysctl_net_ipv6.c +++ b/trunk/net/ipv6/sysctl_net_ipv6.c @@ -150,19 +150,3 @@ void ipv6_sysctl_unregister(void) unregister_net_sysctl_table(ip6_header); unregister_pernet_subsys(&ipv6_sysctl_net_ops); } - -static struct ctl_table_header *ip6_base; - -int ipv6_static_sysctl_register(void) -{ - static struct ctl_table empty[1]; - ip6_base = register_net_sysctl_rotable(net_ipv6_ctl_path, empty); - if (ip6_base == NULL) - return -ENOMEM; - return 0; -} - -void ipv6_static_sysctl_unregister(void) -{ - unregister_net_sysctl_table(ip6_base); -} diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index cff778b23a7f..ae45f9835014 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -421,7 +421,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, /* ICMPs are not backlogged, hence we cannot get * an established socket here. */ - WARN_ON(req->sk != NULL); + BUG_TRAP(req->sk == NULL); if (seq != tcp_rsk(req)->snt_isn) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index d628df97e02e..f0fc46c8038d 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -96,8 +96,8 @@ static void pfkey_sock_destruct(struct sock *sk) return; } - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(atomic_read(&sk->sk_wmem_alloc)); + BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); + BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); atomic_dec(&pfkey_socks_nr); } diff --git a/trunk/net/netfilter/nf_conntrack_extend.c b/trunk/net/netfilter/nf_conntrack_extend.c index 4b2c769d555f..3469bc71a385 100644 --- a/trunk/net/netfilter/nf_conntrack_extend.c +++ b/trunk/net/netfilter/nf_conntrack_extend.c @@ -95,7 +95,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) newlen = newoff + t->len; rcu_read_unlock(); - new = __krealloc(ct->ext, newlen, gfp); + new = krealloc(ct->ext, newlen, gfp); if (!new) return NULL; @@ -115,10 +115,10 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) ct->ext = new; } - new->offset[id] = newoff; - new->len = newlen; - memset((void *)new + newoff, 0, newlen - newoff); - return (void *)new + newoff; + ct->ext->offset[id] = newoff; + ct->ext->len = newlen; + memset((void *)ct->ext + newoff, 0, newlen - newoff); + return (void *)ct->ext + newoff; } EXPORT_SYMBOL(__nf_ct_ext_add); diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index b0eacc0007cc..98bfe277eab2 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -158,10 +158,9 @@ static void netlink_sock_destruct(struct sock *sk) printk(KERN_ERR "Freeing alive netlink socket %p\n", sk); return; } - - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(atomic_read(&sk->sk_wmem_alloc)); - WARN_ON(nlk_sk(sk)->groups); + BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); + BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); + BUG_TRAP(!nlk_sk(sk)->groups); } /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index c718e7e3f7de..d56cae112dc8 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -260,8 +260,8 @@ static inline struct packet_sock *pkt_sk(struct sock *sk) static void packet_sock_destruct(struct sock *sk) { - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(atomic_read(&sk->sk_wmem_alloc)); + BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); + BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); if (!sock_flag(sk, SOCK_DEAD)) { printk("Attempt to release alive packet socket: %p\n", sk); diff --git a/trunk/net/rxrpc/af_rxrpc.c b/trunk/net/rxrpc/af_rxrpc.c index 32e489118beb..4b2682feeedc 100644 --- a/trunk/net/rxrpc/af_rxrpc.c +++ b/trunk/net/rxrpc/af_rxrpc.c @@ -660,9 +660,9 @@ static void rxrpc_sock_destructor(struct sock *sk) rxrpc_purge_queue(&sk->sk_receive_queue); - WARN_ON(atomic_read(&sk->sk_wmem_alloc)); - WARN_ON(!sk_unhashed(sk)); - WARN_ON(sk->sk_socket); + BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); + BUG_TRAP(sk_unhashed(sk)); + BUG_TRAP(!sk->sk_socket); if (!sock_flag(sk, SOCK_DEAD)) { printk("Attempt to release alive rxrpc socket: %p\n", sk); diff --git a/trunk/net/sched/act_api.c b/trunk/net/sched/act_api.c index d308c19aa3f9..74e662cbb2c5 100644 --- a/trunk/net/sched/act_api.c +++ b/trunk/net/sched/act_api.c @@ -41,7 +41,7 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) return; } } - WARN_ON(1); + BUG_TRAP(0); } EXPORT_SYMBOL(tcf_hash_destroy); diff --git a/trunk/net/sched/act_police.c b/trunk/net/sched/act_police.c index 38015b493947..32c3f9d9fb7a 100644 --- a/trunk/net/sched/act_police.c +++ b/trunk/net/sched/act_police.c @@ -116,7 +116,7 @@ static void tcf_police_destroy(struct tcf_police *p) return; } } - WARN_ON(1); + BUG_TRAP(0); } static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = { diff --git a/trunk/net/sched/cls_u32.c b/trunk/net/sched/cls_u32.c index 246f9065ce34..527db2559dd2 100644 --- a/trunk/net/sched/cls_u32.c +++ b/trunk/net/sched/cls_u32.c @@ -345,7 +345,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode* key) } } } - WARN_ON(1); + BUG_TRAP(0); return 0; } @@ -368,7 +368,7 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht) struct tc_u_common *tp_c = tp->data; struct tc_u_hnode **hn; - WARN_ON(ht->refcnt); + BUG_TRAP(!ht->refcnt); u32_clear_hnode(tp, ht); @@ -380,7 +380,7 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht) } } - WARN_ON(1); + BUG_TRAP(0); return -ENOENT; } @@ -389,7 +389,7 @@ static void u32_destroy(struct tcf_proto *tp) struct tc_u_common *tp_c = tp->data; struct tc_u_hnode *root_ht = xchg(&tp->root, NULL); - WARN_ON(root_ht == NULL); + BUG_TRAP(root_ht != NULL); if (root_ht && --root_ht->refcnt == 0) u32_destroy_hnode(tp, root_ht); @@ -407,7 +407,7 @@ static void u32_destroy(struct tcf_proto *tp) while ((ht = tp_c->hlist) != NULL) { tp_c->hlist = ht->next; - WARN_ON(ht->refcnt != 0); + BUG_TRAP(ht->refcnt == 0); kfree(ht); } diff --git a/trunk/net/sched/sch_atm.c b/trunk/net/sched/sch_atm.c index 6b517b9dac5b..04faa835be17 100644 --- a/trunk/net/sched/sch_atm.c +++ b/trunk/net/sched/sch_atm.c @@ -162,7 +162,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl) qdisc_destroy(flow->q); tcf_destroy_chain(&flow->filter_list); if (flow->sock) { - pr_debug("atm_tc_put: f_count %ld\n", + pr_debug("atm_tc_put: f_count %d\n", file_count(flow->sock->file)); flow->vcc->pop = flow->old_pop; sockfd_put(flow->sock); @@ -259,7 +259,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, sock = sockfd_lookup(fd, &error); if (!sock) return error; /* f_count++ */ - pr_debug("atm_tc_change: f_count %ld\n", file_count(sock->file)); + pr_debug("atm_tc_change: f_count %d\n", file_count(sock->file)); if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) { error = -EPROTOTYPE; goto err_out; diff --git a/trunk/net/sched/sch_cbq.c b/trunk/net/sched/sch_cbq.c index 14954bf4a683..f1d2f8ec8b4c 100644 --- a/trunk/net/sched/sch_cbq.c +++ b/trunk/net/sched/sch_cbq.c @@ -1175,7 +1175,7 @@ static void cbq_unlink_class(struct cbq_class *this) this->tparent->children = NULL; } } else { - WARN_ON(this->sibling != this); + BUG_TRAP(this->sibling == this); } } @@ -1699,7 +1699,7 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) { struct cbq_sched_data *q = qdisc_priv(sch); - WARN_ON(cl->filters); + BUG_TRAP(!cl->filters); tcf_destroy_chain(&cl->filter_list); qdisc_destroy(cl->q); diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index fd2a6cadb115..43abd4d27ea6 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -746,5 +746,5 @@ void dev_shutdown(struct net_device *dev) { netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); shutdown_scheduler_queue(dev, &dev->rx_queue, NULL); - WARN_ON(timer_pending(&dev->watchdog_timer)); + BUG_TRAP(!timer_pending(&dev->watchdog_timer)); } diff --git a/trunk/net/sched/sch_htb.c b/trunk/net/sched/sch_htb.c index 75a40951c4f2..30c999c61b01 100644 --- a/trunk/net/sched/sch_htb.c +++ b/trunk/net/sched/sch_htb.c @@ -524,7 +524,7 @@ htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, long *diff) */ static inline void htb_activate(struct htb_sched *q, struct htb_class *cl) { - WARN_ON(cl->level || !cl->un.leaf.q || !cl->un.leaf.q->q.qlen); + BUG_TRAP(!cl->level && cl->un.leaf.q && cl->un.leaf.q->q.qlen); if (!cl->prio_activity) { cl->prio_activity = 1 << (cl->un.leaf.aprio = cl->un.leaf.prio); @@ -542,7 +542,7 @@ static inline void htb_activate(struct htb_sched *q, struct htb_class *cl) */ static inline void htb_deactivate(struct htb_sched *q, struct htb_class *cl) { - WARN_ON(!cl->prio_activity); + BUG_TRAP(cl->prio_activity); htb_deactivate_prios(q, cl); cl->prio_activity = 0; @@ -757,7 +757,7 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio, u32 *pid; } stk[TC_HTB_MAXDEPTH], *sp = stk; - WARN_ON(!tree->rb_node); + BUG_TRAP(tree->rb_node); sp->root = tree->rb_node; sp->pptr = pptr; sp->pid = pid; @@ -777,7 +777,7 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio, *sp->pptr = (*sp->pptr)->rb_left; if (sp > stk) { sp--; - WARN_ON(!*sp->pptr); + BUG_TRAP(*sp->pptr); if (!*sp->pptr) return NULL; htb_next_rb_node(sp->pptr); @@ -792,7 +792,7 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio, sp->pid = cl->un.inner.last_ptr_id + prio; } } - WARN_ON(1); + BUG_TRAP(0); return NULL; } @@ -810,7 +810,7 @@ static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio, do { next: - WARN_ON(!cl); + BUG_TRAP(cl); if (!cl) return NULL; @@ -1185,7 +1185,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, { struct htb_class *parent = cl->parent; - WARN_ON(cl->level || !cl->un.leaf.q || cl->prio_activity); + BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity); if (parent->cmode != HTB_CAN_SEND) htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level); @@ -1205,7 +1205,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) { if (!cl->level) { - WARN_ON(!cl->un.leaf.q); + BUG_TRAP(cl->un.leaf.q); qdisc_destroy(cl->un.leaf.q); } gen_kill_estimator(&cl->bstats, &cl->rate_est); diff --git a/trunk/net/sched/sch_sfq.c b/trunk/net/sched/sch_sfq.c index 8589da666568..73f53844ce97 100644 --- a/trunk/net/sched/sch_sfq.c +++ b/trunk/net/sched/sch_sfq.c @@ -536,7 +536,14 @@ static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb) opt.limit = q->limit; opt.divisor = SFQ_HASH_DIVISOR; - opt.flows = q->limit; + opt.flows = 0; + if (q->tail != SFQ_DEPTH) { + unsigned int i; + + for (i = 0; i < SFQ_HASH_DIVISOR; i++) + if (q->ht[i] != SFQ_DEPTH) + opt.flows++; + } NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index 8472b8b349c4..ec2a0a33fd78 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -464,7 +464,7 @@ static void sctp_association_destroy(struct sctp_association *asoc) spin_unlock_bh(&sctp_assocs_id_lock); } - WARN_ON(atomic_read(&asoc->rmem_alloc)); + BUG_TRAP(!atomic_read(&asoc->rmem_alloc)); if (asoc->base.malloced) { kfree(asoc); diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 8ef8ba81b9e2..1310a82cbba7 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -265,7 +265,7 @@ static void sock_destroy_inode(struct inode *inode) container_of(inode, struct socket_alloc, vfs_inode)); } -static void init_once(void *foo) +static void init_once(struct kmem_cache *cachep, void *foo) { struct socket_alloc *ei = (struct socket_alloc *)foo; diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 23a2b8f6dc49..5a9b0e7828cd 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -897,7 +897,7 @@ static struct file_system_type rpc_pipe_fs_type = { }; static void -init_once(void *foo) +init_once(struct kmem_cache * cachep, void *foo) { struct rpc_inode *rpci = (struct rpc_inode *) foo; diff --git a/trunk/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/trunk/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 84d328329d98..a19b22b452a3 100644 --- a/trunk/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/trunk/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -169,8 +169,7 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp, (void *) vec->sge[xdr_sge_no].iov_base + sge_off, sge_bytes, DMA_TO_DEVICE); - if (dma_mapping_error(xprt->sc_cm_id->device->dma_device, - sge[sge_no].addr)) + if (dma_mapping_error(sge[sge_no].addr)) goto err; sge_off = 0; sge_no++; diff --git a/trunk/net/sysctl_net.c b/trunk/net/sysctl_net.c index 972201cd5fa7..63ada437fc2f 100644 --- a/trunk/net/sysctl_net.c +++ b/trunk/net/sysctl_net.c @@ -29,15 +29,10 @@ #include #endif -static struct ctl_table_set * +static struct list_head * net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces) { - return &namespaces->net_ns->sysctls; -} - -static int is_seen(struct ctl_table_set *set) -{ - return ¤t->nsproxy->net_ns->sysctls == set; + return &namespaces->net_ns->sysctl_table_headers; } /* Return standard mode bits for table entry. */ @@ -58,6 +53,13 @@ static struct ctl_table_root net_sysctl_root = { .permissions = net_ctl_permissions, }; +static LIST_HEAD(net_sysctl_ro_tables); +static struct list_head *net_ctl_ro_header_lookup(struct ctl_table_root *root, + struct nsproxy *namespaces) +{ + return &net_sysctl_ro_tables; +} + static int net_ctl_ro_header_perms(struct ctl_table_root *root, struct nsproxy *namespaces, struct ctl_table *table) { @@ -68,20 +70,19 @@ static int net_ctl_ro_header_perms(struct ctl_table_root *root, } static struct ctl_table_root net_sysctl_ro_root = { + .lookup = net_ctl_ro_header_lookup, .permissions = net_ctl_ro_header_perms, }; static int sysctl_net_init(struct net *net) { - setup_sysctl_set(&net->sysctls, - &net_sysctl_ro_root.default_set, - is_seen); + INIT_LIST_HEAD(&net->sysctl_table_headers); return 0; } static void sysctl_net_exit(struct net *net) { - WARN_ON(!list_empty(&net->sysctls.list)); + WARN_ON(!list_empty(&net->sysctl_table_headers)); return; } @@ -97,7 +98,6 @@ static __init int sysctl_init(void) if (ret) goto out; register_sysctl_root(&net_sysctl_root); - setup_sysctl_set(&net_sysctl_ro_root.default_set, NULL, NULL); register_sysctl_root(&net_sysctl_ro_root); out: return ret; diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 015606b54d9b..70ceb1604ad8 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -227,7 +227,7 @@ static void __unix_remove_socket(struct sock *sk) static void __unix_insert_socket(struct hlist_head *list, struct sock *sk) { - WARN_ON(!sk_unhashed(sk)); + BUG_TRAP(sk_unhashed(sk)); sk_add_node(sk, list); } @@ -350,9 +350,9 @@ static void unix_sock_destructor(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); - WARN_ON(atomic_read(&sk->sk_wmem_alloc)); - WARN_ON(!sk_unhashed(sk)); - WARN_ON(sk->sk_socket); + BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); + BUG_TRAP(sk_unhashed(sk)); + BUG_TRAP(!sk->sk_socket); if (!sock_flag(sk, SOCK_DEAD)) { printk("Attempt to release alive unix socket: %p\n", sk); return; @@ -603,7 +603,7 @@ static struct sock * unix_create1(struct net *net, struct socket *sock) u->dentry = NULL; u->mnt = NULL; spin_lock_init(&u->lock); - atomic_long_set(&u->inflight, 0); + atomic_set(&u->inflight, 0); INIT_LIST_HEAD(&u->link); mutex_init(&u->readlock); /* single task reading lock */ init_waitqueue_head(&u->peer_wait); diff --git a/trunk/net/unix/garbage.c b/trunk/net/unix/garbage.c index 2a27b84f740b..ebdff3d877a1 100644 --- a/trunk/net/unix/garbage.c +++ b/trunk/net/unix/garbage.c @@ -127,7 +127,7 @@ void unix_inflight(struct file *fp) if(s) { struct unix_sock *u = unix_sk(s); spin_lock(&unix_gc_lock); - if (atomic_long_inc_return(&u->inflight) == 1) { + if (atomic_inc_return(&u->inflight) == 1) { BUG_ON(!list_empty(&u->link)); list_add_tail(&u->link, &gc_inflight_list); } else { @@ -145,7 +145,7 @@ void unix_notinflight(struct file *fp) struct unix_sock *u = unix_sk(s); spin_lock(&unix_gc_lock); BUG_ON(list_empty(&u->link)); - if (atomic_long_dec_and_test(&u->inflight)) + if (atomic_dec_and_test(&u->inflight)) list_del_init(&u->link); unix_tot_inflight--; spin_unlock(&unix_gc_lock); @@ -237,17 +237,17 @@ static void scan_children(struct sock *x, void (*func)(struct unix_sock *), static void dec_inflight(struct unix_sock *usk) { - atomic_long_dec(&usk->inflight); + atomic_dec(&usk->inflight); } static void inc_inflight(struct unix_sock *usk) { - atomic_long_inc(&usk->inflight); + atomic_inc(&usk->inflight); } static void inc_inflight_move_tail(struct unix_sock *u) { - atomic_long_inc(&u->inflight); + atomic_inc(&u->inflight); /* * If this is still a candidate, move it to the end of the * list, so that it's checked even if it was already passed @@ -288,11 +288,11 @@ void unix_gc(void) * before the detach without atomicity guarantees. */ list_for_each_entry_safe(u, next, &gc_inflight_list, link) { - long total_refs; - long inflight_refs; + int total_refs; + int inflight_refs; total_refs = file_count(u->sk.sk_socket->file); - inflight_refs = atomic_long_read(&u->inflight); + inflight_refs = atomic_read(&u->inflight); BUG_ON(inflight_refs < 1); BUG_ON(total_refs < inflight_refs); @@ -324,7 +324,7 @@ void unix_gc(void) /* Move cursor to after the current position. */ list_move(&cursor, &u->link); - if (atomic_long_read(&u->inflight) > 0) { + if (atomic_read(&u->inflight) > 0) { list_move_tail(&u->link, &gc_inflight_list); u->gc_candidate = 0; scan_children(&u->sk, inc_inflight_move_tail, NULL); diff --git a/trunk/net/xfrm/xfrm_algo.c b/trunk/net/xfrm/xfrm_algo.c index 96036cf2216d..23a2cc04b8cd 100644 --- a/trunk/net/xfrm/xfrm_algo.c +++ b/trunk/net/xfrm/xfrm_algo.c @@ -718,7 +718,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -748,7 +748,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, for (; list; list = list->next) { int end; - WARN_ON(start > offset + len); + BUG_TRAP(start <= offset + len); end = start + list->len; if ((copy = end - offset) > 0) { diff --git a/trunk/net/xfrm/xfrm_ipcomp.c b/trunk/net/xfrm/xfrm_ipcomp.c index c609a4b98e15..800f669083fb 100644 --- a/trunk/net/xfrm/xfrm_ipcomp.c +++ b/trunk/net/xfrm/xfrm_ipcomp.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -250,7 +251,7 @@ static void ipcomp_free_tfms(struct crypto_comp **tfms) break; } - WARN_ON(!pos); + BUG_TRAP(pos); if (--pos->users) return; diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index 4c6914ef7d92..72fddafd891a 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -538,7 +538,7 @@ EXPORT_SYMBOL(xfrm_state_alloc); void __xfrm_state_destroy(struct xfrm_state *x) { - WARN_ON(x->km.state != XFRM_STATE_DEAD); + BUG_TRAP(x->km.state == XFRM_STATE_DEAD); spin_lock_bh(&xfrm_state_lock); list_del(&x->all); diff --git a/trunk/scripts/Makefile.headersinst b/trunk/scripts/Makefile.headersinst index 612dc13ddd85..53dae3eb3d1f 100644 --- a/trunk/scripts/Makefile.headersinst +++ b/trunk/scripts/Makefile.headersinst @@ -1,98 +1,194 @@ # ========================================================================== # Installing headers # -# header-y - list files to be installed. They are preprocessed -# to remove __KERNEL__ section of the file -# unifdef-y - Same as header-y. Obsolete -# objhdr-y - Same as header-y but for generated files +# header-y files will be installed verbatim +# unifdef-y are the files where unifdef will be run before installing files +# objhdr-y are generated files that will be installed verbatim # # ========================================================================== -# called may set destination dir (when installing to asm/) +UNIFDEF := scripts/unifdef -U__KERNEL__ + +# Eliminate the contents of (and inclusions of) compiler.h +HDRSED := sed -e "s/ inline / __inline__ /g" \ + -e "s/[[:space:]]__user[[:space:]]\{1,\}/ /g" \ + -e "s/(__user[[:space:]]\{1,\}/ (/g" \ + -e "s/[[:space:]]__force[[:space:]]\{1,\}/ /g" \ + -e "s/(__force[[:space:]]\{1,\}/ (/g" \ + -e "s/[[:space:]]__iomem[[:space:]]\{1,\}/ /g" \ + -e "s/(__iomem[[:space:]]\{1,\}/ (/g" \ + -e "s/[[:space:]]__attribute_const__[[:space:]]\{1,\}/\ /g" \ + -e "s/[[:space:]]__attribute_const__$$//" \ + -e "/^\#include /d" + _dst := $(if $(dst),$(dst),$(obj)) -kbuild-file := $(srctree)/$(obj)/Kbuild -include $(kbuild-file) +ifeq (,$(patsubst include/asm/%,,$(obj)/)) +# For producing the generated stuff in include/asm for biarch builds, include +# both sets of Kbuild files; we'll generate anything which is mentioned in +# _either_ arch, and recurse into subdirectories which are mentioned in either +# arch. Since some directories may exist in one but not the other, we must +# use $(wildcard...). +GENASM := 1 +archasm := $(subst include/asm,asm-$(ARCH),$(obj)) +altarchasm := $(subst include/asm,asm-$(ALTARCH),$(obj)) +KBUILDFILES := $(wildcard $(srctree)/include/$(archasm)/Kbuild $(srctree)/include/$(altarchasm)/Kbuild) +else +KBUILDFILES := $(srctree)/$(obj)/Kbuild +endif -include scripts/Kbuild.include +include $(KBUILDFILES) -install := $(INSTALL_HDR_PATH)/$(_dst) +include scripts/Kbuild.include -header-y := $(sort $(header-y) $(unifdef-y)) -subdirs := $(patsubst %/,%,$(filter %/, $(header-y))) -header-y := $(filter-out %/, $(header-y)) +# If this is include/asm-$(ARCH) and there's no $(ALTARCH), then +# override $(_dst) so that we install to include/asm directly. +# Unless $(BIASMDIR) is set, in which case we're probably doing +# a 'headers_install_all' build and we should keep the -$(ARCH) +# in the directory name. +ifeq ($(obj)$(ALTARCH),include/asm-$(ARCH)$(BIASMDIR)) + _dst := include/asm +endif -# files used to track state of install/check -install-file := $(install)/.install -check-file := $(install)/.check +header-y := $(sort $(header-y)) +unifdef-y := $(sort $(unifdef-y)) +subdir-y := $(patsubst %/,%,$(filter %/, $(header-y))) +header-y := $(filter-out %/, $(header-y)) +header-y := $(filter-out $(unifdef-y),$(header-y)) -# all headers files for this dir -all-files := $(header-y) $(objhdr-y) -input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \ - $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) -output-files := $(addprefix $(install)/, $(all-files)) +# stamp files for header checks +check-y := $(patsubst %,.check.%,$(header-y) $(unifdef-y) $(objhdr-y)) # Work out what needs to be removed -oldheaders := $(patsubst $(install)/%,%,$(wildcard $(install)/*.h)) -unwanted := $(filter-out $(all-files),$(oldheaders)) +oldheaders := $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,%,$(wildcard $(INSTALL_HDR_PATH)/$(_dst)/*.h)) +unwanted := $(filter-out $(header-y) $(unifdef-y) $(objhdr-y),$(oldheaders)) -# Prefix unwanted with full paths to $(INSTALL_HDR_PATH) -unwanted-file := $(addprefix $(install)/, $(unwanted)) +oldcheckstamps := $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,%,$(wildcard $(INSTALL_HDR_PATH)/$(_dst)/.check.*.h)) +unwanted += $(filter-out $(check-y),$(oldcheckstamps)) -printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@)) +# Prefix them all with full paths to $(INSTALL_HDR_PATH) +header-y := $(patsubst %,$(INSTALL_HDR_PATH)/$(_dst)/%,$(header-y)) +unifdef-y := $(patsubst %,$(INSTALL_HDR_PATH)/$(_dst)/%,$(unifdef-y)) +objhdr-y := $(patsubst %,$(INSTALL_HDR_PATH)/$(_dst)/%,$(objhdr-y)) +check-y := $(patsubst %,$(INSTALL_HDR_PATH)/$(_dst)/%,$(check-y)) -quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\ - file$(if $(word 2, $(all-files)),s)) - cmd_install = \ - $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \ - $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \ - touch $@ -quiet_cmd_remove = REMOVE $(unwanted) - cmd_remove = rm -f $(unwanted-file) - -quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files) - cmd_check = $(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH) \ - $(addprefix $(install)/, $(all-files)); \ - touch $@ +ifdef ALTARCH +ifeq ($(obj),include/asm-$(ARCH)) +altarch-y := altarch-dir +endif +endif -PHONY += __headersinst __headerscheck +# Make the definitions visible for recursive make invocations +export ALTARCH +export ARCHDEF +export ALTARCHDEF + +quiet_cmd_o_hdr_install = INSTALL $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) + cmd_o_hdr_install = cp $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,$(objtree)/$(obj)/%,$@) \ + $(INSTALL_HDR_PATH)/$(_dst) + +quiet_cmd_headers_install = INSTALL $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) + cmd_headers_install = $(HDRSED) $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,$(srctree)/$(obj)/%,$@) \ + > $@ + +quiet_cmd_unifdef = UNIFDEF $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) + cmd_unifdef = $(UNIFDEF) $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,$(srctree)/$(obj)/%,$@) \ + | $(HDRSED) > $@ || : + +quiet_cmd_check = CHECK $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/.check.%,$(_dst)/%,$@) + cmd_check = $(CONFIG_SHELL) $(srctree)/scripts/hdrcheck.sh \ + $(INSTALL_HDR_PATH)/include $(subst /.check.,/,$@) $@ + +quiet_cmd_remove = REMOVE $(_dst)/$@ + cmd_remove = rm -f $(INSTALL_HDR_PATH)/$(_dst)/$@ + +quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) + cmd_mkdir = mkdir -p $@ + +quiet_cmd_gen = GEN $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) + cmd_gen = \ +FNAME=$(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,%,$@); \ +STUBDEF=__ASM_STUB_`echo $$FNAME | tr a-z.- A-Z__`; \ +(echo "/* File autogenerated by 'make headers_install' */" ; \ +echo "\#ifndef $$STUBDEF" ; \ +echo "\#define $$STUBDEF" ; \ +echo "\# if $(ARCHDEF)" ; \ +if [ -r $(subst /$(_dst)/,/include/$(archasm)/,$@) ]; then \ + echo "\# include <$(archasm)/$$FNAME>" ; \ +else \ + echo "\# error $(archasm)/$$FNAME does not exist in" \ + "the $(ARCH) architecture" ; \ +fi ; \ +echo "\# elif $(ALTARCHDEF)" ; \ +if [ -r $(subst /$(_dst)/,/include/$(altarchasm)/,$@) ]; then \ + echo "\# include <$(altarchasm)/$$FNAME>" ; \ +else \ + echo "\# error $(altarchasm)/$$FNAME does not exist in" \ + "the $(ALTARCH) architecture" ; \ +fi ; \ +echo "\# else" ; \ +echo "\# warning This machine appears to be" \ + "neither $(ARCH) nor $(ALTARCH)." ; \ +echo "\# endif" ; \ +echo "\#endif /* $$STUBDEF */" ; \ +) > $@ + +.PHONY: __headersinst __headerscheck + +ifdef HDRCHECK +__headerscheck: $(subdir-y) $(check-y) + @true + +$(check-y) : $(INSTALL_HDR_PATH)/$(_dst)/.check.%.h : $(INSTALL_HDR_PATH)/$(_dst)/%.h + $(call cmd,check) + +# Other dependencies for $(check-y) +include /dev/null $(wildcard $(check-y)) + +# ... but leave $(check-y) as .PHONY for now until those deps are actually correct. +.PHONY: $(check-y) -ifndef HDRCHECK +else # Rules for installing headers -__headersinst: $(subdirs) $(install-file) - @: +__headersinst: $(subdir-y) $(header-y) $(unifdef-y) $(altarch-y) $(objhdr-y) + @true -targets += $(install-file) -$(install-file): scripts/headers_install.pl $(input-files) FORCE - $(if $(unwanted),$(call cmd,remove),) - $(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@))) - $(call if_changed,install) +$(objhdr-y) $(subdir-y) $(header-y) $(unifdef-y): | $(INSTALL_HDR_PATH)/$(_dst) $(unwanted) -else -__headerscheck: $(subdirs) $(check-file) - @: +$(INSTALL_HDR_PATH)/$(_dst): + $(call cmd,mkdir) -targets += $(check-file) -$(check-file): scripts/headers_check.pl $(output-files) FORCE - $(call if_changed,check) +.PHONY: $(unwanted) +$(unwanted): + $(call cmd,remove) -endif +ifdef GENASM +$(objhdr-y) $(header-y) $(unifdef-y): $(KBUILDFILES) + $(call cmd,gen) -# Recursion -hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj -.PHONY: $(subdirs) -$(subdirs): - $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@ +else +$(objhdr-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(objtree)/$(obj)/%.h $(KBUILDFILES) + $(call cmd,o_hdr_install) -targets := $(wildcard $(sort $(targets))) -cmd_files := $(wildcard \ - $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) +$(header-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(srctree)/$(obj)/%.h $(KBUILDFILES) + $(call cmd,headers_install) -ifneq ($(cmd_files),) - include $(cmd_files) +$(unifdef-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(srctree)/$(obj)/%.h $(KBUILDFILES) + $(call cmd,unifdef) endif +endif + +hdrinst := -rR -f $(srctree)/scripts/Makefile.headersinst obj -.PHONY: $(PHONY) -PHONY += FORCE -FORCE: ; +.PHONY: altarch-dir +# All the files in the normal arch dir must be created first, since we test +# for their existence. +altarch-dir: $(subdir-y) $(header-y) $(unifdef-y) $(objhdr-y) + $(Q)$(MAKE) $(hdrinst)=include/asm-$(ALTARCH) dst=include/asm-$(ALTARCH) + $(Q)$(MAKE) $(hdrinst)=include/asm dst=include/asm$(BIASMDIR) + +# Recursion +.PHONY: $(subdir-y) +$(subdir-y): + $(Q)$(MAKE) $(hdrinst)=$(obj)/$@ dst=$(_dst)/$@ rel=../$(rel) diff --git a/trunk/scripts/diffconfig b/trunk/scripts/diffconfig deleted file mode 100755 index b91f3e34d44d..000000000000 --- a/trunk/scripts/diffconfig +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/python -# -# diffconfig - a tool to compare .config files. -# -# originally written in 2006 by Matt Mackall -# (at least, this was in his bloatwatch source code) -# last worked on 2008 by Tim Bird -# - -import sys, os - -def usage(): - print """Usage: diffconfig [-h] [-m] [ ] - -Diffconfig is a simple utility for comparing two .config files. -Using standard diff to compare .config files often includes extraneous and -distracting information. This utility produces sorted output with only the -changes in configuration values between the two files. - -Added and removed items are shown with a leading plus or minus, respectively. -Changed items show the old and new values on a single line. - -If -m is specified, then output will be in "merge" style, which has the -changed and new values in kernel config option format. - -If no config files are specified, .config and .config.old are used. - -Example usage: - $ diffconfig .config config-with-some-changes --EXT2_FS_XATTR n --EXT2_FS_XIP n - CRAMFS n -> y - EXT2_FS y -> n - LOG_BUF_SHIFT 14 -> 16 - PRINTK_TIME n -> y -""" - sys.exit(0) - -# returns a dictionary of name/value pairs for config items in the file -def readconfig(config_file): - d = {} - for line in config_file: - line = line[:-1] - if line[:7] == "CONFIG_": - name, val = line[7:].split("=", 1) - d[name] = val - if line[-11:] == " is not set": - d[line[9:-11]] = "n" - return d - -def print_config(op, config, value, new_value): - global merge_style - - if merge_style: - if new_value: - if new_value=="n": - print "# CONFIG_%s is not set" % config - else: - print "CONFIG_%s=%s" % (config, new_value) - else: - if op=="-": - print "-%s %s" % (config, value) - elif op=="+": - print "+%s %s" % (config, new_value) - else: - print " %s %s -> %s" % (config, value, new_value) - -def main(): - global merge_style - - # parse command line args - if ("-h" in sys.argv or "--help" in sys.argv): - usage() - - merge_style = 0 - if "-m" in sys.argv: - merge_style = 1 - sys.argv.remove("-m") - - argc = len(sys.argv) - if not (argc==1 or argc == 3): - print "Error: incorrect number of arguments or unrecognized option" - usage() - - if argc == 1: - # if no filenames given, assume .config and .config.old - build_dir="" - if os.environ.has_key("KBUILD_OUTPUT"): - build_dir = os.environ["KBUILD_OUTPUT"]+"/" - - configa_filename = build_dir + ".config.old" - configb_filename = build_dir + ".config" - else: - configa_filename = sys.argv[1] - configb_filename = sys.argv[2] - - a = readconfig(file(configa_filename)) - b = readconfig(file(configb_filename)) - - # print items in a but not b (accumulate, sort and print) - old = [] - for config in a: - if config not in b: - old.append(config) - old.sort() - for config in old: - print_config("-", config, a[config], None) - del a[config] - - # print items that changed (accumulate, sort, and print) - changed = [] - for config in a: - if a[config] != b[config]: - changed.append(config) - else: - del b[config] - changed.sort() - for config in changed: - print_config("->", config, a[config], b[config]) - del b[config] - - # now print items in b but not in a - # (items from b that were in a were removed above) - new = b.keys() - new.sort() - for config in new: - print_config("+", config, None, b[config]) - -main() diff --git a/trunk/scripts/hdrcheck.sh b/trunk/scripts/hdrcheck.sh new file mode 100755 index 000000000000..31598584f871 --- /dev/null +++ b/trunk/scripts/hdrcheck.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +for FILE in `grep '^[ \t]*#[ \t]*include[ \t]*<' $2 | cut -f2 -d\< | cut -f1 -d\> | egrep ^linux\|^asm` ; do + if [ ! -r $1/$FILE ]; then + echo $2 requires $FILE, which does not exist in exported headers + exit 1 + fi +done +# FIXME: List dependencies into $3 +touch $3 diff --git a/trunk/scripts/headers.sh b/trunk/scripts/headers.sh deleted file mode 100755 index d33426f866db..000000000000 --- a/trunk/scripts/headers.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh -# Run headers_$1 command for all suitable architectures - -# Stop on error -set -e - -do_command() -{ - if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then - make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 - elif [ -f ${srctree}/include/asm-$2/Kbuild ]; then - make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 - else - printf "Ignoring arch: %s\n" ${arch} - fi -} - -# Do not try this architecture -drop="generic um ppc sparc64 cris" - -archs=$(ls ${srctree}/arch) - -for arch in ${archs}; do - case ${arch} in - um) # no userspace export - ;; - ppc) # headers exported by powerpc - ;; - sparc64) # headers exported by sparc - ;; - cris) # headers export are known broken - ;; - *) - if [ -d ${srctree}/arch/${arch} ]; then - do_command $1 ${arch} - fi - ;; - esac -done - - diff --git a/trunk/scripts/headers_check.pl b/trunk/scripts/headers_check.pl deleted file mode 100644 index 15d53a6b1a1f..000000000000 --- a/trunk/scripts/headers_check.pl +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl -# -# headers_check.pl execute a number of trivial consistency checks -# -# Usage: headers_check.pl dir [files...] -# dir: dir to look for included files -# arch: architecture -# files: list of files to check -# -# The script reads the supplied files line by line and: -# -# 1) for each include statement it checks if the -# included file actually exists. -# Only include files located in asm* and linux* are checked. -# The rest are assumed to be system include files. -# -# 2) TODO: check for leaked CONFIG_ symbols - -use strict; -use warnings; - -my ($dir, $arch, @files) = @ARGV; - -my $ret = 0; -my $line; -my $lineno = 0; -my $filename; - -foreach my $file (@files) { - $filename = $file; - open(my $fh, '<', "$filename") or die "$filename: $!\n"; - $lineno = 0; - while ($line = <$fh>) { - $lineno++; - check_include(); - } - close $fh; -} -exit $ret; - -sub check_include -{ - if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) { - my $inc = $1; - my $found; - $found = stat($dir . "/" . $inc); - if (!$found) { - $inc =~ s#asm/#asm-$arch/#; - $found = stat($dir . "/" . $inc); - } - if (!$found) { - printf STDERR "$filename:$lineno: included file '$inc' is not exported\n"; - $ret = 1; - } - } -} diff --git a/trunk/scripts/headers_install.pl b/trunk/scripts/headers_install.pl deleted file mode 100644 index 68591cd08731..000000000000 --- a/trunk/scripts/headers_install.pl +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl -# -# headers_install prepare the listed header files for use in -# user space and copy the files to their destination. -# -# Usage: headers_install.pl readdir installdir arch [files...] -# readdir: dir to open files -# installdir: dir to install the files -# arch: current architecture -# arch is used to force a reinstallation when the arch -# changes because kbuild then detect a command line change. -# files: list of files to check -# -# Step in preparation for users space: -# 1) Drop all use of compiler.h definitions -# 2) Drop include of compiler.h -# 3) Drop all sections defined out by __KERNEL__ (using unifdef) - -use strict; -use warnings; - -my ($readdir, $installdir, $arch, @files) = @ARGV; - -my $unifdef = "scripts/unifdef -U__KERNEL__"; - -foreach my $file (@files) { - my $tmpfile = "$installdir/$file.tmp"; - open(my $infile, '<', "$readdir/$file") - or die "$readdir/$file: $!\n"; - open(my $outfile, '>', "$tmpfile") or die "$tmpfile: $!\n"; - while (my $line = <$infile>) { - $line =~ s/([\s(])__user\s/$1/g; - $line =~ s/([\s(])__force\s/$1/g; - $line =~ s/([\s(])__iomem\s/$1/g; - $line =~ s/\s__attribute_const__\s/ /g; - $line =~ s/\s__attribute_const__$//g; - $line =~ s/^#include //; - printf $outfile "%s", $line; - } - close $outfile; - close $infile; - system $unifdef . " $tmpfile > $installdir/$file"; - unlink $tmpfile; -} -exit 0; diff --git a/trunk/scripts/kconfig/conf.c b/trunk/scripts/kconfig/conf.c index 9fba838c7069..fda63136ae68 100644 --- a/trunk/scripts/kconfig/conf.c +++ b/trunk/scripts/kconfig/conf.c @@ -76,6 +76,7 @@ static void check_stdin(void) static int conf_askvalue(struct symbol *sym, const char *def) { enum symbol_type type = sym_get_type(sym); + tristate val; if (!sym_has_value(sym)) printf(_("(NEW) ")); @@ -91,6 +92,15 @@ static int conf_askvalue(struct symbol *sym, const char *def) } switch (input_mode) { + case set_no: + case set_mod: + case set_yes: + case set_random: + if (sym_has_value(sym)) { + printf("%s\n", def); + return 0; + } + break; case ask_new: case ask_silent: if (sym_has_value(sym)) { @@ -102,6 +112,9 @@ static int conf_askvalue(struct symbol *sym, const char *def) fflush(stdout); fgets(line, 128, stdin); return 1; + case set_default: + printf("%s\n", def); + return 1; default: break; } @@ -115,6 +128,52 @@ static int conf_askvalue(struct symbol *sym, const char *def) default: ; } + switch (input_mode) { + case set_yes: + if (sym_tristate_within_range(sym, yes)) { + line[0] = 'y'; + line[1] = '\n'; + line[2] = 0; + break; + } + case set_mod: + if (type == S_TRISTATE) { + if (sym_tristate_within_range(sym, mod)) { + line[0] = 'm'; + line[1] = '\n'; + line[2] = 0; + break; + } + } else { + if (sym_tristate_within_range(sym, yes)) { + line[0] = 'y'; + line[1] = '\n'; + line[2] = 0; + break; + } + } + case set_no: + if (sym_tristate_within_range(sym, no)) { + line[0] = 'n'; + line[1] = '\n'; + line[2] = 0; + break; + } + case set_random: + do { + val = (tristate)(rand() % 3); + } while (!sym_tristate_within_range(sym, val)); + switch (val) { + case no: line[0] = 'n'; break; + case mod: line[0] = 'm'; break; + case yes: line[0] = 'y'; break; + } + line[1] = '\n'; + line[2] = 0; + break; + default: + break; + } printf("%s", line); return 1; } @@ -315,7 +374,15 @@ static int conf_choice(struct menu *menu) else continue; break; - default: + case set_random: + if (is_new) + def = (rand() % cnt) + 1; + case set_default: + case set_yes: + case set_mod: + case set_no: + cnt = def; + printf("%d\n", cnt); break; } @@ -427,43 +494,6 @@ static void check_conf(struct menu *menu) check_conf(child); } -static void conf_do_update(void) -{ - /* Update until a loop caused no more changes */ - do { - conf_cnt = 0; - check_conf(&rootmenu); - } while (conf_cnt); -} - -static int conf_silent_update(void) -{ - const char *name; - - if (conf_get_changed()) { - name = getenv("KCONFIG_NOSILENTUPDATE"); - if (name && *name) { - fprintf(stderr, - _("\n*** Kernel configuration requires explicit update.\n\n")); - return 1; - } - conf_do_update(); - } - return 0; -} - -static int conf_update(void) -{ - rootEntry = &rootmenu; - conf(&rootmenu); - if (input_mode == ask_all) { - input_mode = ask_silent; - valid_stdin = 1; - } - conf_do_update(); - return 0; -} - int main(int ac, char **av) { int opt; @@ -569,43 +599,36 @@ int main(int ac, char **av) default: break; } - switch (input_mode) { - case set_no: - conf_set_all_new_symbols(def_no); - break; - case set_yes: - conf_set_all_new_symbols(def_yes); - break; - case set_mod: - conf_set_all_new_symbols(def_mod); - break; - case set_random: - conf_set_all_new_symbols(def_random); - break; - case set_default: - conf_set_all_new_symbols(def_default); - break; - case ask_silent: - case ask_new: - if (conf_silent_update()) - exit(1); - break; - case ask_all: - if (conf_update()) - exit(1); - break; - } - if (conf_get_changed() && conf_write(NULL)) { + if (input_mode != ask_silent) { + rootEntry = &rootmenu; + conf(&rootmenu); + if (input_mode == ask_all) { + input_mode = ask_silent; + valid_stdin = 1; + } + } else if (conf_get_changed()) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + fprintf(stderr, _("\n*** Kernel configuration requires explicit update.\n\n")); + return 1; + } + } else + goto skip_check; + + do { + conf_cnt = 0; + check_conf(&rootmenu); + } while (conf_cnt); + if (conf_write(NULL)) { fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); - exit(1); + return 1; } - /* ask_silent is used during the build so we shall update autoconf. - * All other commands are only used to generate a config. - */ +skip_check: if (input_mode == ask_silent && conf_write_autoconf()) { fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); return 1; } + return 0; } diff --git a/trunk/scripts/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c index 07597611cc50..ee5fe943d58d 100644 --- a/trunk/scripts/kconfig/confdata.c +++ b/trunk/scripts/kconfig/confdata.c @@ -812,73 +812,3 @@ void conf_set_changed_callback(void (*fn)(void)) { conf_changed_callback = fn; } - - -void conf_set_all_new_symbols(enum conf_def_mode mode) -{ - struct symbol *sym, *csym; - struct property *prop; - struct expr *e; - int i, cnt, def; - - for_all_symbols(i, sym) { - if (sym_has_value(sym)) - continue; - switch (sym_get_type(sym)) { - case S_BOOLEAN: - case S_TRISTATE: - switch (mode) { - case def_yes: - sym->def[S_DEF_USER].tri = yes; - break; - case def_mod: - sym->def[S_DEF_USER].tri = mod; - break; - case def_no: - sym->def[S_DEF_USER].tri = no; - break; - case def_random: - sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); - break; - default: - continue; - } - if (!sym_is_choice(sym) || mode != def_random) - sym->flags |= SYMBOL_DEF_USER; - break; - default: - break; - } - - } - - if (modules_sym) - sym_calc_value(modules_sym); - - if (mode != def_random) - return; - - for_all_symbols(i, csym) { - if (sym_has_value(csym) || !sym_is_choice(csym)) - continue; - - sym_calc_value(csym); - prop = sym_get_choice_prop(csym); - def = -1; - while (1) { - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) { - if (sym->visible == no) - continue; - if (def == cnt++) { - csym->def[S_DEF_USER].val = sym; - break; - } - } - if (def >= 0 || cnt < 2) - break; - def = (rand() % cnt) + 1; - } - csym->flags |= SYMBOL_DEF_USER; - } -} diff --git a/trunk/scripts/kconfig/lkc.h b/trunk/scripts/kconfig/lkc.h index 4a9af6f7886b..96521cb087ec 100644 --- a/trunk/scripts/kconfig/lkc.h +++ b/trunk/scripts/kconfig/lkc.h @@ -42,14 +42,6 @@ extern "C" { #define TF_PARAM 0x0002 #define TF_OPTION 0x0004 -enum conf_def_mode { - def_default, - def_yes, - def_mod, - def_no, - def_random -}; - #define T_OPT_MODULES 1 #define T_OPT_DEFCONFIG_LIST 2 #define T_OPT_ENV 3 @@ -77,7 +69,6 @@ const char *conf_get_configname(void); char *conf_get_default_confname(void); void sym_set_change_count(int count); void sym_add_change_count(int count); -void conf_set_all_new_symbols(enum conf_def_mode mode); /* kconfig_load.c */ void kconfig_load(void); diff --git a/trunk/scripts/kernel-doc b/trunk/scripts/kernel-doc index d8f77e26081c..88e3934a8b8c 100755 --- a/trunk/scripts/kernel-doc +++ b/trunk/scripts/kernel-doc @@ -1643,7 +1643,6 @@ sub dump_function($$) { $prototype =~ s/^__always_inline +//; $prototype =~ s/^noinline +//; $prototype =~ s/__devinit +//; - $prototype =~ s/__init +//; $prototype =~ s/^#define\s+//; #ak added $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; diff --git a/trunk/scripts/setlocalversion b/trunk/scripts/setlocalversion index 83b75126c9f7..1c1bdaf7348a 100755 --- a/trunk/scripts/setlocalversion +++ b/trunk/scripts/setlocalversion @@ -12,9 +12,7 @@ cd "${1:-.}" || usage if head=`git rev-parse --verify HEAD 2>/dev/null`; then # Do we have an untagged version? if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then - if tag=`git describe 2>/dev/null`; then - echo $tag | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' - fi + git describe | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' fi # Are there uncommitted changes? diff --git a/trunk/security/capability.c b/trunk/security/capability.c index 63d10da515a5..5b01c0b02422 100644 --- a/trunk/security/capability.c +++ b/trunk/security/capability.c @@ -211,7 +211,8 @@ static int cap_inode_follow_link(struct dentry *dentry, return 0; } -static int cap_inode_permission(struct inode *inode, int mask) +static int cap_inode_permission(struct inode *inode, int mask, + struct nameidata *nd) { return 0; } diff --git a/trunk/security/security.c b/trunk/security/security.c index ff7068727757..59f23b5918b3 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -429,11 +429,11 @@ int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) return security_ops->inode_follow_link(dentry, nd); } -int security_inode_permission(struct inode *inode, int mask) +int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd) { if (unlikely(IS_PRIVATE(inode))) return 0; - return security_ops->inode_permission(inode, mask); + return security_ops->inode_permission(inode, mask, nd); } int security_inode_setattr(struct dentry *dentry, struct iattr *attr) @@ -442,7 +442,6 @@ int security_inode_setattr(struct dentry *dentry, struct iattr *attr) return 0; return security_ops->inode_setattr(dentry, attr); } -EXPORT_SYMBOL_GPL(security_inode_setattr); int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) { diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 40d06c533f89..63f131fc42e4 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -1971,6 +1971,22 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) return __vm_enough_memory(mm, pages, cap_sys_admin); } +/** + * task_tracer_task - return the task that is tracing the given task + * @task: task to consider + * + * Returns NULL if noone is tracing @task, or the &struct task_struct + * pointer to its tracer. + * + * Must be called under rcu_read_lock(). + */ +static struct task_struct *task_tracer_task(struct task_struct *task) +{ + if (task->ptrace & PT_PTRACED) + return rcu_dereference(task->parent); + return NULL; +} + /* binprm security operations */ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) @@ -2222,7 +2238,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) u32 ptsid = 0; rcu_read_lock(); - tracer = tracehook_tracer_task(current); + tracer = task_tracer_task(current); if (likely(tracer != NULL)) { sec = tracer->security; ptsid = sec->sid; @@ -2624,11 +2640,12 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na return dentry_has_perm(current, NULL, dentry, FILE__READ); } -static int selinux_inode_permission(struct inode *inode, int mask) +static int selinux_inode_permission(struct inode *inode, int mask, + struct nameidata *nd) { int rc; - rc = secondary_ops->inode_permission(inode, mask); + rc = secondary_ops->inode_permission(inode, mask, nd); if (rc) return rc; @@ -5230,7 +5247,7 @@ static int selinux_setprocattr(struct task_struct *p, Otherwise, leave SID unchanged and fail. */ task_lock(p); rcu_read_lock(); - tracer = tracehook_tracer_task(p); + tracer = task_tracer_task(p); if (tracer != NULL) { struct task_security_struct *ptsec = tracer->security; u32 ptsid = ptsec->sid; @@ -5653,20 +5670,27 @@ static struct nf_hook_ops selinux_ipv6_ops[] = { static int __init selinux_nf_ip_init(void) { int err = 0; + u32 iter; if (!selinux_enabled) goto out; printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n"); - err = nf_register_hooks(selinux_ipv4_ops, ARRAY_SIZE(selinux_ipv4_ops)); - if (err) - panic("SELinux: nf_register_hooks for IPv4: error %d\n", err); + for (iter = 0; iter < ARRAY_SIZE(selinux_ipv4_ops); iter++) { + err = nf_register_hook(&selinux_ipv4_ops[iter]); + if (err) + panic("SELinux: nf_register_hook for IPv4: error %d\n", + err); + } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - err = nf_register_hooks(selinux_ipv6_ops, ARRAY_SIZE(selinux_ipv6_ops)); - if (err) - panic("SELinux: nf_register_hooks for IPv6: error %d\n", err); + for (iter = 0; iter < ARRAY_SIZE(selinux_ipv6_ops); iter++) { + err = nf_register_hook(&selinux_ipv6_ops[iter]); + if (err) + panic("SELinux: nf_register_hook for IPv6: error %d\n", + err); + } #endif /* IPV6 */ out: @@ -5678,11 +5702,15 @@ __initcall(selinux_nf_ip_init); #ifdef CONFIG_SECURITY_SELINUX_DISABLE static void selinux_nf_ip_exit(void) { + u32 iter; + printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n"); - nf_unregister_hooks(selinux_ipv4_ops, ARRAY_SIZE(selinux_ipv4_ops)); + for (iter = 0; iter < ARRAY_SIZE(selinux_ipv4_ops); iter++) + nf_unregister_hook(&selinux_ipv4_ops[iter]); #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - nf_unregister_hooks(selinux_ipv6_ops, ARRAY_SIZE(selinux_ipv6_ops)); + for (iter = 0; iter < ARRAY_SIZE(selinux_ipv6_ops); iter++) + nf_unregister_hook(&selinux_ipv6_ops[iter]); #endif /* IPV6 */ } #endif diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 1b40e558f983..ee5a51cbc5eb 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -522,7 +522,8 @@ static int smack_inode_rename(struct inode *old_inode, * * Returns 0 if access is permitted, -EACCES otherwise */ -static int smack_inode_permission(struct inode *inode, int mask) +static int smack_inode_permission(struct inode *inode, int mask, + struct nameidata *nd) { /* * No permission to check. Existence test. Yup, it's there. diff --git a/trunk/sound/isa/cs423x/cs4236.c b/trunk/sound/isa/cs423x/cs4236.c index 4d4b8ddc26ba..dbe63db4bfd6 100644 --- a/trunk/sound/isa/cs423x/cs4236.c +++ b/trunk/sound/isa/cs423x/cs4236.c @@ -325,7 +325,6 @@ static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev) static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard, struct pnp_dev *pdev) { - acard->wss = pdev; if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0) return -EBUSY; cport[dev] = -1; diff --git a/trunk/sound/isa/opti9xx/opti92x-ad1848.c b/trunk/sound/isa/opti9xx/opti92x-ad1848.c index 0797ca441a37..41c047e665ec 100644 --- a/trunk/sound/isa/opti9xx/opti92x-ad1848.c +++ b/trunk/sound/isa/opti9xx/opti92x-ad1848.c @@ -68,9 +68,7 @@ MODULE_SUPPORTED_DEVICE("{{OPTi,82C924 (AD1848)}," static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ //static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ -#ifdef CONFIG_PNP static int isapnp = 1; /* Enable ISA PnP detection */ -#endif static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */ static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */ static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */ @@ -87,10 +85,8 @@ module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for opti9xx based soundcard."); //module_param(enable, bool, 0444); //MODULE_PARM_DESC(enable, "Enable opti9xx soundcard."); -#ifdef CONFIG_PNP module_param(isapnp, bool, 0444); MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard."); -#endif module_param(port, long, 0444); MODULE_PARM_DESC(port, "WSS port # for opti9xx driver."); module_param(mpu_port, long, 0444); @@ -692,7 +688,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) if (chip) { #ifdef OPTi93X struct snd_cs4231 *codec = chip->codec; - if (codec && codec->irq > 0) { + if (codec->irq > 0) { disable_irq(codec->irq); free_irq(codec->irq, codec); } diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 8c49a00a5e39..07364c00768a 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -161,7 +161,6 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, -{ 0x54524103, 0xffffffff, "TR28023", NULL, NULL }, { 0x54524106, 0xffffffff, "TR28026", NULL, NULL }, { 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99] { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] @@ -170,7 +169,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF { 0x56494182, 0xffffffff, "VIA1618", NULL, NULL }, { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, -{ 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL }, +{ 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, { 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL}, { 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL}, diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index f4fbc795ee81..0746e9ccc20b 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -3381,8 +3381,8 @@ static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, } /* create a virtual master control and add slaves */ -static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, - const unsigned int *tlv, const char **slaves) +int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, + const unsigned int *tlv, const char **slaves) { struct snd_kcontrol *kctl; const char **s; diff --git a/trunk/sound/pci/azt3328.h b/trunk/sound/pci/azt3328.h index 974e05122f00..7e3e8942d073 100644 --- a/trunk/sound/pci/azt3328.h +++ b/trunk/sound/pci/azt3328.h @@ -94,7 +94,7 @@ enum azf_freq_t { AZF_FREQ(48000), AZF_FREQ(66200), #undef AZF_FREQ -}; +} AZF_FREQUENCIES; /** recording area (see also: playback bit flag definitions) **/ #define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */ @@ -210,7 +210,7 @@ enum azf_freq_t { enum { AZF_GAME_LEGACY_IO_PORT = 0x200 -}; +} AZF_GAME_CONFIGS; #define IDX_GAME_LEGACY_COMPATIBLE 0x00 /* in some operation mode, writing anything to this port diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index 9bf95367c882..fbf1124f7c79 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -522,7 +522,7 @@ static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq) return r; cond_resched(); } - snd_printk(KERN_ERR "wait src ready timeout 0x%lx [0x%x]\n", + snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r); return 0; } @@ -1629,7 +1629,6 @@ static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq, memset(&ac97, 0, sizeof(ac97)); ac97.private_data = ensoniq; ac97.private_free = snd_ensoniq_mixer_free_ac97; - ac97.pci = ensoniq->pci; ac97.scaps = AC97_SCAP_AUDIO; if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0) return err; diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index ef9f072b47fc..16715a68ba5e 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -1047,13 +1047,9 @@ static int azx_setup_periods(struct azx *chip, pos_adj = bdl_pos_adj[chip->dev_index]; if (pos_adj > 0) { struct snd_pcm_runtime *runtime = substream->runtime; - int pos_align = pos_adj; pos_adj = (pos_adj * runtime->rate + 47999) / 48000; if (!pos_adj) - pos_adj = pos_align; - else - pos_adj = ((pos_adj + pos_align - 1) / pos_align) * - pos_align; + pos_adj = 1; pos_adj = frames_to_bytes(runtime, pos_adj); if (pos_adj >= period_bytes) { snd_printk(KERN_WARNING "Too big adjustment %d\n", diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index add4e87e0b20..2807bc840d26 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -122,8 +122,6 @@ enum { /* ALC269 models */ enum { ALC269_BASIC, - ALC269_ASUS_EEEPC_P703, - ALC269_ASUS_EEEPC_P901, ALC269_AUTO, ALC269_MODEL_LAST /* last tag */ }; @@ -7907,7 +7905,6 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), @@ -10949,23 +10946,7 @@ static int patch_alc268(struct hda_codec *codec) static hda_nid_t alc269_adc_nids[1] = { /* ADC1 */ - 0x08, -}; - -static struct hda_input_mux alc269_eeepc_dmic_capture_source = { - .num_items = 2, - .items = { - { "i-Mic", 0x5 }, - { "e-Mic", 0x0 }, - }, -}; - -static struct hda_input_mux alc269_eeepc_amic_capture_source = { - .num_items = 2, - .items = { - { "i-Mic", 0x1 }, - { "e-Mic", 0x0 }, - }, + 0x07, }; #define alc269_modes alc260_modes @@ -10987,27 +10968,10 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { { } /* end */ }; -/* bind volumes of both NID 0x0c and 0x0d */ -static struct hda_bind_ctls alc269_epc_bind_vol = { - .ops = &snd_hda_bind_vol, - .values = { - HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), - HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), - 0 - }, -}; - -static struct snd_kcontrol_new alc269_eeepc_mixer[] = { - HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol), - HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT), - { } /* end */ -}; - /* capture mixer elements */ static struct snd_kcontrol_new alc269_capture_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* The multiple "Capture Source" controls confuse alsamixer @@ -11023,13 +10987,6 @@ static struct snd_kcontrol_new alc269_capture_mixer[] = { { } /* end */ }; -/* capture mixer elements */ -static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - { } /* end */ -}; - /* * generic initialization of ADC, input mixers and output mixers */ @@ -11037,7 +10994,7 @@ static struct hda_verb alc269_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the * analog-loopback mixer widget @@ -11100,98 +11057,6 @@ static struct hda_verb alc269_init_verbs[] = { { } }; -static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - {} -}; - -static struct hda_verb alc269_eeepc_amic_init_verbs[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, - {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - {} -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc269_speaker_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned int bits; - - present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? AMP_IN_MUTE(0) : 0; - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); -} - -static void alc269_eeepc_dmic_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL, - present ? 0 : 5); -} - -static void alc269_eeepc_amic_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, - present ? AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0)); - snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, - present ? AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1)); -} - -/* unsolicited event for HP jack sensing */ -static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc269_speaker_automute(codec); - - if ((res >> 26) == ALC880_MIC_EVENT) - alc269_eeepc_dmic_automute(codec); -} - -static void alc269_eeepc_dmic_inithook(struct hda_codec *codec) -{ - alc269_speaker_automute(codec); - alc269_eeepc_dmic_automute(codec); -} - -/* unsolicited event for HP jack sensing */ -static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc269_speaker_automute(codec); - - if ((res >> 26) == ALC880_MIC_EVENT) - alc269_eeepc_amic_automute(codec); -} - -static void alc269_eeepc_amic_inithook(struct hda_codec *codec) -{ - alc269_speaker_automute(codec); - alc269_eeepc_amic_automute(codec); -} - /* add playback controls from the parsed DAC table */ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) @@ -11323,9 +11188,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; - spec->mixers[spec->num_mixers] = alc269_capture_mixer; - spec->num_mixers++; - return 1; } @@ -11353,16 +11215,12 @@ static const char *alc269_models[ALC269_MODEL_LAST] = { }; static struct snd_pci_quirk alc269_cfg_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", - ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", - ALC269_ASUS_EEEPC_P901), {} }; static struct alc_config_preset alc269_presets[] = { [ALC269_BASIC] = { - .mixers = { alc269_base_mixer, alc269_capture_mixer }, + .mixers = { alc269_base_mixer }, .init_verbs = { alc269_init_verbs }, .num_dacs = ARRAY_SIZE(alc269_dac_nids), .dac_nids = alc269_dac_nids, @@ -11371,32 +11229,6 @@ static struct alc_config_preset alc269_presets[] = { .channel_mode = alc269_modes, .input_mux = &alc269_capture_source, }, - [ALC269_ASUS_EEEPC_P703] = { - .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer }, - .init_verbs = { alc269_init_verbs, - alc269_eeepc_amic_init_verbs }, - .num_dacs = ARRAY_SIZE(alc269_dac_nids), - .dac_nids = alc269_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc269_modes), - .channel_mode = alc269_modes, - .input_mux = &alc269_eeepc_amic_capture_source, - .unsol_event = alc269_eeepc_amic_unsol_event, - .init_hook = alc269_eeepc_amic_inithook, - }, - [ALC269_ASUS_EEEPC_P901] = { - .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer}, - .init_verbs = { alc269_init_verbs, - alc269_eeepc_dmic_init_verbs }, - .num_dacs = ARRAY_SIZE(alc269_dac_nids), - .dac_nids = alc269_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc269_modes), - .channel_mode = alc269_modes, - .input_mux = &alc269_eeepc_dmic_capture_source, - .unsol_event = alc269_eeepc_dmic_unsol_event, - .init_hook = alc269_eeepc_dmic_inithook, - }, }; static int patch_alc269(struct hda_codec *codec) @@ -11450,6 +11282,8 @@ static int patch_alc269(struct hda_codec *codec) spec->adc_nids = alc269_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); + spec->mixers[spec->num_mixers] = alc269_capture_mixer; + spec->num_mixers++; codec->patch_ops = alc_patch_ops; if (board_config == ALC269_AUTO) @@ -13160,7 +12994,6 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), - SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 7fdafcb0015d..08cb77f51880 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -94,9 +94,6 @@ enum { STAC_INTEL_MAC_V3, STAC_INTEL_MAC_V4, STAC_INTEL_MAC_V5, - STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter - * is given, one of the above models will be - * chosen according to the subsystem id. */ /* for backward compatibility */ STAC_MACMINI, STAC_MACBOOK, @@ -1486,7 +1483,6 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, - [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs, /* for backward compatibility */ [STAC_MACMINI] = intel_mac_v3_pin_configs, [STAC_MACBOOK] = intel_mac_v5_pin_configs, @@ -1509,7 +1505,6 @@ static const char *stac922x_models[STAC_922X_MODELS] = { [STAC_INTEL_MAC_V3] = "intel-mac-v3", [STAC_INTEL_MAC_V4] = "intel-mac-v4", [STAC_INTEL_MAC_V5] = "intel-mac-v5", - [STAC_INTEL_MAC_AUTO] = "intel-mac-auto", /* for backward compatibility */ [STAC_MACMINI] = "macmini", [STAC_MACBOOK] = "macbook", @@ -1581,9 +1576,9 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, "Intel D945P", STAC_D945GTP5), /* other systems */ - /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ + /* Apple Mac Mini (early 2006) */ SND_PCI_QUIRK(0x8384, 0x7680, - "Mac", STAC_INTEL_MAC_AUTO), + "Mac Mini", STAC_INTEL_MAC_V3), /* Dell systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, "unknown Dell", STAC_922X_DELL_D81), @@ -3730,7 +3725,7 @@ static int patch_stac922x(struct hda_codec *codec) spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, stac922x_models, stac922x_cfg_tbl); - if (spec->board_config == STAC_INTEL_MAC_AUTO) { + if (spec->board_config == STAC_INTEL_MAC_V3) { spec->gpio_mask = spec->gpio_dir = 0x03; spec->gpio_data = 0x03; /* Intel Macs have all same PCI SSID, so we need to check @@ -3762,9 +3757,6 @@ static int patch_stac922x(struct hda_codec *codec) case 0x106b2200: spec->board_config = STAC_INTEL_MAC_V5; break; - default: - spec->board_config = STAC_INTEL_MAC_V3; - break; } } diff --git a/trunk/sound/soc/au1x/psc-i2s.c b/trunk/sound/soc/au1x/psc-i2s.c index 9384702c7ebd..ba4b5c199f21 100644 --- a/trunk/sound/soc/au1x/psc-i2s.c +++ b/trunk/sound/soc/au1x/psc-i2s.c @@ -231,7 +231,7 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype) /* if both TX and RX are idle, disable PSC */ stat = au_readl(I2S_STAT(pscdata)); - if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) { + if (!(stat & (PSC_I2SSTAT_RB | PSC_I2SSTAT_RB))) { au_writel(0, I2S_CFG(pscdata)); au_sync(); au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); diff --git a/trunk/sound/soc/codecs/wm9712.c b/trunk/sound/soc/codecs/wm9712.c index 1fb7f9a7aecd..9fc8edd82225 100644 --- a/trunk/sound/soc/codecs/wm9712.c +++ b/trunk/sound/soc/codecs/wm9712.c @@ -427,20 +427,20 @@ static const struct snd_soc_dapm_route audio_map[] = { {"HPOUTR", NULL, "Headphone PGA"}, {"Headphone PGA", NULL, "Right HP Mixer"}, - /* mono mixer */ - {"Mono Mixer", NULL, "Left HP Mixer"}, - {"Mono Mixer", NULL, "Right HP Mixer"}, + /* mono hp mixer */ + {"Mono HP Mixer", NULL, "Left HP Mixer"}, + {"Mono HP Mixer", NULL, "Right HP Mixer"}, /* Out3 Mux */ {"Out3 Mux", "Left", "Left HP Mixer"}, {"Out3 Mux", "Mono", "Phone Mixer"}, - {"Out3 Mux", "Left + Right", "Mono Mixer"}, + {"Out3 Mux", "Left + Right", "Mono HP Mixer"}, {"Out 3 PGA", NULL, "Out3 Mux"}, {"OUT3", NULL, "Out 3 PGA"}, /* speaker Mux */ {"Speaker Mux", "Speaker Mix", "Speaker Mixer"}, - {"Speaker Mux", "Headphone Mix", "Mono Mixer"}, + {"Speaker Mux", "Headphone Mix", "Mono HP Mixer"}, {"Speaker PGA", NULL, "Speaker Mux"}, {"LOUT2", NULL, "Speaker PGA"}, {"ROUT2", NULL, "Speaker PGA"}, diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index 820347c9ae4b..2c87061c2a6b 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -523,6 +523,24 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) continue; } + /* programmable gain/attenuation */ + if (w->id == snd_soc_dapm_pga) { + int on; + in = is_connected_input_ep(w); + dapm_clear_walk(w->codec); + out = is_connected_output_ep(w); + dapm_clear_walk(w->codec); + w->power = on = (out != 0 && in != 0) ? 1 : 0; + + if (!on) + dapm_set_pga(w, on); /* lower volume to reduce pops */ + dapm_update_bits(w); + if (on) + dapm_set_pga(w, on); /* restore volume from zero */ + + continue; + } + /* pre and post event widgets */ if (w->id == snd_soc_dapm_pre) { if (!w->event) @@ -568,56 +586,45 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) power_change = (w->power == power) ? 0: 1; w->power = power; - if (!power_change) - continue; - /* call any power change event handlers */ - if (w->event) - pr_debug("power %s event for %s flags %x\n", - w->power ? "on" : "off", - w->name, w->event_flags); - - /* power up pre event */ - if (power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - return ret; - } - - /* power down pre event */ - if (!power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - return ret; - } - - /* Lower PGA volume to reduce pops */ - if (w->id == snd_soc_dapm_pga && !power) - dapm_set_pga(w, power); - - dapm_update_bits(w); - - /* Raise PGA volume to reduce pops */ - if (w->id == snd_soc_dapm_pga && power) - dapm_set_pga(w, power); - - /* power up post event */ - if (power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - return ret; - } - - /* power down post event */ - if (!power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - return ret; + if (power_change) { + if (w->event) { + pr_debug("power %s event for %s flags %x\n", + w->power ? "on" : "off", w->name, w->event_flags); + if (power) { + /* power up event */ + if (w->event_flags & SND_SOC_DAPM_PRE_PMU) { + ret = w->event(w, + NULL, SND_SOC_DAPM_PRE_PMU); + if (ret < 0) + return ret; + } + dapm_update_bits(w); + if (w->event_flags & SND_SOC_DAPM_POST_PMU){ + ret = w->event(w, + NULL, SND_SOC_DAPM_POST_PMU); + if (ret < 0) + return ret; + } + } else { + /* power down event */ + if (w->event_flags & SND_SOC_DAPM_PRE_PMD) { + ret = w->event(w, + NULL, SND_SOC_DAPM_PRE_PMD); + if (ret < 0) + return ret; + } + dapm_update_bits(w); + if (w->event_flags & SND_SOC_DAPM_POST_PMD) { + ret = w->event(w, + NULL, SND_SOC_DAPM_POST_PMD); + if (ret < 0) + return ret; + } + } + } else + /* no event handler */ + dapm_update_bits(w); } } }