diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-07-07 12:08:27 +0200 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-07-07 12:08:27 +0200 |
commit | 717cb906bd43a9ac00631d600adda5c6546843a6 (patch) | |
tree | f41b250e9e0fa1e664f002fa9c4608d94527f2f2 | |
parent | drm: Add via unichrome support (diff) | |
parent | Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6 (diff) | |
download | linux-717cb906bd43a9ac00631d600adda5c6546843a6.tar.xz linux-717cb906bd43a9ac00631d600adda5c6546843a6.zip |
Merge ../linux-2.6/
608 files changed, 12346 insertions, 13862 deletions
diff --git a/Documentation/Changes b/Documentation/Changes index afebdbcd553a..dfec7569d450 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -57,7 +57,7 @@ o e2fsprogs 1.29 # tune2fs o jfsutils 1.1.3 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs o xfsprogs 2.6.0 # xfs_db -V -o pcmciautils 001 +o pcmciautils 004 o pcmcia-cs 3.1.21 # cardmgr -V o quota-tools 3.09 # quota -V o PPP 2.4.0 # pppd --version diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 6df1dfd18b65..375ae760dc1e 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -84,6 +84,14 @@ void (*port_disable) (struct ata_port *); Called from ata_bus_probe() and ata_bus_reset() error paths, as well as when unregistering from the SCSI module (rmmod, hot unplug). + This function should do whatever needs to be done to take the + port out of use. In most cases, ata_port_disable() can be used + as this hook. + </para> + <para> + Called from ata_bus_probe() on a failed probe. + Called from ata_bus_reset() on a failed bus reset. + Called from ata_scsi_release(). </para> </sect2> @@ -98,6 +106,13 @@ void (*dev_config) (struct ata_port *, struct ata_device *); found. Typically used to apply device-specific fixups prior to issue of SET FEATURES - XFER MODE, and prior to operation. </para> + <para> + Called by ata_device_add() after ata_dev_identify() determines + a device is present. + </para> + <para> + This entry may be specified as NULL in ata_port_operations. + </para> </sect2> @@ -135,6 +150,8 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); registers / DMA buffers. ->tf_read() is called to read the hardware registers / DMA buffers, to obtain the current set of taskfile register values. + Most drivers for taskfile-based hardware (PIO or MMIO) use + ata_tf_load() and ata_tf_read() for these hooks. </para> </sect2> @@ -147,6 +164,8 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); <para> causes an ATA command, previously loaded with ->tf_load(), to be initiated in hardware. + Most drivers for taskfile-based hardware use ata_exec_command() + for this hook. </para> </sect2> @@ -161,6 +180,10 @@ Allow low-level driver to filter ATA PACKET commands, returning a status indicating whether or not it is OK to use DMA for the supplied PACKET command. </para> + <para> + This hook may be specified as NULL, in which case libata will + assume that atapi dma can be supported. + </para> </sect2> @@ -175,6 +198,14 @@ u8 (*check_err)(struct ata_port *ap); Reads the Status/AltStatus/Error ATA shadow register from hardware. On some hardware, reading the Status register has the side effect of clearing the interrupt condition. + Most drivers for taskfile-based hardware use + ata_check_status() for this hook. + </para> + <para> + Note that because this is called from ata_device_add(), at + least a dummy function that clears device interrupts must be + provided for all drivers, even if the controller doesn't + actually have a taskfile status register. </para> </sect2> @@ -188,7 +219,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); Issues the low-level hardware command(s) that causes one of N hardware devices to be considered 'selected' (active and available for use) on the ATA bus. This generally has no -meaning on FIS-based devices. + meaning on FIS-based devices. + </para> + <para> + Most drivers for taskfile-based hardware use + ata_std_dev_select() for this hook. Controllers which do not + support second drives on a port (such as SATA contollers) will + use ata_noop_dev_select(). </para> </sect2> @@ -204,6 +241,8 @@ void (*phy_reset) (struct ata_port *ap); for device presence (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers typically use the helper functions ata_bus_reset() or sata_phy_reset() for this hook. + Many SATA drivers use sata_phy_reset() or call it from within + their own phy_reset() functions. </para> </sect2> @@ -227,6 +266,25 @@ PCI IDE DMA Status register. These hooks are typically either no-ops, or simply not implemented, in FIS-based drivers. </para> + <para> +Most legacy IDE drivers use ata_bmdma_setup() for the bmdma_setup() +hook. ata_bmdma_setup() will write the pointer to the PRD table to +the IDE PRD Table Address register, enable DMA in the DMA Command +register, and call exec_command() to begin the transfer. + </para> + <para> +Most legacy IDE drivers use ata_bmdma_start() for the bmdma_start() +hook. ata_bmdma_start() will write the ATA_DMA_START flag to the DMA +Command register. + </para> + <para> +Many legacy IDE drivers use ata_bmdma_stop() for the bmdma_stop() +hook. ata_bmdma_stop() clears the ATA_DMA_START flag in the DMA +command register. + </para> + <para> +Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() hook. + </para> </sect2> @@ -250,6 +308,10 @@ int (*qc_issue) (struct ata_queued_cmd *qc); helper function ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers implement their own ->qc_issue. </para> + <para> + ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and + ->bmdma_start() as necessary to initiate a transfer. + </para> </sect2> @@ -279,6 +341,21 @@ void (*irq_clear) (struct ata_port *); before the interrupt handler is registered, to be sure hardware is quiet. </para> + <para> + The second argument, dev_instance, should be cast to a pointer + to struct ata_host_set. + </para> + <para> + Most legacy IDE drivers use ata_interrupt() for the + irq_handler hook, which scans all ports in the host_set, + determines which queued command was active (if any), and calls + ata_host_intr(ap,qc). + </para> + <para> + Most legacy IDE drivers use ata_bmdma_irq_clear() for the + irq_clear() hook, which simply clears the interrupt and error + flags in the DMA status register. + </para> </sect2> @@ -292,6 +369,7 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, <para> Read and write standard SATA phy registers. Currently only used if ->phy_reset hook called the sata_phy_reset() helper function. + sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE. </para> </sect2> @@ -307,17 +385,29 @@ void (*host_stop) (struct ata_host_set *host_set); ->port_start() is called just after the data structures for each port are initialized. Typically this is used to alloc per-port DMA buffers / tables / rings, enable DMA engines, and similar - tasks. + tasks. Some drivers also use this entry point as a chance to + allocate driver-private memory for ap->private_data. + </para> + <para> + Many drivers use ata_port_start() as this hook or call + it from their own port_start() hooks. ata_port_start() + allocates space for a legacy IDE PRD table and returns. </para> <para> ->port_stop() is called after ->host_stop(). It's sole function is to release DMA/memory resources, now that they are no longer - actively being used. + actively being used. Many drivers also free driver-private + data from port at this time. + </para> + <para> + Many drivers use ata_port_stop() as this hook, which frees the + PRD table. </para> <para> ->host_stop() is called after all ->port_stop() calls have completed. The hook must finalize hardware shutdown, release DMA and other resources, etc. + This hook may be specified as NULL, in which case it is not called. </para> </sect2> diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers index de3b252e717d..c3cca924e94b 100644 --- a/Documentation/SubmittingDrivers +++ b/Documentation/SubmittingDrivers @@ -13,13 +13,14 @@ Allocating Device Numbers ------------------------- Major and minor numbers for block and character devices are allocated -by the Linux assigned name and number authority (currently better -known as H Peter Anvin). The site is http://www.lanana.org/. This +by the Linux assigned name and number authority (currently this is +Torben Mathiasen). The site is http://www.lanana.org/. This also deals with allocating numbers for devices that are not going to be submitted to the mainstream kernel. +See Documentation/devices.txt for more information on this. -If you don't use assigned numbers then when you device is submitted it will -get given an assigned number even if that is different from values you may +If you don't use assigned numbers then when your device is submitted it will +be given an assigned number even if that is different from values you may have shipped to customers before. Who To Submit Drivers To @@ -32,7 +33,8 @@ Linux 2.2: If the code area has a general maintainer then please submit it to the maintainer listed in MAINTAINERS in the kernel file. If the maintainer does not respond or you cannot find the appropriate - maintainer then please contact Alan Cox <alan@lxorguk.ukuu.org.uk> + maintainer then please contact the 2.2 kernel maintainer: + Marc-Christian Petersen <m.c.p@wolk-project.de>. Linux 2.4: The same rules apply as 2.2. The final contact point for Linux 2.4 @@ -48,7 +50,7 @@ What Criteria Determine Acceptance Licensing: The code must be released to us under the GNU General Public License. We don't insist on any kind - of exclusively GPL licensing, and if you wish the driver + of exclusive GPL licensing, and if you wish the driver to be useful to other communities such as BSD you may well wish to release under multiple licenses. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 4d1f41b84ebc..6761a7b241a5 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -35,7 +35,7 @@ not in any lower subdirectory. To create a patch for a single file, it is often sufficient to do: - SRCTREE= linux-2.4 + SRCTREE= linux-2.6 MYFILE= drivers/net/mydriver.c cd $SRCTREE @@ -48,17 +48,18 @@ To create a patch for multiple files, you should unpack a "vanilla", or unmodified kernel source tree, and generate a diff against your own source tree. For example: - MYSRC= /devel/linux-2.4 + MYSRC= /devel/linux-2.6 - tar xvfz linux-2.4.0-test11.tar.gz - mv linux linux-vanilla - wget http://www.moses.uklinux.net/patches/dontdiff - diff -uprN -X dontdiff linux-vanilla $MYSRC > /tmp/patch - rm -f dontdiff + tar xvfz linux-2.6.12.tar.gz + mv linux-2.6.12 linux-2.6.12-vanilla + diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \ + linux-2.6.12-vanilla $MYSRC > /tmp/patch "dontdiff" is a list of files which are generated by the kernel during the build process, and should be ignored in any diff(1)-generated -patch. dontdiff is maintained by Tigran Aivazian <tigran@veritas.com> +patch. The "dontdiff" file is included in the kernel tree in +2.6.12 and later. For earlier kernel versions, you can get it +from <http://www.xenotime.net/linux/doc/dontdiff>. Make sure your patch does not include any extra files which do not belong in a patch submission. Make sure to review your patch -after- @@ -66,18 +67,20 @@ generated it with diff(1), to ensure accuracy. If your changes produce a lot of deltas, you may want to look into splitting them into individual patches which modify things in -logical stages, this will facilitate easier reviewing by other +logical stages. This will facilitate easier reviewing by other kernel developers, very important if you want your patch accepted. -There are a number of scripts which can aid in this; +There are a number of scripts which can aid in this: Quilt: http://savannah.nongnu.org/projects/quilt Randy Dunlap's patch scripts: -http://developer.osdl.org/rddunlap/scripts/patching-scripts.tgz +http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz Andrew Morton's patch scripts: -http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.16 +http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20 + + 2) Describe your changes. @@ -163,6 +166,8 @@ patches. Trivial patches must qualify for one of the following rules: since people copy, as long as it's trivial) Any fix by the author/maintainer of the file. (ie. patch monkey in re-transmission mode) +URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/> + @@ -291,6 +296,17 @@ now, but you can do this to mark internal company procedures or just point out some special detail about the sign-off. + +12) More references for submitting patches + +Andrew Morton, "The perfect patch" (tpp). + <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt> + +Jeff Garzik, "Linux kernel patch submission format." + <http://linux.yyz.us/patch-format.html> + + + ----------------------------------- SECTION 2 - HINTS, TIPS, AND TRICKS ----------------------------------- @@ -359,7 +375,5 @@ and 'extern __inline__'. 4) Don't over-design. Don't try to anticipate nebulous future cases which may or may not -be useful: "Make it as simple as you can, and no simpler" - - +be useful: "Make it as simple as you can, and no simpler." diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 89cd417651e0..4ec75c06bca4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -622,6 +622,17 @@ running once the system is up. ips= [HW,SCSI] Adaptec / IBM ServeRAID controller See header of drivers/scsi/ips.c. + irqfixup [HW] + When an interrupt is not handled search all handlers + for it. Intended to get systems with badly broken + firmware running. + + irqpoll [HW] + When an interrupt is not handled search all handlers + for it. Also check all handlers each timer + interrupt. Intended to get systems with badly broken + firmware running. + isapnp= [ISAPNP] Format: <RDP>, <reset>, <pci_scan>, <verbosity> @@ -1030,6 +1041,10 @@ running once the system is up. irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned automatically to PCI devices. You can make the kernel exclude IRQs of your ISA cards this way. + pirqaddr=0xAAAAA [IA-32] Specify the physical address + of the PIRQ table (normally generated + by the BIOS) if it is outside the + F0000h-100000h range. lastbus=N [IA-32] Scan all buses till bus #N. Can be useful if the kernel is unable to find your secondary buses and you want to tell it explicitly which ones they are. diff --git a/Documentation/networking/fib_trie.txt b/Documentation/networking/fib_trie.txt new file mode 100644 index 000000000000..f50d0c673c57 --- /dev/null +++ b/Documentation/networking/fib_trie.txt @@ -0,0 +1,145 @@ + LC-trie implementation notes. + +Node types +---------- +leaf + An end node with data. This has a copy of the relevant key, along + with 'hlist' with routing table entries sorted by prefix length. + See struct leaf and struct leaf_info. + +trie node or tnode + An internal node, holding an array of child (leaf or tnode) pointers, + indexed through a subset of the key. See Level Compression. + +A few concepts explained +------------------------ +Bits (tnode) + The number of bits in the key segment used for indexing into the + child array - the "child index". See Level Compression. + +Pos (tnode) + The position (in the key) of the key segment used for indexing into + the child array. See Path Compression. + +Path Compression / skipped bits + Any given tnode is linked to from the child array of its parent, using + a segment of the key specified by the parent's "pos" and "bits" + In certain cases, this tnode's own "pos" will not be immediately + adjacent to the parent (pos+bits), but there will be some bits + in the key skipped over because they represent a single path with no + deviations. These "skipped bits" constitute Path Compression. + Note that the search algorithm will simply skip over these bits when + searching, making it necessary to save the keys in the leaves to + verify that they actually do match the key we are searching for. + +Level Compression / child arrays + the trie is kept level balanced moving, under certain conditions, the + children of a full child (see "full_children") up one level, so that + instead of a pure binary tree, each internal node ("tnode") may + contain an arbitrarily large array of links to several children. + Conversely, a tnode with a mostly empty child array (see empty_children) + may be "halved", having some of its children moved downwards one level, + in order to avoid ever-increasing child arrays. + +empty_children + the number of positions in the child array of a given tnode that are + NULL. + +full_children + the number of children of a given tnode that aren't path compressed. + (in other words, they aren't NULL or leaves and their "pos" is equal + to this tnode's "pos"+"bits"). + + (The word "full" here is used more in the sense of "complete" than + as the opposite of "empty", which might be a tad confusing.) + +Comments +--------- + +We have tried to keep the structure of the code as close to fib_hash as +possible to allow verification and help up reviewing. + +fib_find_node() + A good start for understanding this code. This function implements a + straightforward trie lookup. + +fib_insert_node() + Inserts a new leaf node in the trie. This is bit more complicated than + fib_find_node(). Inserting a new node means we might have to run the + level compression algorithm on part of the trie. + +trie_leaf_remove() + Looks up a key, deletes it and runs the level compression algorithm. + +trie_rebalance() + The key function for the dynamic trie after any change in the trie + it is run to optimize and reorganize. Tt will walk the trie upwards + towards the root from a given tnode, doing a resize() at each step + to implement level compression. + +resize() + Analyzes a tnode and optimizes the child array size by either inflating + or shrinking it repeatedly until it fullfills the criteria for optimal + level compression. This part follows the original paper pretty closely + and there may be some room for experimentation here. + +inflate() + Doubles the size of the child array within a tnode. Used by resize(). + +halve() + Halves the size of the child array within a tnode - the inverse of + inflate(). Used by resize(); + +fn_trie_insert(), fn_trie_delete(), fn_trie_select_default() + The route manipulation functions. Should conform pretty closely to the + corresponding functions in fib_hash. + +fn_trie_flush() + This walks the full trie (using nextleaf()) and searches for empty + leaves which have to be removed. + +fn_trie_dump() + Dumps the routing table ordered by prefix length. This is somewhat + slower than the corresponding fib_hash function, as we have to walk the + entire trie for each prefix length. In comparison, fib_hash is organized + as one "zone"/hash per prefix length. + +Locking +------- + +fib_lock is used for an RW-lock in the same way that this is done in fib_hash. +However, the functions are somewhat separated for other possible locking +scenarios. It might conceivably be possible to run trie_rebalance via RCU +to avoid read_lock in the fn_trie_lookup() function. + +Main lookup mechanism +--------------------- +fn_trie_lookup() is the main lookup function. + +The lookup is in its simplest form just like fib_find_node(). We descend the +trie, key segment by key segment, until we find a leaf. check_leaf() does +the fib_semantic_match in the leaf's sorted prefix hlist. + +If we find a match, we are done. + +If we don't find a match, we enter prefix matching mode. The prefix length, +starting out at the same as the key length, is reduced one step at a time, +and we backtrack upwards through the trie trying to find a longest matching +prefix. The goal is always to reach a leaf and get a positive result from the +fib_semantic_match mechanism. + +Inside each tnode, the search for longest matching prefix consists of searching +through the child array, chopping off (zeroing) the least significant "1" of +the child index until we find a match or the child index consists of nothing but +zeros. + +At this point we backtrack (t->stats.backtrack++) up the trie, continuing to +chop off part of the key in order to find the longest matching prefix. + +At this point we will repeatedly descend subtries to look for a match, and there +are some optimizations available that can provide us with "shortcuts" to avoid +descending into dead ends. Look for "HL_OPTIMIZE" sections in the code. + +To alleviate any doubts about the correctness of the route selection process, +a new netlink operation has been added. Look for NETLINK_FIB_LOOKUP, which +gives userland access to fib_lookup(). diff --git a/Documentation/pcmcia/devicetable.txt b/Documentation/pcmcia/devicetable.txt index 045511acafc9..3351c0355143 100644 --- a/Documentation/pcmcia/devicetable.txt +++ b/Documentation/pcmcia/devicetable.txt @@ -19,9 +19,8 @@ PCMCIA_DEVICE_PROD_ID1("some_string", 0x(hash_of_some_string)), If the hash is incorrect, the kernel will inform you about this in "dmesg" upon module initialization, and tell you of the correct hash. -You can determine the hash of the product ID strings by running -"pcmcia-modalias %n.%m" [%n being replaced with the socket number and %m being -replaced with the device function] from pcmciautils. It generates a string +You can determine the hash of the product ID strings by catting the file +"modalias" in the sysfs directory of the PCMCIA device. It generates a string in the following form: pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd00000000 diff --git a/Documentation/serial/driver b/Documentation/serial/driver index e9c0178cd202..ac7eabbf662a 100644 --- a/Documentation/serial/driver +++ b/Documentation/serial/driver @@ -107,8 +107,8 @@ hardware. indicate that the signal is permanently active. If RI is not available, the signal should not be indicated as active. - Locking: none. - Interrupts: caller dependent. + Locking: port->lock taken. + Interrupts: locally disabled. This call must not sleep stop_tx(port,tty_stop) diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html index 4b3d8f640a4a..441407b12a9f 100644 --- a/Documentation/video4linux/API.html +++ b/Documentation/video4linux/API.html @@ -1,399 +1,16 @@ -<HTML><HEAD> -<TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE> -</HEAD> -<! Revision History: > -<! 4/30/1999 - Fred Gleason (fredg@wava.com)> -<! Documented extensions for the Radio Data System (RDS) extensions > -<BODY bgcolor="#ffffff"> -<H3>Devices</H3> -Video4Linux provides the following sets of device files. These live on the -character device formerly known as "/dev/bttv". /dev/bttv should be a -symlink to /dev/video0 for most people. -<P> -<TABLE> -<TR><TH>Device Name</TH><TH>Minor Range</TH><TH>Function</TH> -<TR><TD>/dev/video</TD><TD>0-63</TD><TD>Video Capture Interface</TD> -<TR><TD>/dev/radio</TD><TD>64-127</TD><TD>AM/FM Radio Devices</TD> -<TR><TD>/dev/vtx</TD><TD>192-223</TD><TD>Teletext Interface Chips</TD> -<TR><TD>/dev/vbi</TD><TD>224-239</TD><TD>Raw VBI Data (Intercast/teletext)</TD> -</TABLE> -<P> -Video4Linux programs open and scan the devices to find what they are looking -for. Capability queries define what each interface supports. The -described API is only defined for video capture cards. The relevant subset -applies to radio cards. Teletext interfaces talk the existing VTX API. -<P> -<H3>Capability Query Ioctl</H3> -The <B>VIDIOCGCAP</B> ioctl call is used to obtain the capability -information for a video device. The <b>struct video_capability</b> object -passed to the ioctl is completed and returned. It contains the following -information -<P> -<TABLE> -<TR><TD><b>name[32]</b><TD>Canonical name for this interface</TD> -<TR><TD><b>type</b><TD>Type of interface</TD> -<TR><TD><b>channels</b><TD>Number of radio/tv channels if appropriate</TD> -<TR><TD><b>audios</b><TD>Number of audio devices if appropriate</TD> -<TR><TD><b>maxwidth</b><TD>Maximum capture width in pixels</TD> -<TR><TD><b>maxheight</b><TD>Maximum capture height in pixels</TD> -<TR><TD><b>minwidth</b><TD>Minimum capture width in pixels</TD> -<TR><TD><b>minheight</b><TD>Minimum capture height in pixels</TD> -</TABLE> -<P> -The type field lists the capability flags for the device. These are -as follows -<P> -<TABLE> -<TR><TH>Name</TH><TH>Description</TH> -<TR><TD><b>VID_TYPE_CAPTURE</b><TD>Can capture to memory</TD> -<TR><TD><b>VID_TYPE_TUNER</b><TD>Has a tuner of some form</TD> -<TR><TD><b>VID_TYPE_TELETEXT</b><TD>Has teletext capability</TD> -<TR><TD><b>VID_TYPE_OVERLAY</b><TD>Can overlay its image onto the frame buffer</TD> -<TR><TD><b>VID_TYPE_CHROMAKEY</b><TD>Overlay is Chromakeyed</TD> -<TR><TD><b>VID_TYPE_CLIPPING</b><TD>Overlay clipping is supported</TD> -<TR><TD><b>VID_TYPE_FRAMERAM</b><TD>Overlay overwrites frame buffer memory</TD> -<TR><TD><b>VID_TYPE_SCALES</b><TD>The hardware supports image scaling</TD> -<TR><TD><b>VID_TYPE_MONOCHROME</b><TD>Image capture is grey scale only</TD> -<TR><TD><b>VID_TYPE_SUBCAPTURE</b><TD>Capture can be of only part of the image</TD> -</TABLE> -<P> -The minimum and maximum sizes listed for a capture device do not imply all -that all height/width ratios or sizes within the range are possible. A -request to set a size will be honoured by the largest available capture -size whose capture is no large than the requested rectangle in either -direction. For example the quickcam has 3 fixed settings. -<P> -<H3>Frame Buffer</H3> -Capture cards that drop data directly onto the frame buffer must be told the -base address of the frame buffer, its size and organisation. This is a -privileged ioctl and one that eventually X itself should set. -<P> -The <b>VIDIOCSFBUF</b> ioctl sets the frame buffer parameters for a capture -card. If the card does not do direct writes to the frame buffer then this -ioctl will be unsupported. The <b>VIDIOCGFBUF</b> ioctl returns the -currently used parameters. The structure used in both cases is a -<b>struct video_buffer</b>. -<P> -<TABLE> -<TR><TD><b>void *base</b></TD><TD>Base physical address of the buffer</TD> -<TR><TD><b>int height</b></TD><TD>Height of the frame buffer</TD> -<TR><TD><b>int width</b></TD><TD>Width of the frame buffer</TD> -<TR><TD><b>int depth</b></TD><TD>Depth of the frame buffer</TD> -<TR><TD><b>int bytesperline</b></TD><TD>Number of bytes of memory between the start of two adjacent lines</TD> -</TABLE> -<P> -Note that these values reflect the physical layout of the frame buffer. -The visible area may be smaller. In fact under XFree86 this is commonly the -case. XFree86 DGA can provide the parameters required to set up this ioctl. -Setting the base address to NULL indicates there is no physical frame buffer -access. -<P> -<H3>Capture Windows</H3> -The capture area is described by a <b>struct video_window</b>. This defines -a capture area and the clipping information if relevant. The -<b>VIDIOCGWIN</b> ioctl recovers the current settings and the -<b>VIDIOCSWIN</b> sets new values. A successful call to <b>VIDIOCSWIN</b> -indicates that a suitable set of parameters have been chosen. They do not -indicate that exactly what was requested was granted. The program should -call <b>VIDIOCGWIN</b> to check if the nearest match was suitable. The -<b>struct video_window</b> contains the following fields. -<P> -<TABLE> -<TR><TD><b>x</b><TD>The X co-ordinate specified in X windows format.</TD> -<TR><TD><b>y</b><TD>The Y co-ordinate specified in X windows format.</TD> -<TR><TD><b>width</b><TD>The width of the image capture.</TD> -<TR><TD><b>height</b><TD>The height of the image capture.</TD> -<TR><TD><b>chromakey</b><TD>A host order RGB32 value for the chroma key.</TD> -<TR><TD><b>flags</b><TD>Additional capture flags.</TD> -<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em></TD> -<TR><TD><b>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD> -</TABLE> -<P> -Clipping rectangles are passed as an array. Each clip consists of the following -fields available to the user. -<P> -<TABLE> -<TR><TD><b>x</b></TD><TD>X co-ordinate of rectangle to skip</TD> -<TR><TD><b>y</b></TD><TD>Y co-ordinate of rectangle to skip</TD> -<TR><TD><b>width</b></TD><TD>Width of rectangle to skip</TD> -<TR><TD><b>height</b></TD><TD>Height of rectangle to skip</TD> -</TABLE> -<P> -Merely setting the window does not enable capturing. Overlay capturing -(i.e. PCI-PCI transfer to the frame buffer of the video card) -is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and -disabled by passing it a value of 0. -<P> -Some capture devices can capture a subfield of the image they actually see. -This is indicated when VIDEO_TYPE_SUBCAPTURE is defined. -The video_capture describes the time and special subfields to capture. -The video_capture structure contains the following fields. -<P> -<TABLE> -<TR><TD><b>x</b></TD><TD>X co-ordinate of source rectangle to grab</TD> -<TR><TD><b>y</b></TD><TD>Y co-ordinate of source rectangle to grab</TD> -<TR><TD><b>width</b></TD><TD>Width of source rectangle to grab</TD> -<TR><TD><b>height</b></TD><TD>Height of source rectangle to grab</TD> -<TR><TD><b>decimation</b></TD><TD>Decimation to apply</TD> -<TR><TD><b>flags</b></TD><TD>Flag settings for grabbing</TD> -</TABLE> -The available flags are -<P> -<TABLE> -<TR><TH>Name</TH><TH>Description</TH> -<TR><TD><b>VIDEO_CAPTURE_ODD</b><TD>Capture only odd frames</TD> -<TR><TD><b>VIDEO_CAPTURE_EVEN</b><TD>Capture only even frames</TD> -</TABLE> -<P> -<H3>Video Sources</H3> -Each video4linux video or audio device captures from one or more -source <b>channels</b>. Each channel can be queries with the -<b>VDIOCGCHAN</b> ioctl call. Before invoking this function the caller -must set the channel field to the channel that is being queried. On return -the <b>struct video_channel</b> is filled in with information about the -nature of the channel itself. -<P> -The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the -capture to this input. It is not defined whether parameters such as colour -settings or tuning are maintained across a channel switch. The caller should -maintain settings as desired for each channel. (This is reasonable as -different video inputs may have different properties). -<P> -The <b>struct video_channel</b> consists of the following -<P> -<TABLE> -<TR><TD><b>channel</b></TD><TD>The channel number</TD> -<TR><TD><b>name</b></TD><TD>The input name - preferably reflecting the label -on the card input itself</TD> -<TR><TD><b>tuners</b></TD><TD>Number of tuners for this input</TD> -<TR><TD><b>flags</b></TD><TD>Properties the tuner has</TD> -<TR><TD><b>type</b></TD><TD>Input type (if known)</TD> -<TR><TD><b>norm</b><TD>The norm for this channel</TD> -</TABLE> -<P> -The flags defined are -<P> -<TABLE> -<TR><TD><b>VIDEO_VC_TUNER</b><TD>Channel has tuners.</TD> -<TR><TD><b>VIDEO_VC_AUDIO</b><TD>Channel has audio.</TD> -<TR><TD><b>VIDEO_VC_NORM</b><TD>Channel has norm setting.</TD> -</TABLE> -<P> -The types defined are -<P> -<TABLE> -<TR><TD><b>VIDEO_TYPE_TV</b><TD>The input is a TV input.</TD> -<TR><TD><b>VIDEO_TYPE_CAMERA</b><TD>The input is a camera.</TD> -</TABLE> -<P> -<H3>Image Properties</H3> -The image properties of the picture can be queried with the <b>VIDIOCGPICT</b> -ioctl which fills in a <b>struct video_picture</b>. The <b>VIDIOCSPICT</b> -ioctl allows values to be changed. All values except for the palette type -are scaled between 0-65535. -<P> -The <b>struct video_picture</b> consists of the following fields -<P> -<TABLE> -<TR><TD><b>brightness</b><TD>Picture brightness</TD> -<TR><TD><b>hue</b><TD>Picture hue (colour only)</TD> -<TR><TD><b>colour</b><TD>Picture colour (colour only)</TD> -<TR><TD><b>contrast</b><TD>Picture contrast</TD> -<TR><TD><b>whiteness</b><TD>The whiteness (greyscale only)</TD> -<TR><TD><b>depth</b><TD>The capture depth (may need to match the frame buffer depth)</TD> -<TR><TD><b>palette</b><TD>Reports the palette that should be used for this image</TD> -</TABLE> -<P> -The following palettes are defined -<P> -<TABLE> -<TR><TD><b>VIDEO_PALETTE_GREY</b><TD>Linear intensity grey scale (255 is brightest).</TD> -<TR><TD><b>VIDEO_PALETTE_HI240</b><TD>The BT848 8bit colour cube.</TD> -<TR><TD><b>VIDEO_PALETTE_RGB565</b><TD>RGB565 packed into 16 bit words.</TD> -<TR><TD><b>VIDEO_PALETTE_RGB555</b><TD>RGV555 packed into 16 bit words, top bit undefined.</TD> -<TR><TD><b>VIDEO_PALETTE_RGB24</b><TD>RGB888 packed into 24bit words.</TD> -<TR><TD><b>VIDEO_PALETTE_RGB32</b><TD>RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.</TD> -<TR><TD><b>VIDEO_PALETTE_YUV422</b><TD>Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V</TD> -<TR><TD><b>VIDEO_PALETTE_YUYV</b><TD>Describe me</TD> -<TR><TD><b>VIDEO_PALETTE_UYVY</b><TD>Describe me</TD> -<TR><TD><b>VIDEO_PALETTE_YUV420</b><TD>YUV420 capture</TD> -<TR><TD><b>VIDEO_PALETTE_YUV411</b><TD>YUV411 capture</TD> -<TR><TD><b>VIDEO_PALETTE_RAW</b><TD>RAW capture (BT848)</TD> -<TR><TD><b>VIDEO_PALETTE_YUV422P</b><TD>YUV 4:2:2 Planar</TD> -<TR><TD><b>VIDEO_PALETTE_YUV411P</b><TD>YUV 4:1:1 Planar</TD> -</TABLE> -<P> -<H3>Tuning</H3> -Each video input channel can have one or more tuners associated with it. Many -devices will not have tuners. TV cards and radio cards will have one or more -tuners attached. -<P> -Tuners are described by a <b>struct video_tuner</b> which can be obtained by -the <b>VIDIOCGTUNER</b> ioctl. Fill in the tuner number in the structure -then pass the structure to the ioctl to have the data filled in. The -tuner can be switched using <b>VIDIOCSTUNER</b> which takes an integer argument -giving the tuner to use. A struct tuner has the following fields -<P> -<TABLE> -<TR><TD><b>tuner</b><TD>Number of the tuner</TD> -<TR><TD><b>name</b><TD>Canonical name for this tuner (eg FM/AM/TV)</TD> -<TR><TD><b>rangelow</b><TD>Lowest tunable frequency</TD> -<TR><TD><b>rangehigh</b><TD>Highest tunable frequency</TD> -<TR><TD><b>flags</b><TD>Flags describing the tuner</TD> -<TR><TD><b>mode</b><TD>The video signal mode if relevant</TD> -<TR><TD><b>signal</b><TD>Signal strength if known - between 0-65535</TD> -</TABLE> -<P> -The following flags exist -<P> -<TABLE> -<TR><TD><b>VIDEO_TUNER_PAL</b><TD>PAL tuning is supported</TD> -<TR><TD><b>VIDEO_TUNER_NTSC</b><TD>NTSC tuning is supported</TD> -<TR><TD><b>VIDEO_TUNER_SECAM</b><TD>SECAM tuning is supported</TD> -<TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD> -<TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD> -<TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD> -<TR><TD><b>VIDEO_TUNER_RDS_ON</b><TD>The tuner is seeing a RDS datastream</TD> -<TR><TD><b>VIDEO_TUNER_MBS_ON</b><TD>The tuner is seeing a MBS datastream</TD> -</TABLE> -<P> -The following modes are defined -<P> -<TABLE> -<TR><TD><b>VIDEO_MODE_PAL</b><TD>The tuner is in PAL mode</TD> -<TR><TD><b>VIDEO_MODE_NTSC</b><TD>The tuner is in NTSC mode</TD> -<TR><TD><b>VIDEO_MODE_SECAM</b><TD>The tuner is in SECAM mode</TD> -<TR><TD><b>VIDEO_MODE_AUTO</b><TD>The tuner auto switches, or mode does not apply</TD> -</TABLE> -<P> -Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the -<b>VIDEO_TUNER_LOW</b> flag is set they are in 1/16th KHz. The current -frequency is obtained as an unsigned long via the <b>VIDIOCGFREQ</b> ioctl and -set by the <b>VIDIOCSFREQ</b> ioctl. -<P> -<H3>Audio</H3> -TV and Radio devices have one or more audio inputs that may be selected. -The audio properties are queried by passing a <b>struct video_audio</b> to <b>VIDIOCGAUDIO</b> ioctl. The -<b>VIDIOCSAUDIO</b> ioctl sets audio properties. -<P> -The structure contains the following fields -<P> -<TABLE> -<TR><TD><b>audio</b><TD>The channel number</TD> -<TR><TD><b>volume</b><TD>The volume level</TD> -<TR><TD><b>bass</b><TD>The bass level</TD> -<TR><TD><b>treble</b><TD>The treble level</TD> -<TR><TD><b>flags</b><TD>Flags describing the audio channel</TD> -<TR><TD><b>name</b><TD>Canonical name for the audio input</TD> -<TR><TD><b>mode</b><TD>The mode the audio input is in</TD> -<TR><TD><b>balance</b><TD>The left/right balance</TD> -<TR><TD><b>step</b><TD>Actual step used by the hardware</TD> -</TABLE> -<P> -The following flags are defined -<P> -<TABLE> -<TR><TD><b>VIDEO_AUDIO_MUTE</b><TD>The audio is muted</TD> -<TR><TD><b>VIDEO_AUDIO_MUTABLE</b><TD>Audio muting is supported</TD> -<TR><TD><b>VIDEO_AUDIO_VOLUME</b><TD>The volume is controllable</TD> -<TR><TD><b>VIDEO_AUDIO_BASS</b><TD>The bass is controllable</TD> -<TR><TD><b>VIDEO_AUDIO_TREBLE</b><TD>The treble is controllable</TD> -<TR><TD><b>VIDEO_AUDIO_BALANCE</b><TD>The balance is controllable</TD> -</TABLE> -<P> -The following decoding modes are defined -<P> -<TABLE> -<TR><TD><b>VIDEO_SOUND_MONO</b><TD>Mono signal</TD> -<TR><TD><b>VIDEO_SOUND_STEREO</b><TD>Stereo signal (NICAM for TV)</TD> -<TR><TD><b>VIDEO_SOUND_LANG1</b><TD>European TV alternate language 1</TD> -<TR><TD><b>VIDEO_SOUND_LANG2</b><TD>European TV alternate language 2</TD> -</TABLE> -<P> -<H3>Reading Images</H3> -Each call to the <b>read</b> syscall returns the next available image -from the device. It is up to the caller to set format and size (using -the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable -size buffer and length to the function. Not all devices will support -read operations. -<P> -A second way to handle image capture is via the mmap interface if supported. -To use the mmap interface a user first sets the desired image size and depth -properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size -of buffer to mmap and the offset within the buffer for each frame. The -number of frames supported is device dependent and may only be one. -<P> -The video_mbuf structure contains the following fields -<P> -<TABLE> -<TR><TD><b>size</b><TD>The number of bytes to map</TD> -<TR><TD><b>frames</b><TD>The number of frames</TD> -<TR><TD><b>offsets</b><TD>The offset of each frame</TD> -</TABLE> -<P> -Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the -capture to a frame using the format and image size specified in the -video_mmap (which should match or be below the initial query size). -When the VIDIOCMCAPTURE ioctl returns the frame is <em>not</em> -captured yet, the driver just instructed the hardware to start the -capture. The application has to use the VIDIOCSYNC ioctl to wait -until the capture of a frame is finished. VIDIOCSYNC takes the frame -number you want to wait for as argument. -<p> -It is allowed to call VIDIOCMCAPTURE multiple times (with different -frame numbers in video_mmap->frame of course) and thus have multiple -outstanding capture requests. A simple way do to double-buffering -using this feature looks like this: -<pre> -/* setup everything */ -VIDIOCMCAPTURE(0) -while (whatever) { - VIDIOCMCAPTURE(1) - VIDIOCSYNC(0) - /* process frame 0 while the hardware captures frame 1 */ - VIDIOCMCAPTURE(0) - VIDIOCSYNC(1) - /* process frame 1 while the hardware captures frame 0 */ -} -</pre> -Note that you are <em>not</em> limited to only two frames. The API -allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of -frames the driver granted. Thus it is possible to build deeper queues -to avoid loosing frames on load peaks. -<p> -While capturing to memory the driver will make a "best effort" attempt -to capture to screen as well if requested. This normally means all -frames that "miss" memory mapped capture will go to the display. -<P> -A final ioctl exists to allow a device to obtain related devices if a -driver has multiple components (for example video0 may not be associated -with vbi0 which would cause an intercast display program to make a bad -mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated -devices if any exist. The video_unit structure has the following fields. -<P> -<TABLE> -<TR><TD><b>video</b><TD>Video capture device</TD> -<TR><TD><b>vbi</b><TD>VBI capture device</TD> -<TR><TD><b>radio</b><TD>Radio device</TD> -<TR><TD><b>audio</b><TD>Audio mixer</TD> -<TR><TD><b>teletext</b><TD>Teletext device</TD> -</TABLE> -<P> -<H3>RDS Datastreams</H3> -For radio devices that support it, it is possible to receive Radio Data -System (RDS) data by means of a read() on the device. The data is packed in -groups of three, as follows: -<TABLE> -<TR><TD>First Octet</TD><TD>Least Significant Byte of RDS Block</TD></TR> -<TR><TD>Second Octet</TD><TD>Most Significant Byte of RDS Block -<TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit. Indicates that -an uncorrectable error occurred during reception of this block.</TD></TR> -<TR><TD> </TD><TD>Bit 6:</TD><TD>Corrected bit. Indicates that -an error was corrected for this data block.</TD></TR> -<TR><TD> </TD><TD>Bits 5-3:</TD><TD>Received Offset. Indicates the -offset received by the sync system.</TD></TR> -<TR><TD> </TD><TD>Bits 2-0:</TD><TD>Offset Name. Indicates the -offset applied to this data.</TD></TR> -</TABLE> -</BODY> -</HTML> +<TITLE>V4L API</TITLE> +<H1>Video For Linux APIs</H1> +<table border=0> +<tr> +<td> +<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html> +V4L original API</a> +</td><td> +Obsoleted by V4L2 API +</td></tr><tr><td> +<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html> +V4L2 API</a> +</td><td> +Should be used for new projects +</td></tr> +</table> diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index 216f705495cc..4377aa11f567 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 @@ -13,17 +13,17 @@ card=11 - Prolink PlayTV PVR card=12 - ASUS PVR-416 card=13 - MSI TV-@nywhere card=14 - KWorld/VStream XPert DVB-T -card=15 - DVICO FusionHDTV DVB-T1 +card=15 - DViCO FusionHDTV DVB-T1 card=16 - KWorld LTV883RF -card=17 - DViCO - FusionHDTV 3 Gold +card=17 - DViCO FusionHDTV 3 Gold-Q card=18 - Hauppauge Nova-T DVB-T card=19 - Conexant DVB-T reference design card=20 - Provideo PV259 -card=21 - DVICO FusionHDTV DVB-T Plus +card=21 - DViCO FusionHDTV DVB-T Plus card=22 - digitalnow DNTV Live! DVB-T card=23 - pcHDTV HD3000 HDTV card=24 - Hauppauge WinTV 28xxx (Roslyn) models card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC) card=26 - IODATA GV/BCTV7E card=27 - PixelView PlayTV Ultra Pro (Stereo) -card=28 - DViCO - FusionHDTV 3 Gold-T +card=28 - DViCO FusionHDTV 3 Gold-T diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index d5ed95d28500..735e8ba02d9f 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -54,3 +54,9 @@ 55 -> LifeView FlyDVB-T DUO [5168:0306] 56 -> Avermedia AVerTV 307 [1461:a70a] 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] + 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370] + 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 + 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus + 61 -> Philips TOUGH DVB-T reference design + 62 -> Compro VideoMate TV Gold+II + 63 -> Kworld Xpert TV PVR7134 diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index aeb8df8ce890..e78020f68b2e 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -59,3 +59,6 @@ tuner=57 - Philips FQ1236A MK4 tuner=58 - Ymec TVision TVF-8531MF tuner=59 - Ymec TVision TVF-5533MF tuner=60 - Thomson DDT 7611 (ATSC/NTSC) +tuner=61 - Tena TNF9533-D/IF +tuner=62 - Philips TEA5767HN FM Radio +tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner diff --git a/Documentation/video4linux/README.saa7134 b/Documentation/video4linux/README.saa7134 index 1a446c65365e..1f788e498eff 100644 --- a/Documentation/video4linux/README.saa7134 +++ b/Documentation/video4linux/README.saa7134 @@ -57,6 +57,15 @@ Cards can use either of these two crystals (xtal): - 24.576MHz -> .audio_clock=0x200000 (xtal * .audio_clock = 51539600) +Some details about 30/34/35: + + - saa7130 - low-price chip, doesn't have mute, that is why all those + cards should have .mute field defined in their tuner structure. + + - saa7134 - usual chip + + - saa7133/35 - saa7135 is probably a marketing decision, since all those + chips identifies itself as 33 on pci. Credits ======= diff --git a/MAINTAINERS b/MAINTAINERS index 4db63de9652a..302b31960008 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -512,11 +512,11 @@ W: http://linuxppc64.org S: Supported BTTV VIDEO4LINUX DRIVER -P: Gerd Knorr -M: kraxel@bytesex.org +P: Mauro Carvalho Chehab +M: mchehab@brturbo.com.br L: video4linux-list@redhat.com -W: http://bytesex.org/bttv/ -S: Orphan +W: http://linuxtv.org +S: Maintained BUSLOGIC SCSI DRIVER P: Leonard N. Zubkoff @@ -2161,7 +2161,7 @@ UltraSPARC (sparc64): P: David S. Miller M: davem@davemloft.net P: Eddie C. Dost -M: ecd@skynet.be +M: ecd@brainaid.de P: Jakub Jelinek M: jj@sunsite.ms.mff.cuni.cz P: Anton Blanchard @@ -2625,10 +2625,11 @@ W: http://rio500.sourceforge.net S: Maintained VIDEO FOR LINUX -P: Gerd Knorr -M: kraxel@bytesex.org +P: Mauro Carvalho Chehab +M: mchehab@brturbo.com.br L: video4linux-list@redhat.com -S: Orphan +W: http://linuxtv.org +S: Maintained W1 DALLAS'S 1-WIRE BUS P: Evgeniy Polyakov @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 12 -EXTRAVERSION = +SUBLEVEL = 13 +EXTRAVERSION =-rc2 NAME=Woozy Numbat # *DOCUMENTATION* diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index e6ded33c6e22..9d34ce26e5ef 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -55,6 +55,8 @@ do_entInt(unsigned long type, unsigned long vector, #ifdef CONFIG_SMP { long cpu; + + local_irq_disable(); smp_percpu_timer_interrupt(regs); cpu = smp_processor_id(); if (cpu != boot_cpuid) { diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index fd7bd17cc960..6f509a644bdd 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -240,7 +240,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) siginfo_t info; int signo, code; - if (regs->ps == 0) { + if ((regs->ps & ~IPL_MAX) == 0) { if (type == 1) { const unsigned int *data = (const unsigned int *) regs->pc; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c8d94dcd8ef7..620f2ca94ed2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -361,6 +361,11 @@ config NO_IDLE_HZ Alternatively, if you want dynamic tick automatically enabled during boot, pass "dyntick=enable" via the kernel command string. + Please note that dynamic tick may affect the accuracy of + timekeeping on some platforms depending on the implementation. + Currently at least OMAP platform is known to have accurate + timekeeping with dynamic tick. + config ARCH_DISCONTIGMEM_ENABLE bool default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 8330495e2448..eb933dcafba0 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -56,7 +56,7 @@ tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) tune-$(CONFIG_CPU_V6) :=-mtune=strongarm # Need -Uarm for gcc < 3.x -CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float diff --git a/arch/arm/configs/omnimeter_defconfig b/arch/arm/configs/omnimeter_defconfig deleted file mode 100644 index 78fdb4a428b1..000000000000 --- a/arch/arm/configs/omnimeter_defconfig +++ /dev/null @@ -1,803 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 21:31:45 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_CAMELOT is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -CONFIG_ARCH_SA1100=y -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# SA11x0 Implementations -# -# CONFIG_SA1100_ASSABET is not set -# CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_COLLIE is not set -# CONFIG_SA1100_H3100 is not set -# CONFIG_SA1100_H3600 is not set -# CONFIG_SA1100_H3800 is not set -# CONFIG_SA1100_BADGE4 is not set -# CONFIG_SA1100_JORNADA720 is not set -# CONFIG_SA1100_HACKKIT is not set -# CONFIG_SA1100_LART is not set -# CONFIG_SA1100_PLEB is not set -# CONFIG_SA1100_SHANNON is not set -# CONFIG_SA1100_SIMPAD is not set -# CONFIG_SA1100_SSP is not set - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_SA1100=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4=y -CONFIG_CPU_CACHE_V4WB=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WB=y -CONFIG_CPU_MINICACHE=y - -# -# Processor Features -# - -# -# Bus support -# -CONFIG_ISA=y - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_PCMCIA=y - -# -# PC-card bridges -# -CONFIG_I82365=y -# CONFIG_TCIC is not set -CONFIG_PCMCIA_SA1100=y -CONFIG_PCCARD_NONSTATIC=y - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_DISCONTIGMEM=y -# CONFIG_LEDS is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/ram ramdisk=8192 initrd=0xd0000000,4M" -# CONFIG_XIP_KERNEL is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -# CONFIG_FPE_NWFPE is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNP is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_IP_NF_CONNTRACK is not set -# CONFIG_IP_NF_CONNTRACK_MARK is not set -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_SMC91X is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set -# CONFIG_ARLAN is not set -# CONFIG_WAVELAN is not set -CONFIG_PCMCIA_WAVELAN=y -# CONFIG_PCMCIA_NETWAVE is not set - -# -# Wireless 802.11 Frequency Hopping cards support -# -# CONFIG_PCMCIA_RAYCS is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Wireless 802.11b Pcmcia/Cardbus cards support -# -CONFIG_AIRO_CS=y -CONFIG_PCMCIA_WL3501=y -CONFIG_NET_WIRELESS=y - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=y -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_FMVJ18X is not set -CONFIG_PCMCIA_PCNET=y -# CONFIG_PCMCIA_NMCLAN is not set -# CONFIG_PCMCIA_SMC91C92 is not set -# CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_PCMCIA_AXNET is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SA1100=y -CONFIG_SERIAL_SA1100_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SOFT_CURSOR=y -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_SA1100=y -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -# CONFIG_FONT_8x16 is not set -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_VFAT_FS is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -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 - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_FRAME_POINTER=y -# CONFIG_DEBUG_USER is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 4c38bd8bc298..835d450797a1 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -30,9 +30,6 @@ extern void __lshrdi3(void); extern void __modsi3(void); extern void __muldi3(void); extern void __ucmpdi2(void); -extern void __udivdi3(void); -extern void __umoddi3(void); -extern void __udivmoddi4(void); extern void __udivsi3(void); extern void __umodsi3(void); extern void __do_div64(void); @@ -44,7 +41,10 @@ extern void fp_enter(void); * This has a special calling convention; it doesn't * modify any of the usual registers, except for LR. */ +#define EXPORT_CRC_ALIAS(sym) __CRC_SYMBOL(sym, "") + #define EXPORT_SYMBOL_ALIAS(sym,orig) \ + EXPORT_CRC_ALIAS(sym) \ const struct kernel_symbol __ksymtab_##sym \ __attribute__((section("__ksymtab"))) = \ { (unsigned long)&orig, #sym }; @@ -134,9 +134,6 @@ EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__modsi3); EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__ucmpdi2); -EXPORT_SYMBOL(__udivdi3); -EXPORT_SYMBOL(__umoddi3); -EXPORT_SYMBOL(__udivmoddi4); EXPORT_SYMBOL(__udivsi3); EXPORT_SYMBOL(__umodsi3); EXPORT_SYMBOL(__do_div64); diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index bd4823c74645..1155cf07c871 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -344,9 +344,9 @@ __create_page_tables: str r6, [r0] #endif +#ifdef CONFIG_DEBUG_LL bic r7, r7, #0x0c @ turn off cacheable @ and bufferable bits -#ifdef CONFIG_DEBUG_LL /* * Map in IO space for serial debugging. * This allows debug messages to be output @@ -372,28 +372,24 @@ __create_page_tables: teq r1, #MACH_TYPE_NETWINDER teqne r1, #MACH_TYPE_CATS bne 1f - add r0, r4, #0x3fc0 @ ff000000 - mov r3, #0x7c000000 - orr r3, r3, r7 - str r3, [r0], #4 - add r3, r3, #1 << 20 - str r3, [r0], #4 + add r0, r4, #0xff000000 >> 18 + orr r3, r7, #0x7c000000 + str r3, [r0] 1: #endif -#endif #ifdef CONFIG_ARCH_RPC /* * Map in screen at 0x02000000 & SCREEN2_BASE * Similar reasons here - for debug. This is * only for Acorn RiscPC architectures. */ - add r0, r4, #0x80 @ 02000000 - mov r3, #0x02000000 - orr r3, r3, r7 + add r0, r4, #0x02000000 >> 18 + orr r3, r7, #0x02000000 str r3, [r0] - add r0, r4, #0x3600 @ d8000000 + add r0, r4, #0xd8000000 >> 18 str r3, [r0] #endif +#endif mov pc, lr .ltorg diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8cf733daa800..c9b69771f92e 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -359,7 +359,8 @@ void cpu_init(void) "I" (offsetof(struct stack, abt[0])), "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), - "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)); + "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE) + : "r14"); } static struct machine_desc * __init setup_machine(unsigned int nr) @@ -736,8 +737,8 @@ void __init setup_arch(char **cmdline_p) if (mdesc->soft_reboot) reboot_setup("s"); - if (mdesc->param_offset) - tags = phys_to_virt(mdesc->param_offset); + if (mdesc->boot_params) + tags = phys_to_virt(mdesc->boot_params); /* * If we have the old style parameters, convert them to diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 34892758f098..a931409c8fe4 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -502,3 +502,126 @@ int __init setup_profiling_timer(unsigned int multiplier) { return -EINVAL; } + +static int +on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait, + cpumask_t mask) +{ + int ret = 0; + + preempt_disable(); + + ret = smp_call_function_on_cpu(func, info, retry, wait, mask); + if (cpu_isset(smp_processor_id(), mask)) + func(info); + + preempt_enable(); + + return ret; +} + +/**********************************************************************/ + +/* + * TLB operations + */ +struct tlb_args { + struct vm_area_struct *ta_vma; + unsigned long ta_start; + unsigned long ta_end; +}; + +static inline void ipi_flush_tlb_all(void *ignored) +{ + local_flush_tlb_all(); +} + +static inline void ipi_flush_tlb_mm(void *arg) +{ + struct mm_struct *mm = (struct mm_struct *)arg; + + local_flush_tlb_mm(mm); +} + +static inline void ipi_flush_tlb_page(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_page(ta->ta_vma, ta->ta_start); +} + +static inline void ipi_flush_tlb_kernel_page(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_page(ta->ta_start); +} + +static inline void ipi_flush_tlb_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end); +} + +static inline void ipi_flush_tlb_kernel_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end); +} + +void flush_tlb_all(void) +{ + on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + cpumask_t mask = mm->cpu_vm_mask; + + on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask); +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +{ + cpumask_t mask = vma->vm_mm->cpu_vm_mask; + struct tlb_args ta; + + ta.ta_vma = vma; + ta.ta_start = uaddr; + + on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask); +} + +void flush_tlb_kernel_page(unsigned long kaddr) +{ + struct tlb_args ta; + + ta.ta_start = kaddr; + + on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1); +} + +void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + cpumask_t mask = vma->vm_mm->cpu_vm_mask; + struct tlb_args ta; + + ta.ta_vma = vma; + ta.ta_start = start; + ta.ta_end = end; + + on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + struct tlb_args ta; + + ta.ta_start = start; + ta.ta_end = end; + + on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1); +} diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 2fb0a4cfb37a..df2cb06ce424 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -230,16 +230,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) do_exit(SIGSEGV); } -void die_if_kernel(const char *str, struct pt_regs *regs, int err) -{ - if (user_mode(regs)) - return; - - die(str, regs, err); -} - -static void notify_die(const char *str, struct pt_regs *regs, siginfo_t *info, - unsigned long err, unsigned long trap) +void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, + unsigned long err, unsigned long trap) { if (user_mode(regs)) { current->thread.error_code = err; diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c0e65833ffc4..8725d63e4219 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ strnlen_user.o strchr.o strrchr.o testchangebit.o \ testclearbit.o testsetbit.o uaccess.o getuser.o \ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o udivdi3.o lib1funcs.o div64.o \ + ucmpdi2.o lib1funcs.o div64.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o ifeq ($(CONFIG_CPU_32v3),y) diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h deleted file mode 100644 index 90ae647e4d76..000000000000 --- a/arch/arm/lib/longlong.h +++ /dev/null @@ -1,183 +0,0 @@ -/* longlong.h -- based on code from gcc-2.95.3 - - definitions for mixed size 32/64 bit arithmetic. - Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. - - This definition 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 later version. - - This definition file 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. */ - -/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */ - -#ifndef SI_TYPE_SIZE -#define SI_TYPE_SIZE 32 -#endif - -#define __BITS4 (SI_TYPE_SIZE / 4) -#define __ll_B (1L << (SI_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((u32) (t) % __ll_B) -#define __ll_highpart(t) ((u32) (t) / __ll_B) - -/* Define auxiliary asm macros. - - 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) - multiplies two u32 integers MULTIPLER and MULTIPLICAND, - and generates a two-part u32 product in HIGH_PROD and - LOW_PROD. - - 2) __umulsidi3(a,b) multiplies two u32 integers A and B, - and returns a u64 product. This is just a variant of umul_ppmm. - - 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator) divides a two-word unsigned integer, composed by the - integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and - places the quotient in QUOTIENT and the remainder in REMAINDER. - HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. - If, in addition, the most significant bit of DENOMINATOR must be 1, - then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. - - 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator). Like udiv_qrnnd but the numbers are signed. The - quotient is rounded towards 0. - - 5) count_leading_zeros(count, x) counts the number of zero-bits from - the msb to the first non-zero bit. This is the number of steps X - needs to be shifted left to set the msb. Undefined for X == 0. - - 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, - high_addend_2, low_addend_2) adds two two-word unsigned integers, - composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and - LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and - LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is - lost. - - 7) sub_ddmmss(high_difference, low_difference, high_minuend, - low_minuend, high_subtrahend, low_subtrahend) subtracts two - two-word unsigned integers, composed by HIGH_MINUEND_1 and - LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 - respectively. The result is placed in HIGH_DIFFERENCE and - LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, - and is lost. - - If any of these macros are left undefined for a particular CPU, - C macros are used. */ - -#if defined (__arm__) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("adds %1, %4, %5 \n\ - adc %0, %2, %3" \ - : "=r" ((u32) (sh)), \ - "=&r" ((u32) (sl)) \ - : "%r" ((u32) (ah)), \ - "rI" ((u32) (bh)), \ - "%r" ((u32) (al)), \ - "rI" ((u32) (bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subs %1, %4, %5 \n\ - sbc %0, %2, %3" \ - : "=r" ((u32) (sh)), \ - "=&r" ((u32) (sl)) \ - : "r" ((u32) (ah)), \ - "rI" ((u32) (bh)), \ - "r" ((u32) (al)), \ - "rI" ((u32) (bl))) -#define umul_ppmm(xh, xl, a, b) \ -{register u32 __t0, __t1, __t2; \ - __asm__ ("%@ Inlined umul_ppmm \n\ - mov %2, %5, lsr #16 \n\ - mov %0, %6, lsr #16 \n\ - bic %3, %5, %2, lsl #16 \n\ - bic %4, %6, %0, lsl #16 \n\ - mul %1, %3, %4 \n\ - mul %4, %2, %4 \n\ - mul %3, %0, %3 \n\ - mul %0, %2, %0 \n\ - adds %3, %4, %3 \n\ - addcs %0, %0, #65536 \n\ - adds %1, %1, %3, lsl #16 \n\ - adc %0, %0, %3, lsr #16" \ - : "=&r" ((u32) (xh)), \ - "=r" ((u32) (xl)), \ - "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ - : "r" ((u32) (a)), \ - "r" ((u32) (b)));} -#define UMUL_TIME 20 -#define UDIV_TIME 100 -#endif /* __arm__ */ - -#define __umulsidi3(u, v) \ - ({DIunion __w; \ - umul_ppmm (__w.s.high, __w.s.low, u, v); \ - __w.ll; }) - -#define __udiv_qrnnd_c(q, r, n1, n0, d) \ - do { \ - u32 __d1, __d0, __q1, __q0; \ - u32 __r1, __r0, __m; \ - __d1 = __ll_highpart (d); \ - __d0 = __ll_lowpart (d); \ - \ - __r1 = (n1) % __d1; \ - __q1 = (n1) / __d1; \ - __m = (u32) __q1 * __d0; \ - __r1 = __r1 * __ll_B | __ll_highpart (n0); \ - if (__r1 < __m) \ - { \ - __q1--, __r1 += (d); \ - if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ - if (__r1 < __m) \ - __q1--, __r1 += (d); \ - } \ - __r1 -= __m; \ - \ - __r0 = __r1 % __d1; \ - __q0 = __r1 / __d1; \ - __m = (u32) __q0 * __d0; \ - __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ - if (__r0 < __m) \ - { \ - __q0--, __r0 += (d); \ - if (__r0 >= (d)) \ - if (__r0 < __m) \ - __q0--, __r0 += (d); \ - } \ - __r0 -= __m; \ - \ - (q) = (u32) __q1 * __ll_B | __q0; \ - (r) = __r0; \ - } while (0) - -#define UDIV_NEEDS_NORMALIZATION 1 -#define udiv_qrnnd __udiv_qrnnd_c - -#define count_leading_zeros(count, x) \ - do { \ - u32 __xr = (x); \ - u32 __a; \ - \ - if (SI_TYPE_SIZE <= 32) \ - { \ - __a = __xr < ((u32)1<<2*__BITS4) \ - ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \ - : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ - } \ - else \ - { \ - for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \ - if (((__xr >> __a) & 0xff) != 0) \ - break; \ - } \ - \ - (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ - } while (0) diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c deleted file mode 100644 index e343be4c6642..000000000000 --- a/arch/arm/lib/udivdi3.c +++ /dev/null @@ -1,222 +0,0 @@ -/* More subroutines needed by GCC output code on some machines. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. - */ -/* support functions required by the kernel. based on code from gcc-2.95.3 */ -/* I Molton 29/07/01 */ - -#include "gcclib.h" -#include "longlong.h" - -static const u8 __clz_tab[] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 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, - 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, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, -}; - -u64 __udivmoddi4(u64 n, u64 d, u64 * rp) -{ - DIunion ww; - DIunion nn, dd; - DIunion rr; - u32 d0, d1, n0, n1, n2; - u32 q0, q1; - u32 b, bm; - - nn.ll = n; - dd.ll = d; - - d0 = dd.s.low; - d1 = dd.s.high; - n0 = nn.s.low; - n1 = nn.s.high; - - if (d1 == 0) { - if (d0 > n1) { - /* 0q = nn / 0D */ - - count_leading_zeros(bm, d0); - - if (bm != 0) { - /* Normalize, i.e. make the most significant bit of the - denominator set. */ - - d0 = d0 << bm; - n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); - n0 = n0 << bm; - } - - udiv_qrnnd(q0, n0, n1, n0, d0); - q1 = 0; - - /* Remainder in n0 >> bm. */ - } else { - /* qq = NN / 0d */ - - if (d0 == 0) - d0 = 1 / d0; /* Divide intentionally by zero. */ - - count_leading_zeros(bm, d0); - - if (bm == 0) { - /* From (n1 >= d0) /\ (the most significant bit of d0 is set), - conclude (the most significant bit of n1 is set) /\ (the - leading quotient digit q1 = 1). - - This special case is necessary, not an optimization. - (Shifts counts of SI_TYPE_SIZE are undefined.) */ - - n1 -= d0; - q1 = 1; - } else { - /* Normalize. */ - - b = SI_TYPE_SIZE - bm; - - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd(q1, n1, n2, n1, d0); - } - - /* n1 != d0... */ - - udiv_qrnnd(q0, n0, n1, n0, d0); - - /* Remainder in n0 >> bm. */ - } - - if (rp != 0) { - rr.s.low = n0 >> bm; - rr.s.high = 0; - *rp = rr.ll; - } - } else { - if (d1 > n1) { - /* 00 = nn / DD */ - - q0 = 0; - q1 = 0; - - /* Remainder in n1n0. */ - if (rp != 0) { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } else { - /* 0q = NN / dd */ - - count_leading_zeros(bm, d1); - if (bm == 0) { - /* From (n1 >= d1) /\ (the most significant bit of d1 is set), - conclude (the most significant bit of n1 is set) /\ (the - quotient digit q0 = 0 or 1). - - This special case is necessary, not an optimization. */ - - /* The condition on the next line takes advantage of that - n1 >= d1 (true due to program flow). */ - if (n1 > d1 || n0 >= d0) { - q0 = 1; - sub_ddmmss(n1, n0, n1, n0, d1, d0); - } else - q0 = 0; - - q1 = 0; - - if (rp != 0) { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } else { - u32 m1, m0; - /* Normalize. */ - - b = SI_TYPE_SIZE - bm; - - d1 = (d1 << bm) | (d0 >> b); - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd(q0, n1, n2, n1, d1); - umul_ppmm(m1, m0, q0, d0); - - if (m1 > n1 || (m1 == n1 && m0 > n0)) { - q0--; - sub_ddmmss(m1, m0, m1, m0, d1, d0); - } - - q1 = 0; - - /* Remainder in (n1n0 - m1m0) >> bm. */ - if (rp != 0) { - sub_ddmmss(n1, n0, n1, n0, m1, m0); - rr.s.low = (n1 << b) | (n0 >> bm); - rr.s.high = n1 >> bm; - *rp = rr.ll; - } - } - } - } - - ww.s.low = q0; - ww.s.high = q1; - return ww.ll; -} - -u64 __udivdi3(u64 n, u64 d) -{ - return __udivmoddi4(n, d, (u64 *) 0); -} - -u64 __umoddi3(u64 u, u64 v) -{ - u64 w; - - (void)__udivmoddi4(u, v, &w); - - return w; -} diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index 5417ca3f4621..c9d899886648 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c @@ -40,9 +40,11 @@ static void __init aaed2000_map_io(void) } MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform") - MAINTAINER("Nicolas Bellido Y Ortega") - BOOT_MEM(0xf0000000, PIO_BASE, VIO_BASE) - MAPIO(aaed2000_map_io) - INITIRQ(aaed2000_init_irq) + /* Maintainer: Nicolas Bellido Y Ortega */ + .phys_ram = 0xf0000000, + .phys_io = PIO_BASE, + .io_pg_offst = ((VIO_BASE) >> 18) & 0xfffc, + .map_io = aaed2000_map_io, + .init_irq = aaed2000_init_irq, .timer = &aaec2000_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c index c106704a2c34..dc73feb1ffb0 100644 --- a/arch/arm/mach-clps711x/autcpu12.c +++ b/arch/arm/mach-clps711x/autcpu12.c @@ -59,11 +59,13 @@ void __init autcpu12_map_io(void) } MACHINE_START(AUTCPU12, "autronix autcpu12") - MAINTAINER("Thomas Gleixner") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0020000) - MAPIO(autcpu12_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Thomas Gleixner */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0020000, + .map_io = autcpu12_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c index 7664f9cf83b8..a46c82cd2711 100644 --- a/arch/arm/mach-clps711x/cdb89712.c +++ b/arch/arm/mach-clps711x/cdb89712.c @@ -49,10 +49,12 @@ static void __init cdb89712_map_io(void) } MACHINE_START(CDB89712, "Cirrus-CDB89712") - MAINTAINER("Ray Lehtiniemi") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - MAPIO(cdb89712_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Ray Lehtiniemi */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = cdb89712_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c index e4093be3c4cb..780d91805984 100644 --- a/arch/arm/mach-clps711x/ceiva.c +++ b/arch/arm/mach-clps711x/ceiva.c @@ -53,10 +53,12 @@ static void __init ceiva_map_io(void) MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame") - MAINTAINER("Rob Scott") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - MAPIO(ceiva_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Rob Scott */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = ceiva_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c index 9ca21cb481ba..c83f3fd68fcd 100644 --- a/arch/arm/mach-clps711x/clep7312.c +++ b/arch/arm/mach-clps711x/clep7312.c @@ -37,12 +37,14 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags, MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") - MAINTAINER("Nobody") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_clep7312) - MAPIO(clps711x_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Nobody */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_clep7312, + .map_io = clps711x_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c index c6c46324a2e3..255c98b63e15 100644 --- a/arch/arm/mach-clps711x/edb7211-arch.c +++ b/arch/arm/mach-clps711x/edb7211-arch.c @@ -51,11 +51,13 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags, } MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") - MAINTAINER("Jon McClintock") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0020100) /* 0xc0000000 - 0xc001ffff can be video RAM */ - FIXUP(fixup_edb7211) - MAPIO(edb7211_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Jon McClintock */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */ + .fixup = fixup_edb7211, + .map_io = edb7211_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c index c1c5b8e01549..f83a59761e02 100644 --- a/arch/arm/mach-clps711x/fortunet.c +++ b/arch/arm/mach-clps711x/fortunet.c @@ -75,11 +75,13 @@ fortunet_fixup(struct machine_desc *desc, struct tag *tags, } MACHINE_START(FORTUNET, "ARM-FortuNet") - MAINTAINER("FortuNet Inc.") - BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0x00000000) - FIXUP(fortunet_fixup) - MAPIO(clps711x_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: FortuNet Inc. */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0x00000000, + .fixup = fortunet_fixup, + .map_io = clps711x_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c index 29269df054f5..5bdb90edf992 100644 --- a/arch/arm/mach-clps711x/p720t.c +++ b/arch/arm/mach-clps711x/p720t.c @@ -79,12 +79,14 @@ static void __init p720t_map_io(void) } MACHINE_START(P720T, "ARM-Prospector720T") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_p720t) - MAPIO(p720t_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_p720t, + .map_io = p720t_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index 90e85f434f6f..112f1d68fb2b 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -366,11 +366,13 @@ static void __init clps7500_init(void) } MACHINE_START(CLPS7500, "CL-PS7500") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) - MAPIO(clps7500_map_io) - INITIRQ(clps7500_init_irq) - .init_machine = clps7500_init, - .timer = &clps7500_timer, + /* Maintainer: Philip Blundell */ + .phys_ram = 0x10000000, + .phys_io = 0x03000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .map_io = clps7500_map_io, + .init_irq = clps7500_init_irq, + .init_machine = clps7500_init, + .timer = &clps7500_timer, MACHINE_END diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 86ffdbb5626e..23c4da10101b 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -233,13 +233,15 @@ static int __init ebsa110_init(void) arch_initcall(ebsa110_init); MACHINE_START(EBSA110, "EBSA110") - MAINTAINER("Russell King") - BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000) - BOOT_PARAMS(0x00000400) - DISABLE_PARPORT(0) - DISABLE_PARPORT(2) - SOFT_REBOOT - MAPIO(ebsa110_map_io) - INITIRQ(ebsa110_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x00000000, + .phys_io = 0xe0000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x00000400, + .reserve_lp0 = 1, + .reserve_lp2 = 1, + .soft_reboot = 1, + .map_io = ebsa110_map_io, + .init_irq = ebsa110_init_irq, .timer = &ebsa110_timer, MACHINE_END diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c index 1b40340e8a21..7daa021676d0 100644 --- a/arch/arm/mach-epxa10db/arch.c +++ b/arch/arm/mach-epxa10db/arch.c @@ -63,10 +63,12 @@ extern void epxa10db_init_irq(void); extern struct sys_timer epxa10db_timer; MACHINE_START(CAMELOT, "Altera Epxa10db") - MAINTAINER("Altera Corporation") - BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000) - MAPIO(epxa10db_map_io) - INITIRQ(epxa10db_init_irq) + /* Maintainer: Altera Corporation */ + .phys_ram = 0x00000000, + .phys_io = 0x7fffc000, + .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc, + .map_io = epxa10db_map_io, + .init_irq = epxa10db_init_irq, .timer = &epxa10db_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c index d1ced86c379c..49b898af0032 100644 --- a/arch/arm/mach-footbridge/cats-hw.c +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -84,12 +84,14 @@ fixup_cats(struct machine_desc *desc, struct tag *tags, } MACHINE_START(CATS, "Chalice-CATS") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - SOFT_REBOOT - FIXUP(fixup_cats) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Philip Blundell */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .soft_reboot = 1, + .fixup = fixup_cats, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &isa_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c index e1541914fdcd..548a79081688 100644 --- a/arch/arm/mach-footbridge/co285.c +++ b/arch/arm/mach-footbridge/co285.c @@ -28,11 +28,13 @@ fixup_coebsa285(struct machine_desc *desc, struct tag *tags, } MACHINE_START(CO285, "co-EBSA285") - MAINTAINER("Mark van Doesburg") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000) - FIXUP(fixup_coebsa285) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Mark van Doesburg */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc, + .fixup = fixup_coebsa285, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index d0931f5a63c8..1c37605268d5 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c @@ -13,12 +13,15 @@ #include "common.h" MACHINE_START(EBSA285, "EBSA285") - MAINTAINER("Russell King") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - VIDEO(0x000a0000, 0x000bffff) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .video_start = 0x000a0000, + .video_end = 0x000bffff, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index 1e1dfd79f4fe..775f85fc8513 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -647,14 +647,17 @@ fixup_netwinder(struct machine_desc *desc, struct tag *tags, } MACHINE_START(NETWINDER, "Rebel-NetWinder") - MAINTAINER("Russell King/Rebel.com") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - VIDEO(0x000a0000, 0x000bffff) - DISABLE_PARPORT(0) - DISABLE_PARPORT(2) - FIXUP(fixup_netwinder) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Russell King/Rebel.com */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .video_start = 0x000a0000, + .video_end = 0x000bffff, + .reserve_lp0 = 1, + .reserve_lp2 = 1, + .fixup = fixup_netwinder, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &isa_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c index 415086d7bbee..0146b8bb59da 100644 --- a/arch/arm/mach-footbridge/personal.c +++ b/arch/arm/mach-footbridge/personal.c @@ -13,11 +13,13 @@ #include "common.h" MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer") - MAINTAINER("Jamey Hicks / George France") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Jamey Hicks / George France */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c index 9b24b9b0db15..fa59e9e2a5c8 100644 --- a/arch/arm/mach-h720x/h7201-eval.c +++ b/arch/arm/mach-h720x/h7201-eval.c @@ -30,10 +30,12 @@ #include "common.h" MACHINE_START(H7201, "Hynix GMS30C7201") - MAINTAINER("Robert Schwebel, Pengutronix") - BOOT_MEM(0x40000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0xc0001000) - MAPIO(h720x_map_io) - INITIRQ(h720x_init_irq) - .timer = &h7201_timer, + /* Maintainer: Robert Schwebel, Pengutronix */ + .phys_ram = 0x40000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0xc0001000, + .map_io = h720x_map_io, + .init_irq = h720x_init_irq, + .timer = &h7201_timer, MACHINE_END diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c index 3456a00d5f5c..db9078ad008c 100644 --- a/arch/arm/mach-h720x/h7202-eval.c +++ b/arch/arm/mach-h720x/h7202-eval.c @@ -71,11 +71,13 @@ static void __init init_eval_h7202(void) } MACHINE_START(H7202, "Hynix HMS30C7202") - MAINTAINER("Robert Schwebel, Pengutronix") - BOOT_MEM(0x40000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0x40000100) - MAPIO(h720x_map_io) - INITIRQ(h7202_init_irq) - .timer = &h7202_timer, - INIT_MACHINE(init_eval_h7202) + /* Maintainer: Robert Schwebel, Pengutronix */ + .phys_ram = 0x40000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0x40000100, + .map_io = h720x_map_io, + .init_irq = h7202_init_irq, + .timer = &h7202_timer, + .init_machine = init_eval_h7202, MACHINE_END diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index 625dd01c2578..5d25434d332c 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -78,11 +78,13 @@ mx1ads_map_io(void) } MACHINE_START(MX1ADS, "Motorola MX1ADS") - MAINTAINER("Sascha Hauer, Pengutronix") - BOOT_MEM(0x08000000, 0x00200000, 0xe0200000) - BOOT_PARAMS(0x08000100) - MAPIO(mx1ads_map_io) - INITIRQ(imx_init_irq) + /* Maintainer: Sascha Hauer, Pengutronix */ + .phys_ram = 0x08000000, + .phys_io = 0x00200000, + .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, + .boot_params = 0x08000100, + .map_io = mx1ads_map_io, + .init_irq = imx_init_irq, .timer = &imx_timer, - INIT_MACHINE(mx1ads_init) + .init_machine = mx1ads_init, MACHINE_END diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 9222e57bd872..dacbf504dae2 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -20,6 +20,7 @@ #include <asm/irq.h> #include <asm/io.h> #include <asm/hardware/amba.h> +#include <asm/hardware/arm_timer.h> #include <asm/arch/cm.h> #include <asm/system.h> #include <asm/leds.h> @@ -156,16 +157,6 @@ EXPORT_SYMBOL(cm_control); #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - static unsigned long timer_reload; /* @@ -174,7 +165,6 @@ static unsigned long timer_reload; */ unsigned long integrator_gettimeoffset(void) { - volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE; unsigned long ticks1, ticks2, status; /* @@ -183,11 +173,11 @@ unsigned long integrator_gettimeoffset(void) * an interrupt. We get around this by ensuring that the * counter has not reloaded between our two reads. */ - ticks2 = timer1->TimerValue & 0xffff; + ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; do { ticks1 = ticks2; status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); - ticks2 = timer1->TimerValue & 0xffff; + ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; } while (ticks2 > ticks1); /* @@ -213,14 +203,12 @@ unsigned long integrator_gettimeoffset(void) static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - write_seqlock(&xtime_lock); /* * clear the interrupt */ - timer1->TimerClear = 1; + writel(1, TIMER1_VA_BASE + TIMER_INTCLR); /* * the clock tick routines are only processed on the @@ -256,32 +244,29 @@ static struct irqaction integrator_timer_irq = { */ void __init integrator_time_init(unsigned long reload, unsigned int ctrl) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */ + unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; timer_reload = reload; timer_ctrl |= ctrl; if (timer_reload > 0x100000) { timer_reload >>= 8; - timer_ctrl |= 0x08; /* /256 */ + timer_ctrl |= TIMER_CTRL_DIV256; } else if (timer_reload > 0x010000) { timer_reload >>= 4; - timer_ctrl |= 0x04; /* /16 */ + timer_ctrl |= TIMER_CTRL_DIV16; } /* * Initialise to a known state (all timers off) */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); - timer1->TimerLoad = timer_reload; - timer1->TimerValue = timer_reload; - timer1->TimerControl = timer_ctrl; + writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD); + writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE); + writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL); /* * Make irqs happen for the system timer diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 91ba9fd79c87..36e2b6eb67b7 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -292,11 +292,13 @@ static struct sys_timer ap_timer = { }; MACHINE_START(INTEGRATOR, "ARM-Integrator") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) - BOOT_PARAMS(0x00000100) - MAPIO(ap_map_io) - INITIRQ(ap_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x16000000, + .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ap_map_io, + .init_irq = ap_init_irq, .timer = &ap_timer, - INIT_MACHINE(ap_init) + .init_machine = ap_init, MACHINE_END diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index e0a01eef0993..569f328c479d 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -532,11 +532,13 @@ static struct sys_timer cp_timer = { }; MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) - BOOT_PARAMS(0x00000100) - MAPIO(intcp_map_io) - INITIRQ(intcp_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x16000000, + .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = intcp_map_io, + .init_irq = intcp_init_irq, .timer = &cp_timer, - INIT_MACHINE(intcp_init) + .init_machine = intcp_init, MACHINE_END diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c index bf23e0fd2843..0f921ba2750c 100644 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ b/arch/arm/mach-iop3xx/iop321-setup.c @@ -146,23 +146,27 @@ extern void iop321_init_time(void); #if defined(CONFIG_ARCH_IQ80321) MACHINE_START(IQ80321, "Intel IQ80321") - MAINTAINER("Intel Corporation") - BOOT_MEM(PHYS_OFFSET, IQ80321_UART, IQ80321_UART) - MAPIO(iq80321_map_io) - INITIRQ(iop321_init_irq) + /* Maintainer: Intel Corporation */ + .phys_ram = PHYS_OFFSET, + .phys_io = IQ80321_UART, + .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, + .map_io = iq80321_map_io, + .init_irq = iop321_init_irq, .timer = &iop321_timer, - BOOT_PARAMS(0xa0000100) - INIT_MACHINE(iop32x_init) + .boot_params = 0xa0000100, + .init_machine = iop32x_init, MACHINE_END #elif defined(CONFIG_ARCH_IQ31244) MACHINE_START(IQ31244, "Intel IQ31244") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, IQ31244_UART, IQ31244_UART) - MAPIO(iq31244_map_io) - INITIRQ(iop321_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IQ31244_UART, + .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, + .map_io = iq31244_map_io, + .init_irq = iop321_init_irq, .timer = &iop321_timer, - BOOT_PARAMS(0xa0000100) - INIT_MACHINE(iop32x_init) + .boot_params = 0xa0000100, + .init_machine = iop32x_init, MACHINE_END #else #error No machine descriptor defined for this IOP3XX implementation diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index 622e7914819a..fc74b722f72f 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -148,26 +148,28 @@ extern void iq80332_map_io(void); #if defined(CONFIG_ARCH_IQ80331) MACHINE_START(IQ80331, "Intel IQ80331") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical - //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS) - MAPIO(iq80331_map_io) - INITIRQ(iop331_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80331_map_io, + .init_irq = iop331_init_irq, .timer = &iop331_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(iop33x_init) + .boot_params = 0x0100, + .init_machine = iop33x_init, MACHINE_END #elif defined(CONFIG_MACH_IQ80332) MACHINE_START(IQ80332, "Intel IQ80332") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical - //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS) - MAPIO(iq80332_map_io) - INITIRQ(iop331_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80332_map_io, + .init_irq = iop331_init_irq, .timer = &iop331_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(iop33x_init) + .boot_params = 0x0100, + .init_machine = iop33x_init, MACHINE_END #else diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index f3a291b6a9fb..b7ebf3898fc5 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -223,13 +223,15 @@ static void __init enp2611_init_machine(void) MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board") - MAINTAINER("Lennert Buytenhek <buytenh@wantstofly.org>") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixp2000_map_io) - INITIRQ(ixp2000_init_irq) + /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixp2000_map_io, + .init_irq = ixp2000_init_irq, .timer = &enp2611_timer, - INIT_MACHINE(enp2611_init_machine) + .init_machine = enp2611_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index df3ff26c8cdd..fd280a93637e 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -168,12 +168,14 @@ void ixdp2400_init_irq(void) } MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x00_map_io) - INITIRQ(ixdp2400_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x00_map_io, + .init_irq = ixdp2400_init_irq, .timer = &ixdp2400_timer, - INIT_MACHINE(ixdp2x00_init_machine) + .init_machine = ixdp2x00_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index 468a4bbfb724..f9073aa28615 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -284,12 +284,14 @@ void ixdp2800_init_irq(void) } MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x00_map_io) - INITIRQ(ixdp2800_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x00_map_io, + .init_irq = ixdp2800_init_irq, .timer = &ixdp2800_timer, - INIT_MACHINE(ixdp2x00_init_machine) + .init_machine = ixdp2x00_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index e94dace3d412..c73588743ee1 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -375,25 +375,29 @@ static void __init ixdp2x01_init_machine(void) #ifdef CONFIG_ARCH_IXDP2401 MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x01_map_io) - INITIRQ(ixdp2x01_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, .timer = &ixdp2x01_timer, - INIT_MACHINE(ixdp2x01_init_machine) + .init_machine = ixdp2x01_init_machine, MACHINE_END #endif #ifdef CONFIG_ARCH_IXDP2801 MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x01_map_io) - INITIRQ(ixdp2x01_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, .timer = &ixdp2x01_timer, - INIT_MACHINE(ixdp2x01_init_machine) + .init_machine = ixdp2x01_init_machine, MACHINE_END #endif diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index aa92e3708838..2b544363c078 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -453,8 +453,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); res[0].name = "PCI I/O Space"; - res[0].start = 0x00001000; - res[0].end = 0xffff0000; + res[0].start = 0x00000000; + res[0].end = 0x0000ffff; res[0].flags = IORESOURCE_IO; res[1].name = "PCI Memory Space"; diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 8a05a1227e5f..4ff4393ef0ea 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -56,21 +56,24 @@ static struct resource coyote_uart_resource = { .flags = IORESOURCE_MEM, }; -static struct plat_serial8250_port coyote_uart_data = { - .mapbase = IXP4XX_UART2_BASE_PHYS, - .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, - .irq = IRQ_IXP4XX_UART2, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IXP4XX_UART_XTAL, +static struct plat_serial8250_port coyote_uart_data[] = { + { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { }, }; static struct platform_device coyote_uart = { .name = "serial8250", .id = 0, .dev = { - .platform_data = &coyote_uart_data, + .platform_data = coyote_uart_data, }, .num_resources = 1, .resource = &coyote_uart_resource, @@ -87,10 +90,10 @@ static void __init coyote_init(void) *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; if (machine_is_ixdpg425()) { - coyote_uart_data.membase = + coyote_uart_data[0].membase = (char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET); - coyote_uart_data.mapbase = IXP4XX_UART1_BASE_PHYS; - coyote_uart_data.irq = IRQ_IXP4XX_UART1; + coyote_uart_data[0].mapbase = IXP4XX_UART1_BASE_PHYS; + coyote_uart_data[0].irq = IRQ_IXP4XX_UART1; } @@ -100,14 +103,15 @@ static void __init coyote_init(void) #ifdef CONFIG_ARCH_ADI_COYOTE MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(coyote_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = coyote_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(coyote_init) + .boot_params = 0x0100, + .init_machine = coyote_init, MACHINE_END #endif @@ -117,14 +121,15 @@ MACHINE_END */ #ifdef CONFIG_MACH_IXDPG425 MACHINE_START(IXDPG425, "Intel IXDPG425") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(coyote_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = coyote_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(coyote_init) + .boot_params = 0x0100, + .init_machine = coyote_init, MACHINE_END #endif diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index e77c86efd21d..8ba1cd9406e7 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -140,14 +140,15 @@ static void __init gtwx5715_init(void) MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)") - MAINTAINER("George Joseph") - BOOT_MEM(PHYS_OFFSET, IXP4XX_UART2_BASE_PHYS, - IXP4XX_UART2_BASE_VIRT) - MAPIO(gtwx5715_map_io) - INITIRQ(ixp4xx_init_irq) - .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(gtwx5715_init) + /* Maintainer: George Joseph */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_UART2_BASE_PHYS, + .io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc, + .map_io = gtwx5715_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, + .boot_params = 0x0100, + .init_machine = gtwx5715_init, MACHINE_END diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 77346c1f676b..c2ba759e9946 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -95,7 +95,8 @@ static struct plat_serial8250_port ixdp425_uart_data[] = { .iotype = UPIO_MEM, .regshift = 2, .uartclk = IXP4XX_UART_XTAL, - } + }, + { }, }; static struct platform_device ixdp425_uart = { @@ -128,36 +129,39 @@ static void __init ixdp425_init(void) } MACHINE_START(IXDP425, "Intel IXDP425 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END MACHINE_START(IXDP465, "Intel IXDP465 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END /* @@ -168,14 +172,15 @@ MACHINE_END */ #ifdef CONFIG_ARCH_AVILA MACHINE_START(AVILA, "Gateworks Avila Network Platform") - MAINTAINER("Deepak Saxena <dsaxena@plexity.net>") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END #endif diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c index 606ca95f8217..2a7fee2a7635 100644 --- a/arch/arm/mach-l7200/core.c +++ b/arch/arm/mach-l7200/core.c @@ -81,9 +81,11 @@ static void __init l7200_map_io(void) } MACHINE_START(L7200, "LinkUp Systems L7200") - MAINTAINER("Steve Hill / Scott McConnell") - BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000) - MAPIO(l7200_map_io) - INITIRQ(l7200_init_irq) + /* Maintainer: Steve Hill / Scott McConnell */ + .phys_ram = 0xf0000000, + .phys_io = 0x80040000, + .io_pg_offst = ((0xd0000000) >> 18) & 0xfffc, + .map_io = l7200_map_io, + .init_irq = l7200_init_irq, MACHINE_END diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c index be5d17fe9dcb..cb3dcd3bd00a 100644 --- a/arch/arm/mach-lh7a40x/arch-kev7a400.c +++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c @@ -102,10 +102,12 @@ void __init lh7a40x_init_board_irq (void) } MACHINE_START (KEV7A400, "Sharp KEV7a400") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (kev7a400_map_io) - INITIRQ (lh7a400_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = kev7a400_map_io, + .init_irq = lh7a400_init_irq, .timer = &lh7a40x_timer, MACHINE_END diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index c823447a150f..6eb61a17c63b 100644 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c @@ -260,13 +260,15 @@ lpd7a400_map_io(void) #ifdef CONFIG_MACH_LPD7A400 MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (lpd7a400_map_io) - INITIRQ (lh7a400_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lpd7a400_map_io, + .init_irq = lh7a400_init_irq, .timer = &lh7a40x_timer, - INIT_MACHINE (lpd7a40x_init) + .init_machine = lpd7a40x_init, MACHINE_END #endif @@ -274,13 +276,15 @@ MACHINE_END #ifdef CONFIG_MACH_LPD7A404 MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (lpd7a400_map_io) - INITIRQ (lh7a404_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lpd7a400_map_io, + .init_irq = lh7a404_init_irq, .timer = &lh7a40x_timer, - INIT_MACHINE (lpd7a40x_init) + .init_machine = lpd7a40x_init, MACHINE_END #endif diff --git a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap/board-generic.c index 2102a2cd1013..384bc7cec1db 100644 --- a/arch/arm/mach-omap/board-generic.c +++ b/arch/arm/mach-omap/board-generic.c @@ -88,11 +88,13 @@ static void __init omap_generic_map_io(void) } MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") - MAINTAINER("Tony Lindgren <tony@atomide.com>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(omap_generic_map_io) - INITIRQ(omap_generic_init_irq) - INIT_MACHINE(omap_generic_init) + /* Maintainer: Tony Lindgren <tony@atomide.com> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = omap_generic_map_io, + .init_irq = omap_generic_init_irq, + .init_machine = omap_generic_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-h2.c b/arch/arm/mach-omap/board-h2.c index 1f067830d1fc..f37c76a9b163 100644 --- a/arch/arm/mach-omap/board-h2.c +++ b/arch/arm/mach-omap/board-h2.c @@ -177,11 +177,13 @@ static void __init h2_map_io(void) } MACHINE_START(OMAP_H2, "TI-H2") - MAINTAINER("Imre Deak <imre.deak@nokia.com>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(h2_map_io) - INITIRQ(h2_init_irq) - INIT_MACHINE(h2_init) + /* Maintainer: Imre Deak <imre.deak@nokia.com> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = h2_map_io, + .init_irq = h2_init_irq, + .init_machine = h2_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-h3.c b/arch/arm/mach-omap/board-h3.c index 486a5a006c9a..705e48594e9a 100644 --- a/arch/arm/mach-omap/board-h3.c +++ b/arch/arm/mach-omap/board-h3.c @@ -195,11 +195,13 @@ static void __init h3_map_io(void) } MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") - MAINTAINER("Texas Instruments, Inc.") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(h3_map_io) - INITIRQ(h3_init_irq) - INIT_MACHINE(h3_init) + /* Maintainer: Texas Instruments, Inc. */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = h3_map_io, + .init_irq = h3_init_irq, + .init_machine = h3_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c index 57cf4da88d55..523363f18cc0 100644 --- a/arch/arm/mach-omap/board-innovator.c +++ b/arch/arm/mach-omap/board-innovator.c @@ -270,11 +270,13 @@ static void __init innovator_map_io(void) } MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(innovator_map_io) - INITIRQ(innovator_init_irq) - INIT_MACHINE(innovator_init) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = innovator_map_io, + .init_irq = innovator_init_irq, + .init_machine = innovator_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-netstar.c b/arch/arm/mach-omap/board-netstar.c index 54acbd215c4b..8c653734d5a3 100644 --- a/arch/arm/mach-omap/board-netstar.c +++ b/arch/arm/mach-omap/board-netstar.c @@ -141,11 +141,13 @@ static int __init netstar_late_init(void) postcore_initcall(netstar_late_init); MACHINE_START(NETSTAR, "NetStar OMAP5910") - MAINTAINER("Ladislav Michl <michl@2n.cz>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(netstar_map_io) - INITIRQ(netstar_init_irq) - INIT_MACHINE(netstar_init) - .timer = &omap_timer, + /* Maintainer: Ladislav Michl <michl@2n.cz> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = netstar_map_io, + .init_irq = netstar_init_irq, + .init_machine = netstar_init, + .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c index a951fc82459b..cb433436aa08 100644 --- a/arch/arm/mach-omap/board-osk.c +++ b/arch/arm/mach-omap/board-osk.c @@ -159,11 +159,13 @@ static void __init osk_map_io(void) } MACHINE_START(OMAP_OSK, "TI-OSK") - MAINTAINER("Dirk Behme <dirk.behme@de.bosch.com>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(osk_map_io) - INITIRQ(osk_init_irq) - INIT_MACHINE(osk_init) + /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = osk_map_io, + .init_irq = osk_init_irq, + .init_machine = osk_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c index 64515aeb49cf..d5342043d48f 100644 --- a/arch/arm/mach-omap/board-perseus2.c +++ b/arch/arm/mach-omap/board-perseus2.c @@ -179,11 +179,13 @@ static void __init omap_perseus2_map_io(void) } MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") - MAINTAINER("Kevin Hilman <kjh@hilman.org>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(omap_perseus2_map_io) - INITIRQ(omap_perseus2_init_irq) - INIT_MACHINE(omap_perseus2_init) + /* Maintainer: Kevin Hilman <kjh@hilman.org> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = omap_perseus2_map_io, + .init_irq = omap_perseus2_init_irq, + .init_machine = omap_perseus2_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-voiceblue.c b/arch/arm/mach-omap/board-voiceblue.c index f1a5bffac666..6b0c5003d719 100644 --- a/arch/arm/mach-omap/board-voiceblue.c +++ b/arch/arm/mach-omap/board-voiceblue.c @@ -246,11 +246,13 @@ EXPORT_SYMBOL(voiceblue_wdt_disable); EXPORT_SYMBOL(voiceblue_wdt_ping); MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") - MAINTAINER("Ladislav Michl <michl@2n.cz>") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(voiceblue_map_io) - INITIRQ(voiceblue_init_irq) - INIT_MACHINE(voiceblue_init) - .timer = &omap_timer, + /* Maintainer: Ladislav Michl <michl@2n.cz> */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = voiceblue_map_io, + .init_irq = voiceblue_init_irq, + .init_machine = voiceblue_init, + .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c index 00fac155df2a..6b03ccdc1e92 100644 --- a/arch/arm/mach-omap/pm.c +++ b/arch/arm/mach-omap/pm.c @@ -41,7 +41,9 @@ #include <linux/pm.h> #include <asm/io.h> +#include <asm/mach/time.h> #include <asm/mach-types.h> + #include <asm/arch/omap16xx.h> #include <asm/arch/pm.h> #include <asm/arch/mux.h> @@ -80,13 +82,13 @@ void omap_pm_idle(void) return; } mask32 = omap_readl(ARM_SYSST); - local_fiq_enable(); - local_irq_enable(); -#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ) - /* Override timer to use VST for the next cycle */ - omap_32k_timer_next_vst_interrupt(); -#endif + /* + * Since an interrupt may set up a timer, we don't want to + * reprogram the hardware timer with interrupts enabled. + * Re-enable interrupts only after returning from idle. + */ + timer_dyn_reprogram(); if ((mask32 & DSP_IDLE) == 0) { __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); @@ -102,6 +104,8 @@ void omap_pm_idle(void) func_ptr(); } + local_fiq_enable(); + local_irq_enable(); } /* diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c index 589e8b2740dd..dd34e9f4c413 100644 --- a/arch/arm/mach-omap/time.c +++ b/arch/arm/mach-omap/time.c @@ -4,7 +4,7 @@ * OMAP Timers * * Copyright (C) 2004 Nokia Corporation - * Partial timer rewrite and additional VST timer support by + * Partial timer rewrite and additional dynamic tick timer support by * Tony Lindgen <tony@atomide.com> and * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> * @@ -261,7 +261,6 @@ unsigned long long sched_clock(void) * so with HZ = 100, TVR = 327.68. */ #define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) -#define MAX_SKIP_JIFFIES 25 #define TIMER_32K_SYNCHRONIZED 0xfffbc410 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ @@ -347,6 +346,42 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, return IRQ_HANDLED; } +#ifdef CONFIG_NO_IDLE_HZ +/* + * Programs the next timer interrupt needed. Called when dynamic tick is + * enabled, and to reprogram the ticks to skip from pm_idle. Note that + * we can keep the timer continuous, and don't need to set it to run in + * one-shot mode. This is because the timer will get reprogrammed again + * after next interrupt. + */ +void omap_32k_timer_reprogram(unsigned long next_tick) +{ + omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); +} + +static struct irqaction omap_32k_timer_irq; +extern struct timer_update_handler timer_update; + +static int omap_32k_timer_enable_dyn_tick(void) +{ + /* No need to reprogram timer, just use the next interrupt */ + return 0; +} + +static int omap_32k_timer_disable_dyn_tick(void) +{ + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); + return 0; +} + +static struct dyn_tick_timer omap_dyn_tick_timer = { + .enable = omap_32k_timer_enable_dyn_tick, + .disable = omap_32k_timer_disable_dyn_tick, + .reprogram = omap_32k_timer_reprogram, + .handler = omap_32k_timer_interrupt, +}; +#endif /* CONFIG_NO_IDLE_HZ */ + static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", .flags = SA_INTERRUPT | SA_TIMER, @@ -355,6 +390,11 @@ static struct irqaction omap_32k_timer_irq = { static __init void omap_init_32k_timer(void) { + +#ifdef CONFIG_NO_IDLE_HZ + omap_timer.dyn_tick = &omap_dyn_tick_timer; +#endif + setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); omap_timer.offset = omap_32k_timer_gettimeoffset; omap_32k_last_tick = omap_32k_sync_timer_read(); diff --git a/arch/arm/mach-omap/usb.c b/arch/arm/mach-omap/usb.c index 7f37857b1a28..fd483ff9f8fe 100644 --- a/arch/arm/mach-omap/usb.c +++ b/arch/arm/mach-omap/usb.c @@ -41,7 +41,6 @@ /* These routines should handle the standard chip-specific modes * for usb0/1/2 ports, covering basic mux and transceiver setup. - * Call omap_usb_init() once, from INIT_MACHINE(). * * Some board-*.c files will need to set up additional mux options, * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c4e6d2523585..efc2f657184e 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -24,3 +24,7 @@ obj-$(CONFIG_LEDS) += $(led-y) # Misc features obj-$(CONFIG_PM) += pm.o sleep.o + +ifeq ($(CONFIG_PXA27x),y) +obj-$(CONFIG_PM) += standby.o +endif diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index f691cf77d390..86b862f56e7e 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -287,34 +287,40 @@ static void __init corgi_map_io(void) #ifdef CONFIG_MACH_CORGI MACHINE_START(CORGI, "SHARP Corgi") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif #ifdef CONFIG_MACH_SHEPHERD MACHINE_START(SHEPHERD, "SHARP Shepherd") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif #ifdef CONFIG_MACH_HUSKY MACHINE_START(HUSKY, "SHARP Husky") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index c5a66bf4d3d5..386e107b53cc 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -181,10 +181,12 @@ static void __init idp_map_io(void) MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") - MAINTAINER("Vibren Technologies") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(idp_map_io) - INITIRQ(idp_init_irq) + /* Maintainer: Vibren Technologies */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = idp_map_io, + .init_irq = idp_init_irq, .timer = &pxa_timer, - INIT_MACHINE(idp_init) + .init_machine = idp_init, MACHINE_END diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index f2c9e0d2b24b..6309853b59be 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -268,10 +268,12 @@ static void __init lubbock_map_io(void) } MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") - MAINTAINER("MontaVista Software Inc.") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(lubbock_map_io) - INITIRQ(lubbock_init_irq) + /* Maintainer: MontaVista Software Inc. */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = lubbock_map_io, + .init_irq = lubbock_init_irq, .timer = &pxa_timer, - INIT_MACHINE(lubbock_init) + .init_machine = lubbock_init, MACHINE_END diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 9896afca751f..827b7b5a5be8 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -345,10 +345,12 @@ static void __init mainstone_map_io(void) } MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") - MAINTAINER("MontaVista Software Inc.") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(mainstone_map_io) - INITIRQ(mainstone_init_irq) + /* Maintainer: MontaVista Software Inc. */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = mainstone_map_io, + .init_irq = mainstone_init_irq, .timer = &pxa_timer, - INIT_MACHINE(mainstone_init) + .init_machine = mainstone_init, MACHINE_END diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index b6c746ea3830..0e4f6fab100a 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -180,10 +180,12 @@ static void __init poodle_map_io(void) } MACHINE_START(POODLE, "SHARP Poodle") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_poodle) - MAPIO(poodle_map_io) - INITIRQ(pxa_init_irq) - .timer = &pxa_timer, - .init_machine = poodle_init, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .fixup = fixup_poodle, + .map_io = poodle_map_io, + .init_irq = pxa_init_irq, + .timer = &pxa_timer, + .init_machine = poodle_init, MACHINE_END diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 893964fb9659..9a791b07118d 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -126,6 +126,7 @@ int pxa_cpu_pm_prepare(suspend_state_t state) { switch (state) { case PM_SUSPEND_MEM: + case PM_SUSPEND_STANDBY: return 0; default: return -EINVAL; @@ -138,7 +139,10 @@ void pxa_cpu_pm_enter(suspend_state_t state) extern void pxa_cpu_suspend(unsigned int); extern void pxa_cpu_resume(void); - CKEN = CKEN22_MEMC | CKEN9_OSTIMER; + if (state == PM_SUSPEND_STANDBY) + CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0; + else + CKEN = CKEN22_MEMC | CKEN9_OSTIMER; /* ensure voltage-change sequencer not initiated, which hangs */ PCFR &= ~PCFR_FVC; @@ -147,6 +151,9 @@ void pxa_cpu_pm_enter(suspend_state_t state) PEDR = 0xDF12FE1B; switch (state) { + case PM_SUSPEND_STANDBY: + pxa_cpu_standby(); + break; case PM_SUSPEND_MEM: /* set resume return address */ PSPR = virt_to_phys(pxa_cpu_resume); diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S new file mode 100644 index 000000000000..8a3f27b76784 --- /dev/null +++ b/arch/arm/mach-pxa/standby.S @@ -0,0 +1,32 @@ +/* + * PXA27x standby mode + * + * Author: David Burrage + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> + +#include <asm/arch/pxa-regs.h> + + .text + +ENTRY(pxa_cpu_standby) + ldr r0, =PSSR + mov r1, #(PSSR_PH | PSSR_STS) + mov r2, #2 + mov r3, #UNCACHED_PHYS_0 @ Read mem context in. + ldr ip, [r3] + b 1f + + .align 5 +1: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby + str r1, [r0] @ make sure PSSR_PH/STS are clear + mov pc, lr diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 437106881436..a10268618f74 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -163,12 +163,14 @@ arch_initcall(rpc_init); extern struct sys_timer ioc_timer; MACHINE_START(RISCPC, "Acorn-RiscPC") - MAINTAINER("Russell King") - BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) - BOOT_PARAMS(0x10000100) - DISABLE_PARPORT(0) - DISABLE_PARPORT(1) - MAPIO(rpc_map_io) - INITIRQ(rpc_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x10000000, + .phys_io = 0x03000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .reserve_lp0 = 1, + .reserve_lp1 = 1, + .map_io = rpc_map_io, + .init_irq = rpc_init_irq, .timer = &ioc_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 534df0c6c770..d4d03d0daaec 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -154,6 +154,11 @@ config S3C2410_PM_CHECK_CHUNKSIZE the CRC data block will take more memory, but wil identify any faults with better precision. +config PM_SIMTEC + bool + depends on PM && (ARCH_BAST || MACH_VR1000) + default y + config S3C2410_LOWLEVEL_UART_PORT int "S3C2410 UART to use for low-level messages" default 0 diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 7c379aad5d62..f99b689e4392 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o # Power Management support obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o # S3C2440 support diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index 64792f678668..4664bd11adc1 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c @@ -96,8 +96,8 @@ struct platform_device s3c_device_lcd = { .num_resources = ARRAY_SIZE(s3c_lcd_resource), .resource = s3c_lcd_resource, .dev = { - .dma_mask = &s3c_device_lcd_dmamask, - .coherent_dma_mask = 0xffffffffUL + .dma_mask = &s3c_device_lcd_dmamask, + .coherent_dma_mask = 0xffffffffUL } }; diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index b668c48f4399..cf9f46d88061 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -40,8 +40,11 @@ * 04-Nov-2004 Ben Dooks * Fix standard IRQ wake for EINT0..4 and RTC * - * 22-Feb-2004 Ben Dooks + * 22-Feb-2005 Ben Dooks * Fixed edge-triggering on ADC IRQ + * + * 28-Jun-2005 Ben Dooks + * Mark IRQ_LCD valid */ #include <linux/init.h> @@ -366,7 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = { #define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) -#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) static inline void s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, @@ -716,7 +718,6 @@ void __init s3c24xx_init_irq(void) case IRQ_UART0: case IRQ_UART1: case IRQ_UART2: - case IRQ_LCD: case IRQ_ADCPARENT: set_irq_chip(irqno, &s3c_irq_level_chip); set_irq_handler(irqno, do_level_IRQ); diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index f3e970039b65..ccb6bcefa46c 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -27,6 +27,7 @@ * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 14-Mar-2006 BJD Updated for __iomem changes * 22-Jun-2006 BJD Added DM9000 platform information + * 28-Jun-2006 BJD Moved pm functionality out to common code */ #include <linux/kernel.h> @@ -67,7 +68,6 @@ #include "devs.h" #include "cpu.h" #include "usb-simtec.h" -#include "pm.h" #define COPYRIGHT ", (c) 2004-2005 Simtec Electronics" @@ -405,44 +405,14 @@ void __init bast_map_io(void) usb_simtec_init(); } -void __init bast_init_irq(void) -{ - s3c24xx_init_irq(); -} - -#ifdef CONFIG_PM - -/* bast_init_machine - * - * enable the power management functions for the EB2410ITX -*/ - -static __init void bast_init_machine(void) -{ - unsigned long gstatus4; - - printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n"); - - gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; - gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; - gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); - - __raw_writel(gstatus4, S3C2410_GSTATUS4); - - s3c2410_pm_init(); -} - -#else -#define bast_init_machine NULL -#endif - MACHINE_START(BAST, "Simtec-BAST") - MAINTAINER("Ben Dooks <ben@simtec.co.uk>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(bast_map_io) - INITIRQ(bast_init_irq) - .init_machine = bast_init_machine, + /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = bast_map_io, + .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 2924afc068a4..ea4fb1a97a50 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -117,10 +117,12 @@ void __init h1940_init_irq(void) } MACHINE_START(H1940, "IPAQ-H1940") - MAINTAINER("Ben Dooks <ben@fluff.org>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(h1940_map_io) - INITIRQ(h1940_init_irq) + /* Maintainer: Ben Dooks <ben@fluff.org> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = h1940_map_io, + .init_irq = h1940_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index bd15998c129b..79044d9bce38 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -137,10 +137,11 @@ void __init n30_init(void) } MACHINE_START(N30, "Acer-N30") - MAINTAINER("Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - + /* Maintainer: Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .timer = &s3c24xx_timer, .init_machine = n30_init, .init_irq = n30_init_irq, diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c index 70487bf4b71e..d24c242414ca 100644 --- a/arch/arm/mach-s3c2410/mach-nexcoder.c +++ b/arch/arm/mach-s3c2410/mach-nexcoder.c @@ -147,9 +147,11 @@ void __init nexcoder_map_io(void) MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") - MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = nexcoder_map_io, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index 67d8ce8fb00f..d901ed492ff5 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c @@ -115,9 +115,11 @@ void __init otom11_map_io(void) MACHINE_START(OTOM, "Nex Vision - Otom 1.1") - MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = otom11_map_io, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index f8d3a9784e71..a73d61c1de46 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c @@ -131,11 +131,13 @@ static void __init rx3715_init_machine(void) #endif MACHINE_START(RX3715, "IPAQ-RX3715") - MAINTAINER("Ben Dooks <ben@fluff.org>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(rx3715_map_io) - INITIRQ(rx3715_init_irq) - INIT_MACHINE(rx3715_init_machine) + /* Maintainer: Ben Dooks <ben@fluff.org> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = rx3715_map_io, + .init_irq = rx3715_init_irq, + .init_machine = rx3715_init_machine, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index c1a4a1420ea0..67e903a700d3 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -112,11 +112,13 @@ void __init smdk2410_init_irq(void) MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch * to SMDK2410 */ - MAINTAINER("Jonas Dietsche") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(smdk2410_map_io) - INITIRQ(smdk2410_init_irq) + /* Maintainer: Jonas Dietsche */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = smdk2410_map_io, + .init_irq = smdk2410_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index 7857176d9bcb..357522106f68 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -124,9 +124,11 @@ void __init smdk2440_machine_init(void) } MACHINE_START(S3C2440, "SMDK2440") - MAINTAINER("Ben Dooks <ben@fluff.org>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Ben Dooks <ben@fluff.org> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .init_irq = s3c24xx_init_irq, .map_io = smdk2440_map_io, diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 76be074944a0..924e8464c212 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -371,16 +371,14 @@ void __init vr1000_map_io(void) usb_simtec_init(); } -void __init vr1000_init_irq(void) -{ - s3c24xx_init_irq(); -} MACHINE_START(VR1000, "Thorcom-VR1000") - MAINTAINER("Ben Dooks <ben@simtec.co.uk>") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(vr1000_map_io) - INITIRQ(vr1000_init_irq) + /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = vr1000_map_io, + .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c new file mode 100644 index 000000000000..2cb798832223 --- /dev/null +++ b/arch/arm/mach-s3c2410/pm-simtec.c @@ -0,0 +1,65 @@ +/* linux/arch/arm/mach-s3c2410/pm-simtec.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://armlinux.simtec.co.uk/ + * + * Power Management helpers for Simtec S3C24XX implementations + * + * 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 <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/hardware.h> +#include <asm/io.h> + +#include <asm/arch/map.h> +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-mem.h> + +#include <asm/mach-types.h> + +#include "pm.h" + +#define COPYRIGHT ", (c) 2005 Simtec Electronics" + +/* pm_simtec_init + * + * enable the power management functions +*/ + +static __init int pm_simtec_init(void) +{ + unsigned long gstatus4; + + /* check which machine we are running on */ + + if (!machine_is_bast() && !machine_is_vr1000()) + return 0; + + printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); + + gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; + gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; + gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); + + __raw_writel(gstatus4, S3C2410_GSTATUS4); + + return s3c2410_pm_init(); +} + +arch_initcall(pm_simtec_init); diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index bedf88fafe08..4d4d303ee3a8 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -431,11 +431,13 @@ static void __init assabet_map_io(void) MACHINE_START(ASSABET, "Intel-Assabet") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_assabet) - MAPIO(assabet_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_assabet, + .map_io = assabet_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = assabet_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index 6a60b497ab42..b6169cb09196 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -285,9 +285,11 @@ static void __init badge4_map_io(void) } MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(badge4_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = badge4_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index f8edde5e7cbf..0aa918e24c31 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -123,10 +123,12 @@ static void __init cerf_init(void) } MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube") - MAINTAINER("support@intrinsyc.com") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(cerf_map_io) - INITIRQ(cerf_init_irq) + /* Maintainer: support@intrinsyc.com */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = cerf_map_io, + .init_irq = cerf_init_irq, .timer = &sa1100_timer, .init_machine = cerf_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 99287890d396..8cb69113a57c 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -184,9 +184,11 @@ static void __init collie_map_io(void) } MACHINE_START(COLLIE, "Sharp-Collie") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(collie_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = collie_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = collie_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 8d2a89a2ea01..04c94ab6c18b 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -271,8 +271,7 @@ static int sa1110_target(struct cpufreq_policy *policy, */ sdram_set_refresh(2); if (!irqs_disabled()) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(20 * HZ / 1000); + msleep(20); } else { mdelay(20); } diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index 65dbe991426d..e7aa2681ca64 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -380,10 +380,12 @@ static void __init h3100_map_io(void) } MACHINE_START(H3100, "Compaq iPAQ H3100") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3100_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3100_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END @@ -496,10 +498,12 @@ static void __init h3600_map_io(void) } MACHINE_START(H3600, "Compaq iPAQ H3600") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3600_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3600_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END @@ -881,10 +885,12 @@ static void __init h3800_map_io(void) } MACHINE_START(H3800, "Compaq iPAQ H3800") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3800_map_io) - INITIRQ(h3800_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3800_map_io, + .init_irq = h3800_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c index 570841779714..502d65cfe654 100644 --- a/arch/arm/mach-sa1100/hackkit.c +++ b/arch/arm/mach-sa1100/hackkit.c @@ -191,10 +191,12 @@ static void __init hackkit_init(void) */ MACHINE_START(HACKKIT, "HackKit Cpu Board") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(hackkit_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = hackkit_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = hackkit_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 6be78291a878..eee3cbc5ec4f 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -97,9 +97,11 @@ static void __init jornada720_map_io(void) } MACHINE_START(JORNADA720, "HP Jornada 720") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(jornada720_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = jornada720_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index 51c08ccfb8db..870b488aeda4 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c @@ -41,9 +41,11 @@ static void __init lart_map_io(void) } MACHINE_START(LART, "LART") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(lart_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lart_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 5606bd71b024..e17b58fb9c9c 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c @@ -146,9 +146,11 @@ static void __init pleb_map_io(void) } MACHINE_START(PLEB, "PLEB") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(pleb_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = pleb_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = pleb_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index edddd559be02..43a00359fcdd 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c @@ -76,10 +76,12 @@ static void __init shannon_map_io(void) } MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(shannon_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = shannon_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = shannon_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index 8d113d629867..77978586b126 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -215,10 +215,12 @@ arch_initcall(simpad_init); MACHINE_START(SIMPAD, "Simpad") - MAINTAINER("Holger Freyther") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(simpad_map_io) - INITIRQ(sa1100_init_irq) + /* Maintainer: Holger Freyther */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = simpad_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index aa0e2f6e02f6..726445895b5c 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -105,10 +105,12 @@ static struct sys_timer shark_timer = { }; MACHINE_START(SHARK, "Shark") - MAINTAINER("Alexander Schulz") - BOOT_MEM(0x08000000, 0x40000000, 0xe0000000) - BOOT_PARAMS(0x08003000) - MAPIO(shark_map_io) - INITIRQ(shark_init_irq) + /* Maintainer: Alexander Schulz */ + .phys_ram = 0x08000000, + .phys_io = 0x40000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x08003000, + .map_io = shark_map_io, + .init_irq = shark_init_irq, .timer = &shark_timer, MACHINE_END diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 9d1f2253e987..f01c0f8a2bb3 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -33,6 +33,7 @@ #include <asm/mach-types.h> #include <asm/hardware/amba.h> #include <asm/hardware/amba_clcd.h> +#include <asm/hardware/arm_timer.h> #include <asm/hardware/icst307.h> #include <asm/mach/arch.h> @@ -788,38 +789,25 @@ void __init versatile_init(void) */ #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) #if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ -#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ +#define TIMER_RELOAD (TIMER_INTERVAL >> 8) +#define TIMER_DIVISOR (TIMER_CTRL_DIV256) #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) #elif TIMER_INTERVAL >= 0x10000 #define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV16) #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) #else #define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_CTRL 0x80 /* Enable */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV1) #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ - -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - /* * Returns number of ms since last clock interrupt. Note that interrupts * will have been disabled by do_gettimeoffset() */ static unsigned long versatile_gettimeoffset(void) { - volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE; unsigned long ticks1, ticks2, status; /* @@ -828,11 +816,11 @@ static unsigned long versatile_gettimeoffset(void) * an interrupt. We get around this by ensuring that the * counter has not reloaded between our two reads. */ - ticks2 = timer0->TimerValue & 0xffff; + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; do { ticks1 = ticks2; status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); - ticks2 = timer0->TimerValue & 0xffff; + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; } while (ticks2 > ticks1); /* @@ -859,12 +847,10 @@ static unsigned long versatile_gettimeoffset(void) */ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - write_seqlock(&xtime_lock); // ...clear the interrupt - timer0->TimerClear = 1; + writel(1, TIMER0_VA_BASE + TIMER_INTCLR); timer_tick(regs); @@ -884,31 +870,32 @@ static struct irqaction versatile_timer_irq = { */ static void __init versatile_timer_init(void) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE; + u32 val; /* * set clock frequency: * VERSATILE_REFCLK is 32KHz * VERSATILE_TIMCLK is 1MHz */ - *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= - ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | - (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); + val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE)); + writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, + IO_ADDRESS(VERSATILE_SCTL_BASE)); /* * Initialise to a known state (all timers off) */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; - timer3->TimerControl = 0; - - timer0->TimerLoad = TIMER_RELOAD; - timer0->TimerValue = TIMER_RELOAD; - timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); + writel(0, TIMER3_VA_BASE + TIMER_CTRL); + + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE); + writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC | + TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL); /* * Make irqs happen for the system timer diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c index d332084586cf..8b0b3bef24ae 100644 --- a/arch/arm/mach-versatile/versatile_ab.c +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -35,11 +35,13 @@ #include "core.h" MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) - BOOT_PARAMS(0x00000100) - MAPIO(versatile_map_io) - INITIRQ(versatile_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x101f1000, + .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = versatile_map_io, + .init_irq = versatile_init_irq, .timer = &versatile_timer, - INIT_MACHINE(versatile_init) + .init_machine = versatile_init, MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 2702099a68f3..7c3078c38916 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -99,11 +99,13 @@ static int __init versatile_pb_init(void) arch_initcall(versatile_pb_init); MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) - BOOT_PARAMS(0x00000100) - MAPIO(versatile_map_io) - INITIRQ(versatile_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x101f1000, + .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = versatile_map_io, + .init_irq = versatile_init_irq, .timer = &versatile_timer, - INIT_MACHINE(versatile_init) + .init_machine = versatile_init, MACHINE_END diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c index 806c6eeb1b0c..4f5ee2d08996 100644 --- a/arch/arm/mm/blockops.c +++ b/arch/arm/mm/blockops.c @@ -25,13 +25,14 @@ blk_flush_kern_dcache_page(void *kaddr) { asm( "add r1, r0, %0 \n\ + sub r1, r1, %1 \n\ 1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\ mov r0, #0 \n\ mcr p15, 0, r0, c7, c5, 0 \n\ mcr p15, 0, r0, c7, c10, 4 \n\ mov pc, lr" : - : "I" (PAGE_SIZE)); + : "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES)); } /* diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index e25b4fd8412c..65bfe84b6d67 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -372,49 +372,50 @@ do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs) static struct fsr_info { int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs); int sig; + int code; const char *name; } fsr_info[] = { /* * The following are the standard ARMv3 and ARMv4 aborts. ARMv5 * defines these to be "precise" aborts. */ - { do_bad, SIGSEGV, "vector exception" }, - { do_bad, SIGILL, "alignment exception" }, - { do_bad, SIGKILL, "terminal exception" }, - { do_bad, SIGILL, "alignment exception" }, - { do_bad, SIGBUS, "external abort on linefetch" }, - { do_translation_fault, SIGSEGV, "section translation fault" }, - { do_bad, SIGBUS, "external abort on linefetch" }, - { do_page_fault, SIGSEGV, "page translation fault" }, - { do_bad, SIGBUS, "external abort on non-linefetch" }, - { do_bad, SIGSEGV, "section domain fault" }, - { do_bad, SIGBUS, "external abort on non-linefetch" }, - { do_bad, SIGSEGV, "page domain fault" }, - { do_bad, SIGBUS, "external abort on translation" }, - { do_sect_fault, SIGSEGV, "section permission fault" }, - { do_bad, SIGBUS, "external abort on translation" }, - { do_page_fault, SIGSEGV, "page permission fault" }, + { do_bad, SIGSEGV, 0, "vector exception" }, + { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, + { do_bad, SIGKILL, 0, "terminal exception" }, + { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, + { do_bad, SIGBUS, 0, "external abort on linefetch" }, + { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" }, + { do_bad, SIGBUS, 0, "external abort on linefetch" }, + { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" }, + { do_bad, SIGBUS, 0, "external abort on non-linefetch" }, + { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" }, + { do_bad, SIGBUS, 0, "external abort on non-linefetch" }, + { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" }, + { do_bad, SIGBUS, 0, "external abort on translation" }, + { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" }, + { do_bad, SIGBUS, 0, "external abort on translation" }, + { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" }, /* * The following are "imprecise" aborts, which are signalled by bit * 10 of the FSR, and may not be recoverable. These are only * supported if the CPU abort handler supports bit 10. */ - { do_bad, SIGBUS, "unknown 16" }, - { do_bad, SIGBUS, "unknown 17" }, - { do_bad, SIGBUS, "unknown 18" }, - { do_bad, SIGBUS, "unknown 19" }, - { do_bad, SIGBUS, "lock abort" }, /* xscale */ - { do_bad, SIGBUS, "unknown 21" }, - { do_bad, SIGBUS, "imprecise external abort" }, /* xscale */ - { do_bad, SIGBUS, "unknown 23" }, - { do_bad, SIGBUS, "dcache parity error" }, /* xscale */ - { do_bad, SIGBUS, "unknown 25" }, - { do_bad, SIGBUS, "unknown 26" }, - { do_bad, SIGBUS, "unknown 27" }, - { do_bad, SIGBUS, "unknown 28" }, - { do_bad, SIGBUS, "unknown 29" }, - { do_bad, SIGBUS, "unknown 30" }, - { do_bad, SIGBUS, "unknown 31" } + { do_bad, SIGBUS, 0, "unknown 16" }, + { do_bad, SIGBUS, 0, "unknown 17" }, + { do_bad, SIGBUS, 0, "unknown 18" }, + { do_bad, SIGBUS, 0, "unknown 19" }, + { do_bad, SIGBUS, 0, "lock abort" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 21" }, + { do_bad, SIGBUS, BUS_OBJERR, "imprecise external abort" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 23" }, + { do_bad, SIGBUS, 0, "dcache parity error" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 25" }, + { do_bad, SIGBUS, 0, "unknown 26" }, + { do_bad, SIGBUS, 0, "unknown 27" }, + { do_bad, SIGBUS, 0, "unknown 28" }, + { do_bad, SIGBUS, 0, "unknown 29" }, + { do_bad, SIGBUS, 0, "unknown 30" }, + { do_bad, SIGBUS, 0, "unknown 31" } }; void __init @@ -435,15 +436,19 @@ asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); + struct siginfo info; if (!inf->fn(addr, fsr, regs)) return; printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", inf->name, fsr, addr); - force_sig(inf->sig, current); - show_pte(current->mm, addr); - die_if_kernel("Oops", regs, 0); + + info.si_signo = inf->sig; + info.si_errno = 0; + info.si_code = inf->code; + info.si_addr = (void __user *)addr; + notify_die("", regs, &info, fsr, 0); } asmlinkage void diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 6dcb23d64bf5..edffa47a4b2a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -437,7 +437,7 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) memtable_init(mi); if (mdesc->map_io) mdesc->map_io(); - flush_tlb_all(); + local_flush_tlb_all(); /* * initialise the zones within each node diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 052ab443ec4e..c3bd503b43a2 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -682,7 +682,7 @@ void __init memtable_init(struct meminfo *mi) } flush_cache_all(); - flush_tlb_all(); + local_flush_tlb_all(); top_pmd = pmd_off_k(0xffff0000); } diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 1f325231b9e4..5c0ae5260d1c 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -445,14 +445,14 @@ __arm1020_setup: /* * R * .RVI ZFRS BLDP WCAM - * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ + * .011 1001 ..11 0101 */ .type arm1020_cr1_clear, #object .type arm1020_cr1_set, #object arm1020_cr1_clear: .word 0x593f arm1020_cr1_set: - .word 0x1935 + .word 0x3935 __INITDATA diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 142a2c2d6f0b..d69389c4d4ba 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -427,14 +427,14 @@ __arm1020e_setup: /* * R * .RVI ZFRS BLDP WCAM - * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ + * .011 1001 ..11 0101 */ .type arm1020e_cr1_clear, #object .type arm1020e_cr1_set, #object arm1020e_cr1_clear: .word 0x5f3f arm1020e_cr1_set: - .word 0x1935 + .word 0x3935 __INITDATA diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index e3d8510f4340..352db98ee269 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -200,7 +200,7 @@ __v6_setup: mcr p15, 0, r4, c2, c0, 1 @ load TTB1 #ifdef CONFIG_VFP mrc p15, 0, r0, c1, c0, 2 - orr r0, r0, #(3 << 20) + orr r0, r0, #(0xf << 20) mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP #endif mrc p15, 0, r0, c1, c0, 0 @ read control register diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index ba1a6e9f2b28..8ffb523e6c77 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile @@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) -oprofile-y := $(DRIVER_OBJS) init.o +oprofile-y := $(DRIVER_OBJS) init.o backtrace.o oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c new file mode 100644 index 000000000000..ec58d3e2eb8b --- /dev/null +++ b/arch/arm/oprofile/backtrace.c @@ -0,0 +1,144 @@ +/* + * Arm specific backtracing code for oprofile + * + * Copyright 2005 Openedhand Ltd. + * + * Author: Richard Purdie <rpurdie@openedhand.com> + * + * Based on i386 oprofile backtrace code by John Levon, David Smith + * + * 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 <linux/oprofile.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/ptrace.h> +#include <asm/uaccess.h> + + +/* + * The registers we're interested in are at the end of the variable + * length saved register structure. The fp points at the end of this + * structure so the address of this struct is: + * (struct frame_tail *)(xxx->fp)-1 + */ +struct frame_tail { + struct frame_tail *fp; + unsigned long sp; + unsigned long lr; +} __attribute__((packed)); + + +#ifdef CONFIG_FRAME_POINTER +static struct frame_tail* kernel_backtrace(struct frame_tail *tail) +{ + oprofile_add_trace(tail->lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= tail->fp) + return NULL; + + return tail->fp-1; +} +#endif + +static struct frame_tail* user_backtrace(struct frame_tail *tail) +{ + struct frame_tail buftail; + + /* hardware pte might not be valid due to dirty/accessed bit emulation + * so we use copy_from_user and benefit from exception fixups */ + if (copy_from_user(&buftail, tail, sizeof(struct frame_tail))) + return NULL; + + oprofile_add_trace(buftail.lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= buftail.fp) + return NULL; + + return buftail.fp-1; +} + +/* Compare two addresses and see if they're on the same page */ +#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \ + == ((((unsigned long) y) + offset) >> PAGE_SHIFT)) + +/* check that the page(s) containing the frame tail are present */ +static int pages_present(struct frame_tail *tail) +{ + struct mm_struct * mm = current->mm; + + if (!check_user_page_readable(mm, (unsigned long)tail)) + return 0; + + if (CMP_ADDR_EQUAL(tail, tail, 8)) + return 1; + + if (!check_user_page_readable(mm, ((unsigned long)tail) + 8)) + return 0; + + return 1; +} + +/* + * | | /\ Higher addresses + * | | + * --------------- stack base (address of current_thread_info) + * | thread info | + * . . + * | stack | + * --------------- saved regs->ARM_fp value if valid (frame_tail address) + * . . + * --------------- struct pt_regs stored on stack (struct pt_regs *) + * | | + * . . + * | | + * --------------- %esp + * | | + * | | \/ Lower addresses + * + * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values + */ +static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) +{ + unsigned long tailaddr = (unsigned long)tail; + unsigned long stack = (unsigned long)regs; + unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; + + return (tailaddr > stack) && (tailaddr < stack_base); +} + +void arm_backtrace(struct pt_regs const *regs, unsigned int depth) +{ + struct frame_tail *tail; + unsigned long last_address = 0; + + tail = ((struct frame_tail *) regs->ARM_fp) - 1; + + if (!user_mode(regs)) { + +#ifdef CONFIG_FRAME_POINTER + while (depth-- && tail && valid_kernel_stack(tail, regs)) { + tail = kernel_backtrace(tail); + } +#endif + return; + } + + while (depth-- && tail && !((unsigned long) tail & 3)) { + if ((!CMP_ADDR_EQUAL(last_address, tail, 0) + || !CMP_ADDR_EQUAL(last_address, tail, 8)) + && !pages_present(tail)) + return; + last_address = (unsigned long) tail; + tail = user_backtrace(tail); + } +} + diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c index cce3d3015eb7..d315a3a86c86 100644 --- a/arch/arm/oprofile/init.c +++ b/arch/arm/oprofile/init.c @@ -20,6 +20,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ret = pmu_init(ops, &op_xscale_spec); #endif + ops->backtrace = arm_backtrace; + return ret; } diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h index 2d4caf4781ad..2148d07484b7 100644 --- a/arch/arm/oprofile/op_arm_model.h +++ b/arch/arm/oprofile/op_arm_model.h @@ -24,6 +24,8 @@ struct op_arm_model_spec { extern struct op_arm_model_spec op_xscale_spec; #endif +extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); + extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); extern void pmu_exit(void); #endif /* OP_ARM_MODEL_H */ diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h index 55a02bc994a3..4b97950984e9 100644 --- a/arch/arm/vfp/vfp.h +++ b/arch/arm/vfp/vfp.h @@ -117,7 +117,13 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) if (nh >= m) return ~0ULL; mh = m >> 32; - z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32; + if (mh << 32 <= nh) { + z = 0xffffffff00000000ULL; + } else { + z = nh; + do_div(z, mh); + z <<= 32; + } mul64to128(&termh, &terml, m, z); sub128(&remh, &reml, nh, nl, termh, terml); ml = m << 32; @@ -126,7 +132,12 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) add128(&remh, &reml, remh, reml, mh, ml); } remh = (remh << 32) | (reml >> 32); - z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh; + if (mh << 32 <= remh) { + z |= 0xffffffff; + } else { + do_div(remh, mh); + z |= remh; + } return z; } diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index fa3053e84db5..b801cd66b6ea 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -32,6 +32,8 @@ */ #include <linux/kernel.h> #include <linux/bitops.h> + +#include <asm/div64.h> #include <asm/ptrace.h> #include <asm/vfp.h> diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 3aeedd2afc70..22f3da4e0829 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -89,7 +89,7 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) current->thread.error_code = 0; current->thread.trap_no = 6; - force_sig_info(SIGFPE, &info, current); + send_sig_info(SIGFPE, &info, current); } static void vfp_panic(char *reason) diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 6849fe35cb2e..14dd696ddeb1 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -32,6 +32,8 @@ */ #include <linux/kernel.h> #include <linux/bitops.h> + +#include <asm/div64.h> #include <asm/ptrace.h> #include <asm/vfp.h> @@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) if (z <= a) return (s32)a >> 1; } - return (u32)(((u64)a << 31) / z) + (z >> 1); + { + u64 v = (u64)a << 31; + do_div(v, z); + return v + (z >> 1); + } } static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) @@ -1107,7 +1113,11 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) vsn.significand >>= 1; vsd.exponent++; } - vsd.significand = ((u64)vsn.significand << 32) / vsm.significand; + { + u64 significand = (u64)vsn.significand << 32; + do_div(significand, vsm.significand); + vsd.significand = significand; + } if ((vsd.significand & 0x3f) == 0) vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 4a17956512e1..6835f6d47c31 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c @@ -70,7 +70,8 @@ void usage(void) int main(int argc, char ** argv) { - unsigned int i, c, sz, setup_sectors; + unsigned int i, sz, setup_sectors; + int c; u32 sys_size; byte major_root, minor_root; struct stat sb; diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 9f63ae0f404b..b7808a89d945 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) #endif #ifdef CONFIG_PCI_MMCONFIG -static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +struct acpi_table_mcfg_config *pci_mmcfg_config; +int pci_mmcfg_config_num; + +int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg; + unsigned long i; + int config_size; if (!phys_addr || !size) return -EINVAL; @@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) return -ENODEV; } - if (mcfg->base_reserved) { - printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); + /* how many config structures do we have */ + pci_mmcfg_config_num = 0; + i = size - sizeof(struct acpi_table_mcfg); + while (i >= sizeof(struct acpi_table_mcfg_config)) { + ++pci_mmcfg_config_num; + i -= sizeof(struct acpi_table_mcfg_config); + }; + if (pci_mmcfg_config_num == 0) { + printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); return -ENODEV; } - pci_mmcfg_base_addr = mcfg->base_address; + config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); + pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); + if (!pci_mmcfg_config) { + printk(KERN_WARNING PREFIX + "No memory for MCFG config tables\n"); + return -ENOMEM; + } + + memcpy(pci_mmcfg_config, &mcfg->config, config_size); + for (i = 0; i < pci_mmcfg_config_num; ++i) { + if (mcfg->config[i].base_reserved) { + printk(KERN_ERR PREFIX + "MMCONFIG not in low 4GB of memory\n"); + return -ENODEV; + } + } return 0; } -#else -#define acpi_parse_mcfg NULL -#endif /* !CONFIG_PCI_MMCONFIG */ +#endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC static int __init @@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu) EXPORT_SYMBOL(acpi_unmap_lsapic); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +int +acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_register_ioapic); + +int +acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_unregister_ioapic); + static unsigned long __init acpi_scan_rsdp ( unsigned long start, @@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void) acpi_process_madt(); acpi_table_parse(ACPI_HPET, acpi_parse_hpet); - acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); return 0; } diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 93df90bbb87e..bd1dbf3bd223 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -35,6 +35,7 @@ #include <asm/desc.h> #include <asm/arch_hooks.h> #include <asm/hpet.h> +#include <asm/i8253.h> #include <mach_apic.h> @@ -879,7 +880,6 @@ fake_ioapic_page: */ static unsigned int __devinit get_8254_timer_count(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index d48ce9290963..064211d5f41b 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -228,10 +228,10 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/desc.h> +#include <asm/i8253.h> #include "io_ports.h" -extern spinlock_t i8253_lock; extern unsigned long get_cmos_time(void); extern void machine_real_restart(unsigned char *, int); @@ -1168,8 +1168,7 @@ static void get_time_diff(void) static void reinit_timer(void) { #ifdef INIT_TIMER_AFTER_SUSPEND - unsigned long flags; - extern spinlock_t i8253_lock; + unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); /* set the clock to 100 Hz */ diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index 1a49adb1f4a6..e86ea486c311 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c @@ -190,7 +190,7 @@ static __init struct pci_dev *gx_detect_chipset(void) /* detect which companion chip is used */ while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { - if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) { + if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) { return gx_pci; } } diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 35eb8e29c485..6578f40bd501 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -37,6 +37,7 @@ #include <asm/smp.h> #include <asm/desc.h> #include <asm/timer.h> +#include <asm/i8259.h> #include <mach_apic.h> @@ -1566,7 +1567,6 @@ void print_all_local_APICs (void) void /*__init*/ print_PIC(void) { - extern spinlock_t i8259A_lock; unsigned int v; unsigned long flags; diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index fc8b17521761..a6d8c45961d3 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -537,7 +537,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index e68d9fdb0759..2854c357377f 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -68,7 +68,8 @@ #include "io_ports.h" -extern spinlock_t i8259A_lock; +#include <asm/i8259.h> + int pit_latch_buggy; /* extern */ #include "do_timer.h" @@ -85,6 +86,8 @@ extern unsigned long wall_jiffies; DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); +#include <asm/i8253.h> + DEFINE_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); diff --git a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c index f6f1206a11bb..13892a65c941 100644 --- a/arch/i386/kernel/timers/timer_cyclone.c +++ b/arch/i386/kernel/timers/timer_cyclone.c @@ -17,9 +17,9 @@ #include <asm/io.h> #include <asm/pgtable.h> #include <asm/fixmap.h> -#include "io_ports.h" +#include <asm/i8253.h> -extern spinlock_t i8253_lock; +#include "io_ports.h" /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c index 967d5453cd0e..06de036a820c 100644 --- a/arch/i386/kernel/timers/timer_pit.c +++ b/arch/i386/kernel/timers/timer_pit.c @@ -15,9 +15,8 @@ #include <asm/smp.h> #include <asm/io.h> #include <asm/arch_hooks.h> +#include <asm/i8253.h> -extern spinlock_t i8259A_lock; -extern spinlock_t i8253_lock; #include "do_timer.h" #include "io_ports.h" @@ -166,7 +165,6 @@ struct init_timer_opts __initdata timer_pit_init = { void setup_pit_timer(void) { - extern spinlock_t i8253_lock; unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index f46e625bab67..8f4e4d5bc560 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c @@ -24,6 +24,7 @@ #include "mach_timer.h" #include <asm/hpet.h> +#include <asm/i8253.h> #ifdef CONFIG_HPET_TIMER static unsigned long hpet_usec_quotient; @@ -35,8 +36,6 @@ static inline void cpufreq_delayed_get(void); int tsc_disable __devinitdata = 0; -extern spinlock_t i8253_lock; - static int use_tsc; /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c index 602aea240e9b..3e439ce5e1b2 100644 --- a/arch/i386/mach-voyager/voyager_basic.c +++ b/arch/i386/mach-voyager/voyager_basic.c @@ -30,6 +30,7 @@ #include <linux/irq.h> #include <asm/tlbflush.h> #include <asm/arch_hooks.h> +#include <asm/i8253.h> /* * Power off function, if any @@ -182,7 +183,6 @@ voyager_timer_interrupt(struct pt_regs *regs) * and swiftly introduce it to something sharp and * pointy. */ __u16 val; - extern spinlock_t i8253_lock; spin_lock(&i8253_lock); diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 720975e1af50..70bcd53451f6 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | int pci_routeirq; int pcibios_last_bus = -1; -struct pci_bus *pci_root_bus = NULL; +unsigned long pirq_table_addr; +struct pci_bus *pci_root_bus; struct pci_raw_ops *raw_pci_ops; static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) @@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); - return pci_scan_bus(busnum, &pci_root_ops, NULL); + return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); } extern u8 pci_cache_line_size; @@ -164,6 +165,7 @@ static int __init pcibios_init(void) if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) pcibios_sort(); #endif + pci_assign_unassigned_resources(); return 0; } @@ -188,6 +190,9 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "biosirq")) { pci_probe |= PCI_BIOS_IRQ_SCAN; return NULL; + } else if (!strncmp(str, "pirqaddr=", 9)) { + pirq_table_addr = simple_strtoul(str+9, NULL, 0); + return NULL; } #endif #ifdef CONFIG_PCI_DIRECT diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index c205ea7e233b..93a364c82150 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c @@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) if ((dev = bus->self)) { for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { r = &dev->resource[idx]; - if (!r->start) + if (!r->flags) continue; pr = pci_find_parent_resource(dev, r); - if (!pr || request_resource(pr, r) < 0) + if (!r->start || !pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); + /* Something is wrong with the region. + Invalidate the resource to prevent child + resource allocations in this range. */ + r->flags = 0; + } } } pcibios_allocate_bus_resources(&bus->children); @@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for(idx=0; idx<6; idx++) { + for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) { /* Only set up the requested stuff */ if (!(mask & (1<<idx))) continue; diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 83458f81e661..78ca1ecbb907 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -58,6 +58,35 @@ struct irq_router_handler { int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; /* + * Check passed address for the PCI IRQ Routing Table signature + * and perform checksum verification. + */ + +static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) +{ + struct irq_routing_table *rt; + int i; + u8 sum; + + rt = (struct irq_routing_table *) addr; + if (rt->signature != PIRQ_SIGNATURE || + rt->version != PIRQ_VERSION || + rt->size % 16 || + rt->size < sizeof(struct irq_routing_table)) + return NULL; + sum = 0; + for (i=0; i < rt->size; i++) + sum += addr[i]; + if (!sum) { + DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + return rt; + } + return NULL; +} + + + +/* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. */ @@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) { u8 *addr; struct irq_routing_table *rt; - int i; - u8 sum; + if (pirq_table_addr) { + rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr)); + if (rt) + return rt; + printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); + } for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { - rt = (struct irq_routing_table *) addr; - if (rt->signature != PIRQ_SIGNATURE || - rt->version != PIRQ_VERSION || - rt->size % 16 || - rt->size < sizeof(struct irq_routing_table)) - continue; - sum = 0; - for(i=0; i<rt->size; i++) - sum += addr[i]; - if (!sum) { - DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + rt = pirq_check_routing_table(addr); + if (rt) return rt; - } } return NULL; } diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 1492e3753869..149a9588c256 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c @@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) printk("PCI: Probing PCI hardware\n"); pci_root_bus = pcibios_scan_root(0); + if (pci_root_bus) + pci_bus_add_devices(pci_root_bus); pcibios_fixup_peer_bridges(); diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 021a50aa51f4..60f0e7a1162a 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -11,11 +11,9 @@ #include <linux/pci.h> #include <linux/init.h> +#include <linux/acpi.h> #include "pci.h" -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -u32 pci_mmcfg_base_addr; - #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) /* The base address of the last MMCONFIG device accessed */ @@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device; /* * Functions for accessing PCI configuration space with MMCONFIG accesses */ +static u32 get_base_addr(unsigned int seg, int bus) +{ + int cfg_num = -1; + struct acpi_table_mcfg_config *cfg; + + while (1) { + ++cfg_num; + if (cfg_num >= pci_mmcfg_config_num) { + /* something bad is going on, no cfg table is found. */ + /* so we fall back to the old way we used to do this */ + /* and just rely on the first entry to be correct. */ + return pci_mmcfg_config[0].base_address; + } + cfg = &pci_mmcfg_config[cfg_num]; + if (cfg->pci_segment_group_number != seg) + continue; + if ((cfg->start_bus_number <= bus) && + (cfg->end_bus_number >= bus)) + return cfg->base_address; + } +} -static inline void pci_exp_set_dev_base(int bus, int devfn) +static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) { - u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); + u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { mmcfg_last_accessed_device = dev_base; set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); @@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(bus, devfn); + pci_exp_set_dev_base(seg, bus, devfn); switch (len) { case 1: @@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(bus, devfn); + pci_exp_set_dev_base(seg, bus, devfn); switch (len) { case 1: @@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) goto out; - if (!pci_mmcfg_base_addr) + + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if ((pci_mmcfg_config_num == 0) || + (pci_mmcfg_config == NULL) || + (pci_mmcfg_config[0].base_address == 0)) goto out; /* Kludge for now. Don't use mmconfig on AMD systems because diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index 9e3695461899..adbe17a38f6f 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c @@ -115,6 +115,8 @@ static int __init pci_numa_init(void) return 0; pci_root_bus = pcibios_scan_root(0); + if (pci_root_bus) + pci_bus_add_devices(pci_root_bus); if (num_online_nodes() > 1) for_each_online_node(quad) { if (quad == 0) diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index a8fc80ca69f3..a80f0f55ff51 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -27,6 +27,7 @@ #define PCI_ASSIGN_ALL_BUSSES 0x4000 extern unsigned int pci_probe; +extern unsigned long pirq_table_addr; /* pci-i386.c */ diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 487d2e36b0a6..c05613980300 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -99,7 +99,7 @@ CONFIG_ACPI_DEALLOCATE_IRQ=y # Firmware Drivers # CONFIG_EFI_VARS=y -# CONFIG_EFI_PCDP is not set +CONFIG_EFI_PCDP=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set @@ -650,7 +650,7 @@ CONFIG_MMTIMER=y # # Console display driver support # -# CONFIG_VGA_CONSOLE is not set +CONFIG_VGA_CONSOLE=y CONFIG_DUMMY_CONSOLE=y # diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 47f45341ac62..73454eee26f1 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-20050621 -# Tue Jun 21 14:03:24 2005 +# Linux kernel version: 2.6.13-rc1-20050629 +# Wed Jun 29 15:28:12 2005 # # @@ -80,18 +80,29 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y CONFIG_IA64_CYCLONE=y CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT 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_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -257,6 +268,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -395,6 +407,7 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -407,6 +420,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set CONFIG_IP_TCPDIAG=y # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -598,9 +613,7 @@ CONFIG_GAMEPORT=m # CONFIG_GAMEPORT_NS558 is not set # CONFIG_GAMEPORT_L4 is not set # CONFIG_GAMEPORT_EMU10K1 is not set -# CONFIG_GAMEPORT_VORTEX is not set # CONFIG_GAMEPORT_FM801 is not set -# CONFIG_GAMEPORT_CS461X is not set # # Character devices @@ -629,7 +642,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -743,6 +755,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y @@ -779,9 +792,11 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -838,7 +853,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_TEST is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -857,12 +872,17 @@ CONFIG_USB_HIDINPUT=y # CONFIG_INFINIBAND is not set # +# SN Devices +# + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y @@ -922,7 +942,6 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y @@ -953,15 +972,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m @@ -1069,6 +1091,7 @@ CONFIG_LOG_BUF_SHIFT=20 # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set +# CONFIG_KPROBES is not set CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_IA64_PRINT_HAZARDS is not set @@ -1090,7 +1113,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 21d6f9bab5e9..b7755e4436d2 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10 -# Wed Dec 29 09:05:48 2004 +# Linux kernel version: 2.6.13-rc1-20050629 +# Wed Jun 29 15:31:11 2005 # # @@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -24,23 +25,26 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -59,12 +63,15 @@ CONFIG_IA64=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_TIME_INTERPOLATION=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_IA64_GENERIC is not set # CONFIG_IA64_DIG is not set CONFIG_IA64_HP_ZX1=y +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_ITANIUM is not set @@ -73,22 +80,36 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_HOLES_IN_ZONE=y # CONFIG_IA64_CYCLONE is not set CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=16 # CONFIG_HOTPLUG_CPU is not set +# CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT 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_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y +CONFIG_ACPI_DEALLOCATE_IRQ=y # # Firmware Drivers @@ -120,6 +141,7 @@ CONFIG_ACPI_BUS=y CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y +# CONFIG_ACPI_CONTAINER is not set # # Bus options (PCI, PCMCIA) @@ -129,6 +151,7 @@ CONFIG_PCI_DOMAINS=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCI Hotplug Support @@ -138,7 +161,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set # CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_PCIE is not set # CONFIG_HOTPLUG_PCI_SHPC is not set # @@ -147,10 +169,6 @@ CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_PCCARD is not set # -# PC-card bridges -# - -# # Device Drivers # @@ -184,6 +202,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -203,6 +222,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -246,6 +266,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -275,6 +296,7 @@ CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -288,6 +310,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # # SCSI low-level drivers @@ -303,13 +326,10 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set @@ -319,8 +339,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y @@ -331,7 +349,7 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -344,9 +362,9 @@ CONFIG_SCSI_QLA2XXX=y # # Fusion MPT device support # -CONFIG_FUSION=y -CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set # # IEEE 1394 (FireWire) support @@ -368,12 +386,12 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -386,6 +404,8 @@ CONFIG_IP_MULTICAST=y # CONFIG_INET_TUNNEL is not set # CONFIG_IP_TCPDIAG is not set # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -405,8 +425,6 @@ CONFIG_NETFILTER=y CONFIG_IP_NF_ARPTABLES=y # CONFIG_IP_NF_ARPFILTER is not set # CONFIG_IP_NF_ARP_MANGLE is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set # # SCTP Configuration (EXPERIMENTAL) @@ -483,7 +501,6 @@ CONFIG_NET_PCI=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -505,9 +522,11 @@ CONFIG_E1000=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -565,18 +584,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - -# # Input Device Drivers # # CONFIG_INPUT_KEYBOARD is not set @@ -586,6 +593,16 @@ CONFIG_SERIO=y # CONFIG_INPUT_MISC is not set # +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# # Character devices # CONFIG_VT=y @@ -603,7 +620,6 @@ CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -611,6 +627,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -644,6 +661,12 @@ CONFIG_DRM_RADEON=y # CONFIG_DRM_SIS is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -668,6 +691,7 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -691,10 +715,14 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -705,21 +733,29 @@ CONFIG_I2C_ALGOPCF=y # 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_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -746,6 +782,7 @@ CONFIG_VIDEO_DEV=y # # Video Adapters # +# CONFIG_TUNER_MULTI_I2C is not set # CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5246A is not set @@ -778,6 +815,11 @@ CONFIG_VIDEO_DEV=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_CIRRUS is not set @@ -785,6 +827,7 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON_OLD is not set @@ -801,6 +844,7 @@ CONFIG_FB_RADEON_DEBUG=y # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_PM3 is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -820,6 +864,7 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -869,6 +914,8 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_CS46XX is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set # CONFIG_SND_KORG1212 is not set # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set @@ -876,6 +923,7 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_RME96 is not set # CONFIG_SND_RME9652 is not set # CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set # CONFIG_SND_TRIDENT is not set # CONFIG_SND_YMFPCI is not set # CONFIG_SND_ALS4000 is not set @@ -893,13 +941,14 @@ CONFIG_SND_FM801_TEA575X=y # CONFIG_SND_INTEL8X0M is not set # CONFIG_SND_SONICVIBES is not set # CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set # # USB devices # # CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set # # Open Sound System @@ -909,6 +958,8 @@ CONFIG_SND_FM801_TEA575X=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -920,8 +971,6 @@ CONFIG_USB_BANDWIDTH=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -929,7 +978,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set @@ -947,12 +999,11 @@ CONFIG_USB_UHCI_HCD=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -966,9 +1017,11 @@ CONFIG_USB_HIDINPUT=y CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -978,7 +1031,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -992,6 +1044,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_SE401 is not set # CONFIG_USB_SN9C102 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set # # USB Network Adapters @@ -1001,6 +1054,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -1016,7 +1070,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -1025,9 +1078,11 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -1041,12 +1096,22 @@ CONFIG_USB_HIDDEV=y # CONFIG_MMC is not set # +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -1056,6 +1121,10 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1089,7 +1158,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y @@ -1120,15 +1188,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y @@ -1209,6 +1280,8 @@ CONFIG_NLS_UTF8=y # CONFIG_CRC_CCITT is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y # # Profiling support @@ -1218,14 +1291,18 @@ CONFIG_CRC32=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_KPROBES=y CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set CONFIG_IA64_PRINT_HAZARDS=y @@ -1252,6 +1329,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index b8db6e3e5e81..11957598a8b9 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -156,10 +156,13 @@ */ #define DELAYED_RESOURCE_CNT 64 +#define PCI_DEVICE_ID_HP_SX2000_IOC 0x12ec + #define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX2_IOC_ID ((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP) #define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP) #define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP) +#define SX2000_IOC_ID ((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ @@ -1726,6 +1729,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, { ZX2_IOC_ID, "zx2", NULL }, { SX1000_IOC_ID, "sx1000", NULL }, + { SX2000_IOC_ID, "sx2000", NULL }, }; static struct ioc * __init diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 786e70718ce4..7a8ae0f4b387 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -30,6 +30,7 @@ #include <linux/module.h> #include <linux/serial.h> #include <linux/serialP.h> +#include <linux/sysrq.h> #include <asm/irq.h> #include <asm/hw_irq.h> @@ -149,12 +150,17 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) seen_esc = 2; continue; } else if ( seen_esc == 2 ) { - if ( ch == 'P' ) show_state(); /* F1 key */ -#ifdef CONFIG_KDB - if ( ch == 'S' ) - kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs); + if ( ch == 'P' ) /* F1 */ + show_state(); +#ifdef CONFIG_MAGIC_SYSRQ + if ( ch == 'S' ) { /* F4 */ + do + ch = ia64_ssc(0, 0, 0, 0, + SSC_GETCHAR); + while (!ch); + handle_sysrq(ch, regs, NULL); + } #endif - seen_esc = 0; continue; } diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 72dfd9e7de0f..cda06f88c66e 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end) if (BAD_MADT_ENTRY(iosapic, end)) return -EINVAL; - iosapic_init(iosapic->address, iosapic->global_irq_base); - - return 0; + return iosapic_init(iosapic->address, iosapic->global_irq_base); } @@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic); #ifdef CONFIG_ACPI_NUMA -acpi_status __init +acpi_status __devinit acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; @@ -825,4 +823,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) return AE_OK; } #endif /* CONFIG_NUMA */ + +int +acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base) +{ + int err; + + if ((err = iosapic_init(phys_addr, gsi_base))) + return err; + +#if CONFIG_ACPI_NUMA + acpi_map_iosapic(handle, 0, NULL, NULL); +#endif /* CONFIG_ACPI_NUMA */ + + return 0; +} +EXPORT_SYMBOL(acpi_register_ioapic); + +int +acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base) +{ + return iosapic_remove(gsi_base); +} +EXPORT_SYMBOL(acpi_unregister_ioapic); + #endif /* CONFIG_ACPI_BOOT */ diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 785a51b0ad8e..69f88d561d62 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -470,18 +470,6 @@ ENTRY(load_switch_stack) br.cond.sptk.many b7 END(load_switch_stack) -GLOBAL_ENTRY(__ia64_syscall) - .regstk 6,0,0,0 - mov r15=in5 // put syscall number in place - break __BREAK_SYSCALL - movl r2=errno - cmp.eq p6,p7=-1,r10 - ;; -(p6) st4 [r2]=r8 -(p6) mov r8=-1 - br.ret.sptk.many rp -END(__ia64_syscall) - GLOBAL_ENTRY(execve) mov r15=__NR_execve // put syscall number in place break __BREAK_SYSCALL @@ -637,7 +625,7 @@ END(ia64_ret_from_syscall) * r8-r11: restored (syscall return value(s)) * r12: restored (user-level stack pointer) * r13: restored (user-level thread pointer) - * r14: cleared + * r14: set to __kernel_syscall_via_epc * r15: restored (syscall #) * r16-r17: cleared * r18: user-level b6 @@ -658,7 +646,7 @@ END(ia64_ret_from_syscall) * pr: restored (user-level pr) * b0: restored (user-level rp) * b6: restored - * b7: cleared + * b7: set to __kernel_syscall_via_epc * ar.unat: restored (user-level ar.unat) * ar.pfs: restored (user-level ar.pfs) * ar.rsc: restored (user-level ar.rsc) @@ -704,72 +692,79 @@ ENTRY(ia64_leave_syscall) ;; (p6) ld4 r31=[r18] // load current_thread_info()->flags ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" - mov b7=r0 // clear b7 + nop.i 0 ;; - ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) + mov r16=ar.bsp // M2 get existing backing store pointer ld8 r18=[r2],PT(R9)-PT(B6) // load b6 (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? ;; - mov r16=ar.bsp // M2 get existing backing store pointer + ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) (p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? (p6) br.cond.spnt .work_pending_syscall ;; // start restoring the state saved on the kernel stack (struct pt_regs): ld8 r9=[r2],PT(CR_IPSR)-PT(R9) ld8 r11=[r3],PT(CR_IIP)-PT(R11) - mov f6=f0 // clear f6 +(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! ;; invala // M0|1 invalidate ALAT - rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection - mov f9=f0 // clear f9 + rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection + cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs - ld8 r29=[r2],16 // load cr.ipsr - ld8 r28=[r3],16 // load cr.iip - mov f8=f0 // clear f8 + ld8 r29=[r2],16 // M0|1 load cr.ipsr + ld8 r28=[r3],16 // M0|1 load cr.iip + mov r22=r0 // A clear r22 ;; ld8 r30=[r2],16 // M0|1 load cr.ifs ld8 r25=[r3],16 // M0|1 load ar.unat - cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 ;; ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs -(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled - mov f10=f0 // clear f10 +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled + nop 0 ;; - ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 - ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc - mov f11=f0 // clear f11 + ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0 + ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc + mov f6=f0 // F clear f6 ;; - ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) - ld8 r31=[r3],PT(R1)-PT(PR) // load predicates -(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 + ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage) + ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates + mov f7=f0 // F clear f7 ;; - ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr - ld8.fill r1=[r3],16 // load r1 -(pUStk) mov r17=1 + ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr + ld8.fill r1=[r3],16 // M0|1 load r1 +(pUStk) mov r17=1 // A ;; - srlz.d // M0 ensure interruption collection is off - ld8.fill r13=[r3],16 - mov f7=f0 // clear f7 +(pUStk) st1 [r14]=r17 // M2|3 + ld8.fill r13=[r3],16 // M0|1 + mov f8=f0 // F clear f8 ;; - ld8.fill r12=[r2] // restore r12 (sp) - mov.m ar.ssd=r0 // M2 clear ar.ssd - mov r22=r0 // clear r22 + ld8.fill r12=[r2] // M0|1 restore r12 (sp) + ld8.fill r15=[r3] // M0|1 restore r15 + mov b6=r18 // I0 restore b6 - ld8.fill r15=[r3] // restore r15 -(pUStk) st1 [r14]=r17 - addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A + mov f9=f0 // F clear f9 +(pKStk) br.cond.dpnt.many skip_rbs_switch // B + + srlz.d // M0 ensure interruption collection is off (for cover) + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + cover // B add current frame into dirty partition & set cr.ifs ;; -(pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 - mov.m ar.csd=r0 // M2 clear ar.csd - mov b6=r18 // I0 restore b6 +(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 + mov r19=ar.bsp // M2 get new backing store pointer + mov f10=f0 // F clear f10 + + nop.m 0 + movl r14=__kernel_syscall_via_epc // X ;; - mov r14=r0 // clear r14 - shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition -(pKStk) br.cond.dpnt.many skip_rbs_switch + mov.m ar.csd=r0 // M2 clear ar.csd + mov.m ar.ccv=r0 // M2 clear ar.ccv + mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) - mov.m ar.ccv=r0 // clear ar.ccv -(pNonSys) br.cond.dpnt.many dont_preserve_current_frame - br.cond.sptk.many rbs_switch + mov.m ar.ssd=r0 // M2 clear ar.ssd + mov f11=f0 // F clear f11 + br.cond.sptk.many rbs_switch // B END(ia64_leave_syscall) #ifdef CONFIG_IA32_SUPPORT @@ -885,7 +880,7 @@ GLOBAL_ENTRY(ia64_leave_kernel) ldf.fill f7=[r2],PT(F11)-PT(F7) ldf.fill f8=[r3],32 ;; - srlz.i // ensure interruption collection is off + srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned) mov ar.ccv=r15 ;; ldf.fill f11=[r2] @@ -945,11 +940,10 @@ GLOBAL_ENTRY(ia64_leave_kernel) * NOTE: alloc, loadrs, and cover can't be predicated. */ (pNonSys) br.cond.dpnt dont_preserve_current_frame - -rbs_switch: cover // add current frame into dirty partition and set cr.ifs ;; mov r19=ar.bsp // get new backing store pointer +rbs_switch: sub r16=r16,r18 // krbs = old bsp - size of dirty partition cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs ;; @@ -1024,14 +1018,14 @@ rse_clear_invalid: mov loc5=0 mov loc6=0 mov loc7=0 -(pRecurse) br.call.sptk.few b0=rse_clear_invalid +(pRecurse) br.call.dptk.few b0=rse_clear_invalid ;; mov loc8=0 mov loc9=0 cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret mov loc10=0 mov loc11=0 -(pReturn) br.ret.sptk.many b0 +(pReturn) br.ret.dptk.many b0 #endif /* !CONFIG_ITANIUM */ # undef pRecurse # undef pReturn diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 962b6c4e32b5..7d7684a369d3 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -531,93 +531,114 @@ GLOBAL_ENTRY(fsys_bubble_down) .altrp b6 .body /* - * We get here for syscalls that don't have a lightweight handler. For those, we - * need to bubble down into the kernel and that requires setting up a minimal - * pt_regs structure, and initializing the CPU state more or less as if an - * interruption had occurred. To make syscall-restarts work, we setup pt_regs - * such that cr_iip points to the second instruction in syscall_via_break. - * Decrementing the IP hence will restart the syscall via break and not - * decrementing IP will return us to the caller, as usual. Note that we preserve - * the value of psr.pp rather than initializing it from dcr.pp. This makes it - * possible to distinguish fsyscall execution from other privileged execution. + * We get here for syscalls that don't have a lightweight + * handler. For those, we need to bubble down into the kernel + * and that requires setting up a minimal pt_regs structure, + * and initializing the CPU state more or less as if an + * interruption had occurred. To make syscall-restarts work, + * we setup pt_regs such that cr_iip points to the second + * instruction in syscall_via_break. Decrementing the IP + * hence will restart the syscall via break and not + * decrementing IP will return us to the caller, as usual. + * Note that we preserve the value of psr.pp rather than + * initializing it from dcr.pp. This makes it possible to + * distinguish fsyscall execution from other privileged + * execution. * * On entry: - * - normal fsyscall handler register usage, except that we also have: + * - normal fsyscall handler register usage, except + * that we also have: * - r18: address of syscall entry point * - r21: ar.fpsr * - r26: ar.pfs * - r27: ar.rsc * - r29: psr + * + * We used to clear some PSR bits here but that requires slow + * serialization. Fortuntely, that isn't really necessary. + * The rationale is as follows: we used to clear bits + * ~PSR_PRESERVED_BITS in PSR.L. Since + * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we + * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}. + * However, + * + * PSR.BE : already is turned off in __kernel_syscall_via_epc() + * PSR.AC : don't care (kernel normally turns PSR.AC on) + * PSR.I : already turned off by the time fsys_bubble_down gets + * invoked + * PSR.DFL: always 0 (kernel never turns it on) + * PSR.DFH: don't care --- kernel never touches f32-f127 on its own + * initiative + * PSR.DI : always 0 (kernel never turns it on) + * PSR.SI : always 0 (kernel never turns it on) + * PSR.DB : don't care --- kernel never enables kernel-level + * breakpoints + * PSR.TB : must be 0 already; if it wasn't zero on entry to + * __kernel_syscall_via_epc, the branch to fsys_bubble_down + * will trigger a taken branch; the taken-trap-handler then + * converts the syscall into a break-based system-call. */ -# define PSR_PRESERVED_BITS (IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \ - | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \ - | IA64_PSR_IC) /* - * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have - * to synthesize. + * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. + * The rest we have to synthesize. */ -# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \ +# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) \ + | (0x1 << IA64_PSR_RI_BIT) \ | IA64_PSR_BN | IA64_PSR_I) - invala - movl r8=PSR_ONE_BITS + invala // M0|1 + movl r14=ia64_ret_from_syscall // X - mov r25=ar.unat // save ar.unat (5 cyc) - movl r9=PSR_PRESERVED_BITS + nop.m 0 + movl r28=__kernel_syscall_via_break // X create cr.iip + ;; - mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 - movl r28=__kernel_syscall_via_break + mov r2=r16 // A get task addr to addl-addressable register + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A + mov r31=pr // I0 save pr (2 cyc) ;; - mov r23=ar.bspstore // save ar.bspstore (12 cyc) - mov r31=pr // save pr (2 cyc) - mov r20=r1 // save caller's gp in r20 + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + addl r22=IA64_RBS_OFFSET,r2 // A compute base of RBS + add r3=TI_FLAGS+IA64_TASK_SIZE,r2 // A ;; - mov r2=r16 // copy current task addr to addl-addressable register - and r9=r9,r29 - mov r19=b6 // save b6 (2 cyc) + ld4 r3=[r3] // M0|1 r3 = current_thread_info()->flags + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch register backing-store + nop.i 0 ;; - mov psr.l=r9 // slam the door (17 cyc to srlz.i) - or r29=r8,r29 // construct cr.ipsr value to save - addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS + mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 + nop.m 0 + nop.i 0 ;; - // GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks - // we may be reading ar.itc after writing to psr.l. Avoid that message with - // this directive: - dv_serialize_data - mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) - lfetch.fault.excl.nt1 [r22] - adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2 - - // ensure previous insn group is issued before we stall for srlz.i: + mov r23=ar.bspstore // M2 (12 cyc) save ar.bspstore + mov.m r24=ar.rnat // M2 (5 cyc) read ar.rnat (dual-issues!) + nop.i 0 ;; - srlz.i // ensure new psr.l has been established - ///////////////////////////////////////////////////////////////////////////// - ////////// from this point on, execution is not interruptible anymore - ///////////////////////////////////////////////////////////////////////////// - addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack - cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 + mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS + movl r8=PSR_ONE_BITS // X ;; - st1 [r16]=r0 // clear current->thread.on_ustack flag - mov ar.bspstore=r22 // switch to kernel RBS - mov b6=r18 // copy syscall entry-point to b6 (7 cyc) - add r3=TI_FLAGS+IA64_TASK_SIZE,r2 + mov r25=ar.unat // M2 (5 cyc) save ar.unat + mov r19=b6 // I0 save b6 (2 cyc) + mov r20=r1 // A save caller's gp in r20 ;; - ld4 r3=[r3] // r2 = current_thread_info()->flags - mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc) - mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 - br.call.sptk.many b7=ia64_syscall_setup - ;; - ssm psr.i - movl r2=ia64_ret_from_syscall + or r29=r8,r29 // A construct cr.ipsr value to save + mov b6=r18 // I0 copy syscall entry-point to b6 (7 cyc) + addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack + + mov r18=ar.bsp // M2 save (kernel) ar.bsp (12 cyc) + cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1 + br.call.sptk.many b7=ia64_syscall_setup // B ;; - mov rp=r2 // set the real return addr - and r3=_TIF_SYSCALL_TRACEAUDIT,r3 + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + mov rp=r14 // I0 set the real return addr + and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A ;; - cmp.eq p8,p0=r3,r0 + ssm psr.i // M2 we're on kernel stacks now, reenable irqs + cmp.eq p8,p0=r3,r0 // A +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT -(p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall + nop.m 0 +(p8) br.call.sptk.many b6=b6 // B (ignore return address) + br.cond.spnt ia64_trace_syscall // B END(fsys_bubble_down) .rodata diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index facf75acdc85..86948ce63e43 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -72,38 +72,40 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * bundle get executed. The remaining code must be safe even if * they do not get executed. */ - adds r17=-1024,r15 - mov r10=0 // default to successful syscall execution - epc + adds r17=-1024,r15 // A + mov r10=0 // A default to successful syscall execution + epc // B causes split-issue } ;; - rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be" - LOAD_FSYSCALL_TABLE(r14) - - mov r16=IA64_KR(CURRENT) // 12 cycle read latency - tnat.nz p10,p9=r15 - mov r19=NR_syscalls-1 + rsm psr.be | psr.i // M2 (5 cyc to srlz.d) + LOAD_FSYSCALL_TABLE(r14) // X ;; - shladd r18=r17,3,r14 - - srlz.d - cmp.ne p8,p0=r0,r0 // p8 <- FALSE - /* Note: if r17 is a NaT, p6 will be set to zero. */ - cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? - ;; -(p6) ld8 r18=[r18] - mov r21=ar.fpsr - add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry - ;; -(p6) mov b7=r18 -(p6) tbit.z p8,p0=r18,0 -(p8) br.dptk.many b7 - -(p6) rsm psr.i - mov r27=ar.rsc - mov r26=ar.pfs + mov r16=IA64_KR(CURRENT) // M2 (12 cyc) + shladd r18=r17,3,r14 // A + mov r19=NR_syscalls-1 // A + ;; + lfetch [r18] // M0|1 + mov r29=psr // M2 (12 cyc) + // If r17 is a NaT, p6 will be zero + cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? + ;; + mov r21=ar.fpsr // M2 (12 cyc) + tnat.nz p10,p9=r15 // I0 + mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) + ;; + srlz.d // M0 (forces split-issue) ensure PSR.BE==0 +(p6) ld8 r18=[r18] // M0|1 + nop.i 0 + ;; + nop.m 0 +(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) + nop.i 0 ;; - mov r29=psr // read psr (12 cyc load latency) +(p8) ssm psr.i +(p6) mov b7=r18 // I0 +(p8) br.dptk.many b7 // B + + mov r27=ar.rsc // M2 (12 cyc) /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some @@ -111,6 +113,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * instead. */ #ifdef CONFIG_ITANIUM +(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry + ;; (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down ;; (p6) mov b7=r14 @@ -118,7 +122,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) #else BRL_COND_FSYS_BUBBLE_DOWN(p6) #endif - + ssm psr.i mov r10=-1 (p10) mov r8=EINVAL (p9) mov r8=ENOSYS diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 7bbf019c9867..01572814abe4 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -58,9 +58,6 @@ EXPORT_SYMBOL(__strlen_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(__strnlen_user); -#include <asm/unistd.h> -EXPORT_SYMBOL(__ia64_syscall); - /* from arch/ia64/lib */ extern void __divsi3(void); extern void __udivsi3(void); diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 88b014381df5..c170be095ccd 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -129,14 +129,13 @@ static struct iosapic { char __iomem *addr; /* base address of IOSAPIC */ unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ unsigned short num_rte; /* number of RTE in this IOSAPIC */ + int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ #ifdef CONFIG_NUMA unsigned short node; /* numa node association via pxm */ #endif } iosapic_lists[NR_IOSAPICS]; -static int num_iosapic; - -static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */ +static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ static int iosapic_kmalloc_ok; static LIST_HEAD(free_rte_list); @@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi) { int i; - for (i = 0; i < num_iosapic; i++) { + for (i = 0; i < NR_IOSAPICS; i++) { if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) return i; } @@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, rte->refcnt++; list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); iosapic_intr_info[vector].count++; + iosapic_lists[index].rtes_inuse++; } else if (vector_is_shared(vector)) { struct iosapic_intr_info *info = &iosapic_intr_info[vector]; @@ -778,7 +778,7 @@ void iosapic_unregister_intr (unsigned int gsi) { unsigned long flags; - int irq, vector; + int irq, vector, index; irq_desc_t *idesc; u32 low32; unsigned long trigger, polarity; @@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi) list_del(&rte->rte_list); iosapic_intr_info[vector].count--; iosapic_free_rte(rte); + index = find_iosapic(gsi); + iosapic_lists[index].rtes_inuse--; + WARN_ON(iosapic_lists[index].rtes_inuse < 0); trigger = iosapic_intr_info[vector].trigger; polarity = iosapic_intr_info[vector].polarity; @@ -952,30 +955,86 @@ iosapic_system_init (int system_pcat_compat) } } -void __init +static inline int +iosapic_alloc (void) +{ + int index; + + for (index = 0; index < NR_IOSAPICS; index++) + if (!iosapic_lists[index].addr) + return index; + + printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__); + return -1; +} + +static inline void +iosapic_free (int index) +{ + memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0])); +} + +static inline int +iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) +{ + int index; + unsigned int gsi_end, base, end; + + /* check gsi range */ + gsi_end = gsi_base + ((ver >> 16) & 0xff); + for (index = 0; index < NR_IOSAPICS; index++) { + if (!iosapic_lists[index].addr) + continue; + + base = iosapic_lists[index].gsi_base; + end = base + iosapic_lists[index].num_rte - 1; + + if (gsi_base < base && gsi_end < base) + continue;/* OK */ + + if (gsi_base > end && gsi_end > end) + continue; /* OK */ + + return -EBUSY; + } + return 0; +} + +int __devinit iosapic_init (unsigned long phys_addr, unsigned int gsi_base) { - int num_rte; + int num_rte, err, index; unsigned int isa_irq, ver; char __iomem *addr; + unsigned long flags; + + spin_lock_irqsave(&iosapic_lock, flags); + { + addr = ioremap(phys_addr, 0); + ver = iosapic_version(addr); - addr = ioremap(phys_addr, 0); - ver = iosapic_version(addr); + if ((err = iosapic_check_gsi_range(gsi_base, ver))) { + iounmap(addr); + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; + } - /* - * The MAX_REDIR register holds the highest input pin - * number (starting from 0). - * We add 1 so that we can use it for number of pins (= RTEs) - */ - num_rte = ((ver >> 16) & 0xff) + 1; + /* + * The MAX_REDIR register holds the highest input pin + * number (starting from 0). + * We add 1 so that we can use it for number of pins (= RTEs) + */ + num_rte = ((ver >> 16) & 0xff) + 1; - iosapic_lists[num_iosapic].addr = addr; - iosapic_lists[num_iosapic].gsi_base = gsi_base; - iosapic_lists[num_iosapic].num_rte = num_rte; + index = iosapic_alloc(); + iosapic_lists[index].addr = addr; + iosapic_lists[index].gsi_base = gsi_base; + iosapic_lists[index].num_rte = num_rte; #ifdef CONFIG_NUMA - iosapic_lists[num_iosapic].node = MAX_NUMNODES; + iosapic_lists[index].node = MAX_NUMNODES; #endif - num_iosapic++; + } + spin_unlock_irqrestore(&iosapic_lock, flags); if ((gsi_base == 0) && pcat_compat) { /* @@ -986,10 +1045,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) for (isa_irq = 0; isa_irq < 16; ++isa_irq) iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } + return 0; +} + +#ifdef CONFIG_HOTPLUG +int +iosapic_remove (unsigned int gsi_base) +{ + int index, err = 0; + unsigned long flags; + + spin_lock_irqsave(&iosapic_lock, flags); + { + index = find_iosapic(gsi_base); + if (index < 0) { + printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", + __FUNCTION__, gsi_base); + goto out; + } + + if (iosapic_lists[index].rtes_inuse) { + err = -EBUSY; + printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", + __FUNCTION__, gsi_base); + goto out; + } + + iounmap(iosapic_lists[index].addr); + iosapic_free(index); + } + out: + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; } +#endif /* CONFIG_HOTPLUG */ #ifdef CONFIG_NUMA -void __init +void __devinit map_iosapic_to_node(unsigned int gsi_base, int node) { int index; diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 2bc085a73e30..3bb3a13c4047 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -1,7 +1,7 @@ /* * arch/ia64/kernel/ivt.S * - * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co + * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co * Stephane Eranian <eranian@hpl.hp.com> * David Mosberger <davidm@hpl.hp.com> * Copyright (C) 2000, 2002-2003 Intel Co @@ -692,82 +692,118 @@ ENTRY(break_fault) * to prevent leaking bits from kernel to user level. */ DBG_FAULT(11) - mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat. - mov r17=cr.iim - mov r18=__IA64_BREAK_SYSCALL - mov r21=ar.fpsr - mov r29=cr.ipsr - mov r19=b6 - mov r25=ar.unat - mov r27=ar.rsc - mov r26=ar.pfs - mov r28=cr.iip - mov r31=pr // prepare to save predicates - mov r20=r1 - ;; + mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) + mov r29=cr.ipsr // M2 (12 cyc) + mov r31=pr // I0 (2 cyc) + + mov r17=cr.iim // M2 (2 cyc) + mov.m r27=ar.rsc // M2 (12 cyc) + mov r18=__IA64_BREAK_SYSCALL // A + + mov.m ar.rsc=0 // M2 + mov.m r21=ar.fpsr // M2 (12 cyc) + mov r19=b6 // I0 (2 cyc) + ;; + mov.m r23=ar.bspstore // M2 (12 cyc) + mov.m r24=ar.rnat // M2 (5 cyc) + mov.i r26=ar.pfs // I0 (2 cyc) + + invala // M0|1 + nop.m 0 // M + mov r20=r1 // A save r1 + + nop.m 0 + movl r30=sys_call_table // X + + mov r28=cr.iip // M2 (2 cyc) + cmp.eq p0,p7=r18,r17 // I0 is this a system call? +(p7) br.cond.spnt non_syscall // B no -> + // + // From this point on, we are definitely on the syscall-path + // and we can use (non-banked) scratch registers. + // +/////////////////////////////////////////////////////////////////////// + mov r1=r16 // A move task-pointer to "addl"-addressable reg + mov r2=r16 // A setup r2 for ia64_syscall_setup + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 - cmp.eq p0,p7=r18,r17 // is this a system call? (p7 <- false, if so) -(p7) br.cond.spnt non_syscall + adds r15=-1024,r15 // A subtract 1024 from syscall number + mov r3=NR_syscalls - 1 ;; - ld1 r17=[r16] // load current->thread.on_ustack flag - st1 [r16]=r0 // clear current->thread.on_ustack flag - add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // set r1 for MINSTATE_START_SAVE_MIN_VIRT + ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag + ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags + extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr + + shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) + addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS + cmp.leu p6,p7=r15,r3 // A syscall number in range? ;; - invala - /* adjust return address so we skip over the break instruction: */ + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS +(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point + tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? - extr.u r8=r29,41,2 // extract ei field from cr.ipsr - ;; - cmp.eq p6,p7=2,r8 // isr.ei==2? - mov r2=r1 // setup r2 for ia64_syscall_setup - ;; -(p6) mov r8=0 // clear ei to 0 -(p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped -(p7) adds r8=1,r8 // increment ei to next slot - ;; - cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already? - dep r29=r8,r29,41,2 // insert new ei into cr.ipsr + mov.m ar.bspstore=r22 // M2 switch to kernel RBS + cmp.eq p8,p9=2,r8 // A isr.ei==2? ;; - // switch from user to kernel RBS: - MINSTATE_START_SAVE_MIN_VIRT - br.call.sptk.many b7=ia64_syscall_setup - ;; - MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1 - ssm psr.ic | PSR_DEFAULT_BITS - ;; - srlz.i // guarantee that interruption collection is on - mov r3=NR_syscalls - 1 - ;; -(p15) ssm psr.i // restore psr.i - // p10==true means out registers are more than 8 or r15's Nat is true -(p10) br.cond.spnt.many ia64_ret_from_syscall - ;; - movl r16=sys_call_table +(p8) mov r8=0 // A clear ei to 0 +(p7) movl r30=sys_ni_syscall // X - adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 - movl r2=ia64_ret_from_syscall - ;; - shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) - cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ? - mov rp=r2 // set the real return addr +(p8) adds r28=16,r28 // A switch cr.iip to next bundle +(p9) adds r8=1,r8 // A increment ei to next slot + nop.i 0 ;; -(p6) ld8 r20=[r20] // load address of syscall entry point -(p7) movl r20=sys_ni_syscall - add r2=TI_FLAGS+IA64_TASK_SIZE,r13 - ;; - ld4 r2=[r2] // r2 = current_thread_info()->flags - ;; - and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit + mov.m r25=ar.unat // M2 (5 cyc) + dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr + adds r15=1024,r15 // A restore original syscall number + // + // If any of the above loads miss in L1D, we'll stall here until + // the data arrives. + // +/////////////////////////////////////////////////////////////////////// + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + mov b6=r30 // I0 setup syscall handler branch reg early + cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? + + and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit + mov r18=ar.bsp // M2 (12 cyc) +(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS + ;; +.back_from_break_fixup: +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack + cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? + br.call.sptk.many b7=ia64_syscall_setup // B +1: + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + nop 0 + bsw.1 // B (6 cyc) regs are saved, switch to bank 1 ;; - cmp.eq p8,p0=r2,r0 - mov b6=r20 + + ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection + movl r3=ia64_ret_from_syscall // X ;; -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall + + srlz.i // M0 ensure interruption collection is on + mov rp=r3 // I0 set the real return addr +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT + +(p15) ssm psr.i // M2 restore psr.i +(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) + br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic // NOT REACHED +/////////////////////////////////////////////////////////////////////// + // On entry, we optimistically assumed that we're coming from user-space. + // For the rare cases where a system-call is done from within the kernel, + // we fix things up at this point: +.break_fixup: + add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure + mov ar.rnat=r24 // M2 restore kernel's AR.RNAT + ;; + mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE + br.cond.sptk .back_from_break_fixup END(break_fault) .org ia64_ivt+0x3000 @@ -842,8 +878,6 @@ END(interrupt) * - r31: saved pr * - b0: original contents (to be saved) * On exit: - * - executing on bank 1 registers - * - psr.ic enabled, interrupts restored * - p10: TRUE if syscall is invoked with more than 8 out * registers or r15's Nat is true * - r1: kernel's gp @@ -851,8 +885,11 @@ END(interrupt) * - r8: -EINVAL if p10 is true * - r12: points to kernel stack * - r13: points to current task + * - r14: preserved (same as on entry) + * - p13: preserved * - p15: TRUE if interrupts need to be re-enabled * - ar.fpsr: set to kernel settings + * - b6: preserved (same as on entry) */ GLOBAL_ENTRY(ia64_syscall_setup) #if PT(B6) != 0 @@ -920,10 +957,10 @@ GLOBAL_ENTRY(ia64_syscall_setup) (p13) mov in5=-1 ;; st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr - tnat.nz p14,p0=in6 + tnat.nz p13,p0=in6 cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 ;; - stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) + mov r8=1 (p9) tnat.nz p10,p0=r15 adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) @@ -934,9 +971,9 @@ GLOBAL_ENTRY(ia64_syscall_setup) mov r13=r2 // establish `current' movl r1=__gp // establish kernel global pointer ;; -(p14) mov in6=-1 + st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) +(p13) mov in6=-1 (p8) mov in7=-1 - nop.i 0 cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 movl r17=FPSR_DEFAULT @@ -1007,6 +1044,8 @@ END(dispatch_illegal_op_fault) FAULT(17) ENTRY(non_syscall) + mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER + ;; SAVE_MIN_WITH_COVER // There is no particular reason for this code to be here, other than that @@ -1204,6 +1243,25 @@ END(disabled_fp_reg) // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) ENTRY(nat_consumption) DBG_FAULT(26) + + mov r16=cr.ipsr + mov r17=cr.isr + mov r31=pr // save PR + ;; + and r18=0xf,r17 // r18 = cr.ipsr.code{3:0} + tbit.z p6,p0=r17,IA64_ISR_NA_BIT + ;; + cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18 + dep r16=-1,r16,IA64_PSR_ED_BIT,1 +(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH) + ;; + mov cr.ipsr=r16 // set cr.ipsr.na + mov pr=r31,-1 + ;; + rfi + +1: mov pr=r31,-1 + ;; FAULT(26) END(nat_consumption) diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 3aa3167edbec..884f5cd27d8a 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -713,7 +713,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { trampoline_p.addr = (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 6d57aebad485..bbb8bc7c0552 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -725,12 +725,32 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, break; } + /* + * Note: at the time of this call, the target task is blocked + * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL + * (aka, "pLvSys") we redirect execution from + * .work_pending_syscall_end to .work_processed_kernel. + */ unw_get_pr(&prev_info, &pr); - pr &= ~(1UL << PRED_SYSCALL); + pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL)); pr |= (1UL << PRED_NON_SYSCALL); unw_set_pr(&prev_info, pr); pt->cr_ifs = (1UL << 63) | cfm; + /* + * Clear the memory that is NOT written on syscall-entry to + * ensure we do not leak kernel-state to user when execution + * resumes. + */ + pt->r2 = 0; + pt->r3 = 0; + pt->r14 = 0; + memset(&pt->r16, 0, 16*8); /* clear r16-r31 */ + memset(&pt->f6, 0, 6*16); /* clear f6-f11 */ + pt->b7 = 0; + pt->ar_ccv = 0; + pt->ar_csd = 0; + pt->ar_ssd = 0; } static int diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index d14692e0920a..2693e1522d7c 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -72,6 +72,8 @@ DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); unsigned long ia64_cycles_per_usec; struct ia64_boot_param *ia64_boot_param; struct screen_info screen_info; +unsigned long vga_console_iobase; +unsigned long vga_console_membase; unsigned long ia64_max_cacheline_size; unsigned long ia64_iobase; /* virtual address for I/O accesses */ @@ -273,23 +275,25 @@ io_port_init (void) static inline int __init early_console_setup (char *cmdline) { + int earlycons = 0; + #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE { extern int sn_serial_console_early_setup(void); if (!sn_serial_console_early_setup()) - return 0; + earlycons++; } #endif #ifdef CONFIG_EFI_PCDP if (!efi_setup_pcdp_console(cmdline)) - return 0; + earlycons++; #endif #ifdef CONFIG_SERIAL_8250_CONSOLE if (!early_serial_console_init(cmdline)) - return 0; + earlycons++; #endif - return -1; + return (earlycons) ? 0 : -1; } static inline void diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index b49d4ddaab93..0166a9847095 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -231,13 +231,16 @@ smp_flush_tlb_all (void) void smp_flush_tlb_mm (struct mm_struct *mm) { + preempt_disable(); /* this happens for the common case of a single-threaded fork(): */ if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1)) { local_finish_flush_tlb_mm(mm); + preempt_enable(); return; } + preempt_enable(); /* * We could optimize this further by using mm->cpu_vm_mask to track which CPUs * have been running in the address space. It's not clear that this is worth the diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index e3fc4edea113..720a861f88be 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, &info); - pbus = pci_scan_bus(bus, &pci_root_ops, controller); + pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); if (pbus) pcibios_setup_root_windows(pbus, controller); @@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev, res->end = region->end + offset; } +static int __devinit is_valid_resource(struct pci_dev *dev, int idx) +{ + unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; + struct resource *devr = &dev->resource[idx]; + + if (!dev->bus) + return 0; + for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) { + struct resource *busr = dev->bus->resource[i]; + + if (!busr || ((busr->flags ^ devr->flags) & type_mask)) + continue; + if ((devr->start) && (devr->start >= busr->start) && + (devr->end <= busr->end)) + return 1; + } + return 0; +} + static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) { struct pci_bus_region region; @@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) region.start = dev->resource[i].start; region.end = dev->resource[i].end; pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); - pci_claim_resource(dev, i); + if ((is_valid_resource(dev, i))) + pci_claim_resource(dev, i); } } @@ -398,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b) { struct pci_dev *dev; + if (b->self) { + pci_read_bridge_bases(b); + pcibios_fixup_device_resources(b->self); + } list_for_each_entry(dev, &b->devices, bus_list) pcibios_fixup_device_resources(dev); @@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) u16 cmd, old_cmd; int idx; struct resource *r; + unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; if (!dev) return -EINVAL; pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for (idx=0; idx<6; idx++) { + for (idx=0; idx<PCI_NUM_RESOURCES; idx++) { /* Only set up the desired resources. */ if (!(mask & (1 << idx))) continue; r = &dev->resource[idx]; + if (!(r->flags & type_mask)) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", @@ -441,8 +471,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) if (r->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 9e07f5463f21..783eb4323847 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -384,7 +384,7 @@ static int __init sn_pci_init(void) extern void register_sn_procfs(void); #endif - if (!ia64_platform_is("sn2") || IS_RUNNING_ON_SIMULATOR()) + if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; /* diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c index fec6d8b8237b..7ce3cdad627b 100644 --- a/arch/ia64/sn/kernel/iomv.c +++ b/arch/ia64/sn/kernel/iomv.c @@ -9,12 +9,16 @@ #include <linux/module.h> #include <asm/io.h> #include <asm/delay.h> +#include <asm/vga.h> #include <asm/sn/nodepda.h> #include <asm/sn/simulator.h> #include <asm/sn/pda.h> #include <asm/sn/sn_cpuid.h> #include <asm/sn/shub_mmr.h> +#define IS_LEGACY_VGA_IOPORT(p) \ + (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df)) + /** * sn_io_addr - convert an in/out port to an i/o address * @port: port to convert @@ -26,6 +30,8 @@ void *sn_io_addr(unsigned long port) { if (!IS_RUNNING_ON_SIMULATOR()) { + if (IS_LEGACY_VGA_IOPORT(port)) + port += vga_console_iobase; /* On sn2, legacy I/O ports don't point at anything */ if (port < (64 * 1024)) return NULL; diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 44bfc7f318cb..22e10d282c7f 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -36,6 +36,7 @@ #include <asm/machvec.h> #include <asm/system.h> #include <asm/processor.h> +#include <asm/vga.h> #include <asm/sn/arch.h> #include <asm/sn/addrs.h> #include <asm/sn/pda.h> @@ -95,6 +96,7 @@ u8 sn_coherency_id; EXPORT_SYMBOL(sn_coherency_id); u8 sn_region_size; EXPORT_SYMBOL(sn_region_size); +int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ short physical_node_map[MAX_PHYSNODE_ID]; @@ -273,14 +275,17 @@ void __init sn_setup(char **cmdline_p) ia64_sn_plat_set_error_handling_features(); +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) /* - * If the generic code has enabled vga console support - lets - * get rid of it again. This is a kludge for the fact that ACPI - * currtently has no way of informing us if legacy VGA is available - * or not. + * If there was a primary vga adapter identified through the + * EFI PCDP table, make it the preferred console. Otherwise + * zero out conswitchp. */ -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - if (conswitchp == &vga_con) { + + if (vga_console_membase) { + /* usable vga ... make tty0 the preferred default console */ + add_preferred_console("tty", 0, NULL); + } else { printk(KERN_DEBUG "SGI: Disabling VGA console\n"); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -350,7 +355,7 @@ void __init sn_setup(char **cmdline_p) ia64_mark_idle = &snidle; - /* + /* * For the bootcpu, we do this here. All other cpus will make the * call as part of cpu_init in slave cpu initialization. */ @@ -397,7 +402,7 @@ static void __init sn_init_pdas(char **cmdline_p) nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t)); memset(nodepdaindr[cnode], 0, sizeof(nodepda_t)); - memset(nodepdaindr[cnode]->phys_cpuid, -1, + memset(nodepdaindr[cnode]->phys_cpuid, -1, sizeof(nodepdaindr[cnode]->phys_cpuid)); } @@ -427,7 +432,7 @@ static void __init sn_init_pdas(char **cmdline_p) } /* - * Initialize the per node hubdev. This includes IO Nodes and + * Initialize the per node hubdev. This includes IO Nodes and * headless/memless nodes. */ for (cnode = 0; cnode < numionodes; cnode++) { @@ -455,6 +460,14 @@ void __init sn_cpu_init(void) int i; static int wars_have_been_checked; + if (smp_processor_id() == 0 && IS_MEDUSA()) { + if (ia64_sn_is_fake_prom()) + sn_prom_type = 2; + else + sn_prom_type = 1; + printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake"); + } + memset(pda, 0, sizeof(pda)); if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift, &sn_system_size, &sn_sharing_domain_size, &sn_partition_id, @@ -520,7 +533,7 @@ void __init sn_cpu_init(void) */ { u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0}; - u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, + u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3}; u64 *pio; pio = is_shub1() ? pio1 : pio2; @@ -552,6 +565,10 @@ static void __init scan_for_ionodes(void) int nasid = 0; lboard_t *brd; + /* fakeprom does not support klgraph */ + if (IS_RUNNING_ON_FAKE_PROM()) + return; + /* Setup ionodes with memory */ for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) { char *klgraph_header; @@ -563,8 +580,6 @@ static void __init scan_for_ionodes(void) cnodeid = -1; klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid)); if (!klgraph_header) { - if (IS_RUNNING_ON_SIMULATOR()) - continue; BUG(); /* All nodes must have klconfig tables! */ } cnodeid = nasid_to_cnodeid(nasid); @@ -630,8 +645,8 @@ int nasid_slice_to_cpuid(int nasid, int slice) { long cpu; - - for (cpu=0; cpu < NR_CPUS; cpu++) + + for (cpu=0; cpu < NR_CPUS; cpu++) if (cpuid_to_nasid(cpu) == nasid && cpuid_to_slice(cpu) == slice) return cpu; diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S index 7947312801ec..96cb71d15682 100644 --- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S +++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S @@ -6,6 +6,7 @@ * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. */ +#include <asm/types.h> #include <asm/sn/shub_mmr.h> #define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index a087b274847e..8716f4d5314b 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -204,8 +204,8 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, cx_dev->dev.parent = NULL; cx_dev->dev.bus = &tiocx_bus_type; cx_dev->dev.release = tiocx_bus_release; - snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d.0x%x", - cx_dev->cx_id.nasid, cx_dev->cx_id.part_num); + snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d", + cx_dev->cx_id.nasid); device_register(&cx_dev->dev); get_device(&cx_dev->dev); @@ -236,7 +236,6 @@ int cx_device_unregister(struct cx_dev *cx_dev) */ static int cx_device_reload(struct cx_dev *cx_dev) { - device_remove_file(&cx_dev->dev, &dev_attr_cxdev_control); cx_device_unregister(cx_dev); return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, cx_dev->hubdev); @@ -383,6 +382,7 @@ static int is_fpga_brick(int nasid) switch (tiocx_btchar_get(nasid)) { case L1_BRICKTYPE_SA: case L1_BRICKTYPE_ATHENA: + case L1_BRICKTYPE_DAYTONA: return 1; } return 0; @@ -409,7 +409,7 @@ static int tiocx_reload(struct cx_dev *cx_dev) uint64_t cx_id; cx_id = - *(volatile int32_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + + *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + WIDGET_ID); part_num = XWIDGET_PART_NUM(cx_id); mfg_num = XWIDGET_MFG_NUM(cx_id); @@ -458,6 +458,10 @@ static ssize_t store_cxdev_control(struct device *dev, struct device_attribute * switch (n) { case 1: + tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET); + tiocx_reload(cx_dev); + break; + case 2: tiocx_reload(cx_dev); break; case 3: @@ -537,7 +541,7 @@ static void __exit tiocx_exit(void) bus_unregister(&tiocx_bus_type); } -module_init(tiocx_init); +subsys_initcall(tiocx_init); module_exit(tiocx_exit); /************************************************************************ diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 8dae9eb45456..05aa8c2fe9bb 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -336,7 +336,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) if (!ct_addr) return 0; - bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff); + bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL); node_upper = ct_addr >> 48; if (node_upper > 64) { @@ -464,7 +464,7 @@ map_return: * For mappings created using the direct modes (64 or 48) there are no * resources to release. */ -void +static void tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) { int i, entry; @@ -514,7 +514,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) * The mapping mode used is based on the devices dma_mask. As a last resort * use the GART mapped mode. */ -uint64_t +static uint64_t tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) { uint64_t mapaddr; @@ -580,7 +580,7 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) * On successful setup, returns the kernel version of tioca_common back to * the caller. */ -void * +static void * tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) { struct tioca_common *tioca_common; diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig index 872085dea8a8..6efaa9293eef 100644 --- a/arch/parisc/configs/712_defconfig +++ b/arch/parisc/configs/712_defconfig @@ -506,7 +506,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=17 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig index d28ebfa1070d..30fc03ed0cfb 100644 --- a/arch/parisc/configs/a500_defconfig +++ b/arch/parisc/configs/a500_defconfig @@ -662,7 +662,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=17 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig index 1700d7aec686..46c9511f3229 100644 --- a/arch/parisc/configs/b180_defconfig +++ b/arch/parisc/configs/b180_defconfig @@ -514,7 +514,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig index b27980161c31..67aca6ccc9b0 100644 --- a/arch/parisc/configs/c3000_defconfig +++ b/arch/parisc/configs/c3000_defconfig @@ -661,7 +661,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig index ebd6301aa599..fdae21c503d7 100644 --- a/arch/parisc/defconfig +++ b/arch/parisc/defconfig @@ -517,7 +517,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index 4ea7158e5062..ece6a9fbe09b 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -714,16 +714,24 @@ static int __init scc_enet_init(void) immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */ #endif /* PC_ENET_LBK */ - /* Configure port C pins to enable CLSN and RENA. +#ifdef PE_ENET_TCLK + /* Configure port E for TCLK and RCLK. */ - immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); - + cp->cp_pepar |= (PE_ENET_TCLK | PE_ENET_RCLK); + cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK); + cp->cp_peso &= ~(PE_ENET_TCLK | PE_ENET_RCLK); +#else /* Configure port A for TCLK and RCLK. */ immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK); immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK); +#endif + + /* Configure port C pins to enable CLSN and RENA. + */ + immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); + immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); + immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. @@ -896,14 +904,18 @@ static int __init scc_enet_init(void) /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. */ -#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA)) +#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA) && !defined (PE_ENET_TENA)) immap->im_ioport.iop_pcpar |= PC_ENET_TENA; immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; -#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA)) +#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA)) cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; +#elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA)) + cp->cp_pepar |= PE_ENET_TENA; + cp->cp_pedir &= ~PE_ENET_TENA; + cp->cp_peso |= PE_ENET_TENA; #else -#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA +#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA #endif #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) @@ -936,6 +948,29 @@ static int __init scc_enet_init(void) *((volatile uint *)BCSR1) &= ~BCSR1_ETHEN; #endif +#ifdef CONFIG_MPC885ADS + + /* Deassert PHY reset and enable the PHY. + */ + { + volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE); + uint tmp; + + tmp = in_be32(bcsr + 1 /* BCSR1 */); + tmp |= BCSR1_ETHEN; + out_be32(bcsr + 1, tmp); + tmp = in_be32(bcsr + 4 /* BCSR4 */); + tmp |= BCSR4_ETH10_RST; + out_be32(bcsr + 4, tmp); + iounmap(bcsr); + } + + /* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode + * upon reset. SCC is set to half duplex by default. So this + * inconsistency should be better fixed by the software. + */ +#endif + dev->base_addr = (unsigned long)ep; #if 0 dev->name = "CPM_ENET"; @@ -969,3 +1004,4 @@ static int __init scc_enet_init(void) } module_init(scc_enet_init); + diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index a7835cd3f51f..23b0d2f662c5 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -284,6 +284,9 @@ endmenu menu "Platform options" +config FADS + bool + choice prompt "8xx Machine Type" depends on 8xx @@ -399,8 +402,25 @@ config BSEIP 26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video controller, and two RS232 ports. -config FADS +config MPC8XXFADS bool "FADS" + select FADS + +config MPC86XADS + bool "MPC86XADS" + help + MPC86x Application Development System by Freescale Semiconductor. + The MPC86xADS is meant to serve as a platform for s/w and h/w + development around the MPC86X processor families. + select FADS + +config MPC885ADS + bool "MPC885ADS" + help + Freescale Semiconductor MPC885 Application Development System (ADS). + Also known as DUET. + The MPC885ADS is meant to serve as a platform for s/w and h/w + development around the MPC885 processor family. config TQM823L bool "TQM823L" diff --git a/arch/ppc/configs/mpc86x_ads_defconfig b/arch/ppc/configs/mpc86x_ads_defconfig new file mode 100644 index 000000000000..f63c6f59d68a --- /dev/null +++ b/arch/ppc/configs/mpc86x_ads_defconfig @@ -0,0 +1,633 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc4 +# Tue Jun 14 13:36:35 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_SHMEM is not set +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=1 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +CONFIG_8xx=y +# CONFIG_E500 is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_CPU_FREQ is not set +CONFIG_EMBEDDEDBOOT=y +# CONFIG_PM is not set +CONFIG_NOT_COHERENT_CACHE=y + +# +# Platform options +# +CONFIG_FADS=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_MPC8XXFADS is not set +CONFIG_MPC86XADS=y +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_IVML24 is not set +# CONFIG_SM850 is not set +# CONFIG_HERMES_PRO is not set +# CONFIG_IP860 is not set +# CONFIG_LWMON is not set +# CONFIG_PCU_E is not set +# CONFIG_CCM is not set +# CONFIG_LANTEC is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_QSPAN is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_BOOT_LOAD=0x00400000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_LBD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# 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 is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_OAKNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# 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 +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# 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_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_CPM=y +CONFIG_SERIAL_CPM_CONSOLE=y +# CONFIG_SERIAL_CPM_SCC1 is not set +# CONFIG_SERIAL_CPM_SCC2 is not set +# CONFIG_SERIAL_CPM_SCC3 is not set +# CONFIG_SERIAL_CPM_SCC4 is not set +CONFIG_SERIAL_CPM_SMC1=y +# CONFIG_SERIAL_CPM_SMC2 is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +CONFIG_SCC1_ENET=y +# CONFIG_SCC2_ENET is not set +# CONFIG_SCC3_ENET is not set +# CONFIG_FEC_ENET is not set +# CONFIG_ENET_BIG_BUFFERS is not set + +# +# Generic MPC8xx Options +# +# CONFIG_8xx_COPYBACK is not set +# CONFIG_8xx_CPU6 is not set +CONFIG_NO_UCODE_PATCH=y +# CONFIG_USB_SOF_UCODE_PATCH is not set +# CONFIG_I2C_SPI_UCODE_PATCH is not set +# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# diff --git a/arch/ppc/configs/mpc885ads_defconfig b/arch/ppc/configs/mpc885ads_defconfig new file mode 100644 index 000000000000..016f94d9325f --- /dev/null +++ b/arch/ppc/configs/mpc885ads_defconfig @@ -0,0 +1,622 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc6 +# Thu Jun 9 21:17:29 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +CONFIG_8xx=y +# CONFIG_E500 is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_CPU_FREQ is not set +CONFIG_EMBEDDEDBOOT=y +# CONFIG_PM is not set +CONFIG_NOT_COHERENT_CACHE=y + +# +# Platform options +# +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_FADS is not set +CONFIG_MPC885ADS=y +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_IVML24 is not set +# CONFIG_SM850 is not set +# CONFIG_HERMES_PRO is not set +# CONFIG_IP860 is not set +# CONFIG_LWMON is not set +# CONFIG_PCU_E is not set +# CONFIG_CCM is not set +# CONFIG_LANTEC is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_QSPAN is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_BOOT_LOAD=0x00400000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_LBD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_OAKNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_PPP_DEFLATE=y +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# 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_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_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_CPM=y +CONFIG_SERIAL_CPM_CONSOLE=y +# CONFIG_SERIAL_CPM_SCC1 is not set +# CONFIG_SERIAL_CPM_SCC2 is not set +# CONFIG_SERIAL_CPM_SCC3 is not set +# CONFIG_SERIAL_CPM_SCC4 is not set +CONFIG_SERIAL_CPM_SMC1=y +CONFIG_SERIAL_CPM_SMC2=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +# CONFIG_SCC1_ENET is not set +# CONFIG_SCC2_ENET is not set +CONFIG_SCC3_ENET=y +# CONFIG_FEC_ENET is not set +# CONFIG_ENET_BIG_BUFFERS is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +CONFIG_8xx_CPU6=y +CONFIG_NO_UCODE_PATCH=y +# CONFIG_USB_SOF_UCODE_PATCH is not set +# CONFIG_I2C_SPI_UCODE_PATCH is not set +# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=y +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6d7b92d72458..70cfb6ffd877 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = (unsigned long)hose->io_base_virt; + io_offset = hose->io_base_virt - ___IO_BASE; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* found it! construct the final physical address */ if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - _IO_BASE; + *offset += hose->io_base_phys - io_offset; return rp; } @@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) return result; } +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end) +{ + struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); + unsigned long offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; + + *start = rsrc->start + offset; + *end = rsrc->end + offset; +} + void __init pci_init_resource(struct resource *res, unsigned long start, unsigned long end, int flags, char *name) diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S index 7ff69c4af920..9b2ad48e988c 100644 --- a/arch/ppc/kernel/relocate_kernel.S +++ b/arch/ppc/kernel/relocate_kernel.S @@ -34,9 +34,9 @@ relocate_new_kernel: mr r8, r0 ori r8, r8, MSR_RI|MSR_ME - mtspr SRR1, r8 + mtspr SPRN_SRR1, r8 addi r8, r4, 1f - relocate_new_kernel - mtspr SRR0, r8 + mtspr SPRN_SRR0, r8 sync rfi diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 735866559199..bf4ddca5e853 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -89,6 +89,9 @@ unsigned long tb_to_ns_scale; extern unsigned long wall_jiffies; +/* used for timezone offset */ +static long timezone_offset; + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -170,7 +173,7 @@ void timer_interrupt(struct pt_regs * regs) xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { - if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) + if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else /* Try again one minute later */ @@ -286,7 +289,7 @@ void __init time_init(void) unsigned old_stamp, stamp, elapsed; if (ppc_md.time_init != NULL) - time_offset = ppc_md.time_init(); + timezone_offset = ppc_md.time_init(); if (__USE_RTC()) { /* 601 processor: dec counts down by 128 every 128ns */ @@ -331,10 +334,10 @@ void __init time_init(void) set_dec(tb_ticks_per_jiffy); /* If platform provided a timezone (pmac), we correct the time */ - if (time_offset) { - sys_tz.tz_minuteswest = -time_offset / 60; + if (timezone_offset) { + sys_tz.tz_minuteswest = -timezone_offset / 60; sys_tz.tz_dsttime = 0; - xtime.tv_sec -= time_offset; + xtime.tv_sec -= timezone_offset; } set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index ddd2e9a5bb12..f761fdf160db 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -111,8 +111,8 @@ mpc8540ads_setup_arch(void) memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } + pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); if (pdata) { - pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); pdata->board_flags = 0; pdata->interruptPHY = MPC85xx_IRQ_EXT5; pdata->phyid = 3; diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h index 632b8178ce66..b60c56450b67 100644 --- a/arch/ppc/platforms/fads.h +++ b/arch/ppc/platforms/fads.h @@ -3,7 +3,18 @@ * the Motorola 860T FADS board. Copied from the MBX stuff. * * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + * + * Added MPC86XADS support. + * The MPC86xADS manual says the board "is compatible with the MPC8xxFADS + * for SW point of view". This is 99% correct. + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is licensed + * "as is" without any warranty of any kind, whether express or implied. */ + #ifdef __KERNEL__ #ifndef __ASM_FADS_H__ #define __ASM_FADS_H__ @@ -12,18 +23,45 @@ #include <asm/ppcboot.h> +#if defined(CONFIG_MPC86XADS) + +/* U-Boot maps BCSR to 0xff080000 */ +#define BCSR_ADDR ((uint)0xff080000) + +/* MPC86XADS has one more CPLD and an additional BCSR. + */ +#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) +#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) + +#define BCSR5_T1_RST 0x10 +#define BCSR5_ATM155_RST 0x08 +#define BCSR5_ATM25_RST 0x04 +#define BCSR5_MII1_EN 0x02 +#define BCSR5_MII1_RST 0x01 + +/* There is no PHY link change interrupt */ +#define PHY_INTERRUPT (-1) + +#else /* FADS */ + /* Memory map is configured by the PROM startup. * I tried to follow the FADS manual, although the startup PROM * dictates this and we simply have to move some of the physical * addresses for Linux. */ #define BCSR_ADDR ((uint)0xff010000) + +/* PHY link change interrupt */ +#define PHY_INTERRUPT SIU_IRQ2 + +#endif /* CONFIG_MPC86XADS */ + #define BCSR_SIZE ((uint)(64 * 1024)) -#define BCSR0 ((uint)0xff010000) -#define BCSR1 ((uint)0xff010004) -#define BCSR2 ((uint)0xff010008) -#define BCSR3 ((uint)0xff01000c) -#define BCSR4 ((uint)0xff010010) +#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) +#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) +#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) +#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) +#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) #define IMAP_ADDR ((uint)0xff000000) #define IMAP_SIZE ((uint)(64 * 1024)) @@ -34,8 +72,17 @@ /* Bits of interest in the BCSRs. */ #define BCSR1_ETHEN ((uint)0x20000000) +#define BCSR1_IRDAEN ((uint)0x10000000) #define BCSR1_RS232EN_1 ((uint)0x01000000) +#define BCSR1_PCCEN ((uint)0x00800000) +#define BCSR1_PCCVCC0 ((uint)0x00400000) +#define BCSR1_PCCVPP0 ((uint)0x00200000) +#define BCSR1_PCCVPP1 ((uint)0x00100000) +#define BCSR1_PCCVPP_MASK (BCSR1_PCCVPP0 | BCSR1_PCCVPP1) #define BCSR1_RS232EN_2 ((uint)0x00040000) +#define BCSR1_PCCVCC1 ((uint)0x00010000) +#define BCSR1_PCCVCC_MASK (BCSR1_PCCVCC0 | BCSR1_PCCVCC1) + #define BCSR4_ETHLOOP ((uint)0x80000000) /* EEST Loopback */ #define BCSR4_EEFDX ((uint)0x40000000) /* EEST FDX enable */ #define BCSR4_FETH_EN ((uint)0x08000000) /* PHY enable */ @@ -44,14 +91,64 @@ #define BCSR4_FETHFDE ((uint)0x02000000) /* PHY FDX advertise */ #define BCSR4_FETHRST ((uint)0x00200000) /* PHY Reset */ +/* IO_BASE definition for pcmcia. + */ +#define _IO_BASE 0x80000000 +#define _IO_BASE_SIZE 0x1000 + +#ifdef CONFIG_IDE +#define MAX_HWIFS 1 +#endif + /* Interrupt level assignments. */ #define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ -#define PHY_INTERRUPT SIU_IRQ2 /* PHY link change interrupt */ /* We don't use the 8259. */ #define NR_8259_INTS 0 +/* CPM Ethernet through SCC1 or SCC2 */ + +#ifdef CONFIG_SCC1_ENET /* Probably 860 variant */ +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + * TCLK - CLK1, RCLK - CLK2. + */ +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0100) +#define PA_ENET_RCLK ((ushort)0x0200) +#define PB_ENET_TENA ((uint)0x00001000) +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000002c) +#endif /* CONFIG_SCC1_ENET */ + +#ifdef CONFIG_SCC2_ENET /* Probably 823/850 variant */ +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + * TCLK - CLK1, RCLK - CLK2. + */ +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0400) +#define PA_ENET_RCLK ((ushort)0x0200) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +/* Control bits in the SICR to route TCLK and RCLK to + * SCC2. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002e00) +#endif /* CONFIG_SCC2_ENET */ + #endif /* __ASM_FADS_H__ */ #endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h new file mode 100644 index 000000000000..eb386635b0fd --- /dev/null +++ b/arch/ppc/platforms/mpc885ads.h @@ -0,0 +1,92 @@ +/* + * A collection of structures, addresses, and values associated with + * the Freescale MPC885ADS board. + * Copied from the FADS stuff. + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is licensed + * "as is" without any warranty of any kind, whether express or implied. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_MPC885ADS_H__ +#define __ASM_MPC885ADS_H__ + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +/* U-Boot maps BCSR to 0xff080000 */ +#define BCSR_ADDR ((uint)0xff080000) +#define BCSR_SIZE ((uint)32) +#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) +#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) +#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) +#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) +#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) + +#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) +#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) + +#define IMAP_ADDR ((uint)0xff000000) +#define IMAP_SIZE ((uint)(64 * 1024)) + +#define PCMCIA_MEM_ADDR ((uint)0xff020000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) + +/* Bits of interest in the BCSRs. + */ +#define BCSR1_ETHEN ((uint)0x20000000) +#define BCSR1_IRDAEN ((uint)0x10000000) +#define BCSR1_RS232EN_1 ((uint)0x01000000) +#define BCSR1_PCCEN ((uint)0x00800000) +#define BCSR1_PCCVCC0 ((uint)0x00400000) +#define BCSR1_PCCVPP0 ((uint)0x00200000) +#define BCSR1_PCCVPP1 ((uint)0x00100000) +#define BCSR1_PCCVPP_MASK (BCSR1_PCCVPP0 | BCSR1_PCCVPP1) +#define BCSR1_RS232EN_2 ((uint)0x00040000) +#define BCSR1_PCCVCC1 ((uint)0x00010000) +#define BCSR1_PCCVCC_MASK (BCSR1_PCCVCC0 | BCSR1_PCCVCC1) + +#define BCSR4_ETH10_RST ((uint)0x80000000) /* 10Base-T PHY reset*/ +#define BCSR4_USB_LO_SPD ((uint)0x04000000) +#define BCSR4_USB_VCC ((uint)0x02000000) +#define BCSR4_USB_FULL_SPD ((uint)0x00040000) +#define BCSR4_USB_EN ((uint)0x00020000) + +#define BCSR5_MII2_EN 0x40 +#define BCSR5_MII2_RST 0x20 +#define BCSR5_T1_RST 0x10 +#define BCSR5_ATM155_RST 0x08 +#define BCSR5_ATM25_RST 0x04 +#define BCSR5_MII1_EN 0x02 +#define BCSR5_MII1_RST 0x01 + +/* Interrupt level assignments */ +#define PHY_INTERRUPT SIU_IRQ7 /* PHY link change interrupt */ +#define SIU_INT_FEC1 SIU_LEVEL1 /* FEC1 interrupt */ +#define SIU_INT_FEC2 SIU_LEVEL3 /* FEC2 interrupt */ +#define FEC_INTERRUPT SIU_INT_FEC1 /* FEC interrupt */ + +/* We don't use the 8259 */ +#define NR_8259_INTS 0 + +/* CPM Ethernet through SCC3 */ +#define PA_ENET_RXD ((ushort)0x0040) +#define PA_ENET_TXD ((ushort)0x0080) +#define PE_ENET_TCLK ((uint)0x00004000) +#define PE_ENET_RCLK ((uint)0x00008000) +#define PE_ENET_TENA ((uint)0x00000010) +#define PC_ENET_CLSN ((ushort)0x0400) +#define PC_ENET_RENA ((ushort)0x0800) + +/* Control bits in the SICR to route TCLK (CLK5) and RCLK (CLK6) to + * SCC3. Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero */ +#define SICR_ENET_MASK ((uint)0x00ff0000) +#define SICR_ENET_CLKRT ((uint)0x002c0000) + +#endif /* __ASM_MPC885ADS_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c index 49c0e34e2d6b..1eb4f726ca9f 100644 --- a/arch/ppc/syslib/of_device.c +++ b/arch/ppc/syslib/of_device.c @@ -3,6 +3,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <asm/errno.h> #include <asm/of_device.h> @@ -15,20 +16,20 @@ * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match * of_match_device(const struct of_match *matches, +const struct of_device_id * of_match_device(const struct of_device_id *matches, const struct of_device *dev) { if (!dev->node) return NULL; - while (matches->name || matches->type || matches->compatible) { + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; - if (matches->name && matches->name != OF_ANY_MATCH) + if (matches->name[0]) match &= dev->node->name && !strcmp(matches->name, dev->node->name); - if (matches->type && matches->type != OF_ANY_MATCH) + if (matches->type[0]) match &= dev->node->type && !strcmp(matches->type, dev->node->type); - if (matches->compatible && matches->compatible != OF_ANY_MATCH) + if (matches->compatible[0]) match &= device_is_compatible(dev->node, matches->compatible); if (match) @@ -42,7 +43,7 @@ static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_match * matches = of_drv->match_table; + const struct of_device_id * matches = of_drv->match_table; if (!matches) return 0; @@ -75,7 +76,7 @@ static int of_device_probe(struct device *dev) int error = -ENODEV; struct of_platform_driver *drv; struct of_device *of_dev; - const struct of_match *match; + const struct of_device_id *match; drv = to_of_platform_driver(dev->driver); of_dev = to_of_device(dev); diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c index 05686fa73545..40086212b9c3 100644 --- a/arch/ppc/syslib/ppc4xx_pic.c +++ b/arch/ppc/syslib/ppc4xx_pic.c @@ -110,6 +110,10 @@ static int ppc4xx_pic_get_irq(struct pt_regs *regs) static void __init ppc4xx_pic_impl_init(void) { +#if defined(CONFIG_440GX) + /* Disable 440GP compatibility mode if it was enabled in firmware */ + SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~DCRN_SDR_MFR_PCM); +#endif /* Configure Base UIC */ mtdcr(DCRN_UIC_CR(UICB), 0); mtdcr(DCRN_UIC_TR(UICB), 0); diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index d3e1d6af9203..683b2d43c15f 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -52,7 +52,7 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) -hostprogs-y := piggy addnote addRamDisk +hostprogs-y := addnote addRamDisk targets += zImage zImage.initrd imagesize.c \ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ @@ -78,9 +78,6 @@ addsection = $(CROSS32OBJCOPY) $(1) \ quiet_cmd_addnote = ADDNOTE $@ cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ -quiet_cmd_piggy = PIGGY $@ - cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@ - $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE $(call if_changed,gzip) diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index da12ea2ca464..199d9804f61c 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -17,7 +17,6 @@ extern void *finddevice(const char *); extern int getprop(void *, const char *, void *, int); -extern void printk(char *fmt, ...); extern void printf(const char *fmt, ...); extern int sprintf(char *buf, const char *fmt, ...); void gunzip(void *, int, unsigned char *, int *); @@ -147,10 +146,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr) } a1 = initrd.addr; a2 = initrd.size; - printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", + printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", initrd.addr, (unsigned long)_initrd_start, initrd.size); memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); - printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); + printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); } /* Eventually gunzip the kernel */ @@ -201,9 +200,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr) flush_cache((void *)vmlinux.addr, vmlinux.size); - if (a1) - printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); - kernel_entry = (kernel_entry_t)vmlinux.addr; #ifdef DEBUG printf( "kernel:\n\r" diff --git a/arch/ppc64/boot/mknote.c b/arch/ppc64/boot/mknote.c deleted file mode 100644 index 120cc1d89739..000000000000 --- a/arch/ppc64/boot/mknote.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) Cort Dougan 1999. - * - * 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. - * - * Generate a note section as per the CHRP specification. - * - */ - -#include <stdio.h> - -#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); - -int main(void) -{ -/* header */ - /* namesz */ - PL(strlen("PowerPC")+1); - /* descrsz */ - PL(6*4); - /* type */ - PL(0x1275); - /* name */ - printf("PowerPC"); printf("%c", 0); - -/* descriptor */ - /* real-mode */ - PL(0xffffffff); - /* real-base */ - PL(0x00c00000); - /* real-size */ - PL(0xffffffff); - /* virt-base */ - PL(0xffffffff); - /* virt-size */ - PL(0xffffffff); - /* load-base */ - PL(0x4000); - return 0; -} diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c deleted file mode 100644 index 235c7a87269c..000000000000 --- a/arch/ppc64/boot/piggyback.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2001 IBM Corp - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include <stdio.h> -#include <unistd.h> -#include <string.h> - -extern long ce_exec_config[]; - -int main(int argc, char *argv[]) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[8192]; - char *varname; - if (argc != 2) - { - fprintf(stderr, "usage: %s name <in-file >out-file\n", - argv[0]); - exit(1); - } - - varname = strrchr(argv[1], '/'); - if (varname) - varname++; - else - varname = argv[1]; - - fprintf(stdout, "#\n"); - fprintf(stdout, "# Miscellaneous data structures:\n"); - fprintf(stdout, "# WARNING - this file is automatically generated!\n"); - fprintf(stdout, "#\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl %s_data\n", varname); - fprintf(stdout, "%s_data:\n", varname); - pos = 0; - cksum = 0; - while ((len = read(0, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - fprintf(stdout, "\t.long\t"); - } - fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(stdout, " # %x \n", pos+i-12); - fflush(stdout); - } else - { - fprintf(stdout, ","); - } - } - if (cnt) - { - fprintf(stdout, "0\n"); - } - pos += len; - } - fprintf(stdout, "\t.globl %s_len\n", varname); - fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos); - fflush(stdout); - fclose(stdout); - fprintf(stderr, "cksum = %x\n", cksum); - exit(0); -} - diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index d5218b15824e..5e48b80ff5a0 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c @@ -40,7 +40,7 @@ void *finddevice(const char *name); int getprop(void *phandle, const char *name, void *buf, int buflen); void chrpboot(int a1, int a2, void *prom); /* in main.c */ -void printk(char *fmt, ...); +int printf(char *fmt, ...); /* there is no convenient header to get this from... -- paulus */ extern unsigned long strlen(const char *); @@ -220,7 +220,7 @@ readchar(void) case 1: return ch; case -1: - printk("read(stdin) returned -1\r\n"); + printf("read(stdin) returned -1\r\n"); return -1; } } @@ -627,18 +627,6 @@ int sprintf(char * buf, const char *fmt, ...) static char sprint_buf[1024]; -void -printk(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); -} - int printf(char *fmt, ...) { diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index cdea00d7707f..4231861288a3 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -1,7 +1,7 @@ /* * ItLpQueue.c * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -11,156 +11,252 @@ #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/bootmem.h> +#include <linux/seq_file.h> +#include <linux/proc_fs.h> #include <asm/system.h> #include <asm/paca.h> #include <asm/iSeries/ItLpQueue.h> #include <asm/iSeries/HvLpEvent.h> #include <asm/iSeries/HvCallEvent.h> -static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) -{ - int t; - u32 * inUseP = &(lpQueue->xInUseWord); - - __asm__ __volatile__("\n\ -1: lwarx %0,0,%2 \n\ - cmpwi 0,%0,0 \n\ - li %0,0 \n\ - bne- 2f \n\ - addi %0,%0,1 \n\ - stwcx. %0,0,%2 \n\ - bne- 1b \n\ -2: eieio" - : "=&r" (t), "=m" (lpQueue->xInUseWord) - : "r" (inUseP), "m" (lpQueue->xInUseWord) - : "cc"); - - return t; -} +/* + * The LpQueue is used to pass event data from the hypervisor to + * the partition. This is where I/O interrupt events are communicated. + * + * It is written to by the hypervisor so cannot end up in the BSS. + */ +struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); -static __inline__ void clear_inUse( struct ItLpQueue * lpQueue ) -{ - lpQueue->xInUseWord = 0; -} +DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts); + +static char *event_types[HvLpEvent_Type_NumTypes] = { + "Hypervisor", + "Machine Facilities", + "Session Manager", + "SPD I/O", + "Virtual Bus", + "PCI I/O", + "RIO I/O", + "Virtual Lan", + "Virtual I/O" +}; /* Array of LpEvent handler functions */ extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; -unsigned long ItLpQueueInProcess = 0; -struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) +static struct HvLpEvent * get_next_hvlpevent(void) { - struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - if ( nextLpEvent->xFlags.xValid ) { + struct HvLpEvent * event; + event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + + if (event->xFlags.xValid) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + - LpEventAlign ) / - LpEventAlign ) * - LpEventAlign; + hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + + LpEventAlign) / LpEventAlign) * LpEventAlign; + /* Wrap to beginning if no room at end */ - if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr) - lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr; + if (hvlpevent_queue.xSlicCurEventPtr > + hvlpevent_queue.xSlicLastValidEventPtr) { + hvlpevent_queue.xSlicCurEventPtr = + hvlpevent_queue.xSlicEventStackPtr; + } + } else { + event = NULL; } - else - nextLpEvent = NULL; - return nextLpEvent; + return event; } -int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) +static unsigned long spread_lpevents = NR_CPUS; + +int hvlpevent_is_pending(void) { - int retval = 0; - struct HvLpEvent * nextLpEvent; - if ( lpQueue ) { - nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending; - } - return retval; + struct HvLpEvent *next_event; + + if (smp_processor_id() >= spread_lpevents) + return 0; + + next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + + return next_event->xFlags.xValid | + hvlpevent_queue.xPlicOverflowIntPending; } -void ItLpQueue_clearValid( struct HvLpEvent * event ) +static void hvlpevent_clear_valid(struct HvLpEvent * event) { - /* Clear the valid bit of the event - * Also clear bits within this event that might - * look like valid bits (on 64-byte boundaries) - */ - unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) / - LpEventAlign ) - 1; - switch ( extra ) { - case 3: - ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; - case 2: - ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; - case 1: - ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; - case 0: - ; + /* Tell the Hypervisor that we're done with this event. + * Also clear bits within this event that might look like valid bits. + * ie. on 64-byte boundaries. + */ + struct HvLpEvent *tmp; + unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / + LpEventAlign) - 1; + + switch (extra) { + case 3: + tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); + tmp->xFlags.xValid = 0; + case 2: + tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); + tmp->xFlags.xValid = 0; + case 1: + tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); + tmp->xFlags.xValid = 0; } + mb(); + event->xFlags.xValid = 0; } -unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) +void process_hvlpevents(struct pt_regs *regs) { - unsigned numIntsProcessed = 0; - struct HvLpEvent * nextLpEvent; + struct HvLpEvent * event; /* If we have recursed, just return */ - if ( !set_inUse( lpQueue ) ) - return 0; - - if (ItLpQueueInProcess == 0) - ItLpQueueInProcess = 1; - else - BUG(); + if (!spin_trylock(&hvlpevent_queue.lock)) + return; for (;;) { - nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue ); - if ( nextLpEvent ) { - /* Count events to return to caller - * and count processed events in lpQueue - */ - ++numIntsProcessed; - lpQueue->xLpIntCount++; - /* Call appropriate handler here, passing + event = get_next_hvlpevent(); + if (event) { + /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it * needs it in a bottom half. (perhaps for * an ACK) - * - * Handlers are responsible for ACK processing + * + * Handlers are responsible for ACK processing * * The Hypervisor guarantees that LpEvents will * only be delivered with types that we have * registered for, so no type check is necessary * here! - */ - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - lpQueue->xLpIntCountByType[nextLpEvent->xType]++; - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && - lpEventHandler[nextLpEvent->xType] ) - lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); + */ + if (event->xType < HvLpEvent_Type_NumTypes) + __get_cpu_var(hvlpevent_counts)[event->xType]++; + if (event->xType < HvLpEvent_Type_NumTypes && + lpEventHandler[event->xType]) + lpEventHandler[event->xType](event, regs); else - printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); - - ItLpQueue_clearValid( nextLpEvent ); - } else if ( lpQueue->xPlicOverflowIntPending ) + printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); + + hvlpevent_clear_valid(event); + } else if (hvlpevent_queue.xPlicOverflowIntPending) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents( lpQueue->xIndex); + HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); else break; } - ItLpQueueInProcess = 0; - mb(); - clear_inUse( lpQueue ); + spin_unlock(&hvlpevent_queue.lock); +} + +static int set_spread_lpevents(char *str) +{ + unsigned long val = simple_strtoul(str, NULL, 0); + + /* + * The parameter is the number of processors to share in processing + * lp events. + */ + if (( val > 0) && (val <= NR_CPUS)) { + spread_lpevents = val; + printk("lpevent processing spread over %ld processors\n", val); + } else { + printk("invalid spread_lpevents %ld\n", val); + } - get_paca()->lpevent_count += numIntsProcessed; + return 1; +} +__setup("spread_lpevents=", set_spread_lpevents); + +void setup_hvlpevent_queue(void) +{ + void *eventStack; + + /* + * Allocate a page for the Event Stack. The Hypervisor needs the + * absolute real address, so we subtract out the KERNELBASE and add + * in the absolute real address of the kernel load area. + */ + eventStack = alloc_bootmem_pages(LpEventStackSize); + memset(eventStack, 0, LpEventStackSize); + + /* Invoke the hypervisor to initialize the event stack */ + HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); + + hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; + hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; + hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + + (LpEventStackSize - LpEventMaxSize); + hvlpevent_queue.xIndex = 0; +} + +static int proc_lpevents_show(struct seq_file *m, void *v) +{ + int cpu, i; + unsigned long sum; + static unsigned long cpu_totals[NR_CPUS]; + + /* FIXME: do we care that there's no locking here? */ + sum = 0; + for_each_online_cpu(cpu) { + cpu_totals[cpu] = 0; + for (i = 0; i < HvLpEvent_Type_NumTypes; i++) { + cpu_totals[cpu] += per_cpu(hvlpevent_counts, cpu)[i]; + } + sum += cpu_totals[cpu]; + } + + seq_printf(m, "LpEventQueue 0\n"); + seq_printf(m, " events processed:\t%lu\n", sum); + + for (i = 0; i < HvLpEvent_Type_NumTypes; ++i) { + sum = 0; + for_each_online_cpu(cpu) { + sum += per_cpu(hvlpevent_counts, cpu)[i]; + } + + seq_printf(m, " %-20s %10lu\n", event_types[i], sum); + } + + seq_printf(m, "\n events processed by processor:\n"); + + for_each_online_cpu(cpu) { + seq_printf(m, " CPU%02d %10lu\n", cpu, cpu_totals[cpu]); + } + + return 0; +} + +static int proc_lpevents_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_lpevents_show, NULL); +} - return numIntsProcessed; +static struct file_operations proc_lpevents_operations = { + .open = proc_lpevents_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init proc_lpevents_init(void) +{ + struct proc_dir_entry *e; + + e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); + if (e) + e->proc_fops = &proc_lpevents_operations; + + return 0; } +__initcall(proc_lpevents_init); + diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index badc5a443614..6ffcf67dd507 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c @@ -28,13 +28,6 @@ #include <asm/iSeries/IoHriProcessorVpd.h> #include <asm/iSeries/ItSpCommArea.h> -/* The LpQueue is used to pass event data from the hypervisor to - * the partition. This is where I/O interrupt events are communicated. - */ - -/* May be filled in by the hypervisor so cannot end up in the BSS */ -struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); - /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. @@ -200,7 +193,7 @@ struct ItVpdAreas itVpdAreas = { 0,0,0, /* 13 - 15 */ sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */ 0,0,0,0,0,0, /* 17 - 22 */ - sizeof(struct ItLpQueue),/* 23 length of Lp Queue */ + sizeof(struct hvlpevent_queue), /* 23 length of Lp Queue */ 0,0 /* 24 - 25 */ }, .xSlicVpdAdrs = { /* VPD addresses */ @@ -218,7 +211,7 @@ struct ItVpdAreas itVpdAreas = { 0,0,0, /* 13 - 15 */ &xIoHriProcessorVpd, /* 16 Proc Vpd */ 0,0,0,0,0,0, /* 17 - 22 */ - &xItLpQueue, /* 23 Lp Queue */ + &hvlpevent_queue, /* 23 Lp Queue */ 0,0 } }; diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c index 356bd9931fcc..0fe3116eba29 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/ppc64/kernel/iSeries_proc.c @@ -40,50 +40,6 @@ static int __init iseries_proc_create(void) } core_initcall(iseries_proc_create); -static char *event_types[9] = { - "Hypervisor\t\t", - "Machine Facilities\t", - "Session Manager\t", - "SPD I/O\t\t", - "Virtual Bus\t\t", - "PCI I/O\t\t", - "RIO I/O\t\t", - "Virtual Lan\t\t", - "Virtual I/O\t\t" -}; - -static int proc_lpevents_show(struct seq_file *m, void *v) -{ - unsigned int i; - - seq_printf(m, "LpEventQueue 0\n"); - seq_printf(m, " events processed:\t%lu\n", - (unsigned long)xItLpQueue.xLpIntCount); - - for (i = 0; i < 9; ++i) - seq_printf(m, " %s %10lu\n", event_types[i], - (unsigned long)xItLpQueue.xLpIntCountByType[i]); - - seq_printf(m, "\n events processed by processor:\n"); - - for_each_online_cpu(i) - seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); - - return 0; -} - -static int proc_lpevents_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_lpevents_show, NULL); -} - -static struct file_operations proc_lpevents_operations = { - .open = proc_lpevents_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static unsigned long startTitan = 0; static unsigned long startTb = 0; @@ -148,10 +104,6 @@ static int __init iseries_proc_init(void) { struct proc_dir_entry *e; - e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); - if (e) - e->proc_fops = &proc_lpevents_operations; - e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL); if (e) e->proc_fops = &proc_titantod_operations; diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 86966ce76b58..b3f770f6d402 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -24,7 +24,6 @@ #include <linux/smp.h> #include <linux/param.h> #include <linux/string.h> -#include <linux/bootmem.h> #include <linux/initrd.h> #include <linux/seq_file.h> #include <linux/kdev_t.h> @@ -676,7 +675,6 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) */ static void __init iSeries_setup_arch(void) { - void *eventStack; unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; /* Add an eye catcher and the systemcfg layout version number */ @@ -685,24 +683,7 @@ static void __init iSeries_setup_arch(void) systemcfg->version.minor = SYSTEMCFG_MINOR; /* Setup the Lp Event Queue */ - - /* Allocate a page for the Event Stack - * The hypervisor wants the absolute real address, so - * we subtract out the KERNELBASE and add in the - * absolute real address of the kernel load area - */ - eventStack = alloc_bootmem_pages(LpEventStackSize); - memset(eventStack, 0, LpEventStackSize); - - /* Invoke the hypervisor to initialize the event stack */ - HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); - - /* Initialize fields in our Lp Event Queue */ - xItLpQueue.xSlicEventStackPtr = (char *)eventStack; - xItLpQueue.xSlicCurEventPtr = (char *)eventStack; - xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + - (LpEventStackSize - LpEventMaxSize); - xItLpQueue.xIndex = 0; + setup_hvlpevent_queue(); /* Compute processor frequency */ procFreqHz = ((1UL << 34) * 1000000) / @@ -853,28 +834,6 @@ static int __init iSeries_src_init(void) late_initcall(iSeries_src_init); -static int set_spread_lpevents(char *str) -{ - unsigned long i; - unsigned long val = simple_strtoul(str, NULL, 0); - - /* - * The parameter is the number of processors to share in processing - * lp events. - */ - if (( val > 0) && (val <= NR_CPUS)) { - for (i = 1; i < val; ++i) - paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; - - printk("lpevent processing spread over %ld processors\n", val); - } else { - printk("invalid spread_lpevents %ld\n", val); - } - - return 1; -} -__setup("spread_lpevents=", set_spread_lpevents); - #ifndef CONFIG_PCI void __init iSeries_init_IRQ(void) { } #endif diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index bdf13b4dc1c8..08952c7e6216 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -88,7 +88,7 @@ static int iSeries_idle(void) while (1) { if (lpaca->lppaca.shared_proc) { - if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) + if (hvlpevent_is_pending()) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); @@ -100,7 +100,7 @@ static int iSeries_idle(void) while (!need_resched()) { HMT_medium(); - if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) + if (hvlpevent_is_pending()) process_iSeries_events(); HMT_low(); } diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 3defc8c33adf..f41afe545045 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -66,7 +66,6 @@ EXPORT_SYMBOL(irq_desc); int distribute_irqs = 1; int __irq_offset_value; int ppc_spurious_interrupts; -unsigned long lpevent_count; u64 ppc64_interrupt_controller; int show_interrupts(struct seq_file *p, void *v) @@ -245,7 +244,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) spin_lock(&desc->lock); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; @@ -269,7 +268,6 @@ out: void do_IRQ(struct pt_regs *regs) { struct paca_struct *lpaca; - struct ItLpQueue *lpq; irq_enter(); @@ -295,9 +293,8 @@ void do_IRQ(struct pt_regs *regs) iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ - lpq = lpaca->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, regs); + if (hvlpevent_is_pending()) + process_hvlpevents(regs); irq_exit(); diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 1d2ff6d6b0b3..a3d519518fb8 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -444,7 +444,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index d98bebf7042f..ef4a338ebd01 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -801,10 +801,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) return rc; /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { - extern unsigned long lpevent_count; - struct ItLpQueue *lpq = get_paca()->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, NULL); + if (hvlpevent_is_pending()) + process_hvlpevents(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c index 4e71781a4414..4fb1a9f5060d 100644 --- a/arch/ppc64/kernel/nvram.c +++ b/arch/ppc64/kernel/nvram.c @@ -338,9 +338,8 @@ static int nvram_remove_os_partition(void) */ static int nvram_create_os_partition(void) { - struct list_head * p; - struct nvram_partition *part = NULL; - struct nvram_partition *new_part = NULL; + struct nvram_partition *part; + struct nvram_partition *new_part; struct nvram_partition *free_part = NULL; int seq_init[2] = { 0, 0 }; loff_t tmp_index; @@ -349,8 +348,7 @@ static int nvram_create_os_partition(void) /* Find a free partition that will give us the maximum needed size If can't find one that will give us the minimum size needed */ - list_for_each(p, &nvram_part->partition) { - part = list_entry(p, struct nvram_partition, partition); + list_for_each_entry(part, &nvram_part->partition, partition) { if (part->header.signature != NVRAM_SIG_FREE) continue; diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c index 66bd5ab7c25a..b80e81984ba8 100644 --- a/arch/ppc64/kernel/of_device.c +++ b/arch/ppc64/kernel/of_device.c @@ -3,6 +3,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <asm/errno.h> #include <asm/of_device.h> @@ -15,20 +16,20 @@ * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match * of_match_device(const struct of_match *matches, +const struct of_device_id *of_match_device(const struct of_device_id *matches, const struct of_device *dev) { if (!dev->node) return NULL; - while (matches->name || matches->type || matches->compatible) { + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; - if (matches->name && matches->name != OF_ANY_MATCH) + if (matches->name[0]) match &= dev->node->name && !strcmp(matches->name, dev->node->name); - if (matches->type && matches->type != OF_ANY_MATCH) + if (matches->type[0]) match &= dev->node->type && !strcmp(matches->type, dev->node->type); - if (matches->compatible && matches->compatible != OF_ANY_MATCH) + if (matches->compatible[0]) match &= device_is_compatible(dev->node, matches->compatible); if (match) @@ -42,7 +43,7 @@ static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_match * matches = of_drv->match_table; + const struct of_device_id * matches = of_drv->match_table; if (!matches) return 0; @@ -75,7 +76,7 @@ static int of_device_probe(struct device *dev) int error = -ENODEV; struct of_platform_driver *drv; struct of_device *of_dev; - const struct of_match *match; + const struct of_device_id *match; drv = to_of_platform_driver(dev->driver); of_dev = to_of_device(dev); diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c index a3e0975c26c1..6316188737b6 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/ppc64/kernel/pacaData.c @@ -42,21 +42,7 @@ extern unsigned long __toc_start; * processors. The processor VPD array needs one entry per physical * processor (not thread). */ -#ifdef CONFIG_PPC_ISERIES -#define EXTRA_INITS(number, lpq) \ - .lppaca_ptr = &paca[number].lppaca, \ - .lpqueue_ptr = (lpq), /* &xItLpQueue, */ \ - .reg_save_ptr = &paca[number].reg_save, \ - .reg_save = { \ - .xDesc = 0xd397d9e2, /* "LpRS" */ \ - .xSize = sizeof(struct ItLpRegSave) \ - }, -#else -#define EXTRA_INITS(number, lpq) -#endif - -#define PACAINITDATA(number,start,lpq,asrr,asrv) \ -{ \ +#define PACA_INIT_COMMON(number, start, asrr, asrv) \ .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ .default_decr = 0x00ff0000, /* Initial Decr */ \ @@ -74,147 +60,79 @@ extern unsigned long __toc_start; .end_of_quantum = 0xfffffffffffffffful, \ .slb_count = 64, \ }, \ - EXTRA_INITS((number), (lpq)) \ -} -struct paca_struct paca[] = { #ifdef CONFIG_PPC_ISERIES - PACAINITDATA( 0, 1, &xItLpQueue, 0, STAB0_VIRT_ADDR), +#define PACA_INIT_ISERIES(number) \ + .lppaca_ptr = &paca[number].lppaca, \ + .reg_save_ptr = &paca[number].reg_save, \ + .reg_save = { \ + .xDesc = 0xd397d9e2, /* "LpRS" */ \ + .xSize = sizeof(struct ItLpRegSave) \ + } + +#define PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 0, 0, 0) \ + PACA_INIT_ISERIES(number) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR) \ + PACA_INIT_ISERIES(number) \ +} + #else - PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR), +#define PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 0, 0, 0) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR) \ +} #endif + +struct paca_struct paca[] = { + BOOTCPU_PACA_INIT(0), #if NR_CPUS > 1 - PACAINITDATA( 1, 0, NULL, 0, 0), - PACAINITDATA( 2, 0, NULL, 0, 0), - PACAINITDATA( 3, 0, NULL, 0, 0), + PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), #if NR_CPUS > 4 - PACAINITDATA( 4, 0, NULL, 0, 0), - PACAINITDATA( 5, 0, NULL, 0, 0), - PACAINITDATA( 6, 0, NULL, 0, 0), - PACAINITDATA( 7, 0, NULL, 0, 0), + PACA_INIT( 4), PACA_INIT( 5), PACA_INIT( 6), PACA_INIT( 7), #if NR_CPUS > 8 - PACAINITDATA( 8, 0, NULL, 0, 0), - PACAINITDATA( 9, 0, NULL, 0, 0), - PACAINITDATA(10, 0, NULL, 0, 0), - PACAINITDATA(11, 0, NULL, 0, 0), - PACAINITDATA(12, 0, NULL, 0, 0), - PACAINITDATA(13, 0, NULL, 0, 0), - PACAINITDATA(14, 0, NULL, 0, 0), - PACAINITDATA(15, 0, NULL, 0, 0), - PACAINITDATA(16, 0, NULL, 0, 0), - PACAINITDATA(17, 0, NULL, 0, 0), - PACAINITDATA(18, 0, NULL, 0, 0), - PACAINITDATA(19, 0, NULL, 0, 0), - PACAINITDATA(20, 0, NULL, 0, 0), - PACAINITDATA(21, 0, NULL, 0, 0), - PACAINITDATA(22, 0, NULL, 0, 0), - PACAINITDATA(23, 0, NULL, 0, 0), - PACAINITDATA(24, 0, NULL, 0, 0), - PACAINITDATA(25, 0, NULL, 0, 0), - PACAINITDATA(26, 0, NULL, 0, 0), - PACAINITDATA(27, 0, NULL, 0, 0), - PACAINITDATA(28, 0, NULL, 0, 0), - PACAINITDATA(29, 0, NULL, 0, 0), - PACAINITDATA(30, 0, NULL, 0, 0), - PACAINITDATA(31, 0, NULL, 0, 0), + PACA_INIT( 8), PACA_INIT( 9), PACA_INIT( 10), PACA_INIT( 11), + PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15), + PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19), + PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23), + PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27), + PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31), #if NR_CPUS > 32 - PACAINITDATA(32, 0, NULL, 0, 0), - PACAINITDATA(33, 0, NULL, 0, 0), - PACAINITDATA(34, 0, NULL, 0, 0), - PACAINITDATA(35, 0, NULL, 0, 0), - PACAINITDATA(36, 0, NULL, 0, 0), - PACAINITDATA(37, 0, NULL, 0, 0), - PACAINITDATA(38, 0, NULL, 0, 0), - PACAINITDATA(39, 0, NULL, 0, 0), - PACAINITDATA(40, 0, NULL, 0, 0), - PACAINITDATA(41, 0, NULL, 0, 0), - PACAINITDATA(42, 0, NULL, 0, 0), - PACAINITDATA(43, 0, NULL, 0, 0), - PACAINITDATA(44, 0, NULL, 0, 0), - PACAINITDATA(45, 0, NULL, 0, 0), - PACAINITDATA(46, 0, NULL, 0, 0), - PACAINITDATA(47, 0, NULL, 0, 0), - PACAINITDATA(48, 0, NULL, 0, 0), - PACAINITDATA(49, 0, NULL, 0, 0), - PACAINITDATA(50, 0, NULL, 0, 0), - PACAINITDATA(51, 0, NULL, 0, 0), - PACAINITDATA(52, 0, NULL, 0, 0), - PACAINITDATA(53, 0, NULL, 0, 0), - PACAINITDATA(54, 0, NULL, 0, 0), - PACAINITDATA(55, 0, NULL, 0, 0), - PACAINITDATA(56, 0, NULL, 0, 0), - PACAINITDATA(57, 0, NULL, 0, 0), - PACAINITDATA(58, 0, NULL, 0, 0), - PACAINITDATA(59, 0, NULL, 0, 0), - PACAINITDATA(60, 0, NULL, 0, 0), - PACAINITDATA(61, 0, NULL, 0, 0), - PACAINITDATA(62, 0, NULL, 0, 0), - PACAINITDATA(63, 0, NULL, 0, 0), + PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35), + PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39), + PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43), + PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47), + PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51), + PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55), + PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59), + PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63), #if NR_CPUS > 64 - PACAINITDATA(64, 0, NULL, 0, 0), - PACAINITDATA(65, 0, NULL, 0, 0), - PACAINITDATA(66, 0, NULL, 0, 0), - PACAINITDATA(67, 0, NULL, 0, 0), - PACAINITDATA(68, 0, NULL, 0, 0), - PACAINITDATA(69, 0, NULL, 0, 0), - PACAINITDATA(70, 0, NULL, 0, 0), - PACAINITDATA(71, 0, NULL, 0, 0), - PACAINITDATA(72, 0, NULL, 0, 0), - PACAINITDATA(73, 0, NULL, 0, 0), - PACAINITDATA(74, 0, NULL, 0, 0), - PACAINITDATA(75, 0, NULL, 0, 0), - PACAINITDATA(76, 0, NULL, 0, 0), - PACAINITDATA(77, 0, NULL, 0, 0), - PACAINITDATA(78, 0, NULL, 0, 0), - PACAINITDATA(79, 0, NULL, 0, 0), - PACAINITDATA(80, 0, NULL, 0, 0), - PACAINITDATA(81, 0, NULL, 0, 0), - PACAINITDATA(82, 0, NULL, 0, 0), - PACAINITDATA(83, 0, NULL, 0, 0), - PACAINITDATA(84, 0, NULL, 0, 0), - PACAINITDATA(85, 0, NULL, 0, 0), - PACAINITDATA(86, 0, NULL, 0, 0), - PACAINITDATA(87, 0, NULL, 0, 0), - PACAINITDATA(88, 0, NULL, 0, 0), - PACAINITDATA(89, 0, NULL, 0, 0), - PACAINITDATA(90, 0, NULL, 0, 0), - PACAINITDATA(91, 0, NULL, 0, 0), - PACAINITDATA(92, 0, NULL, 0, 0), - PACAINITDATA(93, 0, NULL, 0, 0), - PACAINITDATA(94, 0, NULL, 0, 0), - PACAINITDATA(95, 0, NULL, 0, 0), - PACAINITDATA(96, 0, NULL, 0, 0), - PACAINITDATA(97, 0, NULL, 0, 0), - PACAINITDATA(98, 0, NULL, 0, 0), - PACAINITDATA(99, 0, NULL, 0, 0), - PACAINITDATA(100, 0, NULL, 0, 0), - PACAINITDATA(101, 0, NULL, 0, 0), - PACAINITDATA(102, 0, NULL, 0, 0), - PACAINITDATA(103, 0, NULL, 0, 0), - PACAINITDATA(104, 0, NULL, 0, 0), - PACAINITDATA(105, 0, NULL, 0, 0), - PACAINITDATA(106, 0, NULL, 0, 0), - PACAINITDATA(107, 0, NULL, 0, 0), - PACAINITDATA(108, 0, NULL, 0, 0), - PACAINITDATA(109, 0, NULL, 0, 0), - PACAINITDATA(110, 0, NULL, 0, 0), - PACAINITDATA(111, 0, NULL, 0, 0), - PACAINITDATA(112, 0, NULL, 0, 0), - PACAINITDATA(113, 0, NULL, 0, 0), - PACAINITDATA(114, 0, NULL, 0, 0), - PACAINITDATA(115, 0, NULL, 0, 0), - PACAINITDATA(116, 0, NULL, 0, 0), - PACAINITDATA(117, 0, NULL, 0, 0), - PACAINITDATA(118, 0, NULL, 0, 0), - PACAINITDATA(119, 0, NULL, 0, 0), - PACAINITDATA(120, 0, NULL, 0, 0), - PACAINITDATA(121, 0, NULL, 0, 0), - PACAINITDATA(122, 0, NULL, 0, 0), - PACAINITDATA(123, 0, NULL, 0, 0), - PACAINITDATA(124, 0, NULL, 0, 0), - PACAINITDATA(125, 0, NULL, 0, 0), - PACAINITDATA(126, 0, NULL, 0, 0), - PACAINITDATA(127, 0, NULL, 0, 0), + PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67), + PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71), + PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75), + PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79), + PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83), + PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87), + PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91), + PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95), + PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99), + PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103), + PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107), + PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111), + PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115), + PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119), + PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123), + PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127), #endif #endif #endif diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 580676f87d23..ae6f579d3fa0 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = (unsigned long)hose->io_base_virt; + io_offset = (unsigned long)hose->io_base_virt - pci_io_base; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* found it! construct the final physical address */ if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - io_offset; + *offset += hose->io_base_phys - io_offset; return rp; } @@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev) } EXPORT_SYMBOL(pci_read_irq_line); +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + unsigned long offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = pci_io_base - (unsigned long)hose->io_base_virt + + hose->io_base_phys; + + *start = rsrc->start + offset; + *end = rsrc->end + offset; +} + #endif /* CONFIG_PPC_MULTIPLATFORM */ diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index c8fa6569b2fd..2f704a2cafb1 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c @@ -400,7 +400,12 @@ static int __init topology_init(void) struct cpu *c = &per_cpu(cpu_devices, cpu); #ifdef CONFIG_NUMA - parent = &node_devices[cpu_to_node(cpu)]; + /* The node to which a cpu belongs can't be known + * until the cpu is made present. + */ + parent = NULL; + if (cpu_present(cpu)) + parent = &node_devices[cpu_to_node(cpu)]; #endif /* * For now, we just see if the system supports making diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 2a532db9138a..909462e1adea 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -99,7 +99,6 @@ unsigned long tb_to_ns_shift; struct gettimeofday_struct do_gtod; extern unsigned long wall_jiffies; -extern unsigned long lpevent_count; extern int smp_tb_synchronized; extern struct timezone sys_tz; @@ -367,11 +366,8 @@ int timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - { - struct ItLpQueue *lpq = lpaca->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, regs); - } + if (hvlpevent_is_pending()) + process_hvlpevents(regs); #endif /* collect purr register values often, for accurate calculations */ diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 262e13d086fe..7a117ef473c5 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -270,66 +270,10 @@ endmenu source "drivers/Kconfig" -config PRINTER - tristate "Parallel printer support" - depends on PARPORT - ---help--- - If you intend to attach a printer to the parallel port of your Linux - box (as opposed to using a serial printer; if the connector at the - printer has 9 or 25 holes ["female"], then it's serial), say Y. - Also read the Printing-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - It is possible to share one parallel port among several devices - (e.g. printer and ZIP drive) and it is safe to compile the - corresponding drivers into the kernel. If you want to compile this - driver as a module however, choose M here and read - <file:Documentation/parport.txt>. The module will be called lp. - - If you have several parallel ports, you can specify which ports to - use with the "lp" kernel command line option. (Try "man bootparam" - or see the documentation of your boot loader (silo) about how to pass - options to the kernel at boot time.) The syntax of the "lp" command - line option can be found in <file:drivers/char/lp.c>. - - If you have more than 8 printers, you need to increase the LP_NO - macro in lp.c and the PARPORT_MAX macro in parport.h. - -source "mm/Kconfig" - -endmenu - -source "drivers/base/Kconfig" - -source "drivers/video/Kconfig" - -source "drivers/mtd/Kconfig" - -source "drivers/serial/Kconfig" - if !SUN4 source "drivers/sbus/char/Kconfig" endif -source "drivers/block/Kconfig" - -# Don't frighten a common SBus user -if PCI - -source "drivers/ide/Kconfig" - -endif - -source "drivers/isdn/Kconfig" - -source "drivers/scsi/Kconfig" - -source "drivers/fc4/Kconfig" - -source "drivers/md/Kconfig" - -source "net/Kconfig" - # This one must be before the filesystem configs. -DaveM menu "Unix98 PTY support" diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index e2b050eb3b96..d78bc13ebbb9 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -444,6 +444,24 @@ config PRINTER If you have more than 8 printers, you need to increase the LP_NO macro in lp.c and the PARPORT_MAX macro in parport.h. +config PPDEV + tristate "Support for user-space parallel port device drivers" + depends on PARPORT + ---help--- + Saying Y to this adds support for /dev/parport device nodes. This + is needed for programs that want portable access to the parallel + port, for instance deviceid (which displays Plug-and-Play device + IDs). + + This is the parallel port equivalent of SCSI generic support (sg). + It is safe to say N to this -- it is not needed for normal printing + or parallel port CD-ROM/disk support. + + To compile this driver as a module, choose M here: the + module will be called ppdev. + + If unsure, say N. + config ENVCTRL tristate "SUNW, envctrl support" depends on PCI diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index eee516a71c14..d3973d8a7195 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -553,13 +553,11 @@ do_ivec: sllx %g3, 5, %g3 or %g2, %lo(ivector_table), %g2 add %g2, %g3, %g3 - ldx [%g3 + 0x08], %g2 /* irq_info */ ldub [%g3 + 0x04], %g4 /* pil */ - brz,pn %g2, do_ivec_spurious - mov 1, %g2 - + mov 1, %g2 sllx %g2, %g4, %g2 sllx %g4, 2, %g4 + lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */ stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */ @@ -567,9 +565,9 @@ do_ivec: retry do_ivec_xcall: mov 0x50, %g1 - ldxa [%g1 + %g0] ASI_INTR_R, %g1 srl %g3, 0, %g3 + mov 0x60, %g7 ldxa [%g7 + %g0] ASI_INTR_R, %g7 stxa %g0, [%g0] ASI_INTR_RECEIVE @@ -581,19 +579,6 @@ do_ivec_xcall: 1: jmpl %g3, %g0 nop -do_ivec_spurious: - stw %g3, [%g6 + 0x00] /* irq_work(cpu, 0) = bucket */ - rdpr %pstate, %g5 - - wrpr %g5, PSTATE_IG | PSTATE_AG, %pstate - sethi %hi(109f), %g7 - ba,pt %xcc, etrap -109: or %g7, %lo(109b), %g7 - call catch_disabled_ivec - add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - clr %l6 - .globl save_alternate_globals save_alternate_globals: /* %o0 = save_area */ rdpr %pstate, %o5 diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 424712577307..daa2fb93052c 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -71,31 +71,7 @@ struct irq_work_struct { struct irq_work_struct __irq_work[NR_CPUS]; #define irq_work(__cpu, __pil) &(__irq_work[(__cpu)].irq_worklists[(__pil)]) -#ifdef CONFIG_PCI -/* This is a table of physical addresses used to deal with IBF_DMA_SYNC. - * It is used for PCI only to synchronize DMA transfers with IRQ delivery - * for devices behind busses other than APB on Sabre systems. - * - * Currently these physical addresses are just config space accesses - * to the command register for that device. - */ -unsigned long pci_dma_wsync; -unsigned long dma_sync_reg_table[256]; -unsigned char dma_sync_reg_table_entry = 0; -#endif - -/* This is based upon code in the 32-bit Sparc kernel written mostly by - * David Redman (djhr@tadpole.co.uk). - */ -#define MAX_STATIC_ALLOC 4 -static struct irqaction static_irqaction[MAX_STATIC_ALLOC]; -static int static_irq_count; - -/* This is exported so that fast IRQ handlers can get at it... -DaveM */ -struct irqaction *irq_action[NR_IRQS+1] = { - NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL -}; +static struct irqaction *irq_action[NR_IRQS+1]; /* This only synchronizes entities which modify IRQ handler * state and some selected user-level spots that want to @@ -241,17 +217,22 @@ void disable_irq(unsigned int irq) * the CPU %tick register and not by some normal vectored interrupt * source. To handle this special case, we use this dummy INO bucket. */ +static struct irq_desc pil0_dummy_desc; static struct ino_bucket pil0_dummy_bucket = { - 0, /* irq_chain */ - 0, /* pil */ - 0, /* pending */ - 0, /* flags */ - 0, /* __unused */ - NULL, /* irq_info */ - 0UL, /* iclr */ - 0UL, /* imap */ + .irq_info = &pil0_dummy_desc, }; +static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup, + unsigned long iclr, unsigned long imap, + struct ino_bucket *bucket) +{ + prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> " + "(%d:%d:%016lx:%016lx), halting...\n", + ino, bucket->pil, bucket->iclr, bucket->imap, + pil, inofixup, iclr, imap); + prom_halt(); +} + unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap) { struct ino_bucket *bucket; @@ -280,28 +261,35 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long prom_halt(); } - /* Ok, looks good, set it up. Don't touch the irq_chain or - * the pending flag. - */ bucket = &ivector_table[ino]; - if ((bucket->flags & IBF_ACTIVE) || - (bucket->irq_info != NULL)) { - /* This is a gross fatal error if it happens here. */ - prom_printf("IRQ: Trying to reinit INO bucket, fatal error.\n"); - prom_printf("IRQ: Request INO %04x (%d:%d:%016lx:%016lx)\n", - ino, pil, inofixup, iclr, imap); - prom_printf("IRQ: Existing (%d:%016lx:%016lx)\n", - bucket->pil, bucket->iclr, bucket->imap); - prom_printf("IRQ: Cannot continue, halting...\n"); + if (bucket->flags & IBF_ACTIVE) + build_irq_error("IRQ: Trying to build active INO bucket.\n", + ino, pil, inofixup, iclr, imap, bucket); + + if (bucket->irq_info) { + if (bucket->imap != imap || bucket->iclr != iclr) + build_irq_error("IRQ: Trying to reinit INO bucket.\n", + ino, pil, inofixup, iclr, imap, bucket); + + goto out; + } + + bucket->irq_info = kmalloc(sizeof(struct irq_desc), GFP_ATOMIC); + if (!bucket->irq_info) { + prom_printf("IRQ: Error, kmalloc(irq_desc) failed.\n"); prom_halt(); } + memset(bucket->irq_info, 0, sizeof(struct irq_desc)); + + /* Ok, looks good, set it up. Don't touch the irq_chain or + * the pending flag. + */ bucket->imap = imap; bucket->iclr = iclr; bucket->pil = pil; bucket->flags = 0; - bucket->irq_info = NULL; - +out: return __irq(bucket); } @@ -319,26 +307,65 @@ static void atomic_bucket_insert(struct ino_bucket *bucket) __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); } +static int check_irq_sharing(int pil, unsigned long irqflags) +{ + struct irqaction *action, *tmp; + + action = *(irq_action + pil); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next) + ; + } else { + return -EBUSY; + } + } + return 0; +} + +static void append_irq_action(int pil, struct irqaction *action) +{ + struct irqaction **pp = irq_action + pil; + + while (*pp) + pp = &((*pp)->next); + *pp = action; +} + +static struct irqaction *get_action_slot(struct ino_bucket *bucket) +{ + struct irq_desc *desc = bucket->irq_info; + int max_irq, i; + + max_irq = 1; + if (bucket->flags & IBF_PCI) + max_irq = MAX_IRQ_DESC_ACTION; + for (i = 0; i < max_irq; i++) { + struct irqaction *p = &desc->action[i]; + u32 mask = (1 << i); + + if (desc->action_active_mask & mask) + continue; + + desc->action_active_mask |= mask; + return p; + } + return NULL; +} + int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *name, void *dev_id) { - struct irqaction *action, *tmp = NULL; + struct irqaction *action; struct ino_bucket *bucket = __bucket(irq); unsigned long flags; int pending = 0; - if ((bucket != &pil0_dummy_bucket) && - (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS])) { - unsigned int *caller; - - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "request_irq: Old style IRQ registry attempt " - "from %p, irq %08x.\n", caller, irq); + if (unlikely(!handler)) return -EINVAL; - } - if (!handler) - return -EINVAL; + + if (unlikely(!bucket->irq_info)) + return -ENODEV; if ((bucket != &pil0_dummy_bucket) && (irqflags & SA_SAMPLE_RANDOM)) { /* @@ -356,93 +383,20 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ spin_lock_irqsave(&irq_action_lock, flags); - action = *(bucket->pil + irq_action); - if (action) { - if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) - for (tmp = action; tmp->next; tmp = tmp->next) - ; - else { - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - } - action = NULL; /* Or else! */ + if (check_irq_sharing(bucket->pil, irqflags)) { + spin_unlock_irqrestore(&irq_action_lock, flags); + return -EBUSY; } - /* If this is flagged as statically allocated then we use our - * private struct which is never freed. - */ - if (irqflags & SA_STATIC_ALLOC) { - if (static_irq_count < MAX_STATIC_ALLOC) - action = &static_irqaction[static_irq_count++]; - else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed " - "using kmalloc\n", irq, name); - } - if (action == NULL) - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - + action = get_action_slot(bucket); if (!action) { spin_unlock_irqrestore(&irq_action_lock, flags); return -ENOMEM; } - if (bucket == &pil0_dummy_bucket) { - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - } else { - if ((bucket->flags & IBF_ACTIVE) != 0) { - void *orig = bucket->irq_info; - void **vector = NULL; - - if ((bucket->flags & IBF_PCI) == 0) { - printk("IRQ: Trying to share non-PCI bucket.\n"); - goto free_and_ebusy; - } - if ((bucket->flags & IBF_MULTI) == 0) { - vector = kmalloc(sizeof(void *) * 4, GFP_ATOMIC); - if (vector == NULL) - goto free_and_enomem; - - /* We might have slept. */ - if ((bucket->flags & IBF_MULTI) != 0) { - int ent; - - kfree(vector); - vector = (void **)bucket->irq_info; - for(ent = 0; ent < 4; ent++) { - if (vector[ent] == NULL) { - vector[ent] = action; - break; - } - } - if (ent == 4) - goto free_and_ebusy; - } else { - vector[0] = orig; - vector[1] = action; - vector[2] = NULL; - vector[3] = NULL; - bucket->irq_info = vector; - bucket->flags |= IBF_MULTI; - } - } else { - int ent; - - vector = (void **)orig; - for (ent = 0; ent < 4; ent++) { - if (vector[ent] == NULL) { - vector[ent] = action; - break; - } - } - if (ent == 4) - goto free_and_ebusy; - } - } else { - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - } + bucket->flags |= IBF_ACTIVE; + pending = 0; + if (bucket != &pil0_dummy_bucket) { pending = bucket->pending; if (pending) bucket->pending = 0; @@ -456,10 +410,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ put_ino_in_irqaction(action, irq); put_smpaff_in_irqaction(action, CPU_MASK_NONE); - if (tmp) - tmp->next = action; - else - *(bucket->pil + irq_action) = action; + append_irq_action(bucket->pil, action); enable_irq(irq); @@ -468,147 +419,103 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ atomic_bucket_insert(bucket); set_softint(1 << bucket->pil); } + spin_unlock_irqrestore(&irq_action_lock, flags); - if ((bucket != &pil0_dummy_bucket) && (!(irqflags & SA_STATIC_ALLOC))) + + if (bucket != &pil0_dummy_bucket) register_irq_proc(__irq_ino(irq)); #ifdef CONFIG_SMP distribute_irqs(); #endif return 0; - -free_and_ebusy: - kfree(action); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - -free_and_enomem: - kfree(action); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -ENOMEM; } EXPORT_SYMBOL(request_irq); -void free_irq(unsigned int irq, void *dev_id) +static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id) { - struct irqaction *action; - struct irqaction *tmp = NULL; - unsigned long flags; - struct ino_bucket *bucket = __bucket(irq), *bp; + struct ino_bucket *bucket = __bucket(irq); + struct irqaction *action, **pp; - if ((bucket != &pil0_dummy_bucket) && - (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS])) { - unsigned int *caller; + pp = irq_action + bucket->pil; + action = *pp; + if (unlikely(!action)) + return NULL; - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "free_irq: Old style IRQ removal attempt " - "from %p, irq %08x.\n", caller, irq); - return; - } - - spin_lock_irqsave(&irq_action_lock, flags); - - action = *(bucket->pil + irq_action); - if (!action->handler) { + if (unlikely(!action->handler)) { printk("Freeing free IRQ %d\n", bucket->pil); - return; - } - if (dev_id) { - for ( ; action; action = action->next) { - if (action->dev_id == dev_id) - break; - tmp = action; - } - if (!action) { - printk("Trying to free free shared IRQ %d\n", bucket->pil); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; - } - } else if (action->flags & SA_SHIRQ) { - printk("Trying to free shared IRQ %d with NULL device ID\n", bucket->pil); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; + return NULL; } - if (action->flags & SA_STATIC_ALLOC) { - printk("Attempt to free statically allocated IRQ %d (%s)\n", - bucket->pil, action->name); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; + while (action && action->dev_id != dev_id) { + pp = &action->next; + action = *pp; } - if (action && tmp) - tmp->next = action->next; - else - *(bucket->pil + irq_action) = action->next; + if (likely(action)) + *pp = action->next; + + return action; +} + +void free_irq(unsigned int irq, void *dev_id) +{ + struct irqaction *action; + struct ino_bucket *bucket; + unsigned long flags; + + spin_lock_irqsave(&irq_action_lock, flags); + + action = unlink_irq_action(irq, dev_id); spin_unlock_irqrestore(&irq_action_lock, flags); + if (unlikely(!action)) + return; + synchronize_irq(irq); spin_lock_irqsave(&irq_action_lock, flags); + bucket = __bucket(irq); if (bucket != &pil0_dummy_bucket) { + struct irq_desc *desc = bucket->irq_info; unsigned long imap = bucket->imap; - void **vector, *orig; - int ent; - - orig = bucket->irq_info; - vector = (void **)orig; - - if ((bucket->flags & IBF_MULTI) != 0) { - int other = 0; - void *orphan = NULL; - for (ent = 0; ent < 4; ent++) { - if (vector[ent] == action) - vector[ent] = NULL; - else if (vector[ent] != NULL) { - orphan = vector[ent]; - other++; - } - } + int ent, i; - /* Only free when no other shared irq - * uses this bucket. - */ - if (other) { - if (other == 1) { - /* Convert back to non-shared bucket. */ - bucket->irq_info = orphan; - bucket->flags &= ~(IBF_MULTI); - kfree(vector); - } - goto out; + for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) { + struct irqaction *p = &desc->action[i]; + + if (p == action) { + desc->action_active_mask &= ~(1 << i); + break; } - } else { - bucket->irq_info = NULL; } - /* This unique interrupt source is now inactive. */ - bucket->flags &= ~IBF_ACTIVE; + if (!desc->action_active_mask) { + /* This unique interrupt source is now inactive. */ + bucket->flags &= ~IBF_ACTIVE; - /* See if any other buckets share this bucket's IMAP - * and are still active. - */ - for (ent = 0; ent < NUM_IVECS; ent++) { - bp = &ivector_table[ent]; - if (bp != bucket && - bp->imap == imap && - (bp->flags & IBF_ACTIVE) != 0) - break; - } + /* See if any other buckets share this bucket's IMAP + * and are still active. + */ + for (ent = 0; ent < NUM_IVECS; ent++) { + struct ino_bucket *bp = &ivector_table[ent]; + if (bp != bucket && + bp->imap == imap && + (bp->flags & IBF_ACTIVE) != 0) + break; + } - /* Only disable when no other sub-irq levels of - * the same IMAP are active. - */ - if (ent == NUM_IVECS) - disable_irq(irq); + /* Only disable when no other sub-irq levels of + * the same IMAP are active. + */ + if (ent == NUM_IVECS) + disable_irq(irq); + } } -out: - kfree(action); spin_unlock_irqrestore(&irq_action_lock, flags); } @@ -647,99 +554,55 @@ void synchronize_irq(unsigned int irq) } #endif /* CONFIG_SMP */ -void catch_disabled_ivec(struct pt_regs *regs) +static void process_bucket(int irq, struct ino_bucket *bp, struct pt_regs *regs) { - int cpu = smp_processor_id(); - struct ino_bucket *bucket = __bucket(*irq_work(cpu, 0)); + struct irq_desc *desc = bp->irq_info; + unsigned char flags = bp->flags; + u32 action_mask, i; + int random; - /* We can actually see this on Ultra/PCI PCI cards, which are bridges - * to other devices. Here a single IMAP enabled potentially multiple - * unique interrupt sources (which each do have a unique ICLR register. - * - * So what we do is just register that the IVEC arrived, when registered - * for real the request_irq() code will check the bit and signal - * a local CPU interrupt for it. - */ -#if 0 - printk("IVEC: Spurious interrupt vector (%x) received at (%016lx)\n", - bucket - &ivector_table[0], regs->tpc); -#endif - *irq_work(cpu, 0) = 0; - bucket->pending = 1; -} - -/* Tune this... */ -#define FORWARD_VOLUME 12 - -#ifdef CONFIG_SMP - -static inline void redirect_intr(int cpu, struct ino_bucket *bp) -{ - /* Ok, here is what is going on: - * 1) Retargeting IRQs on Starfire is very - * expensive so just forget about it on them. - * 2) Moving around very high priority interrupts - * is a losing game. - * 3) If the current cpu is idle, interrupts are - * useful work, so keep them here. But do not - * pass to our neighbour if he is not very idle. - * 4) If sysadmin explicitly asks for directed intrs, - * Just Do It. - */ - struct irqaction *ap = bp->irq_info; - cpumask_t cpu_mask; - unsigned int buddy, ticks; + bp->flags |= IBF_INPROGRESS; - cpu_mask = get_smpaff_in_irqaction(ap); - cpus_and(cpu_mask, cpu_mask, cpu_online_map); - if (cpus_empty(cpu_mask)) - cpu_mask = cpu_online_map; - - if (this_is_starfire != 0 || - bp->pil >= 10 || current->pid == 0) + if (unlikely(!(flags & IBF_ACTIVE))) { + bp->pending = 1; goto out; - - /* 'cpu' is the MID (ie. UPAID), calculate the MID - * of our buddy. - */ - buddy = cpu + 1; - if (buddy >= NR_CPUS) - buddy = 0; - - ticks = 0; - while (!cpu_isset(buddy, cpu_mask)) { - if (++buddy >= NR_CPUS) - buddy = 0; - if (++ticks > NR_CPUS) { - put_smpaff_in_irqaction(ap, CPU_MASK_NONE); - goto out; - } } - if (buddy == cpu) - goto out; + if (desc->pre_handler) + desc->pre_handler(bp, + desc->pre_handler_arg1, + desc->pre_handler_arg2); - /* Voo-doo programming. */ - if (cpu_data(buddy).idle_volume < FORWARD_VOLUME) - goto out; + action_mask = desc->action_active_mask; + random = 0; + for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) { + struct irqaction *p = &desc->action[i]; + u32 mask = (1 << i); - /* This just so happens to be correct on Cheetah - * at the moment. - */ - buddy <<= 26; + if (!(action_mask & mask)) + continue; - /* Push it to our buddy. */ - upa_writel(buddy | IMAP_VALID, bp->imap); + action_mask &= ~mask; + if (p->handler(__irq(bp), p->dev_id, regs) == IRQ_HANDLED) + random |= p->flags; + + if (!action_mask) + break; + } + if (bp->pil != 0) { + upa_writel(ICLR_IDLE, bp->iclr); + /* Test and add entropy */ + if (random & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + } out: - return; + bp->flags &= ~IBF_INPROGRESS; } -#endif - void handler_irq(int irq, struct pt_regs *regs) { - struct ino_bucket *bp, *nbp; + struct ino_bucket *bp; int cpu = smp_processor_id(); #ifndef CONFIG_SMP @@ -757,8 +620,6 @@ void handler_irq(int irq, struct pt_regs *regs) clear_softint(clr_mask); } #else - int should_forward = 0; - clear_softint(1 << irq); #endif @@ -773,63 +634,12 @@ void handler_irq(int irq, struct pt_regs *regs) #else bp = __bucket(xchg32(irq_work(cpu, irq), 0)); #endif - for ( ; bp != NULL; bp = nbp) { - unsigned char flags = bp->flags; - unsigned char random = 0; + while (bp) { + struct ino_bucket *nbp = __bucket(bp->irq_chain); - nbp = __bucket(bp->irq_chain); bp->irq_chain = 0; - - bp->flags |= IBF_INPROGRESS; - - if ((flags & IBF_ACTIVE) != 0) { -#ifdef CONFIG_PCI - if ((flags & IBF_DMA_SYNC) != 0) { - upa_readl(dma_sync_reg_table[bp->synctab_ent]); - upa_readq(pci_dma_wsync); - } -#endif - if ((flags & IBF_MULTI) == 0) { - struct irqaction *ap = bp->irq_info; - int ret; - - ret = ap->handler(__irq(bp), ap->dev_id, regs); - if (ret == IRQ_HANDLED) - random |= ap->flags; - } else { - void **vector = (void **)bp->irq_info; - int ent; - for (ent = 0; ent < 4; ent++) { - struct irqaction *ap = vector[ent]; - if (ap != NULL) { - int ret; - - ret = ap->handler(__irq(bp), - ap->dev_id, - regs); - if (ret == IRQ_HANDLED) - random |= ap->flags; - } - } - } - /* Only the dummy bucket lacks IMAP/ICLR. */ - if (bp->pil != 0) { -#ifdef CONFIG_SMP - if (should_forward) { - redirect_intr(cpu, bp); - should_forward = 0; - } -#endif - upa_writel(ICLR_IDLE, bp->iclr); - - /* Test and add entropy */ - if (random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - } - } else - bp->pending = 1; - - bp->flags &= ~IBF_INPROGRESS; + process_bucket(irq, bp, regs); + bp = nbp; } irq_exit(); } @@ -959,7 +769,10 @@ static void distribute_irqs(void) */ for (level = 1; level < NR_IRQS; level++) { struct irqaction *p = irq_action[level]; - if (level == 12) continue; + + if (level == 12) + continue; + while(p) { cpu = retarget_one_irq(p, cpu); p = p->next; @@ -1104,7 +917,8 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { struct ino_bucket *bp = ivector_table + (long)data; - struct irqaction *ap = bp->irq_info; + struct irq_desc *desc = bp->irq_info; + struct irqaction *ap = desc->action; cpumask_t mask; int len; @@ -1122,11 +936,13 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, static inline void set_intr_affinity(int irq, cpumask_t hw_aff) { struct ino_bucket *bp = ivector_table + irq; + struct irq_desc *desc = bp->irq_info; + struct irqaction *ap = desc->action; /* Users specify affinity in terms of hw cpu ids. * As soon as we do this, handler_irq() might see and take action. */ - put_smpaff_in_irqaction((struct irqaction *)bp->irq_info, hw_aff); + put_smpaff_in_irqaction(ap, hw_aff); /* Migration is simply done by the next cpu to service this * interrupt. diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index bdac631cf011..bbf11f85dab1 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -433,3 +433,8 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) return 0; } +/* architecture specific initialization */ +int arch_init_kprobes(void) +{ + return 0; +} diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 534320ef0db2..91ab466d6c66 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1303,8 +1303,7 @@ static void psycho_controller_hwinit(struct pci_controller_info *p) { u64 tmp; - /* PROM sets the IRQ retry value too low, increase it. */ - psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 0xff); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5); /* Enable arbiter for all PCI slots. */ tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL); diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 53d333b4a4e8..52bf3431a422 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -595,6 +595,23 @@ static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } +/* When a device lives behind a bridge deeper in the PCI bus topology + * than APB, a special sequence must run to make sure all pending DMA + * transfers at the time of IRQ delivery are visible in the coherency + * domain by the cpu. This sequence is to perform a read on the far + * side of the non-APB bridge, then perform a read of Sabre's DMA + * write-sync register. + */ +static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) +{ + struct pci_dev *pdev = _arg1; + unsigned long sync_reg = (unsigned long) _arg2; + u16 _unused; + + pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused); + sabre_read(sync_reg); +} + static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) @@ -639,24 +656,14 @@ static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, if (pdev) { struct pcidev_cookie *pcp = pdev->sysdata; - /* When a device lives behind a bridge deeper in the - * PCI bus topology than APB, a special sequence must - * run to make sure all pending DMA transfers at the - * time of IRQ delivery are visible in the coherency - * domain by the cpu. This sequence is to perform - * a read on the far side of the non-APB bridge, then - * perform a read of Sabre's DMA write-sync register. - * - * Currently, the PCI_CONFIG register for the device - * is used for this read from the far side of the bridge. - */ if (pdev->bus->number != pcp->pbm->pci_first_busno) { - bucket->flags |= IBF_DMA_SYNC; - bucket->synctab_ent = dma_sync_reg_table_entry++; - dma_sync_reg_table[bucket->synctab_ent] = - (unsigned long) sabre_pci_config_mkaddr( - pcp->pbm, - pdev->bus->number, pdev->devfn, PCI_COMMAND); + struct pci_controller_info *p = pcp->pbm->parent; + struct irq_desc *d = bucket->irq_info; + + d->pre_handler = sabre_wsync_handler; + d->pre_handler_arg1 = pdev; + d->pre_handler_arg2 = (void *) + p->pbm_A.controller_regs + SABRE_WRSYNC; } } return __irq(bucket); @@ -1626,10 +1633,9 @@ void __init sabre_init(int pnode, char *model_name) */ p->pbm_A.controller_regs = pr_regs[0].phys_addr; p->pbm_B.controller_regs = pr_regs[0].phys_addr; - pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC; - printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n", - p->pbm_A.controller_regs, pci_dma_wsync); + printk("PCI: Found SABRE, main regs at %016lx\n", + p->pbm_A.controller_regs); /* Clear interrupts */ diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 5753175b94e6..6a182bb66281 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -15,6 +15,7 @@ #include <asm/iommu.h> #include <asm/irq.h> #include <asm/upa.h> +#include <asm/pstate.h> #include "pci_impl.h" #include "iommu_common.h" @@ -326,6 +327,44 @@ static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } +static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) +{ + unsigned long sync_reg = (unsigned long) _arg2; + u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO); + u64 val; + int limit; + + schizo_write(sync_reg, mask); + + limit = 100000; + val = 0; + while (--limit) { + val = schizo_read(sync_reg); + if (!(val & mask)) + break; + } + if (limit <= 0) { + printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n", + val, mask); + } + + if (_arg1) { + static unsigned char cacheline[64] + __attribute__ ((aligned (64))); + + __asm__ __volatile__("rd %%fprs, %0\n\t" + "or %0, %4, %1\n\t" + "wr %1, 0x0, %%fprs\n\t" + "stda %%f0, [%5] %6\n\t" + "wr %0, 0x0, %%fprs\n\t" + "membar #Sync" + : "=&r" (mask), "=&r" (val) + : "0" (mask), "1" (val), + "i" (FPRS_FEF), "r" (&cacheline[0]), + "i" (ASI_BLK_COMMIT_P)); + } +} + static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) @@ -369,6 +408,15 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); bucket->flags |= IBF_PCI; + if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { + struct irq_desc *p = bucket->irq_info; + + p->pre_handler = tomatillo_wsync_handler; + p->pre_handler_arg1 = ((pbm->chip_version <= 4) ? + (void *) 1 : (void *) 0); + p->pre_handler_arg2 = (void *) pbm->sync_reg; + } + return __irq(bucket); } @@ -885,6 +933,7 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs) #define SCHIZO_PCI_CTRL (0x2000UL) #define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ +#define SCHIZO_PCICTRL_DTO_INT (1UL << 61UL) /* Tomatillo */ #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ #define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ #define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ @@ -1887,37 +1936,27 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) { u64 tmp; - /* Set IRQ retry to infinity. */ - schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, - SCHIZO_IRQ_RETRY_INF); + schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); - /* Enable arbiter for all PCI slots. Also, disable PCI interval - * timer so that DTO (Discard TimeOuts) are not reported because - * some Schizo revisions report them erroneously. - */ tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); - if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS && - pbm->chip_version == 0x5 && - pbm->chip_revision == 0x1) - tmp |= 0x0f; - else - tmp |= 0xff; - tmp &= ~SCHIZO_PCICTRL_PTO; + /* Enable arbiter for all PCI slots. */ + tmp |= 0xff; + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - else - tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT; if (!prom_getbool(pbm->prom_node, "no-bus-parking")) tmp |= SCHIZO_PCICTRL_PARK; + else + tmp &= ~SCHIZO_PCICTRL_PARK; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && pbm->chip_version <= 0x1) - tmp |= (1UL << 61); + tmp |= SCHIZO_PCICTRL_DTO_INT; else - tmp &= ~(1UL << 61); + tmp &= ~SCHIZO_PCICTRL_DTO_INT; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) tmp |= (SCHIZO_PCICTRL_MRM_PREF | @@ -2015,6 +2054,9 @@ static void __init schizo_pbm_init(struct pci_controller_info *p, pbm->pbm_regs = pr_regs[0].phys_addr; pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; + if (chip_type == PBM_CHIP_TYPE_TOMATILLO) + pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; + sprintf(pbm->name, (chip_type == PBM_CHIP_TYPE_TOMATILLO ? "TOMATILLO%d PBM%c" : diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 71b4e3807694..b40db389f90b 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -973,7 +973,7 @@ static void sparc64_start_timers(irqreturn_t (*cfunc)(int, void *, struct pt_reg int err; /* Register IRQ handler. */ - err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC, + err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, 0, "timer", NULL); if (err) { diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 7a2431d3abc7..363770893797 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -72,6 +72,7 @@ __flush_tlb_pending: flush %g6 retl wrpr %g7, 0x0, %pstate + nop .align 32 .globl __flush_tlb_kernel_range @@ -249,7 +250,7 @@ __cheetah_flush_tlb_mm: /* 15 insns */ retl wrpr %g7, 0x0, %pstate -__cheetah_flush_tlb_pending: /* 22 insns */ +__cheetah_flush_tlb_pending: /* 23 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ rdpr %pstate, %g7 sllx %o1, 3, %o1 @@ -317,7 +318,7 @@ cheetah_patch_cachetlbops: sethi %hi(__cheetah_flush_tlb_pending), %o1 or %o1, %lo(__cheetah_flush_tlb_pending), %o1 call cheetah_patch_one - mov 22, %o2 + mov 23, %o2 #ifdef DCACHE_ALIASING_POSSIBLE sethi %hi(__flush_dcache_page), %o0 diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 8a73794f9b90..428915697675 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -65,7 +65,9 @@ CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o libs-y += arch/x86_64/lib/ -core-y += arch/x86_64/kernel/ arch/x86_64/mm/ +core-y += arch/x86_64/kernel/ \ + arch/x86_64/mm/ \ + arch/x86_64/crypto/ core-$(CONFIG_IA32_EMULATION) += arch/x86_64/ia32/ drivers-$(CONFIG_PCI) += arch/x86_64/pci/ drivers-$(CONFIG_OPROFILE) += arch/x86_64/oprofile/ diff --git a/arch/x86_64/crypto/Makefile b/arch/x86_64/crypto/Makefile new file mode 100644 index 000000000000..426d20f4b72e --- /dev/null +++ b/arch/x86_64/crypto/Makefile @@ -0,0 +1,9 @@ +# +# x86_64/crypto/Makefile +# +# Arch-specific CryptoAPI modules. +# + +obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o + +aes-x86_64-y := aes-x86_64-asm.o aes.o diff --git a/arch/x86_64/crypto/aes-x86_64-asm.S b/arch/x86_64/crypto/aes-x86_64-asm.S new file mode 100644 index 000000000000..483cbb23ab8d --- /dev/null +++ b/arch/x86_64/crypto/aes-x86_64-asm.S @@ -0,0 +1,186 @@ +/* AES (Rijndael) implementation (FIPS PUB 197) for x86_64 + * + * Copyright (C) 2005 Andreas Steinmetz, <ast@domdv.de> + * + * License: + * This code can be distributed under the terms of the GNU General Public + * License (GPL) Version 2 provided that the above header down to and + * including this sentence is retained in full. + */ + +.extern aes_ft_tab +.extern aes_it_tab +.extern aes_fl_tab +.extern aes_il_tab + +.text + +#define R1 %rax +#define R1E %eax +#define R1X %ax +#define R1H %ah +#define R1L %al +#define R2 %rbx +#define R2E %ebx +#define R2X %bx +#define R2H %bh +#define R2L %bl +#define R3 %rcx +#define R3E %ecx +#define R3X %cx +#define R3H %ch +#define R3L %cl +#define R4 %rdx +#define R4E %edx +#define R4X %dx +#define R4H %dh +#define R4L %dl +#define R5 %rsi +#define R5E %esi +#define R6 %rdi +#define R6E %edi +#define R7 %rbp +#define R7E %ebp +#define R8 %r8 +#define R9 %r9 +#define R10 %r10 +#define R11 %r11 + +#define prologue(FUNC,BASE,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \ + .global FUNC; \ + .type FUNC,@function; \ + .align 8; \ +FUNC: movq r1,r2; \ + movq r3,r4; \ + leaq BASE+52(r8),r9; \ + movq r10,r11; \ + movl (r7),r5 ## E; \ + movl 4(r7),r1 ## E; \ + movl 8(r7),r6 ## E; \ + movl 12(r7),r7 ## E; \ + movl (r8),r10 ## E; \ + xorl -48(r9),r5 ## E; \ + xorl -44(r9),r1 ## E; \ + xorl -40(r9),r6 ## E; \ + xorl -36(r9),r7 ## E; \ + cmpl $24,r10 ## E; \ + jb B128; \ + leaq 32(r9),r9; \ + je B192; \ + leaq 32(r9),r9; + +#define epilogue(r1,r2,r3,r4,r5,r6,r7,r8,r9) \ + movq r1,r2; \ + movq r3,r4; \ + movl r5 ## E,(r9); \ + movl r6 ## E,4(r9); \ + movl r7 ## E,8(r9); \ + movl r8 ## E,12(r9); \ + ret; + +#define round(TAB,OFFSET,r1,r2,r3,r4,r5,r6,r7,r8,ra,rb,rc,rd) \ + movzbl r2 ## H,r5 ## E; \ + movzbl r2 ## L,r6 ## E; \ + movl TAB+1024(,r5,4),r5 ## E;\ + movw r4 ## X,r2 ## X; \ + movl TAB(,r6,4),r6 ## E; \ + roll $16,r2 ## E; \ + shrl $16,r4 ## E; \ + movzbl r4 ## H,r7 ## E; \ + movzbl r4 ## L,r4 ## E; \ + xorl OFFSET(r8),ra ## E; \ + xorl OFFSET+4(r8),rb ## E; \ + xorl TAB+3072(,r7,4),r5 ## E;\ + xorl TAB+2048(,r4,4),r6 ## E;\ + movzbl r1 ## L,r7 ## E; \ + movzbl r1 ## H,r4 ## E; \ + movl TAB+1024(,r4,4),r4 ## E;\ + movw r3 ## X,r1 ## X; \ + roll $16,r1 ## E; \ + shrl $16,r3 ## E; \ + xorl TAB(,r7,4),r5 ## E; \ + movzbl r3 ## H,r7 ## E; \ + movzbl r3 ## L,r3 ## E; \ + xorl TAB+3072(,r7,4),r4 ## E;\ + xorl TAB+2048(,r3,4),r5 ## E;\ + movzbl r1 ## H,r7 ## E; \ + movzbl r1 ## L,r3 ## E; \ + shrl $16,r1 ## E; \ + xorl TAB+3072(,r7,4),r6 ## E;\ + movl TAB+2048(,r3,4),r3 ## E;\ + movzbl r1 ## H,r7 ## E; \ + movzbl r1 ## L,r1 ## E; \ + xorl TAB+1024(,r7,4),r6 ## E;\ + xorl TAB(,r1,4),r3 ## E; \ + movzbl r2 ## H,r1 ## E; \ + movzbl r2 ## L,r7 ## E; \ + shrl $16,r2 ## E; \ + xorl TAB+3072(,r1,4),r3 ## E;\ + xorl TAB+2048(,r7,4),r4 ## E;\ + movzbl r2 ## H,r1 ## E; \ + movzbl r2 ## L,r2 ## E; \ + xorl OFFSET+8(r8),rc ## E; \ + xorl OFFSET+12(r8),rd ## E; \ + xorl TAB+1024(,r1,4),r3 ## E;\ + xorl TAB(,r2,4),r4 ## E; + +#define move_regs(r1,r2,r3,r4) \ + movl r3 ## E,r1 ## E; \ + movl r4 ## E,r2 ## E; + +#define entry(FUNC,BASE,B128,B192) \ + prologue(FUNC,BASE,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11) + +#define return epilogue(R8,R2,R9,R7,R5,R6,R3,R4,R11) + +#define encrypt_round(TAB,OFFSET) \ + round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4) \ + move_regs(R1,R2,R5,R6) + +#define encrypt_final(TAB,OFFSET) \ + round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4) + +#define decrypt_round(TAB,OFFSET) \ + round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) \ + move_regs(R1,R2,R5,R6) + +#define decrypt_final(TAB,OFFSET) \ + round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) + +/* void aes_encrypt(void *ctx, u8 *out, const u8 *in) */ + + entry(aes_encrypt,0,enc128,enc192) + encrypt_round(aes_ft_tab,-96) + encrypt_round(aes_ft_tab,-80) +enc192: encrypt_round(aes_ft_tab,-64) + encrypt_round(aes_ft_tab,-48) +enc128: encrypt_round(aes_ft_tab,-32) + encrypt_round(aes_ft_tab,-16) + encrypt_round(aes_ft_tab, 0) + encrypt_round(aes_ft_tab, 16) + encrypt_round(aes_ft_tab, 32) + encrypt_round(aes_ft_tab, 48) + encrypt_round(aes_ft_tab, 64) + encrypt_round(aes_ft_tab, 80) + encrypt_round(aes_ft_tab, 96) + encrypt_final(aes_fl_tab,112) + return + +/* void aes_decrypt(void *ctx, u8 *out, const u8 *in) */ + + entry(aes_decrypt,240,dec128,dec192) + decrypt_round(aes_it_tab,-96) + decrypt_round(aes_it_tab,-80) +dec192: decrypt_round(aes_it_tab,-64) + decrypt_round(aes_it_tab,-48) +dec128: decrypt_round(aes_it_tab,-32) + decrypt_round(aes_it_tab,-16) + decrypt_round(aes_it_tab, 0) + decrypt_round(aes_it_tab, 16) + decrypt_round(aes_it_tab, 32) + decrypt_round(aes_it_tab, 48) + decrypt_round(aes_it_tab, 64) + decrypt_round(aes_it_tab, 80) + decrypt_round(aes_it_tab, 96) + decrypt_final(aes_il_tab,112) + return diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c new file mode 100644 index 000000000000..2b5c4010ce38 --- /dev/null +++ b/arch/x86_64/crypto/aes.c @@ -0,0 +1,324 @@ +/* + * Cryptographic API. + * + * AES Cipher Algorithm. + * + * Based on Brian Gladman's code. + * + * Linux developers: + * Alexander Kjeldaas <astor@fast.no> + * Herbert Valerio Riedel <hvr@hvrlab.org> + * Kyle McMartin <kyle@debian.org> + * Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API). + * Andreas Steinmetz <ast@domdv.de> (adapted to x86_64 assembler) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * --------------------------------------------------------------------------- + * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. + * All rights reserved. + * + * LICENSE TERMS + * + * The free distribution and use of this software in both source and binary + * form is allowed (with or without changes) provided that: + * + * 1. distributions of this source code include the above copyright + * notice, this list of conditions and the following disclaimer; + * + * 2. distributions in binary form include the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other associated materials; + * + * 3. the copyright holder's name is not used to endorse products + * built using this software without specific written permission. + * + * ALTERNATIVELY, provided that this notice is retained in full, this product + * may be distributed under the terms of the GNU General Public License (GPL), + * in which case the provisions of the GPL apply INSTEAD OF those given above. + * + * DISCLAIMER + * + * This software is provided 'as is' with no explicit or implied warranties + * in respect of its properties, including, but not limited to, correctness + * and/or fitness for purpose. + * --------------------------------------------------------------------------- + */ + +/* Some changes from the Gladman version: + s/RIJNDAEL(e_key)/E_KEY/g + s/RIJNDAEL(d_key)/D_KEY/g +*/ + +#include <asm/byteorder.h> +#include <linux/bitops.h> +#include <linux/crypto.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/types.h> + +#define AES_MIN_KEY_SIZE 16 +#define AES_MAX_KEY_SIZE 32 + +#define AES_BLOCK_SIZE 16 + +/* + * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) + */ +static inline u8 byte(const u32 x, const unsigned n) +{ + return x >> (n << 3); +} + +#define u32_in(x) le32_to_cpu(*(const __le32 *)(x)) + +struct aes_ctx +{ + u32 key_length; + u32 E[60]; + u32 D[60]; +}; + +#define E_KEY ctx->E +#define D_KEY ctx->D + +static u8 pow_tab[256] __initdata; +static u8 log_tab[256] __initdata; +static u8 sbx_tab[256] __initdata; +static u8 isb_tab[256] __initdata; +static u32 rco_tab[10]; +u32 aes_ft_tab[4][256]; +u32 aes_it_tab[4][256]; + +u32 aes_fl_tab[4][256]; +u32 aes_il_tab[4][256]; + +static inline u8 f_mult(u8 a, u8 b) +{ + u8 aa = log_tab[a], cc = aa + log_tab[b]; + + return pow_tab[cc + (cc < aa ? 1 : 0)]; +} + +#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0) + +#define ls_box(x) \ + (aes_fl_tab[0][byte(x, 0)] ^ \ + aes_fl_tab[1][byte(x, 1)] ^ \ + aes_fl_tab[2][byte(x, 2)] ^ \ + aes_fl_tab[3][byte(x, 3)]) + +static void __init gen_tabs(void) +{ + u32 i, t; + u8 p, q; + + /* log and power tables for GF(2**8) finite field with + 0x011b as modular polynomial - the simplest primitive + root is 0x03, used here to generate the tables */ + + for (i = 0, p = 1; i < 256; ++i) { + pow_tab[i] = (u8)p; + log_tab[p] = (u8)i; + + p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; + + for (i = 0, p = 1; i < 10; ++i) { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + for (i = 0; i < 256; ++i) { + p = (i ? pow_tab[255 - log_tab[i]] : 0); + q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2)); + p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2)); + sbx_tab[i] = p; + isb_tab[p] = (u8)i; + } + + for (i = 0; i < 256; ++i) { + p = sbx_tab[i]; + + t = p; + aes_fl_tab[0][i] = t; + aes_fl_tab[1][i] = rol32(t, 8); + aes_fl_tab[2][i] = rol32(t, 16); + aes_fl_tab[3][i] = rol32(t, 24); + + t = ((u32)ff_mult(2, p)) | + ((u32)p << 8) | + ((u32)p << 16) | ((u32)ff_mult(3, p) << 24); + + aes_ft_tab[0][i] = t; + aes_ft_tab[1][i] = rol32(t, 8); + aes_ft_tab[2][i] = rol32(t, 16); + aes_ft_tab[3][i] = rol32(t, 24); + + p = isb_tab[i]; + + t = p; + aes_il_tab[0][i] = t; + aes_il_tab[1][i] = rol32(t, 8); + aes_il_tab[2][i] = rol32(t, 16); + aes_il_tab[3][i] = rol32(t, 24); + + t = ((u32)ff_mult(14, p)) | + ((u32)ff_mult(9, p) << 8) | + ((u32)ff_mult(13, p) << 16) | + ((u32)ff_mult(11, p) << 24); + + aes_it_tab[0][i] = t; + aes_it_tab[1][i] = rol32(t, 8); + aes_it_tab[2][i] = rol32(t, 16); + aes_it_tab[3][i] = rol32(t, 24); + } +} + +#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) + +#define imix_col(y, x) \ + u = star_x(x); \ + v = star_x(u); \ + w = star_x(v); \ + t = w ^ (x); \ + (y) = u ^ v ^ w; \ + (y) ^= ror32(u ^ t, 8) ^ \ + ror32(v ^ t, 16) ^ \ + ror32(t, 24) + +/* initialise the key schedule from the user supplied key */ + +#define loop4(i) \ +{ \ + t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \ + t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \ + t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \ + t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \ +} + +#define loop6(i) \ +{ \ + t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \ + t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \ + t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \ + t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \ + t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \ + t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \ +} + +#define loop8(i) \ +{ \ + t = ror32(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \ + t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \ + t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \ + t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \ + t = E_KEY[8 * i + 4] ^ ls_box(t); \ + E_KEY[8 * i + 12] = t; \ + t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \ + t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \ + t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ +} + +static int aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, + u32 *flags) +{ + struct aes_ctx *ctx = ctx_arg; + u32 i, j, t, u, v, w; + + if (key_len != 16 && key_len != 24 && key_len != 32) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + ctx->key_length = key_len; + + D_KEY[key_len + 24] = E_KEY[0] = u32_in(in_key); + D_KEY[key_len + 25] = E_KEY[1] = u32_in(in_key + 4); + D_KEY[key_len + 26] = E_KEY[2] = u32_in(in_key + 8); + D_KEY[key_len + 27] = E_KEY[3] = u32_in(in_key + 12); + + switch (key_len) { + case 16: + t = E_KEY[3]; + for (i = 0; i < 10; ++i) + loop4(i); + break; + + case 24: + E_KEY[4] = u32_in(in_key + 16); + t = E_KEY[5] = u32_in(in_key + 20); + for (i = 0; i < 8; ++i) + loop6 (i); + break; + + case 32: + E_KEY[4] = u32_in(in_key + 16); + E_KEY[5] = u32_in(in_key + 20); + E_KEY[6] = u32_in(in_key + 24); + t = E_KEY[7] = u32_in(in_key + 28); + for (i = 0; i < 7; ++i) + loop8(i); + break; + } + + D_KEY[0] = E_KEY[key_len + 24]; + D_KEY[1] = E_KEY[key_len + 25]; + D_KEY[2] = E_KEY[key_len + 26]; + D_KEY[3] = E_KEY[key_len + 27]; + + for (i = 4; i < key_len + 24; ++i) { + j = key_len + 24 - (i & ~3) + (i & 3); + imix_col(D_KEY[j], E_KEY[i]); + } + + return 0; +} + +extern void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in); +extern void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in); + +static struct crypto_alg aes_alg = { + .cra_name = "aes", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct aes_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = AES_MIN_KEY_SIZE, + .cia_max_keysize = AES_MAX_KEY_SIZE, + .cia_setkey = aes_set_key, + .cia_encrypt = aes_encrypt, + .cia_decrypt = aes_decrypt + } + } +}; + +static int __init aes_init(void) +{ + gen_tabs(); + return crypto_register_alg(&aes_alg); +} + +static void __exit aes_fini(void) +{ + crypto_unregister_alg(&aes_alg); +} + +module_init(aes_init); +module_exit(aes_fini); + +MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); +MODULE_LICENSE("GPL"); diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 157190d986bb..d206d7e49cf5 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1064,7 +1064,6 @@ void print_all_local_APICs (void) void __apicdebuginit print_PIC(void) { - extern spinlock_t i8259A_lock; unsigned int v; unsigned long flags; diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index acd2a778ebe6..5c6dc7051482 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -682,7 +682,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index b693c232fd07..657e88aa0902 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -7,25 +7,50 @@ #include <linux/pci.h> #include <linux/init.h> +#include <linux/acpi.h> #include "pci.h" #define MMCONFIG_APER_SIZE (256*1024*1024) -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -u32 pci_mmcfg_base_addr; - /* Static virtual mapping of the MMCONFIG aperture */ -char *pci_mmcfg_virt; +struct mmcfg_virt { + struct acpi_table_mcfg_config *cfg; + char *virt; +}; +static struct mmcfg_virt *pci_mmcfg_virt; -static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) +static char *get_virt(unsigned int seg, int bus) { - return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); + int cfg_num = -1; + struct acpi_table_mcfg_config *cfg; + + while (1) { + ++cfg_num; + if (cfg_num >= pci_mmcfg_config_num) { + /* something bad is going on, no cfg table is found. */ + /* so we fall back to the old way we used to do this */ + /* and just rely on the first entry to be correct. */ + return pci_mmcfg_virt[0].virt; + } + cfg = pci_mmcfg_virt[cfg_num].cfg; + if (cfg->pci_segment_group_number != seg) + continue; + if ((cfg->start_bus_number <= bus) && + (cfg->end_bus_number >= bus)) + return pci_mmcfg_virt[cfg_num].virt; + } +} + +static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) +{ + + return get_virt(seg, bus) + ((bus << 20) | (devfn << 12)); } static int pci_mmcfg_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { - char *addr = pci_dev_base(bus, devfn); + char *addr = pci_dev_base(seg, bus, devfn); if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; @@ -48,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 value) { - char *addr = pci_dev_base(bus,devfn); + char *addr = pci_dev_base(seg, bus, devfn); if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; @@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = { static int __init pci_mmcfg_init(void) { + int i; + if ((pci_probe & PCI_PROBE_MMCONF) == 0) return 0; - if (!pci_mmcfg_base_addr) + + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if ((pci_mmcfg_config_num == 0) || + (pci_mmcfg_config == NULL) || + (pci_mmcfg_config[0].base_address == 0)) return 0; /* Kludge for now. Don't use mmconfig on AMD systems because @@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void) return 0; /* RED-PEN i386 doesn't do _nocache right now */ - pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); - if (!pci_mmcfg_virt) { - printk("PCI: Cannot map mmconfig aperture\n"); + pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); + if (pci_mmcfg_virt == NULL) { + printk("PCI: Can not allocate memory for mmconfig structures\n"); return 0; - } + } + for (i = 0; i < pci_mmcfg_config_num; ++i) { + pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); + if (!pci_mmcfg_virt[i].virt) { + printk("PCI: Cannot map mmconfig aperture for segment %d\n", + pci_mmcfg_config[i].pci_segment_group_number); + return 0; + } + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); + } - printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 3e89767cea72..c9b5d298e3c4 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -132,7 +132,7 @@ config XTENSA_CPU_CLOCK config GENERIC_CALIBRATE_DELAY bool "Auto calibration of the BogoMIPS value" ---help--- - The BogoMIPS value can easily derived from the CPU frequency. + The BogoMIPS value can easily be derived from the CPU frequency. config CMDLINE_BOOL bool "Default bootloader kernel arguments" @@ -158,6 +158,8 @@ config XTENSA_ISS_NETWORK depends on XTENSA_PLATFORM_ISS default y +source "mm/Kconfig" + endmenu menu "Bus options" diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 4fa27453b1f9..27847e4ffcbf 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -21,23 +21,17 @@ export CPU # Platform configuration -platform-y := common platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss PLATFORM = $(platform-y) export PLATFORM -#LDFLAGS_vmlinux := -T$(word 1,$(LINKSCRIPT)) -AFLAGS_vmlinux.lds.o := -Uxtensa -CPPFLAGS += -Iarch/xtensa -Iinclude/asm -mlongcalls -g -AFLAGS += -Iarch/xtensa -Iinclude/asm -CPP = $(CC) -E $(CFLAGS) +CPPFLAGS += $(if $(KBUILD_SRC),-I$(srctree)/include/asm-xtensa/) +CPPFLAGS += -Iinclude/asm +CFLAGS += -pipe -mlongcalls -cflags-y += -Iarch/xtensa -pipe -mlongcalls - - -KBUILD_DEFCONFIG := common_defconfig +KBUILD_DEFCONFIG := iss_defconfig # ramdisk/initrd support # You need a compressed ramdisk image, named ramdisk.gz in @@ -62,30 +56,36 @@ endif LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) head-y := arch/xtensa/kernel/head.o -core-y += arch/xtensa/kernel/ \ - arch/xtensa/mm/ arch/xtensa/platform-$(PLATFORM)/ +core-y += arch/xtensa/kernel/ arch/xtensa/mm/ +ifneq ($(PLATFORM),) +core-y += arch/xtensa/platform-$(PLATFORM)/ +endif libs-y += arch/xtensa/lib/ $(LIBGCC) -boot := arch/xtensa/boot +boot := arch/xtensa/boot + +archinc := include/asm-xtensa arch/xtensa/kernel/asm-offsets.s: \ - arch/xtensa/kernel/asm-offsets.c \ - include/asm-xtensa/.platform + arch/xtensa/kernel/asm-offsets.c $(archinc)/.platform include/asm-xtensa/offsets.h: arch/xtensa/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) -prepare: include/asm-xtensa/.platform include/asm-xtensa/offsets.h +prepare: $(archinc)/.platform $(archinc)/offsets.h # Update machine cpu and platform symlinks if something which affects # them changed. -include/asm-xtensa/.platform: $(wildcard include/config/arch/*.h) - @echo ' Setting up cpu ($(CPU)) and platform ($(PLATFORM)) symlinks' - $(Q)rm -f include/asm-xtensa/platform - $(Q)rm -f include/asm-xtensa/xtensa/config - $(Q)(cd include/asm-xtensa/; ln -sf platform-$(PLATFORM) platform) - $(Q)(cd include/asm-xtensa/xtensa; ln -sf config-$(CPU) config) +$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER + @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' + $(Q)mkdir -p $(archinc) + $(Q)mkdir -p $(archinc)/xtensa + $(Q)ln -fsn $(srctree)/$(archinc)/xtensa/config-$(CPU) $(archinc)/xtensa/config + @echo ' SYMLINK $(archinc)/platform -> $(archinc)/platform-$(PLATFORM)' + $(Q)ln -fsn $(srctree)/$(archinc)/platform-$(PLATFORM) $(archinc)/platform + @touch $@ + all: zImage @@ -94,7 +94,9 @@ bzImage : zImage zImage zImage.initrd: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ -CLEAN_FILES += arch/xtensa/vmlinux.lds include/asm-xtensa/offset.h +CLEAN_FILES += arch/xtensa/vmlinux.lds $(archinc)/offset.h \ + $(archinc)/platform $(archinc)/xtensa/config \ + $(archinc)/.platform define archhelp @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 260f456ccf0b..820b31d10ae4 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -11,21 +11,19 @@ CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include HOSTFLAGS += -Iarch/$(ARCH)/boot/include -BIG_ENDIAN := $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big) - +BIG_ENDIAN := $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#") export CFLAGS export AFLAGS export BIG_ENDIAN +subdir-y := lib + # Subdirs for the boot loader(s) bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf -subdir-y := lib/ - -subdir-y += boot-elf/ boot-redboot/ zImage zImage.initrd Image Image.initrd: $(bootdir-y) @@ -33,5 +31,3 @@ $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ $(addprefix $(obj)/,$(host-progs)) $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) - - diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index f6ef6a369667..734db7f76583 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile @@ -27,7 +27,7 @@ Image: vmlinux $(OBJS) --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T arch/$(ARCH)/boot/boot-elf/boot.ld \ + -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \ -o arch/$(ARCH)/boot/$@.elf $@.tmp rm -f $@.tmp vmlinux.tmp @@ -41,7 +41,7 @@ Image.initrd: vmlinux $(OBJS) --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T arch/$(ARCH)/boot/boot-elf/boot.ld \ + -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \ -o arch/$(ARCH)/boot/$@.elf $@.tmp rm -f $@.tmp vmlinux.tmp diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile index ca8a68bc8472..f53262c2e1f3 100644 --- a/arch/xtensa/boot/boot-redboot/Makefile +++ b/arch/xtensa/boot/boot-redboot/Makefile @@ -12,24 +12,24 @@ else OBJCOPY_ARGS := -O elf32-xtensa-le endif -LD_ARGS = -T $(obj)/boot.ld +LD_ARGS = -T $(srctree)/$(obj)/boot.ld boot-y := bootstrap.o OBJS := $(addprefix $(obj)/,$(boot-y)) -LIBS := arch/$(ARCH)/boot/lib/lib.a arch/$(ARCH)/lib/lib.a +LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) zImage: vmlinux $(OBJS) $(LIBS) $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ - $(TOPDIR)/vmlinux vmlinux.tmp + vmlinux vmlinux.tmp gzip -vf9 vmlinux.tmp $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ --add-section image=vmlinux.tmp.gz \ --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC) - $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/images/$@.redboot -# rm -f $@.tmp $@.elf vmlinux.tmp.gz + $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot + rm -f $@.tmp $@.elf vmlinux.tmp.gz diff --git a/arch/xtensa/boot/include/zlib.h b/arch/xtensa/boot/include/zlib.h deleted file mode 100644 index ea29b6237852..000000000000 --- a/arch/xtensa/boot/include/zlib.h +++ /dev/null @@ -1,433 +0,0 @@ -/* - * BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort - */ -/* - * This file is derived from zlib.h and zconf.h from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* - * ==FILEVERSION 960122== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 0.95, Aug 16th, 1995. - - Copyright (C) 1995 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - */ - -#ifndef _ZLIB_H -#define _ZLIB_H - -/* #include "zconf.h" */ /* included directly here */ - -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ - -/* - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. - */ - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints - * at addresses which are not a multiple of their size. - * Under DOS, -DFAR=far or -DFAR=__far may be needed. - */ - -#ifndef STDC -# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) -# define STDC -# endif -#endif - -#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ -# include <unix.h> -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -#ifndef FAR -# define FAR -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -/* end of original zconf.h */ - -#define ZLIB_VERSION "0.95P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidp opaque; /* private data object passed to zalloc and zfree */ - - Byte data_type; /* best guess about the data type: ascii or binary */ - -} z_stream; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_FULL_FLUSH 2 -#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ -#define Z_FINISH 4 -#define Z_PACKET_FLUSH 5 -/* See deflate() below for the usage of these constants */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -/* error codes for the compression/decompression functions */ - -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Used to set the data_type field */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -extern char *zlib_version; -/* The application can compare zlib_version and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - */ - - /* basic functions */ - -extern int inflateInit OF((z_stream *strm)); -/* - Initializes the internal stream state for decompression. The fields - zalloc and zfree must be initialized before by the caller. If zalloc and - zfree are set to Z_NULL, inflateInit updates them to use default allocation - functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory. msg is set to null if there is no error message. - inflateInit does not perform any decompression: this will be done by - inflate(). -*/ - - -extern int inflate OF((z_stream *strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() always provides as much output as possible - (until there is no more input data or no more space in the output buffer). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if - the stream structure was inconsistent (for example if next_in or next_out - was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no - progress is possible or if there was not enough room in the output buffer - when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then - call inflateSync to look for a good compression block. */ - - -extern int inflateEnd OF((z_stream *strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* advanced functions */ - -extern int inflateInit2 OF((z_stream *strm, - int windowBits)); -/* - This is another version of inflateInit with more compression options. The - fields next_out, zalloc and zfree must be initialized before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1<<windowBits bytes. If next_out is null, the - library will allocate its own buffer (and leave next_out null). next_in - need not be provided here but must be provided by the application for the - next call of inflate(). - - If the history buffer is provided by the application, next_out must - never be changed by the application since the decompressor maintains - history information inside this buffer from call to call; the application - can only reset next_out to the beginning of the history buffer when - avail_out is zero and all output has been consumed. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was - not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as - windowBits < 8). msg is set to null if there is no error message. - inflateInit2 does not perform any decompression: this will be done by - inflate(). -*/ - -extern int inflateSync OF((z_stream *strm)); -/* - Skips invalid compressed data until the special marker (see deflate() - above) can be found, or until all available input is skipped. No output - is provided. - - inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no marker has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -extern int inflateReset OF((z_stream *strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -extern int inflateIncomp OF((z_stream *strm)); -/* - This function adds the data at next_in (avail_in bytes) to the output - history without performing any output. There must be no pending output, - and the decompressor must be expecting to see the start of a block. - Calling this function is equivalent to decompressing a stored block - containing the data at next_in (except that the data is not output). -*/ - - /* checksum functions */ - -/* - This function is not related to compression but is exported - anyway because it might be useful in applications using the - compression library. -*/ - -extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len)); - -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -#ifndef _Z_UTIL_H - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -#endif /* _ZLIB_H */ diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile index c0a74dc3a0df..9e73bb8aeb7a 100644 --- a/arch/xtensa/boot/lib/Makefile +++ b/arch/xtensa/boot/lib/Makefile @@ -2,5 +2,16 @@ # Makefile for some libs needed by zImage. # +zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c -lib-y := zlib.o zmem.o +lib-y += $(zlib:.c=.o) zmem.o + +EXTRA_CFLAGS += -Ilib/zlib_inflate + +quiet_cmd_copy_zlib = COPY $@ + cmd_copy_zlib = cat $< > $@ + +$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% + $(call cmd,copy_zlib) + +clean-files := $(zlib) diff --git a/arch/xtensa/boot/lib/memcpy.S b/arch/xtensa/boot/lib/memcpy.S deleted file mode 100644 index a029f5df2d5c..000000000000 --- a/arch/xtensa/boot/lib/memcpy.S +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/xtensa/lib/memcpy.S - * - * ANSI C standard library function memcpy - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file "COPYING" in the main directory of - * this archive for more details. - * - * Copyright (C) 2002 Tensilica Inc. - */ - -#define _ASMLANGUAGE -#include <xtensa/config/core.h> - -.text -.align 4 -.global bcopy -.type bcopy,@function -bcopy: - movi a14, xthal_bcopy // a14 safe to use regardless of whether caller - // used call4 or call8 (can't have used call12) - jx a14 // let the Core HAL do the work - -.text -.align 4 -.global memcpy -.type memcpy,@function -memcpy: -.global memmove -.type memmove,@function -memmove: - movi a14, xthal_memcpy // a14 safe to use regardless of whether caller - // used call4 or call8 (can't have used call12) - jx a14 // let the Core HAL do the work - diff --git a/arch/xtensa/boot/lib/zlib.c b/arch/xtensa/boot/lib/zlib.c deleted file mode 100644 index e3859f631077..000000000000 --- a/arch/xtensa/boot/lib/zlib.c +++ /dev/null @@ -1,2150 +0,0 @@ -/* - * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort - */ -/* - * This file is derived from various .h and .c files from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - changed functions not used outside this file to "local" - * - added minCompression parameter to deflateInit2 - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp - * - */ - -/*+++++*/ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ - -#define _Z_UTIL_H - -#include "zlib.h" - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -#define FAR - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern char *z_errmsg[]; /* indexed by 1-zlib_error */ - -#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) -/* To be used only when the state is known to be valid */ - -#ifndef NULL -#define NULL ((void *) 0) -#endif - - /* common constants */ - -#define DEFLATED 8 - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - - /* functions */ - -#include <linux/string.h> -#define zmemcpy memcpy -#define zmemzero(dest, len) memset(dest, 0, len) - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include <stdio.h> -# ifndef verbose -# define verbose 0 -# endif -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); - -/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ -/* void zcfree OF((voidpf opaque, voidpf ptr)); */ - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr, size) \ - (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) -#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} - -/* deflate.h -- internal compression state - * Copyright (C) 1995 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/*+++++*/ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -local inflate_blocks_statef * inflate_blocks_new OF(( - z_stream *z, - check_func c, /* check function */ - uInt w)); /* window size */ - -local int inflate_blocks OF(( - inflate_blocks_statef *, - z_stream *, - int)); /* initial return code */ - -local void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_addhistory OF(( - inflate_blocks_statef *, - z_stream *)); - -local int inflate_packet_flush OF(( - inflate_blocks_statef *)); - -/*+++++*/ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt Nalloc; /* number of these allocated here */ - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - local uInt inflate_hufts; -#endif - -local int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -local int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_stream *)); /* for zfree function */ - - -/*+++++*/ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -local inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_stream *)); - -local int inflate_codes OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -local void inflate_codes_free OF(( - inflate_codes_statef *, - z_stream *)); - - -/*+++++*/ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state, sizeof(struct internal_state)); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2(z, w) -z_stream *z; -int w; -{ - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; -/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ -/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit(z) -z_stream *z; -{ - return inflateInit2(z, DEF_WBITS); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z, f) -z_stream *z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->next_in == Z_NULL) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) - { - z->state->mode = BAD; - z->msg = "unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = "invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - if ((b = NEXTBYTE) & 0x20) - { - z->state->mode = BAD; - z->msg = "invalid reserved bit"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = "incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - z->state->mode = BLOCKS; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = "incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp(z) -z_stream *z; -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync(z) -z_stream *z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE - -/*+++++*/ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ - mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - int nblens; /* # elements allocated at blens */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl, *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define DUMPBITS(j) {b>>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (q<s->read?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* - * The IBM 150 firmware munges the data right after _etext[]. This - * protects it. -- Cort - */ -local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0}; -/* And'ing with mask[n] masks the lower n bits */ -local uInt inflate_mask[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -/*+++++*/ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -local int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_stream *)); - - -/*+++++*/ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* Table for deflate from PKZIP's appnote.txt. */ -local uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -local void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -local inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_stream *z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -local int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = "invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if (((~b) >> 16) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : TYPE; - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.trees.nblens = t; - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - s->mode = BADB; - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - s->mode = BADB; - z->msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = BADB; - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok\n")); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local int inflate_blocks_free(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window, s->end - s->window); - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -local int inflate_addhistory(s, z) -inflate_blocks_statef *s; -z_stream *z; -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WRAP */ /* expand WRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -local int inflate_packet_flush(s) - inflate_blocks_statef *s; -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} - - -/*+++++*/ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - uIntf *, /* list of base values for non-simple codes */ - uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_stream *)); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -local void ffree OF(( - voidpf q, /* opaque pointer (not used) */ - voidpf p, /* what to free (not used) */ - uInt n)); /* number of bytes (not used) */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* actually lengths - 2; also see note #13 above about 258 */ -local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ -local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local uInt cpdext[] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build(b, n, s, d, e, t, m, zs) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= N_MAX) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -uIntf *d; /* list of base values for non-simple codes */ -uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -z_stream *zs; /* for zalloc function */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (all zero length codes or an - over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } - q->word.Nalloc = z + 1; -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -local int inflate_trees_bits(c, bb, tb, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tb, z); - z->msg = "incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - /* build literal/length tree */ - if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_lock = 0; -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local uInt fixed_left = FIXEDH; -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer (not used) */ -uInt n; /* number of items */ -uInt s; /* size of item */ -{ - Assert(s == sizeof(inflate_huft) && n <= fixed_left, - "inflate_trees falloc overflow"); - if (q) s++; /* to make some compilers happy */ - fixed_left -= n; - return (voidpf)(fixed_mem + fixed_left); -} - - -local void ffree(q, p, n) -voidpf q; -voidpf p; -uInt n; -{ - Assert(0, "inflate_trees ffree called!"); - if (q) q = p; /* to make some compilers happy */ -} - - -local int inflate_trees_fixed(bl, bd, tl, td) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -{ - /* build fixed tables if not built already--lock out other instances */ - while (++fixed_lock > 1) - fixed_lock--; - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = ffree; - z.opaque = Z_NULL; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - fixed_built = 1; - } - fixed_lock--; - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -local int inflate_trees_free(t, z) -inflate_huft *t; /* table to free */ -z_stream *z; /* for zfree function */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q; - - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); - p = q; - } - return Z_OK; -} - -/*+++++*/ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl, *td; -z_stream *z; -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -local int inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local void inflate_codes_free(c, z) -inflate_codes_statef *c; -z_stream *z; -{ - ZFREE(z, c, sizeof(struct inflate_codes_state)); - Tracev((stderr, "inflate: codes free\n")); -} - -/*+++++*/ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt n; - Bytef *p, *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - zmemcpy(p, q, n); - p += n; - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - zmemcpy(p, q, n); - p += n; - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} - - -/*+++++*/ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -local int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl, *td; -inflate_blocks_statef *s; -z_stream *z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = "invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = "invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} - - -/*+++++*/ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ - -char *zlib_version = ZLIB_VERSION; - -char *z_errmsg[] = { -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -""}; - - -/*+++++*/ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); -#define DO16(buf) DO8(buf); DO8(buf); - -/* ========================================================================= */ -uLong adler32(adler, buf, len) - uLong adler; - Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - k -= 16; - } - if (k != 0) do { - DO1(buf); - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} diff --git a/arch/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c index 7848f126d67d..d9862aa8ca25 100644 --- a/arch/xtensa/boot/lib/zmem.c +++ b/arch/xtensa/boot/lib/zmem.c @@ -1,4 +1,4 @@ -#include "zlib.h" +#include <linux/zlib.h> /* bits taken from ppc */ @@ -9,11 +9,10 @@ void exit (void) for (;;); } -void *zalloc(void *x, unsigned items, unsigned size) +void *zalloc(unsigned size) { void *p = avail_ram; - size *= items; size = (size + 7) & -8; avail_ram += size; if (avail_ram > end_avail) { @@ -24,11 +23,6 @@ void *zalloc(void *x, unsigned items, unsigned size) return p; } -void zfree(void *x, void *addr, unsigned nb) -{ -} - - #define HEAD_CRC 2 #define EXTRA_FIELD 4 #define ORIG_NAME 8 @@ -43,7 +37,6 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) int r, i, flags; /* skip header */ - i = 10; flags = src[3]; if (src[2] != DEFLATED || (flags & RESERVED) != 0) { @@ -65,9 +58,8 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) exit(); } - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); + s.workspace = zalloc(zlib_inflate_workspacesize()); + r = zlib_inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { //puts("inflateInit2 returned "); puthex(r); puts("\n"); exit(); @@ -76,12 +68,12 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); + r = zlib_inflate(&s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { //puts("inflate returned "); puthex(r); puts("\n"); exit(); } *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); + zlib_inflateEnd(&s); } diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index d29a81648637..09887c96e9a1 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -57,50 +57,6 @@ struct pci_controller** pci_ctrl_tail = &pci_ctrl_head; static int pci_bus_count; -static void pcibios_fixup_resources(struct pci_dev* dev); - -#if 0 // FIXME -struct pci_fixup pcibios_fixups[] = { - { DECLARE_PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, - { 0 } -}; -#endif - -void -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check, mask; - int reg; - struct pci_controller* pci_ctrl = dev->sysdata; - - new = res->start; - if (pci_ctrl && res->flags & IORESOURCE_IO) { - new -= pci_ctrl->io_space.base; - } - new |= (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4*resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - mask = (new & PCI_BASE_ADDRESS_SPACE_IO) ? - PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; - - if ((new ^ check) & mask) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -125,7 +81,7 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size, if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, + " (%ld bytes)\n", pci_name(dev), dev->resource - res, size); } @@ -149,7 +105,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask) r = &dev->resource[idx]; if (!r->start && r->end) { printk (KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); + "of resource collisions\n", pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -161,7 +117,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask) cmd |= PCI_COMMAND_MEMORY; if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); + pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } return 0; @@ -293,7 +249,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) r = &dev->resource[idx]; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); + "of resource collisions\n", pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -303,7 +259,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) } if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); + pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } @@ -325,47 +281,6 @@ pci_controller_num(struct pci_dev *dev) #endif /* CONFIG_PROC_FS */ - -static void -pcibios_fixup_resources(struct pci_dev *dev) -{ - struct pci_controller* pci_ctrl = (struct pci_controller *)dev->sysdata; - int i; - unsigned long offset; - - if (!pci_ctrl) { - printk(KERN_ERR "No pci_ctrl for PCI dev %s!\n",dev->slot_name); - return; - } - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - struct resource *res = dev->resource + i; - if (!res->start || !res->flags) - continue; - if (res->end == 0xffffffff) { - DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", - dev->slot_name, i, res->start, res->end); - res->end -= res->start; - res->start = 0; - continue; - } - offset = 0; - if (res->flags & IORESOURCE_IO) - offset = (unsigned long) pci_ctrl->io_space.base; - else if (res->flags & IORESOURCE_MEM) - offset = (unsigned long) pci_ctrl->mem_space.base; - - if (offset != 0) { - res->start += offset; - res->end += offset; -#ifdef DEBUG - printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n", - i, res->flags, dev->slot_name, - res->start - offset, res->start); -#endif - } - } -} - /* * Platform support for /proc/bus/pci/X/Y mmap()s, * modelled on the sparc64 implementation by Dave Miller. diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 9ef07a4dd2a2..2659efdd4e99 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -22,6 +22,7 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/security.h> +#include <linux/signal.h> #include <asm/pgtable.h> #include <asm/page.h> @@ -239,7 +240,7 @@ int sys_ptrace(long request, long pid, long addr, long data) case PTRACE_CONT: /* restart after signal. */ { ret = -EIO; - if ((unsigned long) data > _NSIG) + if (!valid_signal(data)) break; if (request == PTRACE_SYSCALL) set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); @@ -269,7 +270,7 @@ int sys_ptrace(long request, long pid, long addr, long data) case PTRACE_SINGLESTEP: ret = -EIO; - if ((unsigned long) data > _NSIG) + if (!valid_signal(data)) break; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->ptrace |= PT_SINGLESTEP; diff --git a/crypto/Kconfig b/crypto/Kconfig index 90d6089d60ed..256c0b1fed10 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -146,7 +146,7 @@ config CRYPTO_SERPENT config CRYPTO_AES tristate "AES cipher algorithms" - depends on CRYPTO && !((X86 || UML_X86) && !64BIT) + depends on CRYPTO && !(X86 || UML_X86) help AES cipher algorithms (FIPS-197). AES uses the Rijndael algorithm. @@ -184,6 +184,26 @@ config CRYPTO_AES_586 See <http://csrc.nist.gov/encryption/aes/> for more information. +config CRYPTO_AES_X86_64 + tristate "AES cipher algorithms (x86_64)" + depends on CRYPTO && ((X86 || UML_X86) && 64BIT) + help + AES cipher algorithms (FIPS-197). AES uses the Rijndael + algorithm. + + Rijndael appears to be consistently a very good performer in + both hardware and software across a wide range of computing + environments regardless of its use in feedback or non-feedback + modes. Its key setup time is excellent, and its key agility is + good. Rijndael's very low memory requirements make it very well + suited for restricted-space environments, in which it also + demonstrates excellent performance. Rijndael's operations are + among the easiest to defend against power and timing attacks. + + The AES specifies three key sizes: 128, 192 and 256 bits + + See <http://csrc.nist.gov/encryption/aes/> for more information. + config CRYPTO_CAST5 tristate "CAST5 (CAST-128) cipher algorithm" depends on CRYPTO diff --git a/crypto/api.c b/crypto/api.c index 394169a8577d..b4728811ce3b 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -13,9 +13,12 @@ * any later version. * */ + +#include <linux/compiler.h> #include <linux/init.h> #include <linux/crypto.h> #include <linux/errno.h> +#include <linux/kmod.h> #include <linux/rwsem.h> #include <linux/slab.h> #include "internal.h" @@ -33,7 +36,7 @@ static inline void crypto_alg_put(struct crypto_alg *alg) module_put(alg->cra_module); } -struct crypto_alg *crypto_alg_lookup(const char *name) +static struct crypto_alg *crypto_alg_lookup(const char *name) { struct crypto_alg *q, *alg = NULL; @@ -54,6 +57,13 @@ struct crypto_alg *crypto_alg_lookup(const char *name) return alg; } +/* A far more intelligent version of this is planned. For now, just + * try an exact match on the name of the algorithm. */ +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) +{ + return try_then_request_module(crypto_alg_lookup(name), name); +} + static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) { tfm->crt_flags = 0; @@ -117,20 +127,46 @@ static void crypto_exit_ops(struct crypto_tfm *tfm) } } +static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags) +{ + unsigned int len; + + switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { + default: + BUG(); + + case CRYPTO_ALG_TYPE_CIPHER: + len = crypto_cipher_ctxsize(alg, flags); + break; + + case CRYPTO_ALG_TYPE_DIGEST: + len = crypto_digest_ctxsize(alg, flags); + break; + + case CRYPTO_ALG_TYPE_COMPRESS: + len = crypto_compress_ctxsize(alg, flags); + break; + } + + return len + alg->cra_alignmask; +} + struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) { struct crypto_tfm *tfm = NULL; struct crypto_alg *alg; + unsigned int tfm_size; alg = crypto_alg_mod_lookup(name); if (alg == NULL) goto out; - - tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL); + + tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags); + tfm = kmalloc(tfm_size, GFP_KERNEL); if (tfm == NULL) goto out_put; - memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize); + memset(tfm, 0, tfm_size); tfm->__crt_alg = alg; @@ -155,8 +191,14 @@ out: void crypto_free_tfm(struct crypto_tfm *tfm) { - struct crypto_alg *alg = tfm->__crt_alg; - int size = sizeof(*tfm) + alg->cra_ctxsize; + struct crypto_alg *alg; + int size; + + if (unlikely(!tfm)) + return; + + alg = tfm->__crt_alg; + size = sizeof(*tfm) + alg->cra_ctxsize; crypto_exit_ops(tfm); crypto_alg_put(alg); @@ -168,6 +210,12 @@ int crypto_register_alg(struct crypto_alg *alg) { int ret = 0; struct crypto_alg *q; + + if (alg->cra_alignmask & (alg->cra_alignmask + 1)) + return -EINVAL; + + if (alg->cra_alignmask > PAGE_SIZE) + return -EINVAL; down_write(&crypto_alg_sem); diff --git a/crypto/cipher.c b/crypto/cipher.c index f434ce7c2d0b..1c92c6bb138b 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -4,6 +4,7 @@ * Cipher operations. * * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> + * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> * * 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 @@ -22,10 +23,6 @@ #include "internal.h" #include "scatterwalk.h" -typedef void (cryptfn_t)(void *, u8 *, const u8 *); -typedef void (procfn_t)(struct crypto_tfm *, u8 *, - u8*, cryptfn_t, void *); - static inline void xor_64(u8 *a, const u8 *b) { ((u32 *)a)[0] ^= ((u32 *)b)[0]; @@ -39,63 +36,70 @@ static inline void xor_128(u8 *a, const u8 *b) ((u32 *)a)[2] ^= ((u32 *)b)[2]; ((u32 *)a)[3] ^= ((u32 *)b)[3]; } - -static inline void *prepare_src(struct scatter_walk *walk, int bsize, - void *tmp, int in_place) + +static unsigned int crypt_slow(const struct cipher_desc *desc, + struct scatter_walk *in, + struct scatter_walk *out, unsigned int bsize) { - void *src = walk->data; - int n = bsize; + unsigned int alignmask = crypto_tfm_alg_alignmask(desc->tfm); + u8 buffer[bsize * 2 + alignmask]; + u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + u8 *dst = src + bsize; + unsigned int n; - if (unlikely(scatterwalk_across_pages(walk, bsize))) { - src = tmp; - n = scatterwalk_copychunks(src, walk, bsize, 0); - } - scatterwalk_advance(walk, n); - return src; + n = scatterwalk_copychunks(src, in, bsize, 0); + scatterwalk_advance(in, n); + + desc->prfn(desc, dst, src, bsize); + + n = scatterwalk_copychunks(dst, out, bsize, 1); + scatterwalk_advance(out, n); + + return bsize; } -static inline void *prepare_dst(struct scatter_walk *walk, int bsize, - void *tmp, int in_place) +static inline unsigned int crypt_fast(const struct cipher_desc *desc, + struct scatter_walk *in, + struct scatter_walk *out, + unsigned int nbytes, u8 *tmp) { - void *dst = walk->data; + u8 *src, *dst; - if (unlikely(scatterwalk_across_pages(walk, bsize)) || in_place) + src = in->data; + dst = scatterwalk_samebuf(in, out) ? src : out->data; + + if (tmp) { + memcpy(tmp, in->data, nbytes); + src = tmp; dst = tmp; - return dst; -} + } -static inline void complete_src(struct scatter_walk *walk, int bsize, - void *src, int in_place) -{ -} + nbytes = desc->prfn(desc, dst, src, nbytes); -static inline void complete_dst(struct scatter_walk *walk, int bsize, - void *dst, int in_place) -{ - int n = bsize; + if (tmp) + memcpy(out->data, tmp, nbytes); + + scatterwalk_advance(in, nbytes); + scatterwalk_advance(out, nbytes); - if (unlikely(scatterwalk_across_pages(walk, bsize))) - n = scatterwalk_copychunks(dst, walk, bsize, 1); - else if (in_place) - memcpy(walk->data, dst, bsize); - scatterwalk_advance(walk, n); + return nbytes; } /* * Generic encrypt/decrypt wrapper for ciphers, handles operations across * multiple page boundaries by using temporary blocks. In user context, - * the kernel is given a chance to schedule us once per block. + * the kernel is given a chance to schedule us once per page. */ -static int crypt(struct crypto_tfm *tfm, +static int crypt(const struct cipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes, cryptfn_t crfn, - procfn_t prfn, void *info) + unsigned int nbytes) { struct scatter_walk walk_in, walk_out; + struct crypto_tfm *tfm = desc->tfm; const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); - u8 tmp_src[bsize]; - u8 tmp_dst[bsize]; + unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); + unsigned long buffer = 0; if (!nbytes) return 0; @@ -109,64 +113,144 @@ static int crypt(struct crypto_tfm *tfm, scatterwalk_start(&walk_out, dst); for(;;) { - u8 *src_p, *dst_p; - int in_place; + unsigned int n = nbytes; + u8 *tmp = NULL; + + if (!scatterwalk_aligned(&walk_in, alignmask) || + !scatterwalk_aligned(&walk_out, alignmask)) { + if (!buffer) { + buffer = __get_free_page(GFP_ATOMIC); + if (!buffer) + n = 0; + } + tmp = (u8 *)buffer; + } scatterwalk_map(&walk_in, 0); scatterwalk_map(&walk_out, 1); - in_place = scatterwalk_samebuf(&walk_in, &walk_out); - - do { - src_p = prepare_src(&walk_in, bsize, tmp_src, - in_place); - dst_p = prepare_dst(&walk_out, bsize, tmp_dst, - in_place); - - prfn(tfm, dst_p, src_p, crfn, info); + n = scatterwalk_clamp(&walk_in, n); + n = scatterwalk_clamp(&walk_out, n); - complete_src(&walk_in, bsize, src_p, in_place); - complete_dst(&walk_out, bsize, dst_p, in_place); + if (likely(n >= bsize)) + n = crypt_fast(desc, &walk_in, &walk_out, n, tmp); + else + n = crypt_slow(desc, &walk_in, &walk_out, bsize); - nbytes -= bsize; - } while (nbytes && - !scatterwalk_across_pages(&walk_in, bsize) && - !scatterwalk_across_pages(&walk_out, bsize)); + nbytes -= n; scatterwalk_done(&walk_in, 0, nbytes); scatterwalk_done(&walk_out, 1, nbytes); if (!nbytes) - return 0; + break; crypto_yield(tfm); } + + if (buffer) + free_page(buffer); + + return 0; } -static void cbc_process_encrypt(struct crypto_tfm *tfm, u8 *dst, u8 *src, - cryptfn_t fn, void *info) +static int crypt_iv_unaligned(struct cipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { - u8 *iv = info; + struct crypto_tfm *tfm = desc->tfm; + unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); + u8 *iv = desc->info; - tfm->crt_u.cipher.cit_xor_block(iv, src); - fn(crypto_tfm_ctx(tfm), dst, iv); - memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm)); + if (unlikely(((unsigned long)iv & alignmask))) { + unsigned int ivsize = tfm->crt_cipher.cit_ivsize; + u8 buffer[ivsize + alignmask]; + u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + int err; + + desc->info = memcpy(tmp, iv, ivsize); + err = crypt(desc, dst, src, nbytes); + memcpy(iv, tmp, ivsize); + + return err; + } + + return crypt(desc, dst, src, nbytes); } -static void cbc_process_decrypt(struct crypto_tfm *tfm, u8 *dst, u8 *src, - cryptfn_t fn, void *info) +static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) { - u8 *iv = info; + struct crypto_tfm *tfm = desc->tfm; + void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; + int bsize = crypto_tfm_alg_blocksize(tfm); + + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; + u8 *iv = desc->info; + unsigned int done = 0; + + do { + xor(iv, src); + fn(crypto_tfm_ctx(tfm), dst, iv); + memcpy(iv, dst, bsize); - fn(crypto_tfm_ctx(tfm), dst, src); - tfm->crt_u.cipher.cit_xor_block(dst, iv); - memcpy(iv, src, crypto_tfm_alg_blocksize(tfm)); + src += bsize; + dst += bsize; + } while ((done += bsize) < nbytes); + + return done; } -static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src, - cryptfn_t fn, void *info) +static unsigned int cbc_process_decrypt(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) { - fn(crypto_tfm_ctx(tfm), dst, src); + struct crypto_tfm *tfm = desc->tfm; + void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; + int bsize = crypto_tfm_alg_blocksize(tfm); + + u8 stack[src == dst ? bsize : 0]; + u8 *buf = stack; + u8 **dst_p = src == dst ? &buf : &dst; + + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; + u8 *iv = desc->info; + unsigned int done = 0; + + do { + u8 *tmp_dst = *dst_p; + + fn(crypto_tfm_ctx(tfm), tmp_dst, src); + xor(tmp_dst, iv); + memcpy(iv, src, bsize); + if (tmp_dst != dst) + memcpy(dst, tmp_dst, bsize); + + src += bsize; + dst += bsize; + } while ((done += bsize) < nbytes); + + return done; +} + +static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst, + const u8 *src, unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + int bsize = crypto_tfm_alg_blocksize(tfm); + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; + unsigned int done = 0; + + do { + fn(crypto_tfm_ctx(tfm), dst, src); + + src += bsize; + dst += bsize; + } while ((done += bsize) < nbytes); + + return done; } static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) @@ -185,9 +269,14 @@ static int ecb_encrypt(struct crypto_tfm *tfm, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_encrypt, - ecb_process, NULL); + struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_ecb ?: ecb_process; + + return crypt(&desc, dst, src, nbytes); } static int ecb_decrypt(struct crypto_tfm *tfm, @@ -195,9 +284,14 @@ static int ecb_decrypt(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_decrypt, - ecb_process, NULL); + struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_ecb ?: ecb_process; + + return crypt(&desc, dst, src, nbytes); } static int cbc_encrypt(struct crypto_tfm *tfm, @@ -205,9 +299,15 @@ static int cbc_encrypt(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_encrypt, - cbc_process_encrypt, tfm->crt_cipher.cit_iv); + struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; + desc.info = tfm->crt_cipher.cit_iv; + + return crypt(&desc, dst, src, nbytes); } static int cbc_encrypt_iv(struct crypto_tfm *tfm, @@ -215,9 +315,15 @@ static int cbc_encrypt_iv(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes, u8 *iv) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_encrypt, - cbc_process_encrypt, iv); + struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; + desc.info = iv; + + return crypt_iv_unaligned(&desc, dst, src, nbytes); } static int cbc_decrypt(struct crypto_tfm *tfm, @@ -225,9 +331,15 @@ static int cbc_decrypt(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_decrypt, - cbc_process_decrypt, tfm->crt_cipher.cit_iv); + struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; + desc.info = tfm->crt_cipher.cit_iv; + + return crypt(&desc, dst, src, nbytes); } static int cbc_decrypt_iv(struct crypto_tfm *tfm, @@ -235,9 +347,15 @@ static int cbc_decrypt_iv(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes, u8 *iv) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_decrypt, - cbc_process_decrypt, iv); + struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; + desc.info = iv; + + return crypt_iv_unaligned(&desc, dst, src, nbytes); } static int nocrypt(struct crypto_tfm *tfm, @@ -306,6 +424,8 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm) } if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) { + unsigned int align; + unsigned long addr; switch (crypto_tfm_alg_blocksize(tfm)) { case 8: @@ -325,9 +445,11 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm) } ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm); - ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL); - if (ops->cit_iv == NULL) - ret = -ENOMEM; + align = crypto_tfm_alg_alignmask(tfm) + 1; + addr = (unsigned long)crypto_tfm_ctx(tfm); + addr = ALIGN(addr, align); + addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align); + ops->cit_iv = (void *)addr; } out: @@ -336,6 +458,4 @@ out: void crypto_exit_cipher_ops(struct crypto_tfm *tfm) { - if (tfm->crt_cipher.cit_iv) - kfree(tfm->crt_cipher.cit_iv); } diff --git a/crypto/des.c b/crypto/des.c index 1c7e6de9356c..a3c863dddded 100644 --- a/crypto/des.c +++ b/crypto/des.c @@ -1,18 +1,9 @@ -/* +/* * Cryptographic API. * * DES & Triple DES EDE Cipher Algorithms. * - * Originally released as descore by Dana L. How <how@isl.stanford.edu>. - * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel. - * Derived from Cryptoapi and Nettle implementations, adapted for in-place - * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL. - * - * Copyright (c) 1992 Dana L. How. - * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de> - * Copyright (c) Gisle Sælensminde <gisle@ii.uib.no> - * Copyright (C) 2001 Niels Möller. - * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> + * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no> * * 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 @@ -20,11 +11,11 @@ * (at your option) any later version. * */ + +#include <linux/bitops.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/mm.h> #include <linux/errno.h> -#include <asm/scatterlist.h> #include <linux/crypto.h> #define DES_KEY_SIZE 8 @@ -35,1157 +26,826 @@ #define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS) #define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE -#define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o)) +#define ROL(x, r) ((x) = rol32((x), (r))) +#define ROR(x, r) ((x) = ror32((x), (r))) struct des_ctx { - u8 iv[DES_BLOCK_SIZE]; u32 expkey[DES_EXPKEY_WORDS]; }; struct des3_ede_ctx { - u8 iv[DES_BLOCK_SIZE]; u32 expkey[DES3_EDE_EXPKEY_WORDS]; }; -static const u32 des_keymap[] = { - 0x02080008, 0x02082000, 0x00002008, 0x00000000, - 0x02002000, 0x00080008, 0x02080000, 0x02082008, - 0x00000008, 0x02000000, 0x00082000, 0x00002008, - 0x00082008, 0x02002008, 0x02000008, 0x02080000, - 0x00002000, 0x00082008, 0x00080008, 0x02002000, - 0x02082008, 0x02000008, 0x00000000, 0x00082000, - 0x02000000, 0x00080000, 0x02002008, 0x02080008, - 0x00080000, 0x00002000, 0x02082000, 0x00000008, - 0x00080000, 0x00002000, 0x02000008, 0x02082008, - 0x00002008, 0x02000000, 0x00000000, 0x00082000, - 0x02080008, 0x02002008, 0x02002000, 0x00080008, - 0x02082000, 0x00000008, 0x00080008, 0x02002000, - 0x02082008, 0x00080000, 0x02080000, 0x02000008, - 0x00082000, 0x00002008, 0x02002008, 0x02080000, - 0x00000008, 0x02082000, 0x00082008, 0x00000000, - 0x02000000, 0x02080008, 0x00002000, 0x00082008, - - 0x08000004, 0x00020004, 0x00000000, 0x08020200, - 0x00020004, 0x00000200, 0x08000204, 0x00020000, - 0x00000204, 0x08020204, 0x00020200, 0x08000000, - 0x08000200, 0x08000004, 0x08020000, 0x00020204, - 0x00020000, 0x08000204, 0x08020004, 0x00000000, - 0x00000200, 0x00000004, 0x08020200, 0x08020004, - 0x08020204, 0x08020000, 0x08000000, 0x00000204, - 0x00000004, 0x00020200, 0x00020204, 0x08000200, - 0x00000204, 0x08000000, 0x08000200, 0x00020204, - 0x08020200, 0x00020004, 0x00000000, 0x08000200, - 0x08000000, 0x00000200, 0x08020004, 0x00020000, - 0x00020004, 0x08020204, 0x00020200, 0x00000004, - 0x08020204, 0x00020200, 0x00020000, 0x08000204, - 0x08000004, 0x08020000, 0x00020204, 0x00000000, - 0x00000200, 0x08000004, 0x08000204, 0x08020200, - 0x08020000, 0x00000204, 0x00000004, 0x08020004, - - 0x80040100, 0x01000100, 0x80000000, 0x81040100, - 0x00000000, 0x01040000, 0x81000100, 0x80040000, - 0x01040100, 0x81000000, 0x01000000, 0x80000100, - 0x81000000, 0x80040100, 0x00040000, 0x01000000, - 0x81040000, 0x00040100, 0x00000100, 0x80000000, - 0x00040100, 0x81000100, 0x01040000, 0x00000100, - 0x80000100, 0x00000000, 0x80040000, 0x01040100, - 0x01000100, 0x81040000, 0x81040100, 0x00040000, - 0x81040000, 0x80000100, 0x00040000, 0x81000000, - 0x00040100, 0x01000100, 0x80000000, 0x01040000, - 0x81000100, 0x00000000, 0x00000100, 0x80040000, - 0x00000000, 0x81040000, 0x01040100, 0x00000100, - 0x01000000, 0x81040100, 0x80040100, 0x00040000, - 0x81040100, 0x80000000, 0x01000100, 0x80040100, - 0x80040000, 0x00040100, 0x01040000, 0x81000100, - 0x80000100, 0x01000000, 0x81000000, 0x01040100, - - 0x04010801, 0x00000000, 0x00010800, 0x04010000, - 0x04000001, 0x00000801, 0x04000800, 0x00010800, - 0x00000800, 0x04010001, 0x00000001, 0x04000800, - 0x00010001, 0x04010800, 0x04010000, 0x00000001, - 0x00010000, 0x04000801, 0x04010001, 0x00000800, - 0x00010801, 0x04000000, 0x00000000, 0x00010001, - 0x04000801, 0x00010801, 0x04010800, 0x04000001, - 0x04000000, 0x00010000, 0x00000801, 0x04010801, - 0x00010001, 0x04010800, 0x04000800, 0x00010801, - 0x04010801, 0x00010001, 0x04000001, 0x00000000, - 0x04000000, 0x00000801, 0x00010000, 0x04010001, - 0x00000800, 0x04000000, 0x00010801, 0x04000801, - 0x04010800, 0x00000800, 0x00000000, 0x04000001, - 0x00000001, 0x04010801, 0x00010800, 0x04010000, - 0x04010001, 0x00010000, 0x00000801, 0x04000800, - 0x04000801, 0x00000001, 0x04010000, 0x00010800, - - 0x00000400, 0x00000020, 0x00100020, 0x40100000, - 0x40100420, 0x40000400, 0x00000420, 0x00000000, - 0x00100000, 0x40100020, 0x40000020, 0x00100400, - 0x40000000, 0x00100420, 0x00100400, 0x40000020, - 0x40100020, 0x00000400, 0x40000400, 0x40100420, - 0x00000000, 0x00100020, 0x40100000, 0x00000420, - 0x40100400, 0x40000420, 0x00100420, 0x40000000, - 0x40000420, 0x40100400, 0x00000020, 0x00100000, - 0x40000420, 0x00100400, 0x40100400, 0x40000020, - 0x00000400, 0x00000020, 0x00100000, 0x40100400, - 0x40100020, 0x40000420, 0x00000420, 0x00000000, - 0x00000020, 0x40100000, 0x40000000, 0x00100020, - 0x00000000, 0x40100020, 0x00100020, 0x00000420, - 0x40000020, 0x00000400, 0x40100420, 0x00100000, - 0x00100420, 0x40000000, 0x40000400, 0x40100420, - 0x40100000, 0x00100420, 0x00100400, 0x40000400, - - 0x00800000, 0x00001000, 0x00000040, 0x00801042, - 0x00801002, 0x00800040, 0x00001042, 0x00801000, - 0x00001000, 0x00000002, 0x00800002, 0x00001040, - 0x00800042, 0x00801002, 0x00801040, 0x00000000, - 0x00001040, 0x00800000, 0x00001002, 0x00000042, - 0x00800040, 0x00001042, 0x00000000, 0x00800002, - 0x00000002, 0x00800042, 0x00801042, 0x00001002, - 0x00801000, 0x00000040, 0x00000042, 0x00801040, - 0x00801040, 0x00800042, 0x00001002, 0x00801000, - 0x00001000, 0x00000002, 0x00800002, 0x00800040, - 0x00800000, 0x00001040, 0x00801042, 0x00000000, - 0x00001042, 0x00800000, 0x00000040, 0x00001002, - 0x00800042, 0x00000040, 0x00000000, 0x00801042, - 0x00801002, 0x00801040, 0x00000042, 0x00001000, - 0x00001040, 0x00801002, 0x00800040, 0x00000042, - 0x00000002, 0x00001042, 0x00801000, 0x00800002, - - 0x10400000, 0x00404010, 0x00000010, 0x10400010, - 0x10004000, 0x00400000, 0x10400010, 0x00004010, - 0x00400010, 0x00004000, 0x00404000, 0x10000000, - 0x10404010, 0x10000010, 0x10000000, 0x10404000, - 0x00000000, 0x10004000, 0x00404010, 0x00000010, - 0x10000010, 0x10404010, 0x00004000, 0x10400000, - 0x10404000, 0x00400010, 0x10004010, 0x00404000, - 0x00004010, 0x00000000, 0x00400000, 0x10004010, - 0x00404010, 0x00000010, 0x10000000, 0x00004000, - 0x10000010, 0x10004000, 0x00404000, 0x10400010, - 0x00000000, 0x00404010, 0x00004010, 0x10404000, - 0x10004000, 0x00400000, 0x10404010, 0x10000000, - 0x10004010, 0x10400000, 0x00400000, 0x10404010, - 0x00004000, 0x00400010, 0x10400010, 0x00004010, - 0x00400010, 0x00000000, 0x10404000, 0x10000010, - 0x10400000, 0x10004010, 0x00000010, 0x00404000, - - 0x00208080, 0x00008000, 0x20200000, 0x20208080, - 0x00200000, 0x20008080, 0x20008000, 0x20200000, - 0x20008080, 0x00208080, 0x00208000, 0x20000080, - 0x20200080, 0x00200000, 0x00000000, 0x20008000, - 0x00008000, 0x20000000, 0x00200080, 0x00008080, - 0x20208080, 0x00208000, 0x20000080, 0x00200080, - 0x20000000, 0x00000080, 0x00008080, 0x20208000, - 0x00000080, 0x20200080, 0x20208000, 0x00000000, - 0x00000000, 0x20208080, 0x00200080, 0x20008000, - 0x00208080, 0x00008000, 0x20000080, 0x00200080, - 0x20208000, 0x00000080, 0x00008080, 0x20200000, - 0x20008080, 0x20000000, 0x20200000, 0x00208000, - 0x20208080, 0x00008080, 0x00208000, 0x20200080, - 0x00200000, 0x20000080, 0x20008000, 0x00000000, - 0x00008000, 0x00200000, 0x20200080, 0x00208080, - 0x20000000, 0x20208000, 0x00000080, 0x20008080, +/* Lookup tables for key expansion */ + +static const u8 pc1[256] = { + 0x00, 0x00, 0x40, 0x04, 0x10, 0x10, 0x50, 0x14, + 0x04, 0x40, 0x44, 0x44, 0x14, 0x50, 0x54, 0x54, + 0x02, 0x02, 0x42, 0x06, 0x12, 0x12, 0x52, 0x16, + 0x06, 0x42, 0x46, 0x46, 0x16, 0x52, 0x56, 0x56, + 0x80, 0x08, 0xc0, 0x0c, 0x90, 0x18, 0xd0, 0x1c, + 0x84, 0x48, 0xc4, 0x4c, 0x94, 0x58, 0xd4, 0x5c, + 0x82, 0x0a, 0xc2, 0x0e, 0x92, 0x1a, 0xd2, 0x1e, + 0x86, 0x4a, 0xc6, 0x4e, 0x96, 0x5a, 0xd6, 0x5e, + 0x20, 0x20, 0x60, 0x24, 0x30, 0x30, 0x70, 0x34, + 0x24, 0x60, 0x64, 0x64, 0x34, 0x70, 0x74, 0x74, + 0x22, 0x22, 0x62, 0x26, 0x32, 0x32, 0x72, 0x36, + 0x26, 0x62, 0x66, 0x66, 0x36, 0x72, 0x76, 0x76, + 0xa0, 0x28, 0xe0, 0x2c, 0xb0, 0x38, 0xf0, 0x3c, + 0xa4, 0x68, 0xe4, 0x6c, 0xb4, 0x78, 0xf4, 0x7c, + 0xa2, 0x2a, 0xe2, 0x2e, 0xb2, 0x3a, 0xf2, 0x3e, + 0xa6, 0x6a, 0xe6, 0x6e, 0xb6, 0x7a, 0xf6, 0x7e, + 0x08, 0x80, 0x48, 0x84, 0x18, 0x90, 0x58, 0x94, + 0x0c, 0xc0, 0x4c, 0xc4, 0x1c, 0xd0, 0x5c, 0xd4, + 0x0a, 0x82, 0x4a, 0x86, 0x1a, 0x92, 0x5a, 0x96, + 0x0e, 0xc2, 0x4e, 0xc6, 0x1e, 0xd2, 0x5e, 0xd6, + 0x88, 0x88, 0xc8, 0x8c, 0x98, 0x98, 0xd8, 0x9c, + 0x8c, 0xc8, 0xcc, 0xcc, 0x9c, 0xd8, 0xdc, 0xdc, + 0x8a, 0x8a, 0xca, 0x8e, 0x9a, 0x9a, 0xda, 0x9e, + 0x8e, 0xca, 0xce, 0xce, 0x9e, 0xda, 0xde, 0xde, + 0x28, 0xa0, 0x68, 0xa4, 0x38, 0xb0, 0x78, 0xb4, + 0x2c, 0xe0, 0x6c, 0xe4, 0x3c, 0xf0, 0x7c, 0xf4, + 0x2a, 0xa2, 0x6a, 0xa6, 0x3a, 0xb2, 0x7a, 0xb6, + 0x2e, 0xe2, 0x6e, 0xe6, 0x3e, 0xf2, 0x7e, 0xf6, + 0xa8, 0xa8, 0xe8, 0xac, 0xb8, 0xb8, 0xf8, 0xbc, + 0xac, 0xe8, 0xec, 0xec, 0xbc, 0xf8, 0xfc, 0xfc, + 0xaa, 0xaa, 0xea, 0xae, 0xba, 0xba, 0xfa, 0xbe, + 0xae, 0xea, 0xee, 0xee, 0xbe, 0xfa, 0xfe, 0xfe }; -static const u8 rotors[] = { - 34, 13, 5, 46, 47, 18, 32, 41, 11, 53, 33, 20, - 14, 36, 30, 24, 49, 2, 15, 37, 42, 50, 0, 21, - 38, 48, 6, 26, 39, 4, 52, 25, 12, 27, 31, 40, - 1, 17, 28, 29, 23, 51, 35, 7, 3, 22, 9, 43, - - 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27, - 21, 43, 37, 0, 1, 9, 22, 44, 49, 2, 7, 28, - 45, 55, 13, 33, 46, 11, 6, 32, 19, 34, 38, 47, - 8, 24, 35, 36, 30, 3, 42, 14, 10, 29, 16, 50, - - 55, 34, 26, 38, 11, 39, 53, 5, 32, 45, 54, 41, - 35, 2, 51, 14, 15, 23, 36, 3, 8, 16, 21, 42, - 6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52, 4, - 22, 7, 49, 50, 44, 17, 1, 28, 24, 43, 30, 9, - - 12, 48, 40, 52, 25, 53, 38, 19, 46, 6, 11, 55, - 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35, 1, - 20, 26, 41, 4, 45, 39, 34, 31, 47, 5, 13, 18, - 36, 21, 8, 9, 3, 0, 15, 42, 7, 2, 44, 23, - - 26, 5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12, - 8, 30, 24, 42, 43, 51, 9, 0, 36, 44, 49, 15, - 34, 40, 55, 18, 6, 53, 48, 45, 4, 19, 27, 32, - 50, 35, 22, 23, 17, 14, 29, 1, 21, 16, 3, 37, - - 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26, - 22, 44, 7, 1, 2, 10, 23, 14, 50, 3, 8, 29, - 48, 54, 12, 32, 20, 38, 5, 6, 18, 33, 41, 46, - 9, 49, 36, 37, 0, 28, 43, 15, 35, 30, 17, 51, - - 54, 33, 25, 41, 38, 13, 27, 4, 6, 48, 53, 40, - 36, 3, 21, 15, 16, 24, 37, 28, 9, 17, 22, 43, - 5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31, - 23, 8, 50, 51, 14, 42, 2, 29, 49, 44, 0, 10, - - 11, 47, 39, 55, 52, 27, 41, 18, 20, 5, 38, 54, - 50, 17, 35, 29, 30, 7, 51, 42, 23, 0, 36, 2, - 19, 25, 40, 31, 48, 13, 33, 34, 46, 4, 12, 45, - 37, 22, 9, 10, 28, 1, 16, 43, 8, 3, 14, 24, - - 18, 54, 46, 5, 6, 34, 48, 25, 27, 12, 45, 4, - 2, 24, 42, 36, 37, 14, 3, 49, 30, 7, 43, 9, - 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52, - 44, 29, 16, 17, 35, 8, 23, 50, 15, 10, 21, 0, - - 32, 11, 31, 19, 20, 48, 5, 39, 41, 26, 6, 18, - 16, 7, 1, 50, 51, 28, 17, 8, 44, 21, 2, 23, - 40, 46, 4, 52, 12, 34, 54, 55, 38, 25, 33, 13, - 3, 43, 30, 0, 49, 22, 37, 9, 29, 24, 35, 14, - - 46, 25, 45, 33, 34, 5, 19, 53, 55, 40, 20, 32, - 30, 21, 15, 9, 10, 42, 0, 22, 3, 35, 16, 37, - 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27, - 17, 2, 44, 14, 8, 36, 51, 23, 43, 7, 49, 28, - - 31, 39, 6, 47, 48, 19, 33, 38, 12, 54, 34, 46, - 44, 35, 29, 23, 24, 1, 14, 36, 17, 49, 30, 51, - 11, 45, 32, 27, 40, 5, 25, 26, 13, 53, 4, 41, - 0, 16, 3, 28, 22, 50, 10, 37, 2, 21, 8, 42, - - 45, 53, 20, 4, 5, 33, 47, 52, 26, 11, 48, 31, - 3, 49, 43, 37, 7, 15, 28, 50, 0, 8, 44, 10, - 25, 6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55, - 14, 30, 17, 42, 36, 9, 24, 51, 16, 35, 22, 1, - - 6, 38, 34, 18, 19, 47, 4, 13, 40, 25, 5, 45, - 17, 8, 2, 51, 21, 29, 42, 9, 14, 22, 3, 24, - 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12, - 28, 44, 0, 1, 50, 23, 7, 10, 30, 49, 36, 15, - - 20, 52, 48, 32, 33, 4, 18, 27, 54, 39, 19, 6, - 0, 22, 16, 10, 35, 43, 1, 23, 28, 36, 17, 7, - 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26, - 42, 3, 14, 15, 9, 37, 21, 24, 44, 8, 50, 29, - - 27, 6, 55, 39, 40, 11, 25, 34, 4, 46, 26, 13, - 7, 29, 23, 17, 42, 50, 8, 30, 35, 43, 24, 14, - 31, 41, 52, 19, 32, 54, 45, 18, 5, 20, 53, 33, - 49, 10, 21, 22, 16, 44, 28, 0, 51, 15, 2, 36, +static const u8 rs[256] = { + 0x00, 0x00, 0x80, 0x80, 0x02, 0x02, 0x82, 0x82, + 0x04, 0x04, 0x84, 0x84, 0x06, 0x06, 0x86, 0x86, + 0x08, 0x08, 0x88, 0x88, 0x0a, 0x0a, 0x8a, 0x8a, + 0x0c, 0x0c, 0x8c, 0x8c, 0x0e, 0x0e, 0x8e, 0x8e, + 0x10, 0x10, 0x90, 0x90, 0x12, 0x12, 0x92, 0x92, + 0x14, 0x14, 0x94, 0x94, 0x16, 0x16, 0x96, 0x96, + 0x18, 0x18, 0x98, 0x98, 0x1a, 0x1a, 0x9a, 0x9a, + 0x1c, 0x1c, 0x9c, 0x9c, 0x1e, 0x1e, 0x9e, 0x9e, + 0x20, 0x20, 0xa0, 0xa0, 0x22, 0x22, 0xa2, 0xa2, + 0x24, 0x24, 0xa4, 0xa4, 0x26, 0x26, 0xa6, 0xa6, + 0x28, 0x28, 0xa8, 0xa8, 0x2a, 0x2a, 0xaa, 0xaa, + 0x2c, 0x2c, 0xac, 0xac, 0x2e, 0x2e, 0xae, 0xae, + 0x30, 0x30, 0xb0, 0xb0, 0x32, 0x32, 0xb2, 0xb2, + 0x34, 0x34, 0xb4, 0xb4, 0x36, 0x36, 0xb6, 0xb6, + 0x38, 0x38, 0xb8, 0xb8, 0x3a, 0x3a, 0xba, 0xba, + 0x3c, 0x3c, 0xbc, 0xbc, 0x3e, 0x3e, 0xbe, 0xbe, + 0x40, 0x40, 0xc0, 0xc0, 0x42, 0x42, 0xc2, 0xc2, + 0x44, 0x44, 0xc4, 0xc4, 0x46, 0x46, 0xc6, 0xc6, + 0x48, 0x48, 0xc8, 0xc8, 0x4a, 0x4a, 0xca, 0xca, + 0x4c, 0x4c, 0xcc, 0xcc, 0x4e, 0x4e, 0xce, 0xce, + 0x50, 0x50, 0xd0, 0xd0, 0x52, 0x52, 0xd2, 0xd2, + 0x54, 0x54, 0xd4, 0xd4, 0x56, 0x56, 0xd6, 0xd6, + 0x58, 0x58, 0xd8, 0xd8, 0x5a, 0x5a, 0xda, 0xda, + 0x5c, 0x5c, 0xdc, 0xdc, 0x5e, 0x5e, 0xde, 0xde, + 0x60, 0x60, 0xe0, 0xe0, 0x62, 0x62, 0xe2, 0xe2, + 0x64, 0x64, 0xe4, 0xe4, 0x66, 0x66, 0xe6, 0xe6, + 0x68, 0x68, 0xe8, 0xe8, 0x6a, 0x6a, 0xea, 0xea, + 0x6c, 0x6c, 0xec, 0xec, 0x6e, 0x6e, 0xee, 0xee, + 0x70, 0x70, 0xf0, 0xf0, 0x72, 0x72, 0xf2, 0xf2, + 0x74, 0x74, 0xf4, 0xf4, 0x76, 0x76, 0xf6, 0xf6, + 0x78, 0x78, 0xf8, 0xf8, 0x7a, 0x7a, 0xfa, 0xfa, + 0x7c, 0x7c, 0xfc, 0xfc, 0x7e, 0x7e, 0xfe, 0xfe }; -static const u8 parity[] = { - 8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3, - 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, - 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, - 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, - 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, - 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, - 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, - 4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8, +static const u32 pc2[1024] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00040000, 0x00000000, 0x04000000, 0x00100000, + 0x00400000, 0x00000008, 0x00000800, 0x40000000, + 0x00440000, 0x00000008, 0x04000800, 0x40100000, + 0x00000400, 0x00000020, 0x08000000, 0x00000100, + 0x00040400, 0x00000020, 0x0c000000, 0x00100100, + 0x00400400, 0x00000028, 0x08000800, 0x40000100, + 0x00440400, 0x00000028, 0x0c000800, 0x40100100, + 0x80000000, 0x00000010, 0x00000000, 0x00800000, + 0x80040000, 0x00000010, 0x04000000, 0x00900000, + 0x80400000, 0x00000018, 0x00000800, 0x40800000, + 0x80440000, 0x00000018, 0x04000800, 0x40900000, + 0x80000400, 0x00000030, 0x08000000, 0x00800100, + 0x80040400, 0x00000030, 0x0c000000, 0x00900100, + 0x80400400, 0x00000038, 0x08000800, 0x40800100, + 0x80440400, 0x00000038, 0x0c000800, 0x40900100, + 0x10000000, 0x00000000, 0x00200000, 0x00001000, + 0x10040000, 0x00000000, 0x04200000, 0x00101000, + 0x10400000, 0x00000008, 0x00200800, 0x40001000, + 0x10440000, 0x00000008, 0x04200800, 0x40101000, + 0x10000400, 0x00000020, 0x08200000, 0x00001100, + 0x10040400, 0x00000020, 0x0c200000, 0x00101100, + 0x10400400, 0x00000028, 0x08200800, 0x40001100, + 0x10440400, 0x00000028, 0x0c200800, 0x40101100, + 0x90000000, 0x00000010, 0x00200000, 0x00801000, + 0x90040000, 0x00000010, 0x04200000, 0x00901000, + 0x90400000, 0x00000018, 0x00200800, 0x40801000, + 0x90440000, 0x00000018, 0x04200800, 0x40901000, + 0x90000400, 0x00000030, 0x08200000, 0x00801100, + 0x90040400, 0x00000030, 0x0c200000, 0x00901100, + 0x90400400, 0x00000038, 0x08200800, 0x40801100, + 0x90440400, 0x00000038, 0x0c200800, 0x40901100, + 0x00000200, 0x00080000, 0x00000000, 0x00000004, + 0x00040200, 0x00080000, 0x04000000, 0x00100004, + 0x00400200, 0x00080008, 0x00000800, 0x40000004, + 0x00440200, 0x00080008, 0x04000800, 0x40100004, + 0x00000600, 0x00080020, 0x08000000, 0x00000104, + 0x00040600, 0x00080020, 0x0c000000, 0x00100104, + 0x00400600, 0x00080028, 0x08000800, 0x40000104, + 0x00440600, 0x00080028, 0x0c000800, 0x40100104, + 0x80000200, 0x00080010, 0x00000000, 0x00800004, + 0x80040200, 0x00080010, 0x04000000, 0x00900004, + 0x80400200, 0x00080018, 0x00000800, 0x40800004, + 0x80440200, 0x00080018, 0x04000800, 0x40900004, + 0x80000600, 0x00080030, 0x08000000, 0x00800104, + 0x80040600, 0x00080030, 0x0c000000, 0x00900104, + 0x80400600, 0x00080038, 0x08000800, 0x40800104, + 0x80440600, 0x00080038, 0x0c000800, 0x40900104, + 0x10000200, 0x00080000, 0x00200000, 0x00001004, + 0x10040200, 0x00080000, 0x04200000, 0x00101004, + 0x10400200, 0x00080008, 0x00200800, 0x40001004, + 0x10440200, 0x00080008, 0x04200800, 0x40101004, + 0x10000600, 0x00080020, 0x08200000, 0x00001104, + 0x10040600, 0x00080020, 0x0c200000, 0x00101104, + 0x10400600, 0x00080028, 0x08200800, 0x40001104, + 0x10440600, 0x00080028, 0x0c200800, 0x40101104, + 0x90000200, 0x00080010, 0x00200000, 0x00801004, + 0x90040200, 0x00080010, 0x04200000, 0x00901004, + 0x90400200, 0x00080018, 0x00200800, 0x40801004, + 0x90440200, 0x00080018, 0x04200800, 0x40901004, + 0x90000600, 0x00080030, 0x08200000, 0x00801104, + 0x90040600, 0x00080030, 0x0c200000, 0x00901104, + 0x90400600, 0x00080038, 0x08200800, 0x40801104, + 0x90440600, 0x00080038, 0x0c200800, 0x40901104, + 0x00000002, 0x00002000, 0x20000000, 0x00000001, + 0x00040002, 0x00002000, 0x24000000, 0x00100001, + 0x00400002, 0x00002008, 0x20000800, 0x40000001, + 0x00440002, 0x00002008, 0x24000800, 0x40100001, + 0x00000402, 0x00002020, 0x28000000, 0x00000101, + 0x00040402, 0x00002020, 0x2c000000, 0x00100101, + 0x00400402, 0x00002028, 0x28000800, 0x40000101, + 0x00440402, 0x00002028, 0x2c000800, 0x40100101, + 0x80000002, 0x00002010, 0x20000000, 0x00800001, + 0x80040002, 0x00002010, 0x24000000, 0x00900001, + 0x80400002, 0x00002018, 0x20000800, 0x40800001, + 0x80440002, 0x00002018, 0x24000800, 0x40900001, + 0x80000402, 0x00002030, 0x28000000, 0x00800101, + 0x80040402, 0x00002030, 0x2c000000, 0x00900101, + 0x80400402, 0x00002038, 0x28000800, 0x40800101, + 0x80440402, 0x00002038, 0x2c000800, 0x40900101, + 0x10000002, 0x00002000, 0x20200000, 0x00001001, + 0x10040002, 0x00002000, 0x24200000, 0x00101001, + 0x10400002, 0x00002008, 0x20200800, 0x40001001, + 0x10440002, 0x00002008, 0x24200800, 0x40101001, + 0x10000402, 0x00002020, 0x28200000, 0x00001101, + 0x10040402, 0x00002020, 0x2c200000, 0x00101101, + 0x10400402, 0x00002028, 0x28200800, 0x40001101, + 0x10440402, 0x00002028, 0x2c200800, 0x40101101, + 0x90000002, 0x00002010, 0x20200000, 0x00801001, + 0x90040002, 0x00002010, 0x24200000, 0x00901001, + 0x90400002, 0x00002018, 0x20200800, 0x40801001, + 0x90440002, 0x00002018, 0x24200800, 0x40901001, + 0x90000402, 0x00002030, 0x28200000, 0x00801101, + 0x90040402, 0x00002030, 0x2c200000, 0x00901101, + 0x90400402, 0x00002038, 0x28200800, 0x40801101, + 0x90440402, 0x00002038, 0x2c200800, 0x40901101, + 0x00000202, 0x00082000, 0x20000000, 0x00000005, + 0x00040202, 0x00082000, 0x24000000, 0x00100005, + 0x00400202, 0x00082008, 0x20000800, 0x40000005, + 0x00440202, 0x00082008, 0x24000800, 0x40100005, + 0x00000602, 0x00082020, 0x28000000, 0x00000105, + 0x00040602, 0x00082020, 0x2c000000, 0x00100105, + 0x00400602, 0x00082028, 0x28000800, 0x40000105, + 0x00440602, 0x00082028, 0x2c000800, 0x40100105, + 0x80000202, 0x00082010, 0x20000000, 0x00800005, + 0x80040202, 0x00082010, 0x24000000, 0x00900005, + 0x80400202, 0x00082018, 0x20000800, 0x40800005, + 0x80440202, 0x00082018, 0x24000800, 0x40900005, + 0x80000602, 0x00082030, 0x28000000, 0x00800105, + 0x80040602, 0x00082030, 0x2c000000, 0x00900105, + 0x80400602, 0x00082038, 0x28000800, 0x40800105, + 0x80440602, 0x00082038, 0x2c000800, 0x40900105, + 0x10000202, 0x00082000, 0x20200000, 0x00001005, + 0x10040202, 0x00082000, 0x24200000, 0x00101005, + 0x10400202, 0x00082008, 0x20200800, 0x40001005, + 0x10440202, 0x00082008, 0x24200800, 0x40101005, + 0x10000602, 0x00082020, 0x28200000, 0x00001105, + 0x10040602, 0x00082020, 0x2c200000, 0x00101105, + 0x10400602, 0x00082028, 0x28200800, 0x40001105, + 0x10440602, 0x00082028, 0x2c200800, 0x40101105, + 0x90000202, 0x00082010, 0x20200000, 0x00801005, + 0x90040202, 0x00082010, 0x24200000, 0x00901005, + 0x90400202, 0x00082018, 0x20200800, 0x40801005, + 0x90440202, 0x00082018, 0x24200800, 0x40901005, + 0x90000602, 0x00082030, 0x28200000, 0x00801105, + 0x90040602, 0x00082030, 0x2c200000, 0x00901105, + 0x90400602, 0x00082038, 0x28200800, 0x40801105, + 0x90440602, 0x00082038, 0x2c200800, 0x40901105, + + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000008, 0x00080000, 0x10000000, + 0x02000000, 0x00000000, 0x00000080, 0x00001000, + 0x02000000, 0x00000008, 0x00080080, 0x10001000, + 0x00004000, 0x00000000, 0x00000040, 0x00040000, + 0x00004000, 0x00000008, 0x00080040, 0x10040000, + 0x02004000, 0x00000000, 0x000000c0, 0x00041000, + 0x02004000, 0x00000008, 0x000800c0, 0x10041000, + 0x00020000, 0x00008000, 0x08000000, 0x00200000, + 0x00020000, 0x00008008, 0x08080000, 0x10200000, + 0x02020000, 0x00008000, 0x08000080, 0x00201000, + 0x02020000, 0x00008008, 0x08080080, 0x10201000, + 0x00024000, 0x00008000, 0x08000040, 0x00240000, + 0x00024000, 0x00008008, 0x08080040, 0x10240000, + 0x02024000, 0x00008000, 0x080000c0, 0x00241000, + 0x02024000, 0x00008008, 0x080800c0, 0x10241000, + 0x00000000, 0x01000000, 0x00002000, 0x00000020, + 0x00000000, 0x01000008, 0x00082000, 0x10000020, + 0x02000000, 0x01000000, 0x00002080, 0x00001020, + 0x02000000, 0x01000008, 0x00082080, 0x10001020, + 0x00004000, 0x01000000, 0x00002040, 0x00040020, + 0x00004000, 0x01000008, 0x00082040, 0x10040020, + 0x02004000, 0x01000000, 0x000020c0, 0x00041020, + 0x02004000, 0x01000008, 0x000820c0, 0x10041020, + 0x00020000, 0x01008000, 0x08002000, 0x00200020, + 0x00020000, 0x01008008, 0x08082000, 0x10200020, + 0x02020000, 0x01008000, 0x08002080, 0x00201020, + 0x02020000, 0x01008008, 0x08082080, 0x10201020, + 0x00024000, 0x01008000, 0x08002040, 0x00240020, + 0x00024000, 0x01008008, 0x08082040, 0x10240020, + 0x02024000, 0x01008000, 0x080020c0, 0x00241020, + 0x02024000, 0x01008008, 0x080820c0, 0x10241020, + 0x00000400, 0x04000000, 0x00100000, 0x00000004, + 0x00000400, 0x04000008, 0x00180000, 0x10000004, + 0x02000400, 0x04000000, 0x00100080, 0x00001004, + 0x02000400, 0x04000008, 0x00180080, 0x10001004, + 0x00004400, 0x04000000, 0x00100040, 0x00040004, + 0x00004400, 0x04000008, 0x00180040, 0x10040004, + 0x02004400, 0x04000000, 0x001000c0, 0x00041004, + 0x02004400, 0x04000008, 0x001800c0, 0x10041004, + 0x00020400, 0x04008000, 0x08100000, 0x00200004, + 0x00020400, 0x04008008, 0x08180000, 0x10200004, + 0x02020400, 0x04008000, 0x08100080, 0x00201004, + 0x02020400, 0x04008008, 0x08180080, 0x10201004, + 0x00024400, 0x04008000, 0x08100040, 0x00240004, + 0x00024400, 0x04008008, 0x08180040, 0x10240004, + 0x02024400, 0x04008000, 0x081000c0, 0x00241004, + 0x02024400, 0x04008008, 0x081800c0, 0x10241004, + 0x00000400, 0x05000000, 0x00102000, 0x00000024, + 0x00000400, 0x05000008, 0x00182000, 0x10000024, + 0x02000400, 0x05000000, 0x00102080, 0x00001024, + 0x02000400, 0x05000008, 0x00182080, 0x10001024, + 0x00004400, 0x05000000, 0x00102040, 0x00040024, + 0x00004400, 0x05000008, 0x00182040, 0x10040024, + 0x02004400, 0x05000000, 0x001020c0, 0x00041024, + 0x02004400, 0x05000008, 0x001820c0, 0x10041024, + 0x00020400, 0x05008000, 0x08102000, 0x00200024, + 0x00020400, 0x05008008, 0x08182000, 0x10200024, + 0x02020400, 0x05008000, 0x08102080, 0x00201024, + 0x02020400, 0x05008008, 0x08182080, 0x10201024, + 0x00024400, 0x05008000, 0x08102040, 0x00240024, + 0x00024400, 0x05008008, 0x08182040, 0x10240024, + 0x02024400, 0x05008000, 0x081020c0, 0x00241024, + 0x02024400, 0x05008008, 0x081820c0, 0x10241024, + 0x00000800, 0x00010000, 0x20000000, 0x00000010, + 0x00000800, 0x00010008, 0x20080000, 0x10000010, + 0x02000800, 0x00010000, 0x20000080, 0x00001010, + 0x02000800, 0x00010008, 0x20080080, 0x10001010, + 0x00004800, 0x00010000, 0x20000040, 0x00040010, + 0x00004800, 0x00010008, 0x20080040, 0x10040010, + 0x02004800, 0x00010000, 0x200000c0, 0x00041010, + 0x02004800, 0x00010008, 0x200800c0, 0x10041010, + 0x00020800, 0x00018000, 0x28000000, 0x00200010, + 0x00020800, 0x00018008, 0x28080000, 0x10200010, + 0x02020800, 0x00018000, 0x28000080, 0x00201010, + 0x02020800, 0x00018008, 0x28080080, 0x10201010, + 0x00024800, 0x00018000, 0x28000040, 0x00240010, + 0x00024800, 0x00018008, 0x28080040, 0x10240010, + 0x02024800, 0x00018000, 0x280000c0, 0x00241010, + 0x02024800, 0x00018008, 0x280800c0, 0x10241010, + 0x00000800, 0x01010000, 0x20002000, 0x00000030, + 0x00000800, 0x01010008, 0x20082000, 0x10000030, + 0x02000800, 0x01010000, 0x20002080, 0x00001030, + 0x02000800, 0x01010008, 0x20082080, 0x10001030, + 0x00004800, 0x01010000, 0x20002040, 0x00040030, + 0x00004800, 0x01010008, 0x20082040, 0x10040030, + 0x02004800, 0x01010000, 0x200020c0, 0x00041030, + 0x02004800, 0x01010008, 0x200820c0, 0x10041030, + 0x00020800, 0x01018000, 0x28002000, 0x00200030, + 0x00020800, 0x01018008, 0x28082000, 0x10200030, + 0x02020800, 0x01018000, 0x28002080, 0x00201030, + 0x02020800, 0x01018008, 0x28082080, 0x10201030, + 0x00024800, 0x01018000, 0x28002040, 0x00240030, + 0x00024800, 0x01018008, 0x28082040, 0x10240030, + 0x02024800, 0x01018000, 0x280020c0, 0x00241030, + 0x02024800, 0x01018008, 0x280820c0, 0x10241030, + 0x00000c00, 0x04010000, 0x20100000, 0x00000014, + 0x00000c00, 0x04010008, 0x20180000, 0x10000014, + 0x02000c00, 0x04010000, 0x20100080, 0x00001014, + 0x02000c00, 0x04010008, 0x20180080, 0x10001014, + 0x00004c00, 0x04010000, 0x20100040, 0x00040014, + 0x00004c00, 0x04010008, 0x20180040, 0x10040014, + 0x02004c00, 0x04010000, 0x201000c0, 0x00041014, + 0x02004c00, 0x04010008, 0x201800c0, 0x10041014, + 0x00020c00, 0x04018000, 0x28100000, 0x00200014, + 0x00020c00, 0x04018008, 0x28180000, 0x10200014, + 0x02020c00, 0x04018000, 0x28100080, 0x00201014, + 0x02020c00, 0x04018008, 0x28180080, 0x10201014, + 0x00024c00, 0x04018000, 0x28100040, 0x00240014, + 0x00024c00, 0x04018008, 0x28180040, 0x10240014, + 0x02024c00, 0x04018000, 0x281000c0, 0x00241014, + 0x02024c00, 0x04018008, 0x281800c0, 0x10241014, + 0x00000c00, 0x05010000, 0x20102000, 0x00000034, + 0x00000c00, 0x05010008, 0x20182000, 0x10000034, + 0x02000c00, 0x05010000, 0x20102080, 0x00001034, + 0x02000c00, 0x05010008, 0x20182080, 0x10001034, + 0x00004c00, 0x05010000, 0x20102040, 0x00040034, + 0x00004c00, 0x05010008, 0x20182040, 0x10040034, + 0x02004c00, 0x05010000, 0x201020c0, 0x00041034, + 0x02004c00, 0x05010008, 0x201820c0, 0x10041034, + 0x00020c00, 0x05018000, 0x28102000, 0x00200034, + 0x00020c00, 0x05018008, 0x28182000, 0x10200034, + 0x02020c00, 0x05018000, 0x28102080, 0x00201034, + 0x02020c00, 0x05018008, 0x28182080, 0x10201034, + 0x00024c00, 0x05018000, 0x28102040, 0x00240034, + 0x00024c00, 0x05018008, 0x28182040, 0x10240034, + 0x02024c00, 0x05018000, 0x281020c0, 0x00241034, + 0x02024c00, 0x05018008, 0x281820c0, 0x10241034 }; +/* S-box lookup tables */ + +static const u32 S1[64] = { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; -static void des_small_fips_encrypt(u32 *expkey, u8 *dst, const u8 *src) -{ - u32 x, y, z; - - x = src[7]; - x <<= 8; - x |= src[6]; - x <<= 8; - x |= src[5]; - x <<= 8; - x |= src[4]; - y = src[3]; - y <<= 8; - y |= src[2]; - y <<= 8; - y |= src[1]; - y <<= 8; - y |= src[0]; - z = ((x >> 004) ^ y) & 0x0F0F0F0FL; - x ^= z << 004; - y ^= z; - z = ((y >> 020) ^ x) & 0x0000FFFFL; - y ^= z << 020; - x ^= z; - z = ((x >> 002) ^ y) & 0x33333333L; - x ^= z << 002; - y ^= z; - z = ((y >> 010) ^ x) & 0x00FF00FFL; - y ^= z << 010; - x ^= z; - x = x >> 1 | x << 31; - z = (x ^ y) & 0x55555555L; - y ^= z; - x ^= z; - y = y >> 1 | y << 31; - z = expkey[0]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[1]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[2]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[3]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[4]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[5]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[6]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[7]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[8]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[9]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[10]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[11]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[12]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[13]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[14]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[15]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[16]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[17]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[18]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[19]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[20]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[21]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[22]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[23]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[24]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[25]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[26]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[27]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[28]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[29]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[30]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[31]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - x = x << 1 | x >> 31; - z = (x ^ y) & 0x55555555L; - y ^= z; - x ^= z; - y = y << 1 | y >> 31; - z = ((x >> 010) ^ y) & 0x00FF00FFL; - x ^= z << 010; - y ^= z; - z = ((y >> 002) ^ x) & 0x33333333L; - y ^= z << 002; - x ^= z; - z = ((x >> 020) ^ y) & 0x0000FFFFL; - x ^= z << 020; - y ^= z; - z = ((y >> 004) ^ x) & 0x0F0F0F0FL; - y ^= z << 004; - x ^= z; - dst[0] = x; - x >>= 8; - dst[1] = x; - x >>= 8; - dst[2] = x; - x >>= 8; - dst[3] = x; - dst[4] = y; - y >>= 8; - dst[5] = y; - y >>= 8; - dst[6] = y; - y >>= 8; - dst[7] = y; -} +static const u32 S2[64] = { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; -static void des_small_fips_decrypt(u32 *expkey, u8 *dst, const u8 *src) -{ - u32 x, y, z; - - x = src[7]; - x <<= 8; - x |= src[6]; - x <<= 8; - x |= src[5]; - x <<= 8; - x |= src[4]; - y = src[3]; - y <<= 8; - y |= src[2]; - y <<= 8; - y |= src[1]; - y <<= 8; - y |= src[0]; - z = ((x >> 004) ^ y) & 0x0F0F0F0FL; - x ^= z << 004; - y ^= z; - z = ((y >> 020) ^ x) & 0x0000FFFFL; - y ^= z << 020; - x ^= z; - z = ((x >> 002) ^ y) & 0x33333333L; - x ^= z << 002; - y ^= z; - z = ((y >> 010) ^ x) & 0x00FF00FFL; - y ^= z << 010; - x ^= z; - x = x >> 1 | x << 31; - z = (x ^ y) & 0x55555555L; - y ^= z; - x ^= z; - y = y >> 1 | y << 31; - z = expkey[31]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[30]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[29]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[28]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[27]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[26]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[25]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[24]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[23]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[22]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[21]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[20]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[19]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[18]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[17]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[16]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[15]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[14]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[13]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[12]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[11]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[10]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[9]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[8]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[7]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[6]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[5]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[4]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[3]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[2]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[1]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[0]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - x = x << 1 | x >> 31; - z = (x ^ y) & 0x55555555L; - y ^= z; - x ^= z; - y = y << 1 | y >> 31; - z = ((x >> 010) ^ y) & 0x00FF00FFL; - x ^= z << 010; - y ^= z; - z = ((y >> 002) ^ x) & 0x33333333L; - y ^= z << 002; - x ^= z; - z = ((x >> 020) ^ y) & 0x0000FFFFL; - x ^= z << 020; - y ^= z; - z = ((y >> 004) ^ x) & 0x0F0F0F0FL; - y ^= z << 004; - x ^= z; - dst[0] = x; - x >>= 8; - dst[1] = x; - x >>= 8; - dst[2] = x; - x >>= 8; - dst[3] = x; - dst[4] = y; - y >>= 8; - dst[5] = y; - y >>= 8; - dst[6] = y; - y >>= 8; - dst[7] = y; -} +static const u32 S3[64] = { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const u32 S4[64] = { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const u32 S5[64] = { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const u32 S6[64] = { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const u32 S7[64] = { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const u32 S8[64] = { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* Encryption components: IP, FP, and round function */ + +#define IP(L, R, T) \ + ROL(R, 4); \ + T = L; \ + L ^= R; \ + L &= 0xf0f0f0f0; \ + R ^= L; \ + L ^= T; \ + ROL(R, 12); \ + T = L; \ + L ^= R; \ + L &= 0xffff0000; \ + R ^= L; \ + L ^= T; \ + ROR(R, 14); \ + T = L; \ + L ^= R; \ + L &= 0xcccccccc; \ + R ^= L; \ + L ^= T; \ + ROL(R, 6); \ + T = L; \ + L ^= R; \ + L &= 0xff00ff00; \ + R ^= L; \ + L ^= T; \ + ROR(R, 7); \ + T = L; \ + L ^= R; \ + L &= 0xaaaaaaaa; \ + R ^= L; \ + L ^= T; \ + ROL(L, 1); + +#define FP(L, R, T) \ + ROR(L, 1); \ + T = L; \ + L ^= R; \ + L &= 0xaaaaaaaa; \ + R ^= L; \ + L ^= T; \ + ROL(R, 7); \ + T = L; \ + L ^= R; \ + L &= 0xff00ff00; \ + R ^= L; \ + L ^= T; \ + ROR(R, 6); \ + T = L; \ + L ^= R; \ + L &= 0xcccccccc; \ + R ^= L; \ + L ^= T; \ + ROL(R, 14); \ + T = L; \ + L ^= R; \ + L &= 0xffff0000; \ + R ^= L; \ + L ^= T; \ + ROR(R, 12); \ + T = L; \ + L ^= R; \ + L &= 0xf0f0f0f0; \ + R ^= L; \ + L ^= T; \ + ROR(R, 4); + +#define ROUND(L, R, A, B, K, d) \ + B = K[0]; A = K[1]; K += d; \ + B ^= R; A ^= R; \ + B &= 0x3f3f3f3f; ROR(A, 4); \ + L ^= S8[0xff & B]; A &= 0x3f3f3f3f; \ + L ^= S6[0xff & (B >> 8)]; B >>= 16; \ + L ^= S7[0xff & A]; \ + L ^= S5[0xff & (A >> 8)]; A >>= 16; \ + L ^= S4[0xff & B]; \ + L ^= S2[0xff & (B >> 8)]; \ + L ^= S3[0xff & A]; \ + L ^= S1[0xff & (A >> 8)]; + +/* + * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved + * tables of 128 elements. One set is for C_i and the other for D_i, while + * the 4 interleaved tables correspond to four 7-bit subsets of C_i or D_i. + * + * After PC1 each of the variables a,b,c,d contains a 7 bit subset of C_i + * or D_i in bits 7-1 (bit 0 being the least significant). + */ + +#define T1(x) pt[2 * (x) + 0] +#define T2(x) pt[2 * (x) + 1] +#define T3(x) pt[2 * (x) + 2] +#define T4(x) pt[2 * (x) + 3] + +#define PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a)) /* + * Encryption key expansion + * * RFC2451: Weak key checks SHOULD be performed. + * + * FIPS 74: + * + * Keys having duals are keys which produce all zeros, all ones, or + * alternating zero-one patterns in the C and D registers after Permuted + * Choice 1 has operated on the key. + * */ -static int setkey(u32 *expkey, const u8 *key, unsigned int keylen, u32 *flags) +static unsigned long ekey(u32 *pe, const u8 *k) { - const u8 *k; - u8 *b0, *b1; - u32 n, w; - u8 bits0[56], bits1[56]; - - n = parity[key[0]]; n <<= 4; - n |= parity[key[1]]; n <<= 4; - n |= parity[key[2]]; n <<= 4; - n |= parity[key[3]]; n <<= 4; - n |= parity[key[4]]; n <<= 4; - n |= parity[key[5]]; n <<= 4; - n |= parity[key[6]]; n <<= 4; - n |= parity[key[7]]; - w = 0x88888888L; - - if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY) - && !((n - (w >> 3)) & w)) { /* 1 in 10^10 keys passes this test */ - if (n < 0x41415151) { - if (n < 0x31312121) { - if (n < 0x14141515) { - /* 01 01 01 01 01 01 01 01 */ - if (n == 0x11111111) goto weak; - /* 01 1F 01 1F 01 0E 01 0E */ - if (n == 0x13131212) goto weak; - } else { - /* 01 E0 01 E0 01 F1 01 F1 */ - if (n == 0x14141515) goto weak; - /* 01 FE 01 FE 01 FE 01 FE */ - if (n == 0x16161616) goto weak; - } - } else { - if (n < 0x34342525) { - /* 1F 01 1F 01 0E 01 0E 01 */ - if (n == 0x31312121) goto weak; - /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */ - if (n == 0x33332222) goto weak; - } else { - /* 1F E0 1F E0 0E F1 0E F1 */ - if (n == 0x34342525) goto weak; - /* 1F FE 1F FE 0E FE 0E FE */ - if (n == 0x36362626) goto weak; - } - } - } else { - if (n < 0x61616161) { - if (n < 0x44445555) { - /* E0 01 E0 01 F1 01 F1 01 */ - if (n == 0x41415151) goto weak; - /* E0 1F E0 1F F1 0E F1 0E */ - if (n == 0x43435252) goto weak; - } else { - /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */ - if (n == 0x44445555) goto weak; - /* E0 FE E0 FE F1 FE F1 FE */ - if (n == 0x46465656) goto weak; - } - } else { - if (n < 0x64646565) { - /* FE 01 FE 01 FE 01 FE 01 */ - if (n == 0x61616161) goto weak; - /* FE 1F FE 1F FE 0E FE 0E */ - if (n == 0x63636262) goto weak; - } else { - /* FE E0 FE E0 FE F1 FE F1 */ - if (n == 0x64646565) goto weak; - /* FE FE FE FE FE FE FE FE */ - if (n == 0x66666666) goto weak; - } - } - } - - goto not_weak; -weak: - *flags |= CRYPTO_TFM_RES_WEAK_KEY; - return -EINVAL; + /* K&R: long is at least 32 bits */ + unsigned long a, b, c, d, w; + const u32 *pt = pc2; + + d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d]; + c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c]; + b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b]; + a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a]; + + pe[15 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; + pe[14 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[13 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[12 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[11 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[10 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 9 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 8 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; + pe[ 7 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 6 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 5 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 4 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 3 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 2 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 1 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; + pe[ 0 * 2 + 0] = PC2(b, c, d, a); + + /* Check if first half is weak */ + w = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]); + + /* Skip to next table set */ + pt += 512; + + d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1]; + c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1]; + b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1]; + a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1]; + + /* Check if second half is weak */ + w |= (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]); + + pe[15 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; + pe[14 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[13 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[12 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[11 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[10 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 9 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 8 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; + pe[ 7 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 6 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 5 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 4 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 3 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 2 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 1 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; + pe[ 0 * 2 + 1] = PC2(b, c, d, a); + + /* Fixup: 2413 5768 -> 1357 2468 */ + for (d = 0; d < 16; ++d) { + a = pe[2 * d]; + b = pe[2 * d + 1]; + c = a ^ b; + c &= 0xffff0000; + a ^= c; + b ^= c; + ROL(b, 18); + pe[2 * d] = a; + pe[2 * d + 1] = b; } -not_weak: - - /* explode the bits */ - n = 56; - b0 = bits0; - b1 = bits1; - - do { - w = (256 | *key++) << 2; - do { - --n; - b1[n] = 8 & w; - w >>= 1; - b0[n] = 4 & w; - } while ( w >= 16 ); - } while ( n ); - - /* put the bits in the correct places */ - n = 16; - k = rotors; - - do { - w = (b1[k[ 0 ]] | b0[k[ 1 ]]) << 4; - w |= (b1[k[ 2 ]] | b0[k[ 3 ]]) << 2; - w |= b1[k[ 4 ]] | b0[k[ 5 ]]; - w <<= 8; - w |= (b1[k[ 6 ]] | b0[k[ 7 ]]) << 4; - w |= (b1[k[ 8 ]] | b0[k[ 9 ]]) << 2; - w |= b1[k[10 ]] | b0[k[11 ]]; - w <<= 8; - w |= (b1[k[12 ]] | b0[k[13 ]]) << 4; - w |= (b1[k[14 ]] | b0[k[15 ]]) << 2; - w |= b1[k[16 ]] | b0[k[17 ]]; - w <<= 8; - w |= (b1[k[18 ]] | b0[k[19 ]]) << 4; - w |= (b1[k[20 ]] | b0[k[21 ]]) << 2; - w |= b1[k[22 ]] | b0[k[23 ]]; - expkey[0] = w; - - w = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4; - w |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2; - w |= b1[k[ 4+24]] | b0[k[ 5+24]]; - w <<= 8; - w |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4; - w |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2; - w |= b1[k[10+24]] | b0[k[11+24]]; - w <<= 8; - w |= (b1[k[12+24]] | b0[k[13+24]]) << 4; - w |= (b1[k[14+24]] | b0[k[15+24]]) << 2; - w |= b1[k[16+24]] | b0[k[17+24]]; - w <<= 8; - w |= (b1[k[18+24]] | b0[k[19+24]]) << 4; - w |= (b1[k[20+24]] | b0[k[21+24]]) << 2; - w |= b1[k[22+24]] | b0[k[23+24]]; - - ROR(w, 4, 28); /* could be eliminated */ - expkey[1] = w; - - k += 48; - expkey += 2; - } while (--n); + /* Zero if weak key */ + return w; +} - return 0; +/* + * Decryption key expansion + * + * No weak key checking is performed, as this is only used by triple DES + * + */ +static void dkey(u32 *pe, const u8 *k) +{ + /* K&R: long is at least 32 bits */ + unsigned long a, b, c, d; + const u32 *pt = pc2; + + d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d]; + c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c]; + b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b]; + a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a]; + + pe[ 0 * 2] = PC2(a, b, c, d); d = rs[d]; + pe[ 1 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 2 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 3 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 4 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 5 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 6 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 7 * 2] = PC2(d, a, b, c); c = rs[c]; + pe[ 8 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 9 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[10 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[11 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[12 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[13 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[14 * 2] = PC2(c, d, a, b); b = rs[b]; + pe[15 * 2] = PC2(b, c, d, a); + + /* Skip to next table set */ + pt += 512; + + d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1]; + c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1]; + b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1]; + a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1]; + + pe[ 0 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; + pe[ 1 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 2 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 3 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 4 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 5 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 6 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 7 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; + pe[ 8 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 9 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[10 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[11 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[12 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[13 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[14 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; + pe[15 * 2 + 1] = PC2(b, c, d, a); + + /* Fixup: 2413 5768 -> 1357 2468 */ + for (d = 0; d < 16; ++d) { + a = pe[2 * d]; + b = pe[2 * d + 1]; + c = a ^ b; + c &= 0xffff0000; + a ^= c; + b ^= c; + ROL(b, 18); + pe[2 * d] = a; + pe[2 * d + 1] = b; + } } static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) { - return setkey(((struct des_ctx *)ctx)->expkey, key, keylen, flags); + struct des_ctx *dctx = ctx; + u32 tmp[DES_EXPKEY_WORDS]; + int ret; + + /* Expand to tmp */ + ret = ekey(tmp, key); + + if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { + *flags |= CRYPTO_TFM_RES_WEAK_KEY; + return -EINVAL; + } + + /* Copy to output */ + memcpy(dctx->expkey, tmp, sizeof(dctx->expkey)); + + return 0; } static void des_encrypt(void *ctx, u8 *dst, const u8 *src) { - des_small_fips_encrypt(((struct des_ctx *)ctx)->expkey, dst, src); + const u32 *K = ((struct des_ctx *)ctx)->expkey; + const __le32 *s = (const __le32 *)src; + __le32 *d = (__le32 *)dst; + u32 L, R, A, B; + int i; + + L = le32_to_cpu(s[0]); + R = le32_to_cpu(s[1]); + + IP(L, R, A); + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, 2); + ROUND(R, L, A, B, K, 2); + } + FP(R, L, A); + + d[0] = cpu_to_le32(R); + d[1] = cpu_to_le32(L); } static void des_decrypt(void *ctx, u8 *dst, const u8 *src) { - des_small_fips_decrypt(((struct des_ctx *)ctx)->expkey, dst, src); + const u32 *K = ((struct des_ctx *)ctx)->expkey + DES_EXPKEY_WORDS - 2; + const __le32 *s = (const __le32 *)src; + __le32 *d = (__le32 *)dst; + u32 L, R, A, B; + int i; + + L = le32_to_cpu(s[0]); + R = le32_to_cpu(s[1]); + + IP(L, R, A); + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, -2); + ROUND(R, L, A, B, K, -2); + } + FP(R, L, A); + + d[0] = cpu_to_le32(R); + d[1] = cpu_to_le32(L); } -/* +/* * RFC2451: * * For DES-EDE3, there is no known need to reject weak or @@ -1199,44 +859,86 @@ static void des_decrypt(void *ctx, u8 *dst, const u8 *src) * */ static int des3_ede_setkey(void *ctx, const u8 *key, - unsigned int keylen, u32 *flags) + unsigned int keylen, u32 *flags) { - unsigned int i, off; + const u32 *K = (const u32 *)key; struct des3_ede_ctx *dctx = ctx; + u32 *expkey = dctx->expkey; - if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && - memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], - DES_KEY_SIZE))) { - + if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || + !((K[2] ^ K[4]) | (K[3] ^ K[5])))) + { *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; return -EINVAL; } - - for (i = 0, off = 0; i < 3; i++, off += DES_EXPKEY_WORDS, - key += DES_KEY_SIZE) { - int ret = setkey(&dctx->expkey[off], key, DES_KEY_SIZE, flags); - if (ret < 0) - return ret; - } + + ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE; + dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE; + ekey(expkey, key); + return 0; } static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src) { struct des3_ede_ctx *dctx = ctx; - - des_small_fips_encrypt(dctx->expkey, dst, src); - des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst); - des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, dst); + const u32 *K = dctx->expkey; + const __le32 *s = (const __le32 *)src; + __le32 *d = (__le32 *)dst; + u32 L, R, A, B; + int i; + + L = le32_to_cpu(s[0]); + R = le32_to_cpu(s[1]); + + IP(L, R, A); + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, 2); + ROUND(R, L, A, B, K, 2); + } + for (i = 0; i < 8; i++) { + ROUND(R, L, A, B, K, 2); + ROUND(L, R, A, B, K, 2); + } + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, 2); + ROUND(R, L, A, B, K, 2); + } + FP(R, L, A); + + d[0] = cpu_to_le32(R); + d[1] = cpu_to_le32(L); } static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src) { struct des3_ede_ctx *dctx = ctx; + const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2; + const __le32 *s = (const __le32 *)src; + __le32 *d = (__le32 *)dst; + u32 L, R, A, B; + int i; + + L = le32_to_cpu(s[0]); + R = le32_to_cpu(s[1]); + + IP(L, R, A); + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, -2); + ROUND(R, L, A, B, K, -2); + } + for (i = 0; i < 8; i++) { + ROUND(R, L, A, B, K, -2); + ROUND(L, R, A, B, K, -2); + } + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, -2); + ROUND(R, L, A, B, K, -2); + } + FP(R, L, A); - des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, src); - des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst); - des_small_fips_decrypt(dctx->expkey, dst, dst); + d[0] = cpu_to_le32(R); + d[1] = cpu_to_le32(L); } static struct crypto_alg des_alg = { @@ -1249,7 +951,7 @@ static struct crypto_alg des_alg = { .cra_u = { .cipher = { .cia_min_keysize = DES_KEY_SIZE, .cia_max_keysize = DES_KEY_SIZE, - .cia_setkey = des_setkey, + .cia_setkey = des_setkey, .cia_encrypt = des_encrypt, .cia_decrypt = des_decrypt } } }; @@ -1264,9 +966,9 @@ static struct crypto_alg des3_ede_alg = { .cra_u = { .cipher = { .cia_min_keysize = DES3_EDE_KEY_SIZE, .cia_max_keysize = DES3_EDE_KEY_SIZE, - .cia_setkey = des3_ede_setkey, - .cia_encrypt = des3_ede_encrypt, - .cia_decrypt = des3_ede_decrypt } } + .cia_setkey = des3_ede_setkey, + .cia_encrypt = des3_ede_encrypt, + .cia_decrypt = des3_ede_decrypt } } }; MODULE_ALIAS("des3_ede"); @@ -1274,7 +976,7 @@ MODULE_ALIAS("des3_ede"); static int __init init(void) { int ret = 0; - + ret = crypto_register_alg(&des_alg); if (ret < 0) goto out; @@ -1282,7 +984,7 @@ static int __init init(void) ret = crypto_register_alg(&des3_ede_alg); if (ret < 0) crypto_unregister_alg(&des_alg); -out: +out: return ret; } @@ -1297,3 +999,4 @@ module_exit(fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); +MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>"); diff --git a/crypto/hmac.c b/crypto/hmac.c index 847df9263e16..da0456b37109 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -49,8 +49,7 @@ int crypto_alloc_hmac_block(struct crypto_tfm *tfm) void crypto_free_hmac_block(struct crypto_tfm *tfm) { - if (tfm->crt_digest.dit_hmac_block) - kfree(tfm->crt_digest.dit_hmac_block); + kfree(tfm->crt_digest.dit_hmac_block); } void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen) diff --git a/crypto/internal.h b/crypto/internal.h index 964b9a60ca24..68612874b5fd 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -16,7 +16,7 @@ #include <linux/highmem.h> #include <linux/interrupt.h> #include <linux/init.h> -#include <linux/kmod.h> +#include <linux/kernel.h> #include <asm/kmap_types.h> extern enum km_type crypto_km_types[]; @@ -42,20 +42,6 @@ static inline void crypto_yield(struct crypto_tfm *tfm) cond_resched(); } -static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) -{ - return (void *)&tfm[1]; -} - -struct crypto_alg *crypto_alg_lookup(const char *name); - -/* A far more intelligent version of this is planned. For now, just - * try an exact match on the name of the algorithm. */ -static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) -{ - return try_then_request_module(crypto_alg_lookup(name), name); -} - #ifdef CONFIG_CRYPTO_HMAC int crypto_alloc_hmac_block(struct crypto_tfm *tfm); void crypto_free_hmac_block(struct crypto_tfm *tfm); @@ -76,6 +62,33 @@ static inline void crypto_init_proc(void) { } #endif +static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg, + int flags) +{ + return alg->cra_ctxsize; +} + +static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg, + int flags) +{ + unsigned int len = alg->cra_ctxsize; + + switch (flags & CRYPTO_TFM_MODE_MASK) { + case CRYPTO_TFM_MODE_CBC: + len = ALIGN(len, alg->cra_alignmask + 1); + len += alg->cra_blocksize; + break; + } + + return len; +} + +static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg, + int flags) +{ + return alg->cra_ctxsize; +} + int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags); diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 50c9461e8cc6..47ac90e615f4 100644 --- a/crypto/scatterwalk.c +++ b/crypto/scatterwalk.c @@ -100,7 +100,7 @@ void scatterwalk_done(struct scatter_walk *walk, int out, int more) int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out) { - do { + while (nbytes > walk->len_this_page) { memcpy_dir(buf, walk->data, walk->len_this_page, out); buf += walk->len_this_page; nbytes -= walk->len_this_page; @@ -108,7 +108,7 @@ int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, scatterwalk_unmap(walk, out); scatterwalk_pagedone(walk, out, 1); scatterwalk_map(walk, out); - } while (nbytes > walk->len_this_page); + } memcpy_dir(buf, walk->data, nbytes, out); return nbytes; diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h index 02aa56c649b4..e79925c474a3 100644 --- a/crypto/scatterwalk.h +++ b/crypto/scatterwalk.h @@ -40,10 +40,10 @@ static inline int scatterwalk_samebuf(struct scatter_walk *walk_in, walk_in->offset == walk_out->offset; } -static inline int scatterwalk_across_pages(struct scatter_walk *walk, - unsigned int nbytes) +static inline unsigned int scatterwalk_clamp(struct scatter_walk *walk, + unsigned int nbytes) { - return nbytes > walk->len_this_page; + return nbytes > walk->len_this_page ? walk->len_this_page : nbytes; } static inline void scatterwalk_advance(struct scatter_walk *walk, @@ -55,6 +55,12 @@ static inline void scatterwalk_advance(struct scatter_walk *walk, walk->len_this_segment -= nbytes; } +static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk, + unsigned int alignmask) +{ + return !(walk->offset & alignmask); +} + void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg); int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out); void scatterwalk_map(struct scatter_walk *walk, int out); diff --git a/crypto/serpent.c b/crypto/serpent.c index 7d152e89016f..3cf2c5067eea 100644 --- a/crypto/serpent.c +++ b/crypto/serpent.c @@ -210,7 +210,6 @@ x4 ^= x2; struct serpent_ctx { - u8 iv[SERPENT_BLOCK_SIZE]; u32 expkey[SERPENT_EXPKEY_WORDS]; }; diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 5a0adbf8bc04..97013ddfa202 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -153,7 +153,7 @@ container_device_add(struct acpi_device **device, acpi_handle handle) return_VALUE(-ENODEV); } - result = acpi_bus_scan(*device); + result = acpi_bus_start(*device); return_VALUE(result); } diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 5d19b39e9e2b..5148f3c10b5c 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c @@ -61,15 +61,14 @@ acpi_pci_data_handler ( /** - * acpi_os_get_pci_id + * acpi_get_pci_id * ------------------ * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) * to resolve PCI information for ACPI-PCI devices defined in the namespace. * This typically occurs when resolving PCI operation region information. */ -#ifdef ACPI_FUTURE_USAGE acpi_status -acpi_os_get_pci_id ( +acpi_get_pci_id ( acpi_handle handle, struct acpi_pci_id *id) { @@ -78,7 +77,7 @@ acpi_os_get_pci_id ( struct acpi_device *device = NULL; struct acpi_pci_data *data = NULL; - ACPI_FUNCTION_TRACE("acpi_os_get_pci_id"); + ACPI_FUNCTION_TRACE("acpi_get_pci_id"); if (!id) return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -92,7 +91,7 @@ acpi_os_get_pci_id ( } status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data); - if (ACPI_FAILURE(status) || !data || !data->dev) { + if (ACPI_FAILURE(status) || !data) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid ACPI-PCI context for device %s\n", acpi_device_bid(device))); @@ -115,7 +114,7 @@ acpi_os_get_pci_id ( return_ACPI_STATUS(AE_OK); } -#endif /* ACPI_FUTURE_USAGE */ +EXPORT_SYMBOL(acpi_get_pci_id); int @@ -129,6 +128,8 @@ acpi_pci_bind ( char *pathname = NULL; struct acpi_buffer buffer = {0, NULL}; acpi_handle handle = NULL; + struct pci_dev *dev; + struct pci_bus *bus; ACPI_FUNCTION_TRACE("acpi_pci_bind"); @@ -193,8 +194,20 @@ acpi_pci_bind ( * Locate matching device in PCI namespace. If it doesn't exist * this typically means that the device isn't currently inserted * (e.g. docking station, port replicator, etc.). + * We cannot simply search the global pci device list, since + * PCI devices are added to the global pci list when the root + * bridge start ops are run, which may not have happened yet. */ - data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); + bus = pci_find_bus(data->id.segment, data->id.bus); + if (bus) { + list_for_each_entry(dev, &bus->devices, bus_list) { + if (dev->devfn == PCI_DEVFN(data->id.device, + data->id.function)) { + data->dev = dev; + break; + } + } + } if (!data->dev) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 8dbf802ee7f8..d1f42b972821 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -433,7 +433,7 @@ acpi_pci_irq_enable ( printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", pci_name(dev), ('A' + pin)); /* Interrupt Line values above 0xF are forbidden */ - if (dev->irq >= 0 && (dev->irq <= 0xF)) { + if (dev->irq > 0 && (dev->irq <= 0xF)) { printk(" - using IRQ %d\n", dev->irq); acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); return_VALUE(0); diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 7e6b8e3b2ed4..5d2f77fcd50c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -46,6 +46,7 @@ ACPI_MODULE_NAME ("pci_root") static int acpi_pci_root_add (struct acpi_device *device); static int acpi_pci_root_remove (struct acpi_device *device, int type); +static int acpi_pci_root_start (struct acpi_device *device); static struct acpi_driver acpi_pci_root_driver = { .name = ACPI_PCI_ROOT_DRIVER_NAME, @@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = { .ops = { .add = acpi_pci_root_add, .remove = acpi_pci_root_remove, + .start = acpi_pci_root_start, }, }; @@ -169,6 +171,7 @@ acpi_pci_root_add ( if (!root) return_VALUE(-ENOMEM); memset(root, 0, sizeof(struct acpi_pci_root)); + INIT_LIST_HEAD(&root->node); root->handle = device->handle; strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); @@ -298,12 +301,31 @@ acpi_pci_root_add ( root->id.bus); end: - if (result) + if (result) { + if (!list_empty(&root->node)) + list_del(&root->node); kfree(root); + } return_VALUE(result); } +static int +acpi_pci_root_start ( + struct acpi_device *device) +{ + struct acpi_pci_root *root; + + ACPI_FUNCTION_TRACE("acpi_pci_root_start"); + + list_for_each_entry(root, &acpi_pci_roots, node) { + if (root->handle == device->handle) { + pci_bus_add_devices(root->bus); + return_VALUE(0); + } + } + return_VALUE(-ENODEV); +} static int acpi_pci_root_remove ( diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index f4778747e889..76156ac91bd3 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -723,7 +723,7 @@ int acpi_processor_device_add( return_VALUE(-ENODEV); } - acpi_bus_scan(*device); + acpi_bus_start(*device); pr = acpi_driver_data(*device); if (!pr) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e85885593280..337d49b5564b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -553,20 +553,29 @@ acpi_bus_driver_init ( * upon possible configuration and currently allocated resources. */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); + return_VALUE(0); +} + +int +acpi_start_single_object ( + struct acpi_device *device) +{ + int result = 0; + struct acpi_driver *driver; + + ACPI_FUNCTION_TRACE("acpi_start_single_object"); + + if (!(driver = device->driver)) + return_VALUE(0); + if (driver->ops.start) { result = driver->ops.start(device); if (result && driver->ops.remove) driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); - return_VALUE(result); } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); - - if (driver->ops.scan) { - driver->ops.scan(device); - } - - return_VALUE(0); + return_VALUE(result); } static int acpi_driver_attach(struct acpi_driver * drv) @@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acpi_driver * drv) if (!acpi_bus_match(dev, drv)) { if (!acpi_bus_driver_init(dev, drv)) { + acpi_start_single_object(dev); atomic_inc(&drv->references); count++; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", @@ -1009,8 +1019,8 @@ acpi_bus_remove ( } -int -acpi_bus_add ( +static int +acpi_add_single_object ( struct acpi_device **child, struct acpi_device *parent, acpi_handle handle, @@ -1019,7 +1029,7 @@ acpi_bus_add ( int result = 0; struct acpi_device *device = NULL; - ACPI_FUNCTION_TRACE("acpi_bus_add"); + ACPI_FUNCTION_TRACE("acpi_add_single_object"); if (!child) return_VALUE(-EINVAL); @@ -1140,7 +1150,7 @@ acpi_bus_add ( * * TBD: Assumes LDM provides driver hot-plug capability. */ - acpi_bus_find_driver(device); + result = acpi_bus_find_driver(device); end: if (!result) @@ -1153,10 +1163,10 @@ end: return_VALUE(result); } -EXPORT_SYMBOL(acpi_bus_add); -int acpi_bus_scan (struct acpi_device *start) +static int acpi_bus_scan (struct acpi_device *start, + struct acpi_bus_ops *ops) { acpi_status status = AE_OK; struct acpi_device *parent = NULL; @@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device *start) continue; } - status = acpi_bus_add(&child, parent, chandle, type); - if (ACPI_FAILURE(status)) - continue; + if (ops->acpi_op_add) + status = acpi_add_single_object(&child, parent, + chandle, type); + else + status = acpi_bus_get_device(chandle, &child); + + if (ACPI_FAILURE(status)) + continue; + + if (ops->acpi_op_start) { + status = acpi_start_single_object(child); + if (ACPI_FAILURE(status)) + continue; + } /* * If the device is present, enabled, and functioning then @@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device *start) return_VALUE(0); } -EXPORT_SYMBOL(acpi_bus_scan); +int +acpi_bus_add ( + struct acpi_device **child, + struct acpi_device *parent, + acpi_handle handle, + int type) +{ + int result; + struct acpi_bus_ops ops; + + ACPI_FUNCTION_TRACE("acpi_bus_add"); + + result = acpi_add_single_object(child, parent, handle, type); + if (!result) { + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + result = acpi_bus_scan(*child, &ops); + } + return_VALUE(result); +} +EXPORT_SYMBOL(acpi_bus_add); + +int +acpi_bus_start ( + struct acpi_device *device) +{ + int result; + struct acpi_bus_ops ops; + + ACPI_FUNCTION_TRACE("acpi_bus_start"); + + if (!device) + return_VALUE(-EINVAL); + + result = acpi_start_single_object(device); + if (!result) { + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_start = 1; + result = acpi_bus_scan(device, &ops); + } + return_VALUE(result); +} +EXPORT_SYMBOL(acpi_bus_start); static int acpi_bus_trim(struct acpi_device *start, @@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed ( /* * Enumerate all fixed-feature devices. */ - if (acpi_fadt.pwr_button == 0) - result = acpi_bus_add(&device, acpi_root, + if (acpi_fadt.pwr_button == 0) { + result = acpi_add_single_object(&device, acpi_root, NULL, ACPI_BUS_TYPE_POWER_BUTTON); + if (!result) + result = acpi_start_single_object(device); + } - if (acpi_fadt.sleep_button == 0) - result = acpi_bus_add(&device, acpi_root, + if (acpi_fadt.sleep_button == 0) { + result = acpi_add_single_object(&device, acpi_root, NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); + if (!result) + result = acpi_start_single_object(device); + } return_VALUE(result); } @@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed ( static int __init acpi_scan_init(void) { int result; + struct acpi_bus_ops ops; ACPI_FUNCTION_TRACE("acpi_scan_init"); @@ -1357,17 +1427,23 @@ static int __init acpi_scan_init(void) /* * Create the root device in the bus's device tree */ - result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, + result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, ACPI_BUS_TYPE_SYSTEM); if (result) goto Done; + result = acpi_start_single_object(acpi_root); + /* * Enumerate devices in the ACPI namespace. */ result = acpi_bus_scan_fixed(acpi_root); - if (!result) - result = acpi_bus_scan(acpi_root); + if (!result) { + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + ops.acpi_op_start = 1; + result = acpi_bus_scan(acpi_root, &ops); + } if (result) acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); diff --git a/drivers/base/base.h b/drivers/base/base.h index 645f62692920..783752b68a9a 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -5,6 +5,7 @@ extern int bus_add_driver(struct device_driver *); extern void bus_remove_driver(struct device_driver *); extern void driver_detach(struct device_driver * drv); +extern int driver_probe_device(struct device_driver *, struct device *); static inline struct class_device *to_class_dev(struct kobject *obj) { diff --git a/drivers/base/bus.c b/drivers/base/bus.c index c3fac7fd555e..96fe2f956754 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -133,6 +133,58 @@ static struct kobj_type ktype_bus = { decl_subsys(bus, &ktype_bus, NULL); +/* Manually detach a device from it's associated driver. */ +static int driver_helper(struct device *dev, void *data) +{ + const char *name = data; + + if (strcmp(name, dev->bus_id) == 0) + return 1; + return 0; +} + +static ssize_t driver_unbind(struct device_driver *drv, + const char *buf, size_t count) +{ + struct bus_type *bus = get_bus(drv->bus); + struct device *dev; + int err = -ENODEV; + + dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); + if ((dev) && + (dev->driver == drv)) { + device_release_driver(dev); + err = count; + } + return err; +} +static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); + +/* + * Manually attach a device to a driver. + * Note: the driver must want to bind to the device, + * it is not possible to override the driver's id table. + */ +static ssize_t driver_bind(struct device_driver *drv, + const char *buf, size_t count) +{ + struct bus_type *bus = get_bus(drv->bus); + struct device *dev; + int err = -ENODEV; + + dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); + if ((dev) && + (dev->driver == NULL)) { + down(&dev->sem); + err = driver_probe_device(drv, dev); + up(&dev->sem); + put_device(dev); + } + return err; +} +static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); + + static struct device * next_device(struct klist_iter * i) { struct klist_node * n = klist_next(i); @@ -177,6 +229,39 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, return error; } +/** + * bus_find_device - device iterator for locating a particular device. + * @bus: bus type + * @start: Device to begin with + * @data: Data to pass to match function + * @match: Callback function to check device + * + * This is similar to the bus_for_each_dev() function above, but it + * returns a reference to a device that is 'found' for later use, as + * determined by the @match callback. + * + * The callback should return 0 if the device doesn't match and non-zero + * if it does. If the callback returns non-zero, this function will + * return to the caller and not iterate over any more devices. + */ +struct device * bus_find_device(struct bus_type *bus, + struct device *start, void *data, + int (*match)(struct device *, void *)) +{ + struct klist_iter i; + struct device *dev; + + if (!bus) + return NULL; + + klist_iter_init_node(&bus->klist_devices, &i, + (start ? &start->knode_bus : NULL)); + while ((dev = next_device(&i))) + if (match(dev, data) && get_device(dev)) + break; + klist_iter_exit(&i); + return dev; +} static struct device_driver * next_driver(struct klist_iter * i) @@ -363,6 +448,8 @@ int bus_add_driver(struct device_driver * drv) module_add_driver(drv->owner, drv); driver_add_attrs(bus, drv); + driver_create_file(drv, &driver_attr_unbind); + driver_create_file(drv, &driver_attr_bind); } return error; } @@ -380,6 +467,8 @@ int bus_add_driver(struct device_driver * drv) void bus_remove_driver(struct device_driver * drv) { if (drv->bus) { + driver_remove_file(drv, &driver_attr_bind); + driver_remove_file(drv, &driver_attr_unbind); driver_remove_attrs(drv->bus, drv); klist_remove(&drv->knode_bus); pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); @@ -394,31 +483,22 @@ void bus_remove_driver(struct device_driver * drv) /* Helper for bus_rescan_devices's iter */ static int bus_rescan_devices_helper(struct device *dev, void *data) { - int *count = data; - - if (!dev->driver && (device_attach(dev) > 0)) - (*count)++; - + if (!dev->driver) + device_attach(dev); return 0; } - /** - * bus_rescan_devices - rescan devices on the bus for possible drivers - * @bus: the bus to scan. + * bus_rescan_devices - rescan devices on the bus for possible drivers + * @bus: the bus to scan. * - * This function will look for devices on the bus with no driver - * attached and rescan it against existing drivers to see if it - * matches any. Calls device_attach(). Returns the number of devices - * that were sucessfully bound to a driver. + * This function will look for devices on the bus with no driver + * attached and rescan it against existing drivers to see if it matches + * any by calling device_attach() for the unbound devices. */ -int bus_rescan_devices(struct bus_type * bus) +void bus_rescan_devices(struct bus_type * bus) { - int count = 0; - - bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper); - - return count; + bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); } @@ -557,6 +637,7 @@ int __init buses_init(void) EXPORT_SYMBOL_GPL(bus_for_each_dev); +EXPORT_SYMBOL_GPL(bus_find_device); EXPORT_SYMBOL_GPL(bus_for_each_drv); EXPORT_SYMBOL_GPL(bus_add_device); diff --git a/drivers/base/core.c b/drivers/base/core.c index 86d79755fbfb..efe03a024a5b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -333,7 +333,7 @@ void device_del(struct device * dev) struct device * parent = dev->parent; if (parent) - klist_remove(&dev->knode_parent); + klist_del(&dev->knode_parent); /* Notify the platform of the removal, in case they * need to do anything... diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 6db3a789c54f..16323f9cbff0 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -65,7 +65,7 @@ void device_bind_driver(struct device * dev) * * This function must be called with @dev->sem held. */ -static int driver_probe_device(struct device_driver * drv, struct device * dev) +int driver_probe_device(struct device_driver * drv, struct device * dev) { int ret = 0; diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 1b645886e9eb..291c5954a3af 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -56,6 +56,41 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); /** + * driver_find_device - device iterator for locating a particular device. + * @driver: The device's driver + * @start: Device to begin with + * @data: Data to pass to match function + * @match: Callback function to check device + * + * This is similar to the driver_for_each_device() function above, but + * it returns a reference to a device that is 'found' for later use, as + * determined by the @match callback. + * + * The callback should return 0 if the device doesn't match and non-zero + * if it does. If the callback returns non-zero, this function will + * return to the caller and not iterate over any more devices. + */ +struct device * driver_find_device(struct device_driver *drv, + struct device * start, void * data, + int (*match)(struct device *, void *)) +{ + struct klist_iter i; + struct device *dev; + + if (!drv) + return NULL; + + klist_iter_init_node(&drv->klist_devices, &i, + (start ? &start->knode_driver : NULL)); + while ((dev = next_device(&i))) + if (match(dev, data) && get_device(dev)) + break; + klist_iter_exit(&i); + return dev; +} +EXPORT_SYMBOL_GPL(driver_find_device); + +/** * driver_create_file - create sysfs file for driver. * @drv: driver. * @attr: driver attribute descriptor. diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 97fe13f7f07c..652281402c92 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -74,6 +74,8 @@ static ssize_t firmware_timeout_store(struct class *class, const char *buf, size_t count) { loading_timeout = simple_strtol(buf, NULL, 10); + if (loading_timeout < 0) + loading_timeout = 0; return count; } @@ -138,6 +140,10 @@ firmware_loading_store(struct class_device *class_dev, switch (loading) { case 1: down(&fw_lock); + if (!fw_priv->fw) { + up(&fw_lock); + break; + } vfree(fw_priv->fw->data); fw_priv->fw->data = NULL; fw_priv->fw->size = 0; @@ -178,7 +184,7 @@ firmware_data_read(struct kobject *kobj, down(&fw_lock); fw = fw_priv->fw; - if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { + if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { ret_count = -ENODEV; goto out; } @@ -238,9 +244,10 @@ firmware_data_write(struct kobject *kobj, if (!capable(CAP_SYS_RAWIO)) return -EPERM; + down(&fw_lock); fw = fw_priv->fw; - if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { + if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { retval = -ENODEV; goto out; } @@ -418,7 +425,7 @@ request_firmware(const struct firmware **firmware_p, const char *name, fw_priv = class_get_devdata(class_dev); - if (loading_timeout) { + if (loading_timeout > 0) { fw_priv->timeout.expires = jiffies + loading_timeout * HZ; add_timer(&fw_priv->timeout); } diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 653512b77570..3e9fb6e4a52a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -786,7 +786,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, case CCISS_GETLUNINFO: { LogvolInfo_struct luninfo; - int i; luninfo.LunID = drv->LunID; luninfo.num_opens = drv->usage_count; diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 234fdcfbdf01..692a5fced76e 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1867,19 +1867,20 @@ static void freed_request(request_queue_t *q, int rw) #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist) /* - * Get a free request, queue_lock must not be held + * Get a free request, queue_lock must be held. + * Returns NULL on failure, with queue_lock held. + * Returns !NULL on success, with queue_lock *not held*. */ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask) { struct request *rq = NULL; struct request_list *rl = &q->rq; - struct io_context *ioc = get_io_context(gfp_mask); + struct io_context *ioc = current_io_context(GFP_ATOMIC); if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) goto out; - spin_lock_irq(q->queue_lock); if (rl->count[rw]+1 >= q->nr_requests) { /* * The queue will fill after this allocation, so set it as @@ -1907,11 +1908,18 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, * The queue is full and the allocating process is not a * "batcher", and not exempted by the IO scheduler */ - spin_unlock_irq(q->queue_lock); goto out; } get_rq: + /* + * Only allow batching queuers to allocate up to 50% over the defined + * limit of requests, otherwise we could have thousands of requests + * allocated with any setting of ->nr_requests + */ + if (rl->count[rw] >= (3 * q->nr_requests / 2)) + goto out; + rl->count[rw]++; rl->starved[rw] = 0; if (rl->count[rw] >= queue_congestion_on_threshold(q)) @@ -1941,7 +1949,6 @@ rq_starved: if (unlikely(rl->count[rw] == 0)) rl->starved[rw] = 1; - spin_unlock_irq(q->queue_lock); goto out; } @@ -1951,21 +1958,23 @@ rq_starved: rq_init(q, rq); rq->rl = rl; out: - put_io_context(ioc); return rq; } /* * No available requests for this queue, unplug the device and wait for some * requests to become available. + * + * Called with q->queue_lock held, and returns with it unlocked. */ static struct request *get_request_wait(request_queue_t *q, int rw, struct bio *bio) { - DEFINE_WAIT(wait); struct request *rq; - do { + rq = get_request(q, rw, bio, GFP_NOIO); + while (!rq) { + DEFINE_WAIT(wait); struct request_list *rl = &q->rq; prepare_to_wait_exclusive(&rl->wait[rw], &wait, @@ -1976,7 +1985,8 @@ static struct request *get_request_wait(request_queue_t *q, int rw, if (!rq) { struct io_context *ioc; - generic_unplug_device(q); + __generic_unplug_device(q); + spin_unlock_irq(q->queue_lock); io_schedule(); /* @@ -1985,12 +1995,13 @@ static struct request *get_request_wait(request_queue_t *q, int rw, * up to a big batch of them for a small period time. * See ioc_batching, ioc_set_batching */ - ioc = get_io_context(GFP_NOIO); + ioc = current_io_context(GFP_NOIO); ioc_set_batching(q, ioc); - put_io_context(ioc); + + spin_lock_irq(q->queue_lock); } finish_wait(&rl->wait[rw], &wait); - } while (!rq); + } return rq; } @@ -2001,14 +2012,18 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask) BUG_ON(rw != READ && rw != WRITE); - if (gfp_mask & __GFP_WAIT) + spin_lock_irq(q->queue_lock); + if (gfp_mask & __GFP_WAIT) { rq = get_request_wait(q, rw, NULL); - else + } else { rq = get_request(q, rw, NULL, gfp_mask); + if (!rq) + spin_unlock_irq(q->queue_lock); + } + /* q->queue_lock is unlocked at this point */ return rq; } - EXPORT_SYMBOL(blk_get_request); /** @@ -2512,7 +2527,7 @@ EXPORT_SYMBOL(blk_attempt_remerge); static int __make_request(request_queue_t *q, struct bio *bio) { - struct request *req, *freereq = NULL; + struct request *req; int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; unsigned short prio; sector_t sector; @@ -2540,14 +2555,9 @@ static int __make_request(request_queue_t *q, struct bio *bio) goto end_io; } -again: spin_lock_irq(q->queue_lock); - if (elv_queue_empty(q)) { - blk_plug_device(q); - goto get_rq; - } - if (barrier) + if (unlikely(barrier) || elv_queue_empty(q)) goto get_rq; el_ret = elv_merge(q, &req, bio); @@ -2592,40 +2602,24 @@ again: elv_merged_request(q, req); goto out; - /* - * elevator says don't/can't merge. get new request - */ - case ELEVATOR_NO_MERGE: - break; - + /* ELV_NO_MERGE: elevator says don't/can't merge. */ default: - printk("elevator returned crap (%d)\n", el_ret); - BUG(); + ; } +get_rq: /* - * Grab a free request from the freelist - if that is empty, check - * if we are doing read ahead and abort instead of blocking for - * a free slot. + * Grab a free request. This is might sleep but can not fail. + * Returns with the queue unlocked. + */ + req = get_request_wait(q, rw, bio); + + /* + * After dropping the lock and possibly sleeping here, our request + * may now be mergeable after it had proven unmergeable (above). + * We don't worry about that case for efficiency. It won't happen + * often, and the elevators are able to handle it. */ -get_rq: - if (freereq) { - req = freereq; - freereq = NULL; - } else { - spin_unlock_irq(q->queue_lock); - if ((freereq = get_request(q, rw, bio, GFP_ATOMIC)) == NULL) { - /* - * READA bit set - */ - err = -EWOULDBLOCK; - if (bio_rw_ahead(bio)) - goto end_io; - - freereq = get_request_wait(q, rw, bio); - } - goto again; - } req->flags |= REQ_CMD; @@ -2654,10 +2648,11 @@ get_rq: req->rq_disk = bio->bi_bdev->bd_disk; req->start_time = jiffies; + spin_lock_irq(q->queue_lock); + if (elv_queue_empty(q)) + blk_plug_device(q); add_request(q, req); out: - if (freereq) - __blk_put_request(q, freereq); if (sync) __generic_unplug_device(q); @@ -3284,24 +3279,20 @@ void exit_io_context(void) /* * If the current task has no IO context then create one and initialise it. - * If it does have a context, take a ref on it. + * Otherwise, return its existing IO context. * - * This is always called in the context of the task which submitted the I/O. - * But weird things happen, so we disable local interrupts to ensure exclusive - * access to *current. + * This returned IO context doesn't have a specifically elevated refcount, + * but since the current task itself holds a reference, the context can be + * used in general code, so long as it stays within `current` context. */ -struct io_context *get_io_context(int gfp_flags) +struct io_context *current_io_context(int gfp_flags) { struct task_struct *tsk = current; - unsigned long flags; struct io_context *ret; - local_irq_save(flags); ret = tsk->io_context; - if (ret) - goto out; - - local_irq_restore(flags); + if (likely(ret)) + return ret; ret = kmem_cache_alloc(iocontext_cachep, gfp_flags); if (ret) { @@ -3312,25 +3303,25 @@ struct io_context *get_io_context(int gfp_flags) ret->nr_batch_requests = 0; /* because this is 0 */ ret->aic = NULL; ret->cic = NULL; + tsk->io_context = ret; + } - local_irq_save(flags); - - /* - * very unlikely, someone raced with us in setting up the task - * io context. free new context and just grab a reference. - */ - if (!tsk->io_context) - tsk->io_context = ret; - else { - kmem_cache_free(iocontext_cachep, ret); - ret = tsk->io_context; - } + return ret; +} +EXPORT_SYMBOL(current_io_context); -out: +/* + * If the current task has no IO context then create one and initialise it. + * If it does have a context, take a ref on it. + * + * This is always called in the context of the task which submitted the I/O. + */ +struct io_context *get_io_context(int gfp_flags) +{ + struct io_context *ret; + ret = current_io_context(gfp_flags); + if (likely(ret)) atomic_inc(&ret->refcount); - local_irq_restore(flags); - } - return ret; } EXPORT_SYMBOL(get_io_context); diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 1407945a5892..59f589d733f9 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -686,6 +686,15 @@ static struct pci_device_id agp_amd64_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, + /* SIS 760 */ + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_760, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, { } }; diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c index 7e6ac14c2450..3480535a09c5 100644 --- a/drivers/char/hw_random.c +++ b/drivers/char/hw_random.c @@ -579,7 +579,7 @@ static int __init rng_init (void) /* Probe for Intel, AMD RNGs */ for_each_pci_dev(pdev) { - ent = pci_match_device (rng_pci_tbl, pdev); + ent = pci_match_id(rng_pci_tbl, pdev); if (ent) { rng_ops = &rng_vendor_ops[ent->driver_data]; goto match; diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 1813d0d198f1..e16c13fe698d 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -1088,8 +1088,8 @@ static inline int i_ipmi_request(ipmi_user_t user, long seqid; int broadcast = 0; - if (addr->channel > IPMI_NUM_CHANNELS) { - spin_lock_irqsave(&intf->counter_lock, flags); + if (addr->channel >= IPMI_MAX_CHANNELS) { + spin_lock_irqsave(&intf->counter_lock, flags); intf->sent_invalid_commands++; spin_unlock_irqrestore(&intf->counter_lock, flags); rv = -EINVAL; diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 7c24fbe831f8..95f7046ff059 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -451,7 +451,7 @@ static int __init moxa_init(void) int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1; i = 0; while (i < n) { - while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) + while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) { if (pci_enable_device(p)) continue; diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 7db3370f4972..d7d484024e2b 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c @@ -1095,7 +1095,7 @@ static int __init rio_init(void) #ifdef CONFIG_PCI /* First look for the JET devices: */ - while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, + while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { if (pci_enable_device(pdev)) continue; @@ -1169,7 +1169,7 @@ static int __init rio_init(void) */ /* Then look for the older RIO/PCI devices: */ - while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, + while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { if (pci_enable_device(pdev)) continue; diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index ff4f09804865..d8f9e94ae475 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -78,6 +78,7 @@ #include <linux/sysctl.h> #include <linux/wait.h> #include <linux/bcd.h> +#include <linux/delay.h> #include <asm/current.h> #include <asm/uaccess.h> @@ -894,7 +895,6 @@ static int __init rtc_init(void) struct proc_dir_entry *ent; #if defined(__alpha__) || defined(__mips__) unsigned int year, ctrl; - unsigned long uip_watchdog; char *guess = NULL; #endif #ifdef __sparc__ @@ -1000,12 +1000,8 @@ no_irq: /* Each operating system on an Alpha uses its own epoch. Let's try to guess which one we are using now. */ - uip_watchdog = jiffies; if (rtc_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) { - barrier(); - cpu_relax(); - } + msleep(20); spin_lock_irq(&rtc_lock); year = CMOS_READ(RTC_YEAR); @@ -1213,7 +1209,6 @@ static int rtc_proc_open(struct inode *inode, struct file *file) void rtc_get_rtc_time(struct rtc_time *rtc_tm) { - unsigned long uip_watchdog = jiffies; unsigned char ctrl; #ifdef CONFIG_MACH_DECSTATION unsigned int real_year; @@ -1221,7 +1216,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) /* * read RTC once any update in progress is done. The update - * can take just over 2ms. We wait 10 to 20ms. There is no need to + * can take just over 2ms. We wait 20ms. There is no need to * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. * If you need to know *exactly* when a second has started, enable * periodic update complete interrupts, (via ioctl) and then @@ -1230,10 +1225,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) */ if (rtc_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) { - barrier(); - cpu_relax(); - } + msleep(20); /* * Only the values that we read from the RTC are set. We leave diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 659335d80ee7..ec78d2f161f7 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c @@ -396,7 +396,7 @@ static struct file_operations tipar_fops = { static int __init tipar_setup(char *str) { - int ints[2]; + int ints[3]; str = get_options(str, ARRAY_SIZE(ints), ints); diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 854475c54f0e..049d128ae7f0 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -464,7 +464,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) pci_set_drvdata(pci_dev, NULL); misc_deregister(&chip->vendor->miscdev); - kfree(&chip->vendor->miscdev.name); + kfree(chip->vendor->miscdev.name); sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 58597993954f..f19cf9d7792d 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, ld = tty_ldisc_ref(tty); switch (arg) { case TCIFLUSH: - if (ld->flush_buffer) + if (ld && ld->flush_buffer) ld->flush_buffer(tty); break; case TCIOFLUSH: - if (ld->flush_buffer) + if (ld && ld->flush_buffer) ld->flush_buffer(tty); /* fall through */ case TCOFLUSH: diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 8971484b956b..1d44f69e1fda 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -25,6 +25,7 @@ #include <linux/fs.h> #include <linux/console.h> #include <linux/signal.h> +#include <linux/timex.h> #include <asm/io.h> #include <asm/uaccess.h> @@ -386,7 +387,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, if (!perm) return -EPERM; if (arg) - arg = 1193182 / arg; + arg = CLOCK_TICK_RATE / arg; kd_mksound(arg, 0); return 0; @@ -403,7 +404,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ticks = HZ * ((arg >> 16) & 0xffff) / 1000; count = ticks ? (arg & 0xffff) : 0; if (count) - count = 1193182 / count; + count = CLOCK_TICK_RATE / count; kd_mksound(count, ticks); return 0; } diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c index b14d642439ed..5d07ee59679d 100644 --- a/drivers/char/watchdog/i8xx_tco.c +++ b/drivers/char/watchdog/i8xx_tco.c @@ -401,7 +401,7 @@ static unsigned char __init i8xx_tco_getdevice (void) */ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (pci_match_device(i8xx_tco_pci_tbl, dev)) { + if (pci_match_id(i8xx_tco_pci_tbl, dev)) { i8xx_tco_pci = dev; break; } diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c index 4e98c215e5b1..4b039516cc86 100644 --- a/drivers/char/watchdog/ixp2000_wdt.c +++ b/drivers/char/watchdog/ixp2000_wdt.c @@ -162,7 +162,7 @@ ixp2000_wdt_release(struct inode *inode, struct file *file) if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { wdt_disable(); } else { - printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - " + printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " "timer will not stop\n"); } diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c index 82396e06c8a8..83df369113a4 100644 --- a/drivers/char/watchdog/ixp4xx_wdt.c +++ b/drivers/char/watchdog/ixp4xx_wdt.c @@ -156,7 +156,7 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file) if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { wdt_disable(); } else { - printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - " + printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " "timer will not stop\n"); } diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index ed708b4427b0..71407c578afe 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -49,6 +49,7 @@ #include <linux/errno.h> #include <linux/crypto.h> #include <linux/interrupt.h> +#include <linux/kernel.h> #include <asm/byteorder.h> #include "padlock.h" @@ -59,8 +60,12 @@ #define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t)) struct aes_ctx { - uint32_t e_data[AES_EXTENDED_KEY_SIZE+4]; - uint32_t d_data[AES_EXTENDED_KEY_SIZE+4]; + uint32_t e_data[AES_EXTENDED_KEY_SIZE]; + uint32_t d_data[AES_EXTENDED_KEY_SIZE]; + struct { + struct cword encrypt; + struct cword decrypt; + } cword; uint32_t *E; uint32_t *D; int key_length; @@ -280,10 +285,15 @@ aes_hw_extkey_available(uint8_t key_len) return 0; } +static inline struct aes_ctx *aes_ctx(void *ctx) +{ + return (struct aes_ctx *)ALIGN((unsigned long)ctx, PADLOCK_ALIGNMENT); +} + static int aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags) { - struct aes_ctx *ctx = ctx_arg; + struct aes_ctx *ctx = aes_ctx(ctx_arg); uint32_t i, t, u, v, w; uint32_t P[AES_EXTENDED_KEY_SIZE]; uint32_t rounds; @@ -295,25 +305,36 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t ctx->key_length = key_len; + /* + * If the hardware is capable of generating the extended key + * itself we must supply the plain key for both encryption + * and decryption. + */ ctx->E = ctx->e_data; - ctx->D = ctx->d_data; - - /* Ensure 16-Bytes alignmentation of keys for VIA PadLock. */ - if ((int)(ctx->e_data) & 0x0F) - ctx->E += 4 - (((int)(ctx->e_data) & 0x0F) / sizeof (ctx->e_data[0])); - - if ((int)(ctx->d_data) & 0x0F) - ctx->D += 4 - (((int)(ctx->d_data) & 0x0F) / sizeof (ctx->d_data[0])); + ctx->D = ctx->e_data; E_KEY[0] = uint32_t_in (in_key); E_KEY[1] = uint32_t_in (in_key + 4); E_KEY[2] = uint32_t_in (in_key + 8); E_KEY[3] = uint32_t_in (in_key + 12); + /* Prepare control words. */ + memset(&ctx->cword, 0, sizeof(ctx->cword)); + + ctx->cword.decrypt.encdec = 1; + ctx->cword.encrypt.rounds = 10 + (key_len - 16) / 4; + ctx->cword.decrypt.rounds = ctx->cword.encrypt.rounds; + ctx->cword.encrypt.ksize = (key_len - 16) / 8; + ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize; + /* Don't generate extended keys if the hardware can do it. */ if (aes_hw_extkey_available(key_len)) return 0; + ctx->D = ctx->d_data; + ctx->cword.encrypt.keygen = 1; + ctx->cword.decrypt.keygen = 1; + switch (key_len) { case 16: t = E_KEY[3]; @@ -369,10 +390,9 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t /* ====== Encryption/decryption routines ====== */ -/* This is the real call to PadLock. */ -static inline void -padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key, - void *control_word, uint32_t count) +/* These are the real call to PadLock. */ +static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, + void *control_word, u32 count) { asm volatile ("pushfl; popfl"); /* enforce key reload. */ asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ @@ -380,60 +400,70 @@ padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key, : "d"(control_word), "b"(key), "c"(count)); } -static void -aes_padlock(void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg, int encdec) +static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, + u8 *iv, void *control_word, u32 count) { - /* Don't blindly modify this structure - the items must - fit on 16-Bytes boundaries! */ - struct padlock_xcrypt_data { - uint8_t buf[AES_BLOCK_SIZE]; - union cword cword; - }; - - struct aes_ctx *ctx = ctx_arg; - char bigbuf[sizeof(struct padlock_xcrypt_data) + 16]; - struct padlock_xcrypt_data *data; - void *key; - - /* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */ - if (((long)bigbuf) & 0x0F) - data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F)); - else - data = (void*)bigbuf; - - /* Prepare Control word. */ - memset (data, 0, sizeof(struct padlock_xcrypt_data)); - data->cword.b.encdec = !encdec; /* in the rest of cryptoapi ENC=1/DEC=0 */ - data->cword.b.rounds = 10 + (ctx->key_length - 16) / 4; - data->cword.b.ksize = (ctx->key_length - 16) / 8; - - /* Is the hardware capable to generate the extended key? */ - if (!aes_hw_extkey_available(ctx->key_length)) - data->cword.b.keygen = 1; - - /* ctx->E starts with a plain key - if the hardware is capable - to generate the extended key itself we must supply - the plain key for both Encryption and Decryption. */ - if (encdec == CRYPTO_DIR_ENCRYPT || data->cword.b.keygen == 0) - key = ctx->E; - else - key = ctx->D; - - memcpy(data->buf, in_arg, AES_BLOCK_SIZE); - padlock_xcrypt_ecb(data->buf, data->buf, key, &data->cword, 1); - memcpy(out_arg, data->buf, AES_BLOCK_SIZE); + /* Enforce key reload. */ + asm volatile ("pushfl; popfl"); + /* rep xcryptcbc */ + asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" + : "+S" (input), "+D" (output), "+a" (iv) + : "d" (control_word), "b" (key), "c" (count)); + return iv; } static void aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) { - aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT); + struct aes_ctx *ctx = aes_ctx(ctx_arg); + padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1); } static void aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) { - aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT); + struct aes_ctx *ctx = aes_ctx(ctx_arg); + padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1); +} + +static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, + const u8 *in, unsigned int nbytes) +{ + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); + padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, + nbytes / AES_BLOCK_SIZE); + return nbytes & ~(AES_BLOCK_SIZE - 1); +} + +static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, + const u8 *in, unsigned int nbytes) +{ + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); + padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, + nbytes / AES_BLOCK_SIZE); + return nbytes & ~(AES_BLOCK_SIZE - 1); +} + +static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, + const u8 *in, unsigned int nbytes) +{ + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); + u8 *iv; + + iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info, + &ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE); + memcpy(desc->info, iv, AES_BLOCK_SIZE); + + return nbytes & ~(AES_BLOCK_SIZE - 1); +} + +static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, + const u8 *in, unsigned int nbytes) +{ + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); + padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt, + nbytes / AES_BLOCK_SIZE); + return nbytes & ~(AES_BLOCK_SIZE - 1); } static struct crypto_alg aes_alg = { @@ -441,6 +471,7 @@ static struct crypto_alg aes_alg = { .cra_flags = CRYPTO_ALG_TYPE_CIPHER, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct aes_ctx), + .cra_alignmask = PADLOCK_ALIGNMENT - 1, .cra_module = THIS_MODULE, .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), .cra_u = { @@ -449,7 +480,11 @@ static struct crypto_alg aes_alg = { .cia_max_keysize = AES_MAX_KEY_SIZE, .cia_setkey = aes_set_key, .cia_encrypt = aes_encrypt, - .cia_decrypt = aes_decrypt + .cia_decrypt = aes_decrypt, + .cia_encrypt_ecb = aes_encrypt_ecb, + .cia_decrypt_ecb = aes_decrypt_ecb, + .cia_encrypt_cbc = aes_encrypt_cbc, + .cia_decrypt_cbc = aes_decrypt_cbc, } } }; diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h index 7a500605e449..3cf2b7a12348 100644 --- a/drivers/crypto/padlock.h +++ b/drivers/crypto/padlock.h @@ -13,18 +13,18 @@ #ifndef _CRYPTO_PADLOCK_H #define _CRYPTO_PADLOCK_H +#define PADLOCK_ALIGNMENT 16 + /* Control word. */ -union cword { - uint32_t cword[4]; - struct { - int rounds:4; - int algo:3; - int keygen:1; - int interm:1; - int encdec:1; - int ksize:2; - } b; -}; +struct cword { + int __attribute__ ((__packed__)) + rounds:4, + algo:3, + keygen:1, + interm:1, + encdec:1, + ksize:2; +} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT))); #define PFX "padlock: " diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index 839b44a7e08b..53c95c0bbf46 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c @@ -16,6 +16,7 @@ #include <linux/console.h> #include <linux/efi.h> #include <linux/serial.h> +#include <asm/vga.h> #include "pcdp.h" static int __init @@ -40,10 +41,27 @@ setup_serial_console(struct pcdp_uart *uart) } static int __init -setup_vga_console(struct pcdp_vga *vga) +setup_vga_console(struct pcdp_device *dev) { #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) { + u8 *if_ptr; + + if_ptr = ((u8 *)dev + sizeof(struct pcdp_device)); + if (if_ptr[0] == PCDP_IF_PCI) { + struct pcdp_if_pci if_pci; + + /* struct copy since ifptr might not be correctly aligned */ + + memcpy(&if_pci, if_ptr, sizeof(if_pci)); + + if (if_pci.trans & PCDP_PCI_TRANS_IOPORT) + vga_console_iobase = if_pci.ioport_tra; + + if (if_pci.trans & PCDP_PCI_TRANS_MMIO) + vga_console_membase = if_pci.mmio_tra; + } + + if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) { printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n"); return -ENODEV; } @@ -95,7 +113,7 @@ efi_setup_pcdp_console(char *cmdline) dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) { if (dev->flags & PCDP_PRIMARY_CONSOLE) { if (dev->type == PCDP_CONSOLE_VGA) { - return setup_vga_console((struct pcdp_vga *) dev); + return setup_vga_console(dev); } } } diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h index 1dc7c88b7b4d..e72cc47de33b 100644 --- a/drivers/firmware/pcdp.h +++ b/drivers/firmware/pcdp.h @@ -52,11 +52,34 @@ struct pcdp_uart { u32 clock_rate; u8 pci_prog_intfc; u8 flags; -}; +} __attribute__((packed)); + +#define PCDP_IF_PCI 1 + +/* pcdp_if_pci.trans */ +#define PCDP_PCI_TRANS_IOPORT 0x02 +#define PCDP_PCI_TRANS_MMIO 0x01 + +struct pcdp_if_pci { + u8 interconnect; + u8 reserved; + u16 length; + u8 segment; + u8 bus; + u8 dev; + u8 fun; + u16 dev_id; + u16 vendor_id; + u32 acpi_interrupt; + u64 mmio_tra; + u64 ioport_tra; + u8 flags; + u8 trans; +} __attribute__((packed)); struct pcdp_vga { u8 count; /* address space descriptors */ -}; +} __attribute__((packed)); /* pcdp_device.flags */ #define PCDP_PRIMARY_CONSOLE 1 @@ -66,7 +89,9 @@ struct pcdp_device { u8 flags; u16 length; u16 efi_index; -}; + /* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */ + /* next data is device specific type (currently only pcdp_vga) */ +} __attribute__((packed)); struct pcdp { u8 signature[4]; @@ -81,4 +106,4 @@ struct pcdp { u32 num_uarts; struct pcdp_uart uart[0]; /* actual size is num_uarts */ /* remainder of table is pcdp_device structures */ -}; +} __attribute__((packed)); diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index 363e545fc01f..94ae808314f7 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -698,7 +698,7 @@ dispose_iface(struct device *dev) } static int -create_iface_macio(struct macio_dev* dev, const struct of_match *match) +create_iface_macio(struct macio_dev* dev, const struct of_device_id *match) { return create_iface(dev->ofdev.node, &dev->ofdev.dev); } @@ -710,7 +710,7 @@ dispose_iface_macio(struct macio_dev* dev) } static int -create_iface_of_platform(struct of_device* dev, const struct of_match *match) +create_iface_of_platform(struct of_device* dev, const struct of_device_id *match) { return create_iface(dev->node, &dev->dev); } @@ -721,10 +721,9 @@ dispose_iface_of_platform(struct of_device* dev) return dispose_iface(&dev->dev); } -static struct of_match i2c_keywest_match[] = +static struct of_device_id i2c_keywest_match[] = { { - .name = OF_ANY_MATCH, .type = "i2c", .compatible = "keywest" }, diff --git a/drivers/i2c/chips/atxp1.c b/drivers/i2c/chips/atxp1.c index 5c6597aa2c7f..0bcf82b4c07b 100644 --- a/drivers/i2c/chips/atxp1.c +++ b/drivers/i2c/chips/atxp1.c @@ -144,7 +144,7 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att if (vid == cvid) return count; - dev_info(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid); + dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid); /* Write every 25 mV step to increase stability */ if (cvid > vid) { diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 5be8ad6dc9ed..cca9c075966d 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -20,7 +20,6 @@ ide-core-$(CONFIG_BLK_DEV_CMD640) += pci/cmd640.o # Core IDE code - must come before legacy ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o -ide-core-$(CONFIG_BLK_DEV_IDE_TCQ) += ide-tcq.o ide-core-$(CONFIG_PROC_FS) += ide-proc.o ide-core-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 6806d407e9c1..b09a6537c7a8 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -487,8 +487,7 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) u8 err = 0; local_irq_set(flags); - printk("%s: %s: status=0x%02x", drive->name, msg, stat); - printk(" { "); + printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); if (stat & BUSY_STAT) printk("Busy "); else { @@ -500,15 +499,13 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) if (stat & INDEX_STAT) printk("Index "); if (stat & ERR_STAT) printk("Error "); } - printk("}"); - printk("\n"); + printk("}\n"); if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { err = hwif->INB(IDE_ERROR_REG); - printk("%s: %s: error=0x%02x", drive->name, msg, err); - printk(" { "); + printk("%s: %s: error=0x%02x { ", drive->name, msg, err); if (err & ABRT_ERR) printk("DriveStatusError "); if (err & ICRC_ERR) - printk("Bad%s ", (err & ABRT_ERR) ? "CRC" : "Sector"); + printk((err & ABRT_ERR) ? "BadCRC " : "BadSector "); if (err & ECC_ERR) printk("UncorrectableError "); if (err & ID_ERR) printk("SectorIdNotFound "); if (err & TRK0_ERR) printk("TrackZeroNotFound "); @@ -546,8 +543,8 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) printk(", sector=%llu", (unsigned long long)HWGROUP(drive)->rq->sector); } + printk("\n"); } - printk("\n"); ide_dump_opcode(drive); local_irq_restore(flags); return err; diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index e884cd4b22fd..242029c9c0ca 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c @@ -156,11 +156,13 @@ else \ #if (HD_DELAY > 0) + +#include <asm/i8253.h> + unsigned long last_req; unsigned long read_timer(void) { - extern spinlock_t i8253_lock; unsigned long t, flags; int i; diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 67efb38a9f6c..6cf49394a80f 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -583,7 +583,7 @@ static int ali15x3_dma_setup(ide_drive_t *drive) * appropriate also sets up the 1533 southbridge. */ -static unsigned int __init init_chipset_ali15x3 (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const char *name) { unsigned long flags; u8 tmpbyte; @@ -677,7 +677,7 @@ static unsigned int __init init_chipset_ali15x3 (struct pci_dev *dev, const char * FIXME: frobs bits that are not defined on newer ALi devicea */ -static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) +static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned int ata66 = 0; @@ -748,7 +748,7 @@ static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) * Initialize the IDE structure side of the ALi 15x3 driver. */ -static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif) +static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) { hwif->autodma = 0; hwif->tuneproc = &ali15x3_tune_drive; @@ -794,7 +794,7 @@ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif) * Sparc systems */ -static void __init init_hwif_ali15x3 (ide_hwif_t *hwif) +static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) { u8 ideic, inmir; s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, @@ -847,7 +847,7 @@ static void __init init_hwif_ali15x3 (ide_hwif_t *hwif) * the actual work. */ -static void __init init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase) +static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase) { if (m5229_revision < 0x20) return; diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 4e0f13d1d060..844a6c9fb949 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -73,6 +73,7 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, { 0 } }; @@ -309,7 +310,7 @@ static int amd74xx_ide_dma_check(ide_drive_t *drive) * and initialize its drive independent registers. */ -static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const char *name) { unsigned char t; unsigned int u; @@ -413,7 +414,7 @@ static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char return dev->irq; } -static void __init init_hwif_amd74xx(ide_hwif_t *hwif) +static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) { int i; @@ -489,6 +490,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), + /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -524,6 +526,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 0381961db263..09269e574b3e 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -217,7 +217,7 @@ static int cs5530_config_dma (ide_drive_t *drive) * Initialize the cs5530 bridge for reliable IDE DMA operation. */ -static unsigned int __init init_chipset_cs5530 (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name) { struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; unsigned long flags; @@ -308,7 +308,7 @@ static unsigned int __init init_chipset_cs5530 (struct pci_dev *dev, const char * performs channel-specific pre-initialization before drive probing. */ -static void __init init_hwif_cs5530 (ide_hwif_t *hwif) +static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) { unsigned long basereg; u32 d0_timings; diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 80d67e99ccb5..5a33513f3dd1 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -391,7 +391,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio) /* * this function is called during init and is used to setup the cy82c693 chip */ -static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const char *name) { if (PCI_FUNC(dev->devfn) != 1) return 0; @@ -443,7 +443,7 @@ static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char /* * the init function - called for each ide channel once */ -static void __init init_hwif_cy82c693(ide_hwif_t *hwif) +static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) { hwif->autodma = 0; @@ -467,9 +467,9 @@ static void __init init_hwif_cy82c693(ide_hwif_t *hwif) hwif->drives[1].autodma = hwif->autodma; } -static __initdata ide_hwif_t *primary; +static __devinitdata ide_hwif_t *primary; -void __init init_iops_cy82c693(ide_hwif_t *hwif) +void __devinit init_iops_cy82c693(ide_hwif_t *hwif) { if (PCI_FUNC(hwif->pci_dev->devfn) == 1) primary = hwif; diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c index 631927cf17d4..93462926b9d5 100644 --- a/drivers/ide/pci/it8172.c +++ b/drivers/ide/pci/it8172.c @@ -216,7 +216,7 @@ fast_ata_pio: return 0; } -static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name) { unsigned char progif; @@ -230,7 +230,7 @@ static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char } -static void __init init_hwif_it8172 (ide_hwif_t *hwif) +static void __devinit init_hwif_it8172 (ide_hwif_t *hwif) { struct pci_dev* dev = hwif->pci_dev; unsigned long cmdBase, ctrlBase; diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 205a32fbc2f0..fcd5142f5cfe 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -195,7 +195,7 @@ static int ns87415_ide_dma_check (ide_drive_t *drive) return __ide_dma_check(drive); } -static void __init init_hwif_ns87415 (ide_hwif_t *hwif) +static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned int ctrl, using_inta; diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index cf4fd91d396a..7a7c2ef78ac2 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c @@ -326,7 +326,7 @@ static void opti621_tune_drive (ide_drive_t *drive, u8 pio) /* * init_hwif_opti621() is called once for each hwif found at boot. */ -static void __init init_hwif_opti621 (ide_hwif_t *hwif) +static void __devinit init_hwif_opti621 (ide_hwif_t *hwif) { hwif->autodma = 0; hwif->drives[0].drive_data = PIO_DONT_KNOW; diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 3bc3bf1be49b..10592cec6c43 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -459,7 +459,7 @@ printk("%s: SC1200: resume\n", hwif->name); * This gets invoked by the IDE driver once for each channel, * and performs channel-specific pre-initialization before drive probing. */ -static void __init init_hwif_sc1200 (ide_hwif_t *hwif) +static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) { if (hwif->mate) hwif->serialized = hwif->mate->serialized = 1; diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 1d970a0de21a..ea0806c82be0 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -386,7 +386,7 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) * channel 0 here at least, but channel 1 has to be enabled by * firmware or arch code. We still set both to 16 bits mode. */ -static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char *msg) +static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const char *msg) { u32 val; @@ -399,7 +399,7 @@ static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char return dev->irq; } -static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) +static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) { unsigned int rev; u8 dma_state; @@ -431,7 +431,7 @@ static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) * Initialise the chip */ -static void __init init_hwif_sl82c105(ide_hwif_t *hwif) +static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; u32 val; diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 7fbf36342f73..5112c726633b 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -196,7 +196,7 @@ fast_ata_pio: } #endif /* CONFIG_BLK_DEV_IDEDMA */ -static void __init init_hwif_slc90e66 (ide_hwif_t *hwif) +static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) { u8 reg47 = 0; u8 mask = hwif->channel ? 0x01 : 0x02; /* bit0:Primary */ diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index a1df2bfe3631..f96b56838f33 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -130,7 +130,7 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive) return hwif->ide_dma_off_quietly(drive); } -static void __init init_hwif_triflex(ide_hwif_t *hwif) +static void __devinit init_hwif_triflex(ide_hwif_t *hwif) { hwif->tuneproc = &triflex_tune_drive; hwif->speedproc = &triflex_tune_chipset; diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 069dbffe2116..a4d099c937ff 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -415,7 +415,7 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive) * and initialize its drive independent registers. */ -static unsigned int __init init_chipset_via82cxxx(struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) { struct pci_dev *isa = NULL; u8 t, v; @@ -576,7 +576,7 @@ static unsigned int __init init_chipset_via82cxxx(struct pci_dev *dev, const cha return 0; } -static void __init init_hwif_via82cxxx(ide_hwif_t *hwif) +static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) { int i; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 818380b5fd27..be0fcc8f4b15 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1419,7 +1419,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) * Attach to a macio probed interface */ static int __devinit -pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_match *match) +pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) { void __iomem *base; unsigned long regbase; @@ -1637,27 +1637,19 @@ pmac_ide_pci_resume(struct pci_dev *pdev) return rc; } -static struct of_match pmac_ide_macio_match[] = +static struct of_device_id pmac_ide_macio_match[] = { { .name = "IDE", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, { .name = "ATA", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, { - .name = OF_ANY_MATCH, .type = "ide", - .compatible = OF_ANY_MATCH }, { - .name = OF_ANY_MATCH, .type = "ata", - .compatible = OF_ANY_MATCH }, {}, }; diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index e501675ad72e..77da827b2898 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -847,7 +847,7 @@ static int __init ide_scan_pcidev(struct pci_dev *dev) d = list_entry(l, struct pci_driver, node); if(d->id_table) { - const struct pci_device_id *id = pci_match_device(d->id_table, dev); + const struct pci_device_id *id = pci_match_id(d->id_table, dev); if(id != NULL) { if(d->probe(dev, id) >= 0) diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index 73bd8efd2b6c..0b31429d0a68 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h @@ -38,8 +38,8 @@ struct hpsb_packet { /* These are core internal. */ signed char tlabel; - char ack_code; - char tcode; + signed char ack_code; + unsigned char tcode; unsigned expect_response:1; unsigned no_waiter:1; diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 3e72c9b1461e..ab09cf4093e3 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -60,12 +60,13 @@ static void gameport_disconnect_port(struct gameport *gameport); #if defined(__i386__) +#include <asm/i8253.h> + #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) #define GET_TIME(x) do { x = get_time_pit(); } while (0) static unsigned int get_time_pit(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 504b7d550567..c3a5739030c3 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -140,12 +140,14 @@ struct analog_port { */ #ifdef __i386__ + +#include <asm/i8253.h> + #define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0) #define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0))) #define TIME_NAME (cpu_has_tsc?"TSC":"PIT") static unsigned int get_time_pit(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c index 6e548a222ef1..89497890158d 100644 --- a/drivers/isdn/hardware/eicon/dadapter.c +++ b/drivers/isdn/hardware/eicon/dadapter.c @@ -44,7 +44,7 @@ static didd_adapter_change_notification_t\ Array to held adapter information -------------------------------------------------------------------------- */ static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS]; -dword Adapters = 0; /* Number of adapters */ +static dword Adapters = 0; /* Number of adapters */ /* -------------------------------------------------------------------------- Shadow IDI_DIMAINT and 'shadow' debug stuff diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index 6e7e060716b7..7333377ab31d 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c @@ -312,7 +312,7 @@ wait_busy(hfc4s8s_hw * a) /* function to read critical counter registers that */ /* may be udpated by the chip during read */ /******************************************************/ -static volatile u_char +static u_char Read_hfc8_stable(hfc4s8s_hw * hw, int reg) { u_char ref8; @@ -324,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg) return in8; } -static volatile int +static int Read_hfc16_stable(hfc4s8s_hw * hw, int reg) { int ref16; @@ -1465,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode) /******************************************/ /* disable memory mapped ports / io ports */ /******************************************/ -void +static void release_pci_ports(hfc4s8s_hw * hw) { pci_write_config_word(hw->pdev, PCI_COMMAND, 0); @@ -1481,7 +1481,7 @@ release_pci_ports(hfc4s8s_hw * hw) /*****************************************/ /* enable memory mapped ports / io ports */ /*****************************************/ -void +static void enable_pci_ports(hfc4s8s_hw * hw) { #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index 8ee25b2ccce1..1fd3d4e5f284 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c @@ -42,6 +42,8 @@ typedef struct _hycapi_appl { static hycapi_appl hycapi_applications[CAPI_MAXAPPL]; +static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); + static inline int _hycapi_appCheck(int app_id, int ctrl_no) { if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) || @@ -57,7 +59,7 @@ static inline int _hycapi_appCheck(int app_id, int ctrl_no) Kernel-Capi callback reset_ctr ******************************/ -void +static void hycapi_reset_ctr(struct capi_ctr *ctrl) { hycapictrl_info *cinfo = ctrl->driverdata; @@ -73,7 +75,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl) Kernel-Capi callback remove_ctr ******************************/ -void +static void hycapi_remove_ctr(struct capi_ctr *ctrl) { int i; @@ -215,7 +217,7 @@ Error-checking is done for CAPI-compliance. The application is recorded in the internal list. *************************************************************/ -void +static void hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) { @@ -291,7 +293,7 @@ Release the application from the internal list an remove it's registration at controller-level ******************************************************************/ -void +static void hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl) { int chk; @@ -364,7 +366,7 @@ firmware-releases that do not check the MsgLen-Indication! ***************************************************************/ -u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) +static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) { __u16 appl_id; int _len, _len2; @@ -437,8 +439,8 @@ Informations provided in the /proc/capi-entries. *********************************************************************/ -int hycapi_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *ctrl) +static int hycapi_read_proc(char *page, char **start, off_t off, + int count, int *eof, struct capi_ctr *ctrl) { hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); hysdn_card *card = cinfo->card; @@ -485,7 +487,7 @@ on capi-interface registration. **************************************************************/ -int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) +static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) { #ifdef HYCAPI_PRINTFNAMES printk(KERN_NOTICE "hycapi_load_firmware\n"); @@ -494,7 +496,7 @@ int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) } -char *hycapi_procinfo(struct capi_ctr *ctrl) +static char *hycapi_procinfo(struct capi_ctr *ctrl) { hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); #ifdef HYCAPI_PRINTFNAMES diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c index 6c04281e57b8..7bfba196f315 100644 --- a/drivers/isdn/hysdn/hysdn_boot.c +++ b/drivers/isdn/hysdn/hysdn_boot.c @@ -53,7 +53,7 @@ struct boot_data { /* to be called at start of POF file reading, */ /* before starting any decryption on any POF record. */ /*****************************************************/ -void +static void StartDecryption(struct boot_data *boot) { boot->Cryptor = CRYPT_STARTTERM; @@ -66,7 +66,7 @@ StartDecryption(struct boot_data *boot) /* to HI and LO boot loader and (all) seq tags, because */ /* global Cryptor is started for whole POF. */ /***************************************************************/ -void +static void DecryptBuf(struct boot_data *boot, int cnt) { uchar *bufp = boot->buf.BootBuf; diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h index 4cee26e558ee..432f6f99089e 100644 --- a/drivers/isdn/hysdn/hysdn_defs.h +++ b/drivers/isdn/hysdn/hysdn_defs.h @@ -227,7 +227,6 @@ typedef struct hycapictrl_info hycapictrl_info; /*****************/ /* exported vars */ /*****************/ -extern int cardmax; /* number of found cards */ extern hysdn_card *card_root; /* pointer to first card */ @@ -244,7 +243,6 @@ extern void hysdn_procconf_release(void); /* deinit proc config filesys */ /* hysdn_proclog.c */ extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */ extern void hysdn_proclog_release(hysdn_card *); /* deinit proc log entry */ -extern void put_log_buffer(hysdn_card *, char *); /* output log data */ extern void hysdn_addlog(hysdn_card *, char *,...); /* output data to log */ extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int); /* output card log */ @@ -278,16 +276,6 @@ extern unsigned int hycapi_enable; extern int hycapi_capi_create(hysdn_card *); /* create a new capi device */ extern int hycapi_capi_release(hysdn_card *); /* delete the device */ extern int hycapi_capi_stop(hysdn_card *card); /* suspend */ -extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *); -extern void hycapi_reset_ctr(struct capi_ctr *); -extern void hycapi_remove_ctr(struct capi_ctr *); -extern void hycapi_register_appl(struct capi_ctr *, __u16 appl, - capi_register_params *); -extern void hycapi_release_appl(struct capi_ctr *, __u16 appl); -extern u16 hycapi_send_message(struct capi_ctr *, struct sk_buff *skb); -extern char *hycapi_procinfo(struct capi_ctr *); -extern int hycapi_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *card); extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len); extern void hycapi_tx_capiack(hysdn_card * card); extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card); diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c index 5cac2bf5f4b0..12c8137b5161 100644 --- a/drivers/isdn/hysdn/hysdn_init.c +++ b/drivers/isdn/hysdn/hysdn_init.c @@ -34,7 +34,7 @@ MODULE_AUTHOR("Werner Cornelius"); MODULE_LICENSE("GPL"); static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; -int cardmax; /* number of found cards */ +static int cardmax; /* number of found cards */ hysdn_card *card_root = NULL; /* pointer to first card */ /**********************************************/ diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index 8ef2b7c952a6..4d57011c5737 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -22,6 +22,8 @@ /* the proc subdir for the interface is defined in the procconf module */ extern struct proc_dir_entry *hysdn_proc_entry; +static void put_log_buffer(hysdn_card * card, char *cp); + /*************************************************/ /* structure keeping ascii log for device output */ /*************************************************/ @@ -93,7 +95,7 @@ hysdn_addlog(hysdn_card * card, char *fmt,...) /* opened for read got the contents. */ /* Flushes buffers not longer in use. */ /********************************************/ -void +static void put_log_buffer(hysdn_card * card, char *cp) { struct log_data *ib; diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index f5ae171dbfef..236291bd48a4 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -4,7 +4,7 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_PPC_PMAC) += macio_asic.o +obj-$(CONFIG_PPC_PMAC) += macio_asic.o macio_sysfs.o obj-$(CONFIG_PMAC_MEDIABAY) += mediabay.o obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index d0bda7e3e6aa..1ee003346923 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -33,7 +33,7 @@ static int macio_bus_match(struct device *dev, struct device_driver *drv) { struct macio_dev * macio_dev = to_macio_device(dev); struct macio_driver * macio_drv = to_macio_driver(drv); - const struct of_match * matches = macio_drv->match_table; + const struct of_device_id * matches = macio_drv->match_table; if (!matches) return 0; @@ -66,7 +66,7 @@ static int macio_device_probe(struct device *dev) int error = -ENODEV; struct macio_driver *drv; struct macio_dev *macio_dev; - const struct of_match *match; + const struct of_device_id *match; drv = to_macio_driver(dev->driver); macio_dev = to_macio_device(dev); @@ -126,11 +126,85 @@ static int macio_device_resume(struct device * dev) return 0; } +static int macio_hotplug (struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) +{ + struct macio_dev * macio_dev; + struct of_device * of; + char *scratch, *compat; + int i = 0; + int length = 0; + int cplen, seen = 0; + + if (!dev) + return -ENODEV; + + macio_dev = to_macio_device(dev); + if (!macio_dev) + return -ENODEV; + + of = &macio_dev->ofdev; + scratch = buffer; + + /* stuff we want to pass to /sbin/hotplug */ + envp[i++] = scratch; + length += scnprintf (scratch, buffer_size - length, "OF_NAME=%s", + of->node->name); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i++] = scratch; + length += scnprintf (scratch, buffer_size - length, "OF_TYPE=%s", + of->node->type); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + /* Since the compatible field can contain pretty much anything + * it's not really legal to split it out with commas. We split it + * up using a number of environment variables instead. */ + + compat = (char *) get_property(of->node, "compatible", &cplen); + while (compat && cplen > 0) { + int l; + envp[i++] = scratch; + length += scnprintf (scratch, buffer_size - length, + "OF_COMPATIBLE_%d=%s", seen, compat); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + length++; + scratch += length; + l = strlen (compat) + 1; + compat += l; + cplen -= l; + seen++; + } + + envp[i++] = scratch; + length += scnprintf (scratch, buffer_size - length, + "OF_COMPATIBLE_N=%d", seen); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i] = NULL; + + return 0; +} + +extern struct device_attribute macio_dev_attrs[]; + struct bus_type macio_bus_type = { .name = "macio", .match = macio_bus_match, + .hotplug = macio_hotplug, .suspend = macio_device_suspend, .resume = macio_device_resume, + .dev_attrs = macio_dev_attrs, }; static int __init macio_bus_driver_init(void) diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c new file mode 100644 index 000000000000..97d22bb4516a --- /dev/null +++ b/drivers/macintosh/macio_sysfs.c @@ -0,0 +1,50 @@ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/stat.h> +#include <asm/macio.h> + + +#define macio_config_of_attr(field, format_string) \ +static ssize_t \ +field##_show (struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct macio_dev *mdev = to_macio_device (dev); \ + return sprintf (buf, format_string, mdev->ofdev.node->field); \ +} + +static ssize_t +compatible_show (struct device *dev, struct device_attribute *attr, char *buf) +{ + struct of_device *of; + char *compat; + int cplen; + int length = 0; + + of = &to_macio_device (dev)->ofdev; + compat = (char *) get_property(of->node, "compatible", &cplen); + if (!compat) { + *buf = '\0'; + return 0; + } + while (cplen > 0) { + int l; + length += sprintf (buf, "%s\n", compat); + buf += length; + l = strlen (compat) + 1; + compat += l; + cplen -= l; + } + + return length; +} + +macio_config_of_attr (name, "%s\n"); +macio_config_of_attr (type, "%s\n"); + +struct device_attribute macio_dev_attrs[] = { + __ATTR_RO(name), + __ATTR_RO(type), + __ATTR_RO(compatible), + __ATTR_NULL +}; diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 4be709e13eec..7c16c25fc5d4 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -642,7 +642,7 @@ static int __pmac media_bay_task(void *x) } } -static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_match *match) +static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match) { struct media_bay_info* bay; u32 __iomem *regbase; @@ -797,23 +797,20 @@ static struct mb_ops keylargo_mb_ops __pmacdata = { * Therefore we do it all by polling the media bay once each tick. */ -static struct of_match media_bay_match[] = +static struct of_device_id media_bay_match[] = { { .name = "media-bay", - .type = OF_ANY_MATCH, .compatible = "keylargo-media-bay", .data = &keylargo_mb_ops, }, { .name = "media-bay", - .type = OF_ANY_MATCH, .compatible = "heathrow-media-bay", .data = &heathrow_mb_ops, }, { .name = "media-bay", - .type = OF_ANY_MATCH, .compatible = "ohare-media-bay", .data = &ohare_mb_ops, }, diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index feb4e2413858..703e31973314 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -120,6 +120,7 @@ #include <asm/system.h> #include <asm/sections.h> #include <asm/of_device.h> +#include <asm/macio.h> #include "therm_pm72.h" @@ -1986,7 +1987,7 @@ static void fcu_lookup_fans(struct device_node *fcu_node) } } -static int fcu_of_probe(struct of_device* dev, const struct of_match *match) +static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match) { int rc; @@ -2009,12 +2010,10 @@ static int fcu_of_remove(struct of_device* dev) return 0; } -static struct of_match fcu_of_match[] = +static struct of_device_id fcu_match[] = { { - .name = OF_ANY_MATCH, .type = "fcu", - .compatible = OF_ANY_MATCH }, {}, }; @@ -2022,7 +2021,7 @@ static struct of_match fcu_of_match[] = static struct of_platform_driver fcu_of_platform_driver = { .name = "temperature", - .match_table = fcu_of_match, + .match_table = fcu_match, .probe = fcu_of_probe, .remove = fcu_of_remove }; diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 61400f04015e..cbb72eb0426d 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -43,6 +43,7 @@ #include <asm/system.h> #include <asm/sections.h> #include <asm/of_device.h> +#include <asm/macio.h> #define LOG_TEMP 0 /* continously log temperature */ @@ -450,7 +451,7 @@ do_probe( struct i2c_adapter *adapter, int addr, int kind ) /************************************************************************/ static int -therm_of_probe( struct of_device *dev, const struct of_match *match ) +therm_of_probe( struct of_device *dev, const struct of_device_id *match ) { return i2c_add_driver( &g4fan_driver ); } @@ -461,9 +462,8 @@ therm_of_remove( struct of_device *dev ) return i2c_del_driver( &g4fan_driver ); } -static struct of_match therm_of_match[] = {{ +static struct of_device_id therm_of_match[] = {{ .name = "fan", - .type = OF_ANY_MATCH, .compatible = "adm1030" }, {} }; diff --git a/drivers/md/md.c b/drivers/md/md.c index 3802f7a17f16..4a0c57db2b67 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -338,6 +338,7 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error) if (atomic_dec_and_test(&rdev->mddev->pending_writes)) wake_up(&rdev->mddev->sb_wait); + bio_put(bio); return 0; } diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c index 032d348dafb7..88e125079ca1 100644 --- a/drivers/media/dvb/frontends/tda80xx.c +++ b/drivers/media/dvb/frontends/tda80xx.c @@ -27,7 +27,6 @@ #include <linux/spinlock.h> #include <linux/threads.h> #include <linux/interrupt.h> -#include <linux/irq.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 2dc906fdfa55..810e7aac0a53 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -7,8 +7,7 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o -tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o - +tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 290289a99757..7d62b394c509 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -1,5 +1,5 @@ /* - $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $ + $Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $ bttv - Bt848 frame grabber driver @@ -76,6 +76,9 @@ static unsigned int whitecrush_upper = 0xCF; static unsigned int whitecrush_lower = 0x7F; static unsigned int vcr_hack = 0; static unsigned int irq_iswitch = 0; +static unsigned int uv_ratio = 50; +static unsigned int full_luma_range = 0; +static unsigned int coring = 0; /* API features (turn on/off stuff for testing) */ static unsigned int v4l2 = 1; @@ -106,6 +109,9 @@ module_param(adc_crush, int, 0444); module_param(whitecrush_upper, int, 0444); module_param(whitecrush_lower, int, 0444); module_param(vcr_hack, int, 0444); +module_param(uv_ratio, int, 0444); +module_param(full_luma_range, int, 0444); +module_param(coring, int, 0444); module_param_array(radio, int, NULL, 0444); @@ -124,6 +130,9 @@ MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127"); MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); +MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50"); +MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)"); +MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)"); MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards"); MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); @@ -484,7 +493,10 @@ static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats); #define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5) #define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6) #define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7) -#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 8) +#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8) +#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10) +#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11) static const struct v4l2_queryctrl no_ctl = { .name = "42", @@ -618,8 +630,32 @@ static const struct v4l2_queryctrl bttv_ctls[] = { .step = 1, .default_value = 0x7F, .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_PRIVATE_UV_RATIO, + .name = "uv ratio", + .minimum = 0, + .maximum = 100, + .step = 1, + .default_value = 50, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, + .name = "full luma range", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_PRIVATE_CORING, + .name = "coring", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + .type = V4L2_CTRL_TYPE_INTEGER, } + + }; static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); @@ -833,8 +869,8 @@ static void bt848_sat(struct bttv *btv, int color) btv->saturation = color; /* 0-511 for the color */ - val_u = color >> 7; - val_v = ((color>>7)*180L)/254; + val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; + val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; hibits = (val_u >> 7) & 2; hibits |= (val_v >> 8) & 1; btwrite(val_u & 0xff, BT848_SAT_U_LO); @@ -1151,6 +1187,15 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: c->value = btv->opt_whitecrush_lower; break; + case V4L2_CID_PRIVATE_UV_RATIO: + c->value = btv->opt_uv_ratio; + break; + case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: + c->value = btv->opt_full_luma_range; + break; + case V4L2_CID_PRIVATE_CORING: + c->value = btv->opt_coring; + break; default: return -EINVAL; } @@ -1247,6 +1292,18 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) btv->opt_whitecrush_lower = c->value; btwrite(c->value, BT848_WC_DOWN); break; + case V4L2_CID_PRIVATE_UV_RATIO: + btv->opt_uv_ratio = c->value; + bt848_sat(btv, btv->saturation); + break; + case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: + btv->opt_full_luma_range = c->value; + btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM); + break; + case V4L2_CID_PRIVATE_CORING: + btv->opt_coring = c->value; + btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM); + break; default: return -EINVAL; } @@ -3117,11 +3174,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; memset(v,0,sizeof(*v)); strcpy(v->name, "Radio"); - /* japan: 76.0 MHz - 89.9 MHz - western europe: 87.5 MHz - 108.0 MHz - russia: 65.0 MHz - 108.0 MHz */ - v->rangelow=(int)(65*16); - v->rangehigh=(int)(108*16); bttv_call_i2c_clients(btv,cmd,v); return 0; } @@ -3876,6 +3928,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, btv->opt_vcr_hack = vcr_hack; btv->opt_whitecrush_upper = whitecrush_upper; btv->opt_whitecrush_lower = whitecrush_lower; + btv->opt_uv_ratio = uv_ratio; + btv->opt_full_luma_range = full_luma_range; + btv->opt_coring = coring; /* fill struct bttv with some useful defaults */ btv->init.btv = btv; diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index 7b6f1e856028..f3293e4a15ad 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h @@ -1,5 +1,5 @@ /* - $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $ + $Id: bttvp.h,v 1.19 2005/06/16 21:38:45 nsh Exp $ bttv - Bt848 frame grabber driver @@ -326,6 +326,9 @@ struct bttv { int opt_vcr_hack; int opt_whitecrush_upper; int opt_whitecrush_lower; + int opt_uv_ratio; + int opt_full_luma_range; + int opt_coring; /* radio data/state */ int has_radio; diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index 95ad17b7f38e..9c005cb128d7 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c @@ -1,5 +1,5 @@ /* - * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $ + * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $ * * i2c tv tuner chip device driver * controls microtune tuners, mt2032 + mt2050 at the moment. @@ -295,8 +295,8 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq) int if2 = t->radio_if2; // per Manual for FM tuning: first if center freq. 1085 MHz - mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, - 1085*1000*1000,if2,if2,if2); + mt2032_set_if_freq(c, freq * 1000 / 16, + 1085*1000*1000,if2,if2,if2); } // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index b27cc348d95c..f59d4601cc63 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c @@ -1,5 +1,5 @@ /* - * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $ + * $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $ * * i2c tv tuner chip device driver * controls the philips tda8290+75 tuner chip combo. @@ -69,7 +69,7 @@ static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x04, 0xA3, 0x3F, + 0xfC, 0x04, 0xA3, 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; static unsigned char i2c_set_VS[2] = { 0x30, 0x6F }; @@ -138,16 +138,24 @@ static int tda8290_tune(struct i2c_client *c) static void set_frequency(struct tuner *t, u16 ifc) { - u32 N = (((t->freq<<3)+ifc)&0x3fffc); + u32 freq; + u32 N; - N = N >> get_freq_entry(div_table, t->freq); + if (t->mode == V4L2_TUNER_RADIO) + freq = t->freq / 1000; + else + freq = t->freq; + + N = (((freq<<3)+ifc)&0x3fffc); + + N = N >> get_freq_entry(div_table, freq); t->i2c_set_freq[0] = 0; t->i2c_set_freq[1] = (unsigned char)(N>>8); t->i2c_set_freq[2] = (unsigned char) N; t->i2c_set_freq[3] = 0x40; t->i2c_set_freq[4] = 0x52; - t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq); - t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq); + t->i2c_set_freq[5] = get_freq_entry(band_table, freq); + t->i2c_set_freq[6] = get_freq_entry(agc_table, freq); t->i2c_set_freq[7] = 0x8f; } diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 39773633cc3c..ee35562f4d1a 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -368,7 +368,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) if (t->radio_mode == V4L2_TUNER_MODE_MONO) norm = &radio_mono; else - norm = &radio_stereo; + norm = &radio_stereo; } else { for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { if (tvnorms[i].std & t->std) { @@ -566,7 +566,6 @@ static int tda9887_configure(struct tda9887 *t) if (UNSET != t->pinnacle_id) { tda9887_set_pinnacle(t,buf); } - tda9887_set_config(t,buf); tda9887_set_insmod(t,buf); @@ -615,8 +614,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) t->pinnacle_id = UNSET; t->radio_mode = V4L2_TUNER_MODE_STEREO; - i2c_set_clientdata(&t->client, t); - i2c_attach_client(&t->client); + i2c_set_clientdata(&t->client, t); + i2c_attach_client(&t->client); return 0; } diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c new file mode 100644 index 000000000000..a29f08f81f63 --- /dev/null +++ b/drivers/media/video/tea5767.c @@ -0,0 +1,334 @@ +/* + * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview + * I2C address is allways 0xC0. + * + * $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $ + * + * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) + * This code is placed under the terms of the GNU General Public License + * + * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa + * from their contributions on DScaler. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/videodev.h> +#include <linux/i2c.h> +#include <linux/i2c-algo-bit.h> + +#include <media/tuner.h> + +/* Declared at tuner-core.c */ +extern unsigned int tuner_debug; + +#define PREFIX "TEA5767 " + +/*****************************************************************************/ + +/****************************** + * Write mode register values * + ******************************/ + +/* First register */ +#define TEA5767_MUTE 0x80 /* Mutes output */ +#define TEA5767_SEARCH 0x40 /* Activates station search */ +/* Bits 0-5 for divider MSB */ + +/* Second register */ +/* Bits 0-7 for divider LSB */ + +/* Third register */ + +/* Station search from botton to up */ +#define TEA5767_SEARCH_UP 0x80 + +/* Searches with ADC output = 10 */ +#define TEA5767_SRCH_HIGH_LVL 0x60 + +/* Searches with ADC output = 10 */ +#define TEA5767_SRCH_MID_LVL 0x40 + +/* Searches with ADC output = 5 */ +#define TEA5767_SRCH_LOW_LVL 0x20 + +/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */ +#define TEA5767_HIGH_LO_INJECT 0x10 + +/* Disable stereo */ +#define TEA5767_MONO 0x08 + +/* Disable right channel and turns to mono */ +#define TEA5767_MUTE_RIGHT 0x04 + +/* Disable left channel and turns to mono */ +#define TEA5767_MUTE_LEFT 0x02 + +#define TEA5767_PORT1_HIGH 0x01 + +/* Forth register */ +#define TEA5767_PORT2_HIGH 0x80 +/* Chips stops working. Only I2C bus remains on */ +#define TEA5767_STDBY 0x40 + +/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */ +#define TEA5767_JAPAN_BAND 0x20 + +/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */ +#define TEA5767_XTAL_32768 0x10 + +/* Cuts weak signals */ +#define TEA5767_SOFT_MUTE 0x08 + +/* Activates high cut control */ +#define TEA5767_HIGH_CUT_CTRL 0x04 + +/* Activates stereo noise control */ +#define TEA5767_ST_NOISE_CTL 0x02 + +/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ +#define TEA5767_SRCH_IND 0x01 + +/* Fiveth register */ + +/* By activating, it will use Xtal at 13 MHz as reference for divider */ +#define TEA5767_PLLREF_ENABLE 0x80 + +/* By activating, deemphasis=50, or else, deemphasis of 50us */ +#define TEA5767_DEEMPH_75 0X40 + +/***************************** + * Read mode register values * + *****************************/ + +/* First register */ +#define TEA5767_READY_FLAG_MASK 0x80 +#define TEA5767_BAND_LIMIT_MASK 0X40 +/* Bits 0-5 for divider MSB after search or preset */ + +/* Second register */ +/* Bits 0-7 for divider LSB after search or preset */ + +/* Third register */ +#define TEA5767_STEREO_MASK 0x80 +#define TEA5767_IF_CNTR_MASK 0x7f + +/* Four register */ +#define TEA5767_ADC_LEVEL_MASK 0xf0 + +/* should be 0 */ +#define TEA5767_CHIP_ID_MASK 0x0f + +/* Fiveth register */ +/* Reserved for future extensions */ +#define TEA5767_RESERVED_MASK 0xff + +/*****************************************************************************/ + +static void set_tv_freq(struct i2c_client *c, unsigned int freq) +{ + struct tuner *t = i2c_get_clientdata(c); + + tuner_warn("This tuner doesn't support TV freq.\n"); +} + +static void tea5767_status_dump(unsigned char *buffer) +{ + unsigned int div, frq; + + if (TEA5767_READY_FLAG_MASK & buffer[0]) + printk(PREFIX "Ready Flag ON\n"); + else + printk(PREFIX "Ready Flag OFF\n"); + + if (TEA5767_BAND_LIMIT_MASK & buffer[0]) + printk(PREFIX "Tuner at band limit\n"); + else + printk(PREFIX "Tuner not at band limit\n"); + + div=((buffer[0]&0x3f)<<8) | buffer[1]; + + switch (TEA5767_HIGH_LO_32768) { + case TEA5767_HIGH_LO_13MHz: + frq = 1000*(div*50-700-225)/4; /* Freq in KHz */ + break; + case TEA5767_LOW_LO_13MHz: + frq = 1000*(div*50+700+225)/4; /* Freq in KHz */ + break; + case TEA5767_LOW_LO_32768: + frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */ + break; + case TEA5767_HIGH_LO_32768: + default: + frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */ + break; + } + buffer[0] = (div>>8) & 0x3f; + buffer[1] = div & 0xff; + + printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", + frq/1000,frq%1000,div); + + if (TEA5767_STEREO_MASK & buffer[2]) + printk(PREFIX "Stereo\n"); + else + printk(PREFIX "Mono\n"); + + printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK); + + printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4); + + printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK)); + + printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK)); +} + +/* Freq should be specifyed at 62.5 Hz */ +static void set_radio_freq(struct i2c_client *c, unsigned int frq) +{ + struct tuner *t = i2c_get_clientdata(c); + unsigned char buffer[5]; + unsigned div; + int rc; + + if ( tuner_debug ) + printk(PREFIX "radio freq counter %d\n",frq); + + /* Rounds freq to next decimal value - for 62.5 KHz step */ + /* frq = 20*(frq/16)+radio_frq[frq%16]; */ + + buffer[2] = TEA5767_PORT1_HIGH; + buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND; + buffer[4]=0; + + if (t->audmode == V4L2_TUNER_MODE_MONO) { + tuner_dbg("TEA5767 set to mono\n"); + buffer[2] |= TEA5767_MONO; + } else + tuner_dbg("TEA5767 set to stereo\n"); + + switch (t->type) { + case TEA5767_HIGH_LO_13MHz: + tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); + buffer[2] |= TEA5767_HIGH_LO_INJECT; + buffer[4] |= TEA5767_PLLREF_ENABLE; + div = (frq*4/16+700+225+25)/50; + break; + case TEA5767_LOW_LO_13MHz: + tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); + + buffer[4] |= TEA5767_PLLREF_ENABLE; + div = (frq*4/16-700-225+25)/50; + break; + case TEA5767_LOW_LO_32768: + tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); + buffer[3] |= TEA5767_XTAL_32768; + /* const 700=4000*175 Khz - to adjust freq to right value */ + div = (1000*(frq*4/16-700-225)+16384)>>15; + break; + case TEA5767_HIGH_LO_32768: + default: + tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n"); + + buffer[2] |= TEA5767_HIGH_LO_INJECT; + buffer[3] |= TEA5767_XTAL_32768; + div = (1000*(frq*4/16+700+225)+16384)>>15; + break; + } + buffer[0] = (div>>8) & 0x3f; + buffer[1] = div & 0xff; + + if ( tuner_debug ) + tea5767_status_dump(buffer); + + if (5 != (rc = i2c_master_send(c,buffer,5))) + tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc); +} + +static int tea5767_signal(struct i2c_client *c) +{ + unsigned char buffer[5]; + int rc; + struct tuner *t = i2c_get_clientdata(c); + + memset(buffer,0,sizeof(buffer)); + if (5 != (rc = i2c_master_recv(c,buffer,5))) + tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc); + + return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4)); +} + +static int tea5767_stereo(struct i2c_client *c) +{ + unsigned char buffer[5]; + int rc; + struct tuner *t = i2c_get_clientdata(c); + + memset(buffer,0,sizeof(buffer)); + if (5 != (rc = i2c_master_recv(c,buffer,5))) + tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc); + + rc = buffer[2] & TEA5767_STEREO_MASK; + + if ( tuner_debug ) + tuner_dbg("TEA5767 radio ST GET = %02x\n", rc); + + return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0); +} + +int tea_detection(struct i2c_client *c) +{ + unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff }; + int rc; + struct tuner *t = i2c_get_clientdata(c); + + if (5 != (rc = i2c_master_recv(c,buffer,5))) { + tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc ); + return EINVAL; + } + + /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */ + if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && + buffer[0] == buffer[3] && buffer[0] == buffer[4]) { + tuner_warn ( "All bytes are equal. It is not a TEA5767\n" ); + return EINVAL; + } + + /* Status bytes: + * Byte 4: bit 3:1 : CI (Chip Identification) == 0 + * bit 0 : internally set to 0 + * Byte 5: bit 7:0 : == 0 + */ + + if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) { + tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" ); + return EINVAL; + } + tuner_warn ( "TEA5767 detected.\n" ); + return 0; +} + +int tea5767_tuner_init(struct i2c_client *c) +{ + struct tuner *t = i2c_get_clientdata(c); + + if (tea_detection(c)==EINVAL) return EINVAL; + + tuner_info("type set to %d (%s)\n", + t->type, TEA5767_TUNER_NAME); + strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name)); + + t->tv_freq = set_tv_freq; + t->radio_freq = set_radio_freq; + t->has_signal = tea5767_signal; + t->is_stereo = tea5767_stereo; + + return (0); +} diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index eaabfc858703..6f6bf4a633fc 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $ + * $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $ * * i2c tv tuner chip device driver * core core, i.e. kernel interfaces, registering and so on @@ -26,7 +26,6 @@ /* * comment line bellow to return to old behavor, where only one I2C device is supported */ -#define CONFIG_TUNER_MULTI_I2C /**/ #define UNSET (-1U) @@ -58,9 +57,7 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); MODULE_LICENSE("GPL"); static int this_adap; -#ifdef CONFIG_TUNER_MULTI_I2C static unsigned short first_tuner, tv_tuner, radio_tuner; -#endif static struct i2c_driver driver; static struct i2c_client client_template; @@ -81,26 +78,9 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) return; } if (freq < tv_range[0]*16 || freq > tv_range[1]*16) { - - if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) { - /* V4L2_TUNER_CAP_LOW frequency */ - - tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n"); - - t->tv_freq(c,freq>>10); - - return; - } else { - /* FIXME: better do that chip-specific, but - right now we don't have that in the config - struct and this way is still better than no - check at all */ tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n", freq/16,freq%16*100/16,tv_range[0],tv_range[1]); - return; - } } - tuner_dbg("62.5 Khz freq step selected for TV.\n"); t->tv_freq(c,freq); } @@ -116,31 +96,18 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) tuner_info("no radio tuning for this one, sorry.\n"); return; } - if (freq < radio_range[0]*16 || freq > radio_range[1]*16) { - if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) { - /* V4L2_TUNER_CAP_LOW frequency */ - if (t->type == TUNER_TEA5767) { - tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000); - t->radio_freq(c,freq>>10); - return; - } - - tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n"); - - tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000); - - t->radio_freq(c,freq>>10); - return; - - } else { - tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", - freq/16,freq%16*100/16, - radio_range[0],radio_range[1]); - return; - } + if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) { + if (tuner_debug) + tuner_info("radio freq step 62.5Hz (%d.%06d)\n", + freq/16000,freq%16000*1000/16); + t->radio_freq(c,freq); + } else { + tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", + freq/16,freq%16*100/16, + radio_range[0],radio_range[1]); } - tuner_dbg("62.5 Khz freq step selected for Radio.\n"); - t->radio_freq(c,freq); + + return; } static void set_freq(struct i2c_client *c, unsigned long freq) @@ -166,8 +133,8 @@ static void set_freq(struct i2c_client *c, unsigned long freq) static void set_type(struct i2c_client *c, unsigned int type) { struct tuner *t = i2c_get_clientdata(c); + unsigned char buffer[4]; - tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); /* sanity check */ if (type == UNSET || type == TUNER_ABSENT) return; @@ -179,8 +146,8 @@ static void set_type(struct i2c_client *c, unsigned int type) t->type = type; return; } - if (t->initialized) - /* run only once */ + if ((t->initialized) && (t->type == type)) + /* run only once except type change Hac 04/05*/ return; t->initialized = 1; @@ -193,25 +160,42 @@ static void set_type(struct i2c_client *c, unsigned int type) case TUNER_PHILIPS_TDA8290: tda8290_init(c); break; + case TUNER_TEA5767: + if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT; + break; + case TUNER_PHILIPS_FMD1216ME_MK3: + buffer[0] = 0x0b; + buffer[1] = 0xdc; + buffer[2] = 0x9c; + buffer[3] = 0x60; + i2c_master_send(c,buffer,4); + mdelay(1); + buffer[2] = 0x86; + buffer[3] = 0x54; + i2c_master_send(c,buffer,4); + default_tuner_init(c); + break; default: + /* TEA5767 autodetection code */ + if (tea5767_tuner_init(c)!=EINVAL) { + t->type = TUNER_TEA5767; + if (first_tuner == 0x60) + first_tuner++; + break; + } + default_tuner_init(c); break; } + tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); } -#ifdef CONFIG_TUNER_MULTI_I2C #define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \ - return 0; } else \ + return 0; } else if (tuner_debug) \ tuner_info ("Cmd %s accepted to "tun"\n",cmd); #define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \ CHECK_ADDR(radio_tuner,cmd,"radio") } else \ { CHECK_ADDR(tv_tuner,cmd,"TV"); } -#else -#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd); -#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd); -#endif - -#ifdef CONFIG_TUNER_MULTI_I2C static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) { @@ -242,9 +226,6 @@ static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) } set_type(c,tun_addr->type); } -#else -#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type) -#endif static char pal[] = "-"; module_param_string(pal, pal, sizeof(pal), 0644); @@ -284,17 +265,12 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) { struct tuner *t; -#ifndef CONFIG_TUNER_MULTI_I2C - if (this_adap > 0) - return -1; -#else /* by default, first I2C card is both tv and radio tuner */ if (this_adap == 0) { first_tuner = addr; tv_tuner = addr; radio_tuner = addr; } -#endif this_adap++; client_template.adapter = adap; @@ -308,6 +284,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) i2c_set_clientdata(&t->i2c, t); t->type = UNSET; t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */ + t->audmode = V4L2_TUNER_MODE_STEREO; i2c_attach_client(&t->i2c); tuner_info("chip found @ 0x%x (%s)\n", @@ -325,11 +302,9 @@ static int tuner_probe(struct i2c_adapter *adap) } this_adap = 0; -#ifdef CONFIG_TUNER_MULTI_I2C first_tuner = 0; tv_tuner = 0; radio_tuner = 0; -#endif if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tuner_attach); @@ -392,8 +367,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) t->radio_if2 = 41300 * 1000; break; } - break; - + break; /* --- v4l ioctls --- */ /* take care: bttv does userspace copying, we'll get a kernel pointer here... */ @@ -440,11 +414,18 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) vt->signal = t->has_signal(client); if (t->is_stereo) { if (t->is_stereo(client)) - vt-> flags |= VIDEO_TUNER_STEREO_ON; + vt->flags |= VIDEO_TUNER_STEREO_ON; else - vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON; + vt->flags &= ~VIDEO_TUNER_STEREO_ON; } vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */ + + vt->rangelow = radio_range[0] * 16000; + vt->rangehigh = radio_range[1] * 16000; + + } else { + vt->rangelow = tv_range[0] * 16; + vt->rangehigh = tv_range[1] * 16; } return 0; @@ -510,20 +491,46 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) tuner -> signal = t->has_signal(client); if (t->is_stereo) { if (t->is_stereo(client)) { - tuner -> capability |= V4L2_TUNER_CAP_STEREO; - tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO; + tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; } else { - tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO; + tuner -> rxsubchans = V4L2_TUNER_SUB_MONO; } } + tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; + tuner->audmode = t->audmode; + + tuner->rangelow = radio_range[0] * 16000; + tuner->rangehigh = radio_range[1] * 16000; + } else { + tuner->rangelow = tv_range[0] * 16; + tuner->rangehigh = tv_range[1] * 16; } - /* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step to high at 62.5 Hz */ - tuner->rangelow = tv_range[0] * 16; -// tuner->rangehigh = tv_range[1] * 16; -// tuner->rangelow = tv_range[0] * 16384; - tuner->rangehigh = tv_range[1] * 16384; break; } + case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */ + { + struct v4l2_tuner *tuner = arg; + + CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio"); + SWITCH_V4L2; + + /* To switch the audio mode, applications initialize the + index and audmode fields and the reserved array and + call the VIDIOC_S_TUNER ioctl. */ + /* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO, + V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2, + V4L2_TUNER_MODE_SAP */ + + if (tuner->audmode == V4L2_TUNER_MODE_MONO) + t->audmode = V4L2_TUNER_MODE_MONO; + else + t->audmode = V4L2_TUNER_MODE_STEREO; + + set_radio_freq(client, t->freq); + break; + } + case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */ + break; default: tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd); /* nothing */ diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 539f30557317..c39ed6226ee0 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $ + * $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $ * * i2c tv tuner chip device driver * controls all those simple 4-control-bytes style tuners. @@ -207,28 +207,27 @@ static struct tunertype tuners[] = { { "LG PAL (TAPE series)", LGINNOTEK, PAL, 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, - { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, - 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, - { "Philips FQ1236A MK4", Philips, NTSC, - 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, + { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, + 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, + { "Philips FQ1236A MK4", Philips, NTSC, + 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */ { "Ymec TVision TVF-8531MF", Philips, NTSC, 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, { "Ymec TVision TVF-5533MF", Philips, NTSC, 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, - { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, - { "Tena TNF9533-D/IF", LGINNOTEK, PAL, - 16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623}, + /* Should work for TNF9533-D/IF, TNF9533-B/DF */ + { "Tena TNF9533-D/IF", Philips, PAL, + 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, - /* - * This entry is for TEA5767 FM radio only chip used on several boards - * w/TV tuner - */ + /* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */ { TEA5767_TUNER_NAME, Philips, RADIO, - -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0}, + -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0}, + { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, + 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); @@ -455,24 +454,24 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) int rc; tun=&tuners[t->type]; - div = freq + (int)(16*10.7); + div = (freq / 1000) + (int)(16*10.7); buffer[2] = tun->config; switch (t->type) { case TUNER_TENA_9533_DI: case TUNER_YMEC_TVF_5533MF: - /*These values are empirically determinated */ - div = (freq*122)/16 - 20; + div = (freq * 122) / 16000 - 20; buffer[2] = 0x88; /* could be also 0x80 */ buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */ break; case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: + case TUNER_PHILIPS_FMD1216ME_MK3: buffer[3] = 0x19; break; case TUNER_PHILIPS_FM1256_IH3: - div = (20 * freq)/16 + 333 * 2; + div = (20 * freq) / 16000 + 333 * 2; buffer[2] = 0x80; buffer[3] = 0x19; break; @@ -505,6 +504,7 @@ int default_tuner_init(struct i2c_client *c) t->radio_freq = default_set_radio_freq; t->has_signal = tuner_signal; t->is_stereo = tuner_stereo; + return 0; } diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index d8d65397e06e..353deb25e397 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -364,9 +364,7 @@ static struct pci_driver mptfc_driver = { .id_table = mptfc_pci_table, .probe = mptfc_probe, .remove = __devexit_p(mptscsih_remove), - .driver = { - .shutdown = mptscsih_shutdown, - }, + .shutdown = mptscsih_shutdown, #ifdef CONFIG_PM .suspend = mptscsih_suspend, .resume = mptscsih_resume, diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index a0078ae5b9b8..4f973a49be4c 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -170,7 +170,7 @@ static void mptscsih_fillbuf(char *buffer, int size, int index, int width); #endif void mptscsih_remove(struct pci_dev *); -void mptscsih_shutdown(struct device *); +void mptscsih_shutdown(struct pci_dev *); #ifdef CONFIG_PM int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state); int mptscsih_resume(struct pci_dev *pdev); @@ -988,7 +988,7 @@ mptscsih_remove(struct pci_dev *pdev) #endif #endif - mptscsih_shutdown(&pdev->dev); + mptscsih_shutdown(pdev); sz1=0; @@ -1026,9 +1026,9 @@ mptscsih_remove(struct pci_dev *pdev) * */ void -mptscsih_shutdown(struct device * dev) +mptscsih_shutdown(struct pci_dev *pdev) { - MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev)); + MPT_ADAPTER *ioc = pci_get_drvdata(pdev); struct Scsi_Host *host = ioc->sh; MPT_SCSI_HOST *hd; @@ -1054,7 +1054,7 @@ mptscsih_shutdown(struct device * dev) int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state) { - mptscsih_shutdown(&pdev->dev); + mptscsih_shutdown(pdev); return mpt_suspend(pdev,state); } diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index d73aec33e16a..5ea89bf0df19 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -82,7 +82,7 @@ #endif extern void mptscsih_remove(struct pci_dev *); -extern void mptscsih_shutdown(struct device *); +extern void mptscsih_shutdown(struct pci_dev *); #ifdef CONFIG_PM extern int mptscsih_suspend(struct pci_dev *pdev, u32 state); extern int mptscsih_resume(struct pci_dev *pdev); diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 5f9a61b85b3b..e0c0ee5bc966 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -419,9 +419,7 @@ static struct pci_driver mptspi_driver = { .id_table = mptspi_pci_table, .probe = mptspi_probe, .remove = __devexit_p(mptscsih_remove), - .driver = { - .shutdown = mptscsih_shutdown, - }, + .shutdown = mptscsih_shutdown, #ifdef CONFIG_PM .suspend = mptscsih_suspend, .resume = mptscsih_resume, diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 3a5f6ac5b364..7a42966d755b 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c @@ -20,6 +20,7 @@ #include <linux/mmc/host.h> #include <linux/mmc/protocol.h> +#include <asm/div64.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/scatterlist.h> @@ -70,6 +71,7 @@ static void mmci_stop_data(struct mmci_host *host) static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) { unsigned int datactrl, timeout, irqmask; + unsigned long long clks; void __iomem *base; DBG(host, "blksz %04x blks %04x flags %08x\n", @@ -81,9 +83,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) mmci_init_sg(host, data); - timeout = data->timeout_clks + - ((unsigned long long)data->timeout_ns * host->cclk) / - 1000000000ULL; + clks = (unsigned long long)data->timeout_ns * host->cclk; + do_div(clks, 1000000000UL); + + timeout = data->timeout_clks + (unsigned int)clks; base = host->base; writel(timeout, base + MMCIDATATIMER); diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index b7fbd30b49a0..0c41d4b41a65 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -54,28 +54,6 @@ #define DBGF(x...) do { } while (0) #endif -#ifdef CONFIG_MMC_DEBUG -void DBG_REG(int reg, u8 value) -{ - int i; - - printk(KERN_DEBUG "wbsd: Register %d: 0x%02X %3d '%c' ", - reg, (int)value, (int)value, (value < 0x20)?'.':value); - - for (i = 7;i >= 0;i--) - { - if (value & (1 << i)) - printk("x"); - else - printk("."); - } - - printk("\n"); -} -#else -#define DBG_REG(r, v) do {} while (0) -#endif - /* * Device resources */ @@ -92,6 +70,13 @@ MODULE_DEVICE_TABLE(pnp, pnp_dev_table); #endif /* CONFIG_PNP */ +static const int config_ports[] = { 0x2E, 0x4E }; +static const int unlock_codes[] = { 0x83, 0x87 }; + +static const int valid_ids[] = { + 0x7112, + }; + #ifdef CONFIG_PNP static unsigned int nopnp = 0; #else @@ -1051,6 +1036,20 @@ static struct mmc_host_ops wbsd_ops = { \*****************************************************************************/ /* + * Helper function for card detection + */ +static void wbsd_detect_card(unsigned long data) +{ + struct wbsd_host *host = (struct wbsd_host*)data; + + BUG_ON(host == NULL); + + DBG("Executing card detection\n"); + + mmc_detect_change(host->mmc); +} + +/* * Tasklets */ @@ -1075,7 +1074,6 @@ static void wbsd_tasklet_card(unsigned long param) { struct wbsd_host* host = (struct wbsd_host*)param; u8 csr; - int change = 0; spin_lock(&host->lock); @@ -1094,14 +1092,20 @@ static void wbsd_tasklet_card(unsigned long param) { DBG("Card inserted\n"); host->flags |= WBSD_FCARD_PRESENT; - change = 1; + + /* + * Delay card detection to allow electrical connections + * to stabilise. + */ + mod_timer(&host->timer, jiffies + HZ/2); } + + spin_unlock(&host->lock); } else if (host->flags & WBSD_FCARD_PRESENT) { DBG("Card removed\n"); host->flags &= ~WBSD_FCARD_PRESENT; - change = 1; if (host->mrq) { @@ -1112,15 +1116,14 @@ static void wbsd_tasklet_card(unsigned long param) host->mrq->cmd->error = MMC_ERR_FAILED; tasklet_schedule(&host->finish_tasklet); } - } - - /* - * Unlock first since we might get a call back. - */ - spin_unlock(&host->lock); + + /* + * Unlock first since we might get a call back. + */ + spin_unlock(&host->lock); - if (change) mmc_detect_change(host->mmc); + } } static void wbsd_tasklet_fifo(unsigned long param) @@ -1325,6 +1328,13 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) spin_lock_init(&host->lock); /* + * Set up detection timer + */ + init_timer(&host->timer); + host->timer.data = (unsigned long)host; + host->timer.function = wbsd_detect_card; + + /* * Maximum number of segments. Worst case is one sector per segment * so this will be 64kB/512. */ @@ -1351,11 +1361,17 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) static void __devexit wbsd_free_mmc(struct device* dev) { struct mmc_host* mmc; + struct wbsd_host* host; mmc = dev_get_drvdata(dev); if (!mmc) return; + host = mmc_priv(mmc); + BUG_ON(host == NULL); + + del_timer_sync(&host->timer); + mmc_free_host(mmc); dev_set_drvdata(dev, NULL); diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h index 864f30828d01..661a9f6a6e6f 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/wbsd.h @@ -8,13 +8,6 @@ * published by the Free Software Foundation. */ -const int config_ports[] = { 0x2E, 0x4E }; -const int unlock_codes[] = { 0x83, 0x87 }; - -const int valid_ids[] = { - 0x7112, - }; - #define LOCK_CODE 0xAA #define WBSD_CONF_SWRST 0x02 @@ -187,4 +180,6 @@ struct wbsd_host struct tasklet_struct timeout_tasklet; struct tasklet_struct finish_tasklet; struct tasklet_struct block_tasklet; + + struct timer_list timer; /* Card detection timer */ }; diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index 801e6c7d0892..7363e101eb0f 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c @@ -219,7 +219,7 @@ static int parse_afs_partitions(struct mtd_info *mtd, */ for (idx = off = 0; off < mtd->size; off += mtd->erasesize) { struct image_info_struct iis; - u_int iis_ptr, img_ptr, size; + u_int iis_ptr, img_ptr; /* Read the footer. */ ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); @@ -236,21 +236,9 @@ static int parse_afs_partitions(struct mtd_info *mtd, continue; strcpy(str, iis.name); - size = mtd->erasesize + off - img_ptr; - - /* - * In order to support JFFS2 partitions on this layout, - * we must lie to MTD about the real size of JFFS2 - * partitions; this ensures that the AFS flash footer - * won't be erased by JFFS2. Please ensure that your - * JFFS2 partitions are given image numbers between - * 1000 and 2000 inclusive. - */ - if (iis.imageNumber >= 1000 && iis.imageNumber < 2000) - size -= mtd->erasesize; parts[idx].name = str; - parts[idx].size = size; + parts[idx].size = (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1); parts[idx].offset = img_ptr; parts[idx].mask_flags = 0; diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index d272ea36a578..91d1c4c24d9b 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -822,7 +822,7 @@ static int corkscrew_open(struct net_device *dev) break; /* Bad news! */ skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail); + vp->rx_ring[i].addr = isa_virt_to_bus(skb->data); } vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */ outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr); @@ -1406,7 +1406,7 @@ static int boomerang_rx(struct net_device *dev) break; /* Bad news! */ skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail); + vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data); vp->rx_skbuff[entry] = skb; } vp->rx_ring[entry].status = 0; /* Clear complete bit. */ diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 80ec9aa575bb..07746b95fd83 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -1802,7 +1802,7 @@ vortex_open(struct net_device *dev) break; /* Bad news! */ skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); + vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); } if (i != RX_RING_SIZE) { int j; @@ -2632,7 +2632,7 @@ boomerang_rx(struct net_device *dev) pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); /* 'skb_put()' points to the start of sk_buff data area. */ memcpy(skb_put(skb, pkt_len), - vp->rx_skbuff[entry]->tail, + vp->rx_skbuff[entry]->data, pkt_len); pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); vp->rx_copy++; @@ -2678,7 +2678,7 @@ boomerang_rx(struct net_device *dev) } skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); + vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); vp->rx_skbuff[entry] = skb; } vp->rx_ring[entry].status = 0; /* Clear complete bit. */ diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index e4b3c5c88542..7b293f01c9ed 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -596,7 +596,7 @@ rx_status_loop: mapping = cp->rx_skb[rx_tail].mapping = - pci_map_single(cp->pdev, new_skb->tail, + pci_map_single(cp->pdev, new_skb->data, buflen, PCI_DMA_FROMDEVICE); cp->rx_skb[rx_tail].skb = new_skb; @@ -1101,7 +1101,7 @@ static int cp_refill_rx (struct cp_private *cp) skb_reserve(skb, RX_OFFSET); cp->rx_skb[i].mapping = pci_map_single(cp->pdev, - skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); cp->rx_skb[i].skb = skb; cp->rx_ring[i].opts2 = 0; diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 65f97b1dc581..13b745b39667 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -546,11 +546,11 @@ static inline void init_rx_bufs(struct net_device *dev) rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1)); rbd->b_addr = WSWAPrbd(virt_to_bus(rbd)); rbd->skb = skb; - rbd->v_data = skb->tail; - rbd->b_data = WSWAPchar(virt_to_bus(skb->tail)); + rbd->v_data = skb->data; + rbd->b_data = WSWAPchar(virt_to_bus(skb->data)); rbd->size = PKT_BUF_SZ; #ifdef __mc68000__ - cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ); + cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ); #endif } lp->rbd_head = lp->rbds; @@ -816,10 +816,10 @@ static inline int i596_rx(struct net_device *dev) rx_in_place = 1; rbd->skb = newskb; newskb->dev = dev; - rbd->v_data = newskb->tail; - rbd->b_data = WSWAPchar(virt_to_bus(newskb->tail)); + rbd->v_data = newskb->data; + rbd->b_data = WSWAPchar(virt_to_bus(newskb->data)); #ifdef __mc68000__ - cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ); + cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ); #endif } else @@ -840,7 +840,7 @@ memory_squeeze: skb->protocol=eth_type_trans(skb,dev); skb->len = pkt_len; #ifdef __mc68000__ - cache_clear(virt_to_phys(rbd->skb->tail), + cache_clear(virt_to_phys(rbd->skb->data), pkt_len); #endif netif_rx(skb); diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index b7dd7260cafb..8618012df06a 100755 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -87,6 +87,7 @@ Revision History: #include <linux/if_vlan.h> #include <linux/ctype.h> #include <linux/crc32.h> +#include <linux/dma-mapping.h> #include <asm/system.h> #include <asm/io.h> @@ -2006,12 +2007,11 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, } /* Initialize DMA */ - if(!pci_dma_supported(pdev, 0xffffffff)){ + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) { printk(KERN_ERR "amd8111e: DMA not supported," "exiting.\n"); - goto err_free_reg; - } else - pdev->dma_mask = 0xffffffff; + goto err_free_reg; + } reg_addr = pci_resource_start(pdev, 0); reg_len = pci_resource_len(pdev, 0); diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 2e28c201dcc0..942a2819576c 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -68,7 +68,6 @@ struct etherh_priv { void __iomem *dma_base; unsigned int id; void __iomem *ctrl_port; - void __iomem *base; unsigned char ctrl; u32 supported; }; @@ -178,7 +177,7 @@ etherh_setif(struct net_device *dev) switch (etherh_priv(dev)->id) { case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A: - addr = etherh_priv(dev)->base + EN0_RCNTHI; + addr = (void *)dev->base_addr + EN0_RCNTHI; switch (dev->if_port) { case IF_PORT_10BASE2: @@ -219,7 +218,7 @@ etherh_getifstat(struct net_device *dev) switch (etherh_priv(dev)->id) { case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A: - addr = etherh_priv(dev)->base + EN0_RCNTHI; + addr = (void *)dev->base_addr + EN0_RCNTHI; switch (dev->if_port) { case IF_PORT_10BASE2: stat = 1; @@ -282,7 +281,7 @@ static void etherh_reset(struct net_device *dev) { struct ei_device *ei_local = netdev_priv(dev); - void __iomem *addr = etherh_priv(dev)->base; + void __iomem *addr = (void *)dev->base_addr; writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr); @@ -328,7 +327,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf ei_local->dmaing = 1; - addr = etherh_priv(dev)->base; + addr = (void *)dev->base_addr; dma_base = etherh_priv(dev)->dma_base; count = (count + 1) & ~1; @@ -388,7 +387,7 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ei_local->dmaing = 1; - addr = etherh_priv(dev)->base; + addr = (void *)dev->base_addr; dma_base = etherh_priv(dev)->dma_base; buf = skb->data; @@ -428,7 +427,7 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p ei_local->dmaing = 1; - addr = etherh_priv(dev)->base; + addr = (void *)dev->base_addr; dma_base = etherh_priv(dev)->dma_base; writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); @@ -697,8 +696,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) eh->ctrl_port = eh->ioc_fast; } - eh->base = eh->memc + data->ns8390_offset; - dev->base_addr = (unsigned long)eh->base; + dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset; eh->dma_base = eh->memc + data->dataport_offset; eh->ctrl_port += data->ctrlport_offset; diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index b8ab2b6355eb..e613cc289749 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -34,10 +34,6 @@ only is it difficult to detect, it also moves around in I/O space in response to inb()s from other device probes! */ -/* - 99/03/03 Allied Telesis RE1000 Plus support by T.Hagawa - 99/12/30 port to 2.3.35 by K.Takai -*/ #include <linux/config.h> #include <linux/errno.h> diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 00e5257b176f..8dc657fc8afb 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1261,7 +1261,7 @@ static void bmac_reset_and_enable(struct net_device *dev) spin_unlock_irqrestore(&bp->lock, flags); } -static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_match *match) +static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match) { int j, rev, ret; struct bmac_data *bp; @@ -1645,16 +1645,13 @@ static int __devexit bmac_remove(struct macio_dev *mdev) return 0; } -static struct of_match bmac_match[] = +static struct of_device_id bmac_match[] = { { .name = "bmac", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH, .data = (void *)0, }, { - .name = OF_ANY_MATCH, .type = "network", .compatible = "bmac+", .data = (void *)1, diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index aa42b7a27735..430c628279b3 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -547,7 +547,7 @@ rio_timer (unsigned long data) skb_reserve (skb, 2); np->rx_ring[entry].fraginfo = cpu_to_le64 (pci_map_single - (np->pdev, skb->tail, np->rx_buf_sz, + (np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); } np->rx_ring[entry].fraginfo |= @@ -618,7 +618,7 @@ alloc_list (struct net_device *dev) /* Rubicon now supports 40 bits of addressing space. */ np->rx_ring[i].fraginfo = cpu_to_le64 ( pci_map_single ( - np->pdev, skb->tail, np->rx_buf_sz, + np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48; } @@ -906,7 +906,7 @@ receive_packet (struct net_device *dev) /* 16 byte align the IP header */ skb_reserve (skb, 2); eth_copy_and_sum (skb, - np->rx_skbuff[entry]->tail, + np->rx_skbuff[entry]->data, pkt_len, 0); skb_put (skb, pkt_len); pci_dma_sync_single_for_device(np->pdev, @@ -950,7 +950,7 @@ receive_packet (struct net_device *dev) skb_reserve (skb, 2); np->rx_ring[entry].fraginfo = cpu_to_le64 (pci_map_single - (np->pdev, skb->tail, np->rx_buf_sz, + (np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); } np->rx_ring[entry].fraginfo |= diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 1e56c8eea35f..d0fa2448761d 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2447,9 +2447,8 @@ static int e100_resume(struct pci_dev *pdev) #endif -static void e100_shutdown(struct device *dev) +static void e100_shutdown(struct pci_dev *pdev) { - struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); @@ -2470,11 +2469,7 @@ static struct pci_driver e100_driver = { .suspend = e100_suspend, .resume = e100_resume, #endif - - .driver = { - .shutdown = e100_shutdown, - } - + .shutdown = e100_shutdown, }; static int __init e100_init_module(void) diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 98b3a2fdce90..1795425f512e 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -1269,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *dev) if (skb == NULL) break; /* OK. Just initially short of Rx bufs. */ skb->dev = dev; /* Mark as being used by this device. */ - rxf = (struct RxFD *)skb->tail; + rxf = (struct RxFD *)skb->data; sp->rx_ringp[i] = rxf; sp->rx_ring_dma[i] = pci_map_single(sp->pdev, rxf, @@ -1661,7 +1661,7 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry) sp->rx_ringp[entry] = NULL; return NULL; } - rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail; + rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data; sp->rx_ring_dma[entry] = pci_map_single(sp->pdev, rxf, PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); @@ -1808,10 +1808,10 @@ speedo_rx(struct net_device *dev) #if 1 || USE_IP_CSUM /* Packet is in one chunk -- we can copy + cksum. */ - eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0); + eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); #else - memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail, + memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->data, pkt_len); #endif pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry], diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 81ebaedaa240..87f522738bfc 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -1003,7 +1003,7 @@ static void epic_init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev, - skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn); } ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1274,7 +1274,7 @@ static int epic_rx(struct net_device *dev, int budget) ep->rx_ring[entry].bufaddr, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0); + eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(ep->pci_dev, ep->rx_ring[entry].bufaddr, @@ -1308,7 +1308,7 @@ static int epic_rx(struct net_device *dev, int budget) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, - skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); work_done++; } ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn); diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 9e0303f6d73c..55dbe9a3fd56 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -1107,7 +1107,7 @@ static void allocate_rx_buffers(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ np->lack_rxbuf->skbuff = skb; - np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->tail, + np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); np->lack_rxbuf->status = RXOWN; ++np->really_rx_count; @@ -1300,7 +1300,7 @@ static void init_ring(struct net_device *dev) ++np->really_rx_count; np->rx_ring[i].skbuff = skb; skb->dev = dev; /* Mark as being used by this device. */ - np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->tail, + np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); np->rx_ring[i].status = RXOWN; np->rx_ring[i].control |= RXIC; @@ -1737,11 +1737,11 @@ static int netdev_rx(struct net_device *dev) #if ! defined(__alpha__) eth_copy_and_sum(skb, - np->cur_rx->skbuff->tail, pkt_len, 0); + np->cur_rx->skbuff->data, pkt_len, 0); skb_put(skb, pkt_len); #else memcpy(skb_put(skb, pkt_len), - np->cur_rx->skbuff->tail, pkt_len); + np->cur_rx->skbuff->data, pkt_len); #endif pci_dma_sync_single_for_device(np->pci_dev, np->cur_rx->buffer, diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 3d96714ed3cf..d9df1d9a5739 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -1149,7 +1149,7 @@ static void hamachi_tx_timeout(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, - skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2)); } @@ -1210,7 +1210,7 @@ static void hamachi_init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, - skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); /* -2 because it doesn't REALLY have that first 2 bytes -KDU */ hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | DescEndPacket | DescIntr | (hmp->rx_buf_sz -2)); @@ -1509,7 +1509,7 @@ static int hamachi_rx(struct net_device *dev) desc->addr, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE); - buf_addr = (u8 *) hmp->rx_skbuff[entry]->tail; + buf_addr = (u8 *) hmp->rx_skbuff[entry]->data; frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12]))); if (hamachi_debug > 4) printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n", @@ -1678,7 +1678,7 @@ static int hamachi_rx(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, - skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); } desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz); if (entry >= RX_RING_SIZE-1) @@ -1772,9 +1772,9 @@ static int hamachi_close(struct net_device *dev) readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ', i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr); if (hamachi_debug > 6) { - if (*(u8*)hmp->rx_skbuff[i]->tail != 0x69) { + if (*(u8*)hmp->rx_skbuff[i]->data != 0x69) { u16 *addr = (u16 *) - hmp->rx_skbuff[i]->tail; + hmp->rx_skbuff[i]->data; int j; for (j = 0; j < 0x50; j++) diff --git a/drivers/net/lance.c b/drivers/net/lance.c index ca90f0d1e4b0..b4929beb33b2 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -862,7 +862,7 @@ lance_init_ring(struct net_device *dev, int gfp) lp->rx_skbuff[i] = skb; if (skb) { skb->dev = dev; - rx_buff = skb->tail; + rx_buff = skb->data; } else rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp); if (rx_buff == NULL) diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 5e263fcba669..41bad07ac1ac 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -553,14 +553,14 @@ static inline void init_rx_bufs(struct net_device *dev) if (skb == NULL) panic("%s: alloc_skb() failed", __FILE__); skb_reserve(skb, 2); - dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ, + dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ, DMA_FROM_DEVICE); skb->dev = dev; rbd->v_next = rbd+1; rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1)); rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd)); rbd->skb = skb; - rbd->v_data = skb->tail; + rbd->v_data = skb->data; rbd->b_data = WSWAPchar(dma_addr); rbd->size = PKT_BUF_SZ; } @@ -783,8 +783,8 @@ static inline int i596_rx(struct net_device *dev) rx_in_place = 1; rbd->skb = newskb; newskb->dev = dev; - dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE); - rbd->v_data = newskb->tail; + dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE); + rbd->v_data = newskb->data; rbd->b_data = WSWAPchar(dma_addr); CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); } diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 6ed2d7dbd44c..81d0a26e4f41 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -109,7 +109,7 @@ bitrev(int b) } -static int __devinit mace_probe(struct macio_dev *mdev, const struct of_match *match) +static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match) { struct device_node *mace = macio_get_of_node(mdev); struct net_device *dev; @@ -1009,12 +1009,10 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -static struct of_match mace_match[] = +static struct of_device_id mace_match[] = { { .name = "mace", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, {}, }; diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index babb59e146ea..9d6d2548c2d3 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -1926,7 +1926,7 @@ static void refill_rx(struct net_device *dev) break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ np->rx_dma[entry] = pci_map_single(np->pci_dev, - skb->tail, buflen, PCI_DMA_FROMDEVICE); + skb->data, buflen, PCI_DMA_FROMDEVICE); np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); } np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz); @@ -2280,7 +2280,7 @@ static void netdev_rx(struct net_device *dev) buflen, PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, - np->rx_skbuff[entry]->tail, pkt_len, 0); + np->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(np->pci_dev, np->rx_dma[entry], diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index cc7965271778..e64df4d0800b 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -574,7 +574,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb) dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC; cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR; - buf = pci_map_single(dev->pci_dev, skb->tail, + buf = pci_map_single(dev->pci_dev, skb->data, REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); build_rx_desc(dev, sg, 0, buf, cmdsts, 0); /* update link of previous rx */ @@ -604,7 +604,7 @@ static inline int rx_refill(struct net_device *ndev, int gfp) if (unlikely(!skb)) break; - res = (long)skb->tail & 0xf; + res = (long)skb->data & 0xf; res = 0x10 - res; res &= 0xf; skb_reserve(skb, res); diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 3213f3e50487..113b68099216 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1602,7 +1602,7 @@ pcnet32_init_ring(struct net_device *dev) rmb(); if (lp->rx_dma_addr[i] == 0) - lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, + lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data, PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ); @@ -1983,7 +1983,7 @@ pcnet32_rx(struct net_device *dev) lp->rx_skbuff[entry] = newskb; newskb->dev = dev; lp->rx_dma_addr[entry] = - pci_map_single(lp->pci_dev, newskb->tail, + pci_map_single(lp->pci_dev, newskb->data, PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]); rx_in_place = 1; @@ -2020,7 +2020,7 @@ pcnet32_rx(struct net_device *dev) PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, - (unsigned char *)(lp->rx_skbuff[entry]->tail), + (unsigned char *)(lp->rx_skbuff[entry]->data), pkt_len,0); pci_dma_sync_single_for_device(lp->pci_dev, lp->rx_dma_addr[entry], diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ce449fe90e6d..d5afe05cd826 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1876,7 +1876,7 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, skb_reserve(skb, NET_IP_ALIGN); *sk_buff = skb; - mapping = pci_map_single(pdev, skb->tail, rx_buf_sz, + mapping = pci_map_single(pdev, skb->data, rx_buf_sz, PCI_DMA_FROMDEVICE); rtl8169_map_to_asic(desc, mapping, rx_buf_sz); @@ -2336,7 +2336,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); if (skb) { skb_reserve(skb, NET_IP_ALIGN); - eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0); + eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); *sk_buff = skb; rtl8169_mark_to_asic(desc, rx_buf_sz); ret = 0; diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index bb639a8794d4..ea638b162d3f 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -1699,11 +1699,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) #else ba = &nic->ba[ring_no][block_no][off]; skb_reserve(skb, BUF0_LEN); - tmp = (unsigned long) skb->data; - tmp += ALIGN_SIZE; - tmp &= ~ALIGN_SIZE; - skb->data = (void *) tmp; - skb->tail = (void *) tmp; + tmp = ((unsigned long) skb->data & ALIGN_SIZE); + if (tmp) + skb_reserve(skb, (ALIGN_SIZE + 1) - tmp); memset(rxdp, 0, sizeof(RxD_t)); rxdp->Buffer2_ptr = pci_map_single diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index fd2e7c374906..7abd55a4fb21 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -963,11 +963,11 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb) /* * Do not interrupt per DMA transfer. */ - dsc->dscr_a = virt_to_phys(sb_new->tail) | + dsc->dscr_a = virt_to_phys(sb_new->data) | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | 0; #else - dsc->dscr_a = virt_to_phys(sb_new->tail) | + dsc->dscr_a = virt_to_phys(sb_new->data) | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | M_DMA_DSCRA_INTERRUPT; #endif diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 20edeb345792..3ad0b6751f6f 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -135,10 +135,8 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct shaper *shaper = dev->priv; struct sk_buff *ptr; - - if (down_trylock(&shaper->sem)) - return -1; - + + spin_lock(&shaper->lock); ptr=shaper->sendq.prev; /* @@ -232,7 +230,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) shaper->stats.collisions++; } shaper_kick(shaper); - up(&shaper->sem); + spin_unlock(&shaper->lock); return 0; } @@ -271,11 +269,9 @@ static void shaper_timer(unsigned long data) { struct shaper *shaper = (struct shaper *)data; - if (!down_trylock(&shaper->sem)) { - shaper_kick(shaper); - up(&shaper->sem); - } else - mod_timer(&shaper->timer, jiffies); + spin_lock(&shaper->lock); + shaper_kick(shaper); + spin_unlock(&shaper->lock); } /* @@ -332,21 +328,6 @@ static void shaper_kick(struct shaper *shaper) /* - * Flush the shaper queues on a closedown - */ - -static void shaper_flush(struct shaper *shaper) -{ - struct sk_buff *skb; - - down(&shaper->sem); - while((skb=skb_dequeue(&shaper->sendq))!=NULL) - dev_kfree_skb(skb); - shaper_kick(shaper); - up(&shaper->sem); -} - -/* * Bring the interface up. We just disallow this until a * bind. */ @@ -375,7 +356,15 @@ static int shaper_open(struct net_device *dev) static int shaper_close(struct net_device *dev) { struct shaper *shaper=dev->priv; - shaper_flush(shaper); + struct sk_buff *skb; + + while ((skb = skb_dequeue(&shaper->sendq)) != NULL) + dev_kfree_skb(skb); + + spin_lock_bh(&shaper->lock); + shaper_kick(shaper); + spin_unlock_bh(&shaper->lock); + del_timer_sync(&shaper->timer); return 0; } @@ -576,6 +565,7 @@ static void shaper_init_priv(struct net_device *dev) init_timer(&sh->timer); sh->timer.function=shaper_timer; sh->timer.data=(unsigned long)sh; + spin_lock_init(&sh->lock); } /* diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 127324f014de..23b713c700b3 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -1154,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *net_dev) sis_priv->rx_skbuff[i] = skb; sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE; sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev, - skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); } sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC); @@ -1776,7 +1776,7 @@ static int sis900_rx(struct net_device *net_dev) sis_priv->rx_skbuff[entry] = skb; sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; sis_priv->rx_ring[entry].bufptr = - pci_map_single(sis_priv->pci_dev, skb->tail, + pci_map_single(sis_priv->pci_dev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); sis_priv->dirty_rx++; } @@ -1809,7 +1809,7 @@ static int sis900_rx(struct net_device *net_dev) sis_priv->rx_skbuff[entry] = skb; sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; sis_priv->rx_ring[entry].bufptr = - pci_map_single(sis_priv->pci_dev, skb->tail, + pci_map_single(sis_priv->pci_dev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); } } diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 30e8d589d167..3dbb1cb09ed8 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -7,7 +7,7 @@ * of the original driver such as link fail-over and link management because * those should be done at higher levels. * - * Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org> + * Copyright (C) 2004, 2005 Stephen Hemminger <shemminger@osdl.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 @@ -42,19 +42,20 @@ #include "skge.h" #define DRV_NAME "skge" -#define DRV_VERSION "0.6" +#define DRV_VERSION "0.7" #define PFX DRV_NAME " " #define DEFAULT_TX_RING_SIZE 128 #define DEFAULT_RX_RING_SIZE 512 #define MAX_TX_RING_SIZE 1024 #define MAX_RX_RING_SIZE 4096 +#define RX_COPY_THRESHOLD 128 +#define RX_BUF_SIZE 1536 #define PHY_RETRIES 1000 #define ETH_JUMBO_MTU 9000 #define TX_WATCHDOG (5 * HZ) #define NAPI_WEIGHT 64 #define BLINK_HZ (HZ/4) -#define LINK_POLL_HZ (HZ/10) MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); @@ -70,28 +71,17 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); static const struct pci_device_id skge_id_table[] = { - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_SYSKONNECT, 0x9E00, /* SK-9Exx */ - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_MARVELL, 0x4320, /* Gigabit Ethernet Controller */ - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_MARVELL, 0x5005, /* Marvell (11ab), Belkin */ - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064, - PCI_ANY_ID, PCI_ANY_ID }, + { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940) }, + { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) }, + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ + { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, + { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032) }, + { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) }, { 0 } }; MODULE_DEVICE_TABLE(pci, skge_id_table); @@ -99,19 +89,22 @@ MODULE_DEVICE_TABLE(pci, skge_id_table); static int skge_up(struct net_device *dev); static int skge_down(struct net_device *dev); static void skge_tx_clean(struct skge_port *skge); -static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); -static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); +static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); +static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); static void genesis_get_stats(struct skge_port *skge, u64 *data); static void yukon_get_stats(struct skge_port *skge, u64 *data); static void yukon_init(struct skge_hw *hw, int port); static void yukon_reset(struct skge_hw *hw, int port); static void genesis_mac_init(struct skge_hw *hw, int port); static void genesis_reset(struct skge_hw *hw, int port); +static void genesis_link_up(struct skge_port *skge); +/* Avoid conditionals by using array */ static const int txqaddr[] = { Q_XA1, Q_XA2 }; static const int rxqaddr[] = { Q_R1, Q_R2 }; static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; +static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 }; /* Don't need to look at whole 16K. * last interesting register is descriptor poll timer. @@ -154,7 +147,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, static int wol_supported(const struct skge_hw *hw) { return !((hw->chip_id == CHIP_ID_GENESIS || - (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0))); + (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0))); } static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) @@ -170,7 +163,7 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct skge_port *skge = netdev_priv(dev); struct skge_hw *hw = skge->hw; - if(wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) + if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) return -EOPNOTSUPP; if (wol->wolopts == WAKE_MAGIC && !wol_supported(hw)) @@ -190,6 +183,36 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) return 0; } +/* Determine supported/adverised modes based on hardware. + * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx + */ +static u32 skge_supported_modes(const struct skge_hw *hw) +{ + u32 supported; + + if (iscopper(hw)) { + supported = SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full + | SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full + | SUPPORTED_1000baseT_Half + | SUPPORTED_1000baseT_Full + | SUPPORTED_Autoneg| SUPPORTED_TP; + + if (hw->chip_id == CHIP_ID_GENESIS) + supported &= ~(SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full + | SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full); + + else if (hw->chip_id == CHIP_ID_YUKON) + supported &= ~SUPPORTED_1000baseT_Half; + } else + supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE + | SUPPORTED_Autoneg; + + return supported; +} static int skge_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) @@ -198,38 +221,13 @@ static int skge_get_settings(struct net_device *dev, struct skge_hw *hw = skge->hw; ecmd->transceiver = XCVR_INTERNAL; + ecmd->supported = skge_supported_modes(hw); if (iscopper(hw)) { - if (hw->chip_id == CHIP_ID_GENESIS) - ecmd->supported = SUPPORTED_1000baseT_Full - | SUPPORTED_1000baseT_Half - | SUPPORTED_Autoneg | SUPPORTED_TP; - else { - ecmd->supported = SUPPORTED_10baseT_Half - | SUPPORTED_10baseT_Full - | SUPPORTED_100baseT_Half - | SUPPORTED_100baseT_Full - | SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full - | SUPPORTED_Autoneg| SUPPORTED_TP; - - if (hw->chip_id == CHIP_ID_YUKON) - ecmd->supported &= ~SUPPORTED_1000baseT_Half; - - else if (hw->chip_id == CHIP_ID_YUKON_FE) - ecmd->supported &= ~(SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full); - } - ecmd->port = PORT_TP; ecmd->phy_address = hw->phy_addr; - } else { - ecmd->supported = SUPPORTED_1000baseT_Full - | SUPPORTED_FIBRE - | SUPPORTED_Autoneg; - + } else ecmd->port = PORT_FIBRE; - } ecmd->advertising = skge->advertising; ecmd->autoneg = skge->autoneg; @@ -238,65 +236,57 @@ static int skge_get_settings(struct net_device *dev, return 0; } -static u32 skge_modes(const struct skge_hw *hw) -{ - u32 modes = ADVERTISED_Autoneg - | ADVERTISED_1000baseT_Full | ADVERTISED_1000baseT_Half - | ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half - | ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half; - - if (iscopper(hw)) { - modes |= ADVERTISED_TP; - switch(hw->chip_id) { - case CHIP_ID_GENESIS: - modes &= ~(ADVERTISED_100baseT_Full - | ADVERTISED_100baseT_Half - | ADVERTISED_10baseT_Full - | ADVERTISED_10baseT_Half); - break; - - case CHIP_ID_YUKON: - modes &= ~ADVERTISED_1000baseT_Half; - break; - - case CHIP_ID_YUKON_FE: - modes &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full); - break; - } - } else { - modes |= ADVERTISED_FIBRE; - modes &= ~ADVERTISED_1000baseT_Half; - } - return modes; -} - static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct skge_port *skge = netdev_priv(dev); const struct skge_hw *hw = skge->hw; + u32 supported = skge_supported_modes(hw); if (ecmd->autoneg == AUTONEG_ENABLE) { - if (ecmd->advertising & skge_modes(hw)) - return -EINVAL; + ecmd->advertising = supported; + skge->duplex = -1; + skge->speed = -1; } else { + u32 setting; + switch(ecmd->speed) { case SPEED_1000: - if (hw->chip_id == CHIP_ID_YUKON_FE) + if (ecmd->duplex == DUPLEX_FULL) + setting = SUPPORTED_1000baseT_Full; + else if (ecmd->duplex == DUPLEX_HALF) + setting = SUPPORTED_1000baseT_Half; + else return -EINVAL; break; case SPEED_100: + if (ecmd->duplex == DUPLEX_FULL) + setting = SUPPORTED_100baseT_Full; + else if (ecmd->duplex == DUPLEX_HALF) + setting = SUPPORTED_100baseT_Half; + else + return -EINVAL; + break; + case SPEED_10: - if (iscopper(hw) || hw->chip_id == CHIP_ID_GENESIS) + if (ecmd->duplex == DUPLEX_FULL) + setting = SUPPORTED_10baseT_Full; + else if (ecmd->duplex == DUPLEX_HALF) + setting = SUPPORTED_10baseT_Half; + else return -EINVAL; break; default: return -EINVAL; } + + if ((setting & supported) == 0) + return -EINVAL; + + skge->speed = ecmd->speed; + skge->duplex = ecmd->duplex; } skge->autoneg = ecmd->autoneg; - skge->speed = ecmd->speed; - skge->duplex = ecmd->duplex; skge->advertising = ecmd->advertising; if (netif_running(dev)) { @@ -393,7 +383,7 @@ static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data) { int i; - switch(stringset) { + switch (stringset) { case ETH_SS_STATS: for (i = 0; i < ARRAY_SIZE(skge_stats); i++) memcpy(data + i * ETH_GSTRING_LEN, @@ -511,14 +501,6 @@ static int skge_set_rx_csum(struct net_device *dev, u32 data) return 0; } -/* Only Yukon II supports TSO (not implemented yet) */ -static int skge_set_tso(struct net_device *dev, u32 data) -{ - if (data) - return -EOPNOTSUPP; - return 0; -} - static void skge_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *ecmd) { @@ -540,9 +522,9 @@ static int skge_set_pauseparam(struct net_device *dev, skge->autoneg = ecmd->autoneg; if (ecmd->rx_pause && ecmd->tx_pause) skge->flow_control = FLOW_MODE_SYMMETRIC; - else if(ecmd->rx_pause && !ecmd->tx_pause) + else if (ecmd->rx_pause && !ecmd->tx_pause) skge->flow_control = FLOW_MODE_REM_SEND; - else if(!ecmd->rx_pause && ecmd->tx_pause) + else if (!ecmd->rx_pause && ecmd->tx_pause) skge->flow_control = FLOW_MODE_LOC_SEND; else skge->flow_control = FLOW_MODE_NONE; @@ -559,8 +541,6 @@ static inline u32 hwkhz(const struct skge_hw *hw) { if (hw->chip_id == CHIP_ID_GENESIS) return 53215; /* or: 53.125 MHz */ - else if (hw->chip_id == CHIP_ID_YUKON_EC) - return 125000; /* or: 125.000 MHz */ else return 78215; /* or: 78.125 MHz */ } @@ -643,30 +623,18 @@ static int skge_set_coalesce(struct net_device *dev, static void skge_led_on(struct skge_hw *hw, int port) { if (hw->chip_id == CHIP_ID_GENESIS) { - skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON); + skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); skge_write8(hw, B0_LED, LED_STAT_ON); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_TST), LED_T_ON); - skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 100); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START); + skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON); + skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); + skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); - switch (hw->phy_type) { - case SK_PHY_BCOM: - skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, - PHY_B_PEC_LED_ON); - break; - case SK_PHY_LONE: - skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG, - 0x0800); - break; - default: - skge_write8(hw, SKGEMAC_REG(port, TX_LED_TST), LED_T_ON); - skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 100); - skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START); - } + /* For Broadcom Phy only */ + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); } else { - skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); - skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, + gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); + gm_phy_write(hw, port, PHY_MARV_LED_OVER, PHY_M_LED_MO_DUP(MO_LED_ON) | PHY_M_LED_MO_10(MO_LED_ON) | PHY_M_LED_MO_100(MO_LED_ON) | @@ -678,28 +646,17 @@ static void skge_led_on(struct skge_hw *hw, int port) static void skge_led_off(struct skge_hw *hw, int port) { if (hw->chip_id == CHIP_ID_GENESIS) { - skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_OFF); + skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); skge_write8(hw, B0_LED, LED_STAT_OFF); - skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 0); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_T_OFF); + skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); + skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); - switch (hw->phy_type) { - case SK_PHY_BCOM: - skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, - PHY_B_PEC_LED_OFF); - break; - case SK_PHY_LONE: - skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG, - PHY_L_LC_LEDT); - break; - default: - skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 0); - skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_T_OFF); - } + /* Broadcom only */ + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); } else { - skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); - skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, + gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); + gm_phy_write(hw, port, PHY_MARV_LED_OVER, PHY_M_LED_MO_DUP(MO_LED_OFF) | PHY_M_LED_MO_10(MO_LED_OFF) | PHY_M_LED_MO_100(MO_LED_OFF) | @@ -730,7 +687,7 @@ static int skge_phys_id(struct net_device *dev, u32 data) { struct skge_port *skge = netdev_priv(dev); - if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) + if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); /* start blinking */ @@ -763,8 +720,6 @@ static struct ethtool_ops skge_ethtool_ops = { .set_pauseparam = skge_set_pauseparam, .get_coalesce = skge_get_coalesce, .set_coalesce = skge_set_coalesce, - .get_tso = ethtool_op_get_tso, - .set_tso = skge_set_tso, .get_sg = ethtool_op_get_sg, .set_sg = skge_set_sg, .get_tx_csum = ethtool_op_get_tx_csum, @@ -793,6 +748,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base) for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) { e->desc = d; + e->skb = NULL; if (i == ring->count - 1) { e->next = ring->start; d->next_offset = base; @@ -806,24 +762,23 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base) return 0; } -/* Setup buffer for receiving */ -static inline int skge_rx_alloc(struct skge_port *skge, - struct skge_element *e) +static struct sk_buff *skge_rx_alloc(struct net_device *dev, unsigned int size) { - unsigned long bufsize = skge->netdev->mtu + ETH_HLEN; /* VLAN? */ - struct skge_rx_desc *rd = e->desc; - struct sk_buff *skb; - u64 map; + struct sk_buff *skb = dev_alloc_skb(size); - skb = dev_alloc_skb(bufsize + NET_IP_ALIGN); - if (unlikely(!skb)) { - printk(KERN_DEBUG PFX "%s: out of memory for receive\n", - skge->netdev->name); - return -ENOMEM; + if (likely(skb)) { + skb->dev = dev; + skb_reserve(skb, NET_IP_ALIGN); } + return skb; +} - skb->dev = skge->netdev; - skb_reserve(skb, NET_IP_ALIGN); +/* Allocate and setup a new buffer for receiving */ +static void skge_rx_setup(struct skge_port *skge, struct skge_element *e, + struct sk_buff *skb, unsigned int bufsize) +{ + struct skge_rx_desc *rd = e->desc; + u64 map; map = pci_map_single(skge->hw->pdev, skb->data, bufsize, PCI_DMA_FROMDEVICE); @@ -841,55 +796,69 @@ static inline int skge_rx_alloc(struct skge_port *skge, rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize; pci_unmap_addr_set(e, mapaddr, map); pci_unmap_len_set(e, maplen, bufsize); - return 0; } -/* Free all unused buffers in receive ring, assumes receiver stopped */ +/* Resume receiving using existing skb, + * Note: DMA address is not changed by chip. + * MTU not changed while receiver active. + */ +static void skge_rx_reuse(struct skge_element *e, unsigned int size) +{ + struct skge_rx_desc *rd = e->desc; + + rd->csum2 = 0; + rd->csum2_start = ETH_HLEN; + + wmb(); + + rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | size; +} + + +/* Free all buffers in receive ring, assumes receiver stopped */ static void skge_rx_clean(struct skge_port *skge) { struct skge_hw *hw = skge->hw; struct skge_ring *ring = &skge->rx_ring; struct skge_element *e; - for (e = ring->to_clean; e != ring->to_use; e = e->next) { + e = ring->start; + do { struct skge_rx_desc *rd = e->desc; rd->control = 0; - - pci_unmap_single(hw->pdev, - pci_unmap_addr(e, mapaddr), - pci_unmap_len(e, maplen), - PCI_DMA_FROMDEVICE); - dev_kfree_skb(e->skb); - e->skb = NULL; - } - ring->to_clean = e; + if (e->skb) { + pci_unmap_single(hw->pdev, + pci_unmap_addr(e, mapaddr), + pci_unmap_len(e, maplen), + PCI_DMA_FROMDEVICE); + dev_kfree_skb(e->skb); + e->skb = NULL; + } + } while ((e = e->next) != ring->start); } + /* Allocate buffers for receive ring - * For receive: to_use is refill location - * to_clean is next received frame. - * - * if (to_use == to_clean) - * then ring all frames in ring need buffers - * if (to_use->next == to_clean) - * then ring all frames in ring have buffers + * For receive: to_clean is next received frame. */ static int skge_rx_fill(struct skge_port *skge) { struct skge_ring *ring = &skge->rx_ring; struct skge_element *e; - int ret = 0; + unsigned int bufsize = skge->rx_buf_size; - for (e = ring->to_use; e->next != ring->to_clean; e = e->next) { - if (skge_rx_alloc(skge, e)) { - ret = 1; - break; - } + e = ring->start; + do { + struct sk_buff *skb = skge_rx_alloc(skge->netdev, bufsize); - } - ring->to_use = e; + if (!skb) + return -ENOMEM; + + skge_rx_setup(skge, e, skb, bufsize); + } while ( (e = e->next) != ring->start); - return ret; + ring->to_clean = ring->start; + return 0; } static void skge_link_up(struct skge_port *skge) @@ -919,50 +888,50 @@ static void skge_link_down(struct skge_port *skge) printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); } -static u16 skge_xm_phy_read(struct skge_hw *hw, int port, u16 reg) +static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) { int i; u16 v; - skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); - v = skge_xm_read16(hw, port, XM_PHY_DATA); - if (hw->phy_type != SK_PHY_XMAC) { - for (i = 0; i < PHY_RETRIES; i++) { - udelay(1); - if (skge_xm_read16(hw, port, XM_MMU_CMD) - & XM_MMU_PHY_RDY) - goto ready; - } + xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); + v = xm_read16(hw, port, XM_PHY_DATA); - printk(KERN_WARNING PFX "%s: phy read timed out\n", - hw->dev[port]->name); - return 0; - ready: - v = skge_xm_read16(hw, port, XM_PHY_DATA); + /* Need to wait for external PHY */ + for (i = 0; i < PHY_RETRIES; i++) { + udelay(1); + if (xm_read16(hw, port, XM_MMU_CMD) + & XM_MMU_PHY_RDY) + goto ready; } + printk(KERN_WARNING PFX "%s: phy read timed out\n", + hw->dev[port]->name); + return 0; + ready: + v = xm_read16(hw, port, XM_PHY_DATA); + return v; } -static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) +static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) { int i; - skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); + xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); for (i = 0; i < PHY_RETRIES; i++) { - if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) + if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) goto ready; - cpu_relax(); + udelay(1); } printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", hw->dev[port]->name); ready: - skge_xm_write16(hw, port, XM_PHY_DATA, val); + xm_write16(hw, port, XM_PHY_DATA, val); for (i = 0; i < PHY_RETRIES; i++) { udelay(1); - if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) + if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) return; } printk(KERN_WARNING PFX "%s: phy write timed out\n", @@ -999,34 +968,112 @@ static void genesis_init(struct skge_hw *hw) static void genesis_reset(struct skge_hw *hw, int port) { - int i; - u64 zero = 0; + const u8 zero[8] = { 0 }; /* reset the statistics module */ - skge_xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); - skge_xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ - skge_xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */ - skge_xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ - skge_xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ + xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); + xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ + xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */ + xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ + xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ - /* disable all PHY IRQs */ - if (hw->phy_type == SK_PHY_BCOM) - skge_xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); + /* disable Broadcom PHY IRQ */ + xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); - skge_xm_outhash(hw, port, XM_HSM, (u8 *) &zero); - for (i = 0; i < 15; i++) - skge_xm_outaddr(hw, port, XM_EXM(i), (u8 *) &zero); - skge_xm_outhash(hw, port, XM_SRC_CHK, (u8 *) &zero); + xm_outhash(hw, port, XM_HSM, zero); } -static void genesis_mac_init(struct skge_hw *hw, int port) +/* Convert mode to MII values */ +static const u16 phy_pause_map[] = { + [FLOW_MODE_NONE] = 0, + [FLOW_MODE_LOC_SEND] = PHY_AN_PAUSE_ASYM, + [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP, + [FLOW_MODE_REM_SEND] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM, +}; + + +/* Check status of Broadcom phy link */ +static void bcom_check_link(struct skge_hw *hw, int port) { - struct skge_port *skge = netdev_priv(hw->dev[port]); + struct net_device *dev = hw->dev[port]; + struct skge_port *skge = netdev_priv(dev); + u16 status; + + /* read twice because of latch */ + (void) xm_phy_read(hw, port, PHY_BCOM_STAT); + status = xm_phy_read(hw, port, PHY_BCOM_STAT); + + pr_debug("bcom_check_link status=0x%x\n", status); + + if ((status & PHY_ST_LSYNC) == 0) { + u16 cmd = xm_read16(hw, port, XM_MMU_CMD); + cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); + xm_write16(hw, port, XM_MMU_CMD, cmd); + /* dummy read to ensure writing */ + (void) xm_read16(hw, port, XM_MMU_CMD); + + if (netif_carrier_ok(dev)) + skge_link_down(skge); + } else { + if (skge->autoneg == AUTONEG_ENABLE && + (status & PHY_ST_AN_OVER)) { + u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP); + u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); + + if (lpa & PHY_B_AN_RF) { + printk(KERN_NOTICE PFX "%s: remote fault\n", + dev->name); + return; + } + + /* Check Duplex mismatch */ + switch(aux & PHY_B_AS_AN_RES_MSK) { + case PHY_B_RES_1000FD: + skge->duplex = DUPLEX_FULL; + break; + case PHY_B_RES_1000HD: + skge->duplex = DUPLEX_HALF; + break; + default: + printk(KERN_NOTICE PFX "%s: duplex mismatch\n", + dev->name); + return; + } + + + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ + switch (aux & PHY_B_AS_PAUSE_MSK) { + case PHY_B_AS_PAUSE_MSK: + skge->flow_control = FLOW_MODE_SYMMETRIC; + break; + case PHY_B_AS_PRR: + skge->flow_control = FLOW_MODE_REM_SEND; + break; + case PHY_B_AS_PRT: + skge->flow_control = FLOW_MODE_LOC_SEND; + break; + default: + skge->flow_control = FLOW_MODE_NONE; + } + + skge->speed = SPEED_1000; + } + + if (!netif_carrier_ok(dev)) + genesis_link_up(skge); + } +} + +/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional + * Phy on for 100 or 10Mbit operation + */ +static void bcom_phy_init(struct skge_port *skge, int jumbo) +{ + struct skge_hw *hw = skge->hw; + int port = skge->port; int i; - u32 r; - u16 id1; - u16 ctrl1, ctrl2, ctrl3, ctrl4, ctrl5; + u16 id1, r, ext, ctl; /* magic workaround patterns for Broadcom */ static const struct { @@ -1042,16 +1089,120 @@ static void genesis_mac_init(struct skge_hw *hw, int port) { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, }; + pr_debug("bcom_phy_init\n"); + + /* read Id from external PHY (all have the same address) */ + id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); + + /* Optimize MDIO transfer by suppressing preamble. */ + r = xm_read16(hw, port, XM_MMU_CMD); + r |= XM_MMU_NO_PRE; + xm_write16(hw, port, XM_MMU_CMD,r); + + switch(id1) { + case PHY_BCOM_ID1_C0: + /* + * Workaround BCOM Errata for the C0 type. + * Write magic patterns to reserved registers. + */ + for (i = 0; i < ARRAY_SIZE(C0hack); i++) + xm_phy_write(hw, port, + C0hack[i].reg, C0hack[i].val); + + break; + case PHY_BCOM_ID1_A1: + /* + * Workaround BCOM Errata for the A1 type. + * Write magic patterns to reserved registers. + */ + for (i = 0; i < ARRAY_SIZE(A1hack); i++) + xm_phy_write(hw, port, + A1hack[i].reg, A1hack[i].val); + break; + } + + /* + * Workaround BCOM Errata (#10523) for all BCom PHYs. + * Disable Power Management after reset. + */ + r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); + r |= PHY_B_AC_DIS_PM; + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r); + + /* Dummy read */ + xm_read16(hw, port, XM_ISRC); + + ext = PHY_B_PEC_EN_LTR; /* enable tx led */ + ctl = PHY_CT_SP1000; /* always 1000mbit */ + + if (skge->autoneg == AUTONEG_ENABLE) { + /* + * Workaround BCOM Errata #1 for the C5 type. + * 1000Base-T Link Acquisition Failure in Slave Mode + * Set Repeater/DTE bit 10 of the 1000Base-T Control Register + */ + u16 adv = PHY_B_1000C_RD; + if (skge->advertising & ADVERTISED_1000baseT_Half) + adv |= PHY_B_1000C_AHD; + if (skge->advertising & ADVERTISED_1000baseT_Full) + adv |= PHY_B_1000C_AFD; + xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv); + + ctl |= PHY_CT_ANE | PHY_CT_RE_CFG; + } else { + if (skge->duplex == DUPLEX_FULL) + ctl |= PHY_CT_DUP_MD; + /* Force to slave */ + xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE); + } + + /* Set autonegotiation pause parameters */ + xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, + phy_pause_map[skge->flow_control] | PHY_AN_CSMA); + + /* Handle Jumbo frames */ + if (jumbo) { + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, + PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK); + + ext |= PHY_B_PEC_HIGH_LA; + + } + + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); + xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); + + /* Use link status change interrrupt */ + xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); + + bcom_check_link(hw, port); +} + +static void genesis_mac_init(struct skge_hw *hw, int port) +{ + struct net_device *dev = hw->dev[port]; + struct skge_port *skge = netdev_priv(dev); + int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN; + int i; + u32 r; + const u8 zero[6] = { 0 }; + + /* Clear MIB counters */ + xm_write16(hw, port, XM_STAT_CMD, + XM_SC_CLR_RXC | XM_SC_CLR_TXC); + /* Clear two times according to Errata #3 */ + xm_write16(hw, port, XM_STAT_CMD, + XM_SC_CLR_RXC | XM_SC_CLR_TXC); /* initialize Rx, Tx and Link LED */ - skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON); - skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); + skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); + skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START); - skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START); + skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); + skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); /* Unreset the XMAC. */ - skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); + skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); /* * Perform additional initialization for external PHYs, @@ -1059,67 +1210,56 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * GMII mode. */ spin_lock_bh(&hw->phy_lock); - if (hw->phy_type != SK_PHY_XMAC) { - /* Take PHY out of reset. */ - r = skge_read32(hw, B2_GP_IO); - if (port == 0) - r |= GP_DIR_0|GP_IO_0; - else - r |= GP_DIR_2|GP_IO_2; - - skge_write32(hw, B2_GP_IO, r); - skge_read32(hw, B2_GP_IO); - - /* Enable GMII mode on the XMAC. */ - skge_xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); - - id1 = skge_xm_phy_read(hw, port, PHY_XMAC_ID1); - - /* Optimize MDIO transfer by suppressing preamble. */ - skge_xm_write16(hw, port, XM_MMU_CMD, - skge_xm_read16(hw, port, XM_MMU_CMD) - | XM_MMU_NO_PRE); - - if (id1 == PHY_BCOM_ID1_C0) { - /* - * Workaround BCOM Errata for the C0 type. - * Write magic patterns to reserved registers. - */ - for (i = 0; i < ARRAY_SIZE(C0hack); i++) - skge_xm_phy_write(hw, port, - C0hack[i].reg, C0hack[i].val); - - } else if (id1 == PHY_BCOM_ID1_A1) { - /* - * Workaround BCOM Errata for the A1 type. - * Write magic patterns to reserved registers. - */ - for (i = 0; i < ARRAY_SIZE(A1hack); i++) - skge_xm_phy_write(hw, port, - A1hack[i].reg, A1hack[i].val); - } + /* Take external Phy out of reset */ + r = skge_read32(hw, B2_GP_IO); + if (port == 0) + r |= GP_DIR_0|GP_IO_0; + else + r |= GP_DIR_2|GP_IO_2; - /* - * Workaround BCOM Errata (#10523) for all BCom PHYs. - * Disable Power Management after reset. - */ - r = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); - skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); - } + skge_write32(hw, B2_GP_IO, r); + skge_read32(hw, B2_GP_IO); + spin_unlock_bh(&hw->phy_lock); - /* Dummy read */ - skge_xm_read16(hw, port, XM_ISRC); + /* Enable GMII interfac */ + xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); + + bcom_phy_init(skge, jumbo); + + /* Set Station Address */ + xm_outaddr(hw, port, XM_SA, dev->dev_addr); + + /* We don't use match addresses so clear */ + for (i = 1; i < 16; i++) + xm_outaddr(hw, port, XM_EXM(i), zero); - r = skge_xm_read32(hw, port, XM_MODE); - skge_xm_write32(hw, port, XM_MODE, r|XM_MD_CSA); + /* configure Rx High Water Mark (XM_RX_HI_WM) */ + xm_write16(hw, port, XM_RX_HI_WM, 1450); /* We don't need the FCS appended to the packet. */ - r = skge_xm_read16(hw, port, XM_RX_CMD); - skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_STRIP_FCS); + r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS; + if (jumbo) + r |= XM_RX_BIG_PK_OK; + + if (skge->duplex == DUPLEX_HALF) { + /* + * If in manual half duplex mode the other side might be in + * full duplex mode, so ignore if a carrier extension is not seen + * on frames received + */ + r |= XM_RX_DIS_CEXT; + } + xm_write16(hw, port, XM_RX_CMD, r); + /* We want short frames padded to 60 bytes. */ - r = skge_xm_read16(hw, port, XM_TX_CMD); - skge_xm_write16(hw, port, XM_TX_CMD, r | XM_TX_AUTO_PAD); + xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD); + + /* + * Bump up the transmit threshold. This helps hold off transmit + * underruns when we're blasting traffic from both ports at once. + */ + xm_write16(hw, port, XM_TX_THR, 512); /* * Enable the reception of all error frames. This is is @@ -1135,19 +1275,22 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * case the XMAC will start transfering frames out of the * RX FIFO as soon as the FIFO threshold is reached. */ - r = skge_xm_read32(hw, port, XM_MODE); - skge_xm_write32(hw, port, XM_MODE, - XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT| - XM_MD_RX_ERR|XM_MD_RX_IRLE); + xm_write32(hw, port, XM_MODE, XM_DEF_MODE); - skge_xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr); - skge_xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr); /* - * Bump up the transmit threshold. This helps hold off transmit - * underruns when we're blasting traffic from both ports at once. + * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK) + * - Enable all bits excepting 'Octets Rx OK Low CntOv' + * and 'Octets Rx OK Hi Cnt Ov'. */ - skge_xm_write16(hw, port, XM_TX_THR, 512); + xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK); + + /* + * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK) + * - Enable all bits excepting 'Octets Tx OK Low CntOv' + * and 'Octets Tx OK Hi Cnt Ov'. + */ + xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK); /* Configure MAC arbiter */ skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR); @@ -1164,137 +1307,30 @@ static void genesis_mac_init(struct skge_hw *hw, int port) skge_write8(hw, B3_MA_RCINI_TX2, 0); /* Configure Rx MAC FIFO */ - skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_CLR); - skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT); - skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD); + skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_CLR); + skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT); + skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD); /* Configure Tx MAC FIFO */ - skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_CLR); - skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); - skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD); + skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_CLR); + skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); + skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD); - if (hw->dev[port]->mtu > ETH_DATA_LEN) { + if (jumbo) { /* Enable frame flushing if jumbo frames used */ - skge_write16(hw, SKGEMAC_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH); + skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH); } else { /* enable timeout timers if normal frames */ skge_write16(hw, B3_PA_CTRL, - port == 0 ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2); + (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2); } - - - r = skge_xm_read16(hw, port, XM_RX_CMD); - if (hw->dev[port]->mtu > ETH_DATA_LEN) - skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_BIG_PK_OK); - else - skge_xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK)); - - switch (hw->phy_type) { - case SK_PHY_XMAC: - if (skge->autoneg == AUTONEG_ENABLE) { - ctrl1 = PHY_X_AN_FD | PHY_X_AN_HD; - - switch (skge->flow_control) { - case FLOW_MODE_NONE: - ctrl1 |= PHY_X_P_NO_PAUSE; - break; - case FLOW_MODE_LOC_SEND: - ctrl1 |= PHY_X_P_ASYM_MD; - break; - case FLOW_MODE_SYMMETRIC: - ctrl1 |= PHY_X_P_SYM_MD; - break; - case FLOW_MODE_REM_SEND: - ctrl1 |= PHY_X_P_BOTH_MD; - break; - } - - skge_xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl1); - ctrl2 = PHY_CT_ANE | PHY_CT_RE_CFG; - } else { - ctrl2 = 0; - if (skge->duplex == DUPLEX_FULL) - ctrl2 |= PHY_CT_DUP_MD; - } - - skge_xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl2); - break; - - case SK_PHY_BCOM: - ctrl1 = PHY_CT_SP1000; - ctrl2 = 0; - ctrl3 = PHY_SEL_TYPE; - ctrl4 = PHY_B_PEC_EN_LTR; - ctrl5 = PHY_B_AC_TX_TST; - - if (skge->autoneg == AUTONEG_ENABLE) { - /* - * Workaround BCOM Errata #1 for the C5 type. - * 1000Base-T Link Acquisition Failure in Slave Mode - * Set Repeater/DTE bit 10 of the 1000Base-T Control Register - */ - ctrl2 |= PHY_B_1000C_RD; - if (skge->advertising & ADVERTISED_1000baseT_Half) - ctrl2 |= PHY_B_1000C_AHD; - if (skge->advertising & ADVERTISED_1000baseT_Full) - ctrl2 |= PHY_B_1000C_AFD; - - /* Set Flow-control capabilities */ - switch (skge->flow_control) { - case FLOW_MODE_NONE: - ctrl3 |= PHY_B_P_NO_PAUSE; - break; - case FLOW_MODE_LOC_SEND: - ctrl3 |= PHY_B_P_ASYM_MD; - break; - case FLOW_MODE_SYMMETRIC: - ctrl3 |= PHY_B_P_SYM_MD; - break; - case FLOW_MODE_REM_SEND: - ctrl3 |= PHY_B_P_BOTH_MD; - break; - } - - /* Restart Auto-negotiation */ - ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; - } else { - if (skge->duplex == DUPLEX_FULL) - ctrl1 |= PHY_CT_DUP_MD; - - ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ - } - - skge_xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); - skge_xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); - - if (skge->netdev->mtu > ETH_DATA_LEN) { - ctrl4 |= PHY_B_PEC_HIGH_LA; - ctrl5 |= PHY_B_AC_LONG_PACK; - - skge_xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); - } - - skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); - skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); - break; - } - spin_unlock_bh(&hw->phy_lock); - - /* Clear MIB counters */ - skge_xm_write16(hw, port, XM_STAT_CMD, - XM_SC_CLR_RXC | XM_SC_CLR_TXC); - /* Clear two times according to Errata #3 */ - skge_xm_write16(hw, port, XM_STAT_CMD, - XM_SC_CLR_RXC | XM_SC_CLR_TXC); - - /* Start polling for link status */ - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); } static void genesis_stop(struct skge_port *skge) { struct skge_hw *hw = skge->hw; int port = skge->port; + u32 reg; /* Clear Tx packet arbiter timeout IRQ */ skge_write16(hw, B3_PA_CTRL, @@ -1304,33 +1340,30 @@ static void genesis_stop(struct skge_port *skge) * If the transfer stucks at the MAC the STOP command will not * terminate if we don't flush the XMAC's transmit FIFO ! */ - skge_xm_write32(hw, port, XM_MODE, - skge_xm_read32(hw, port, XM_MODE)|XM_MD_FTF); + xm_write32(hw, port, XM_MODE, + xm_read32(hw, port, XM_MODE)|XM_MD_FTF); /* Reset the MAC */ - skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); + skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); /* For external PHYs there must be special handling */ - if (hw->phy_type != SK_PHY_XMAC) { - u32 reg = skge_read32(hw, B2_GP_IO); - - if (port == 0) { - reg |= GP_DIR_0; - reg &= ~GP_IO_0; - } else { - reg |= GP_DIR_2; - reg &= ~GP_IO_2; - } - skge_write32(hw, B2_GP_IO, reg); - skge_read32(hw, B2_GP_IO); + reg = skge_read32(hw, B2_GP_IO); + if (port == 0) { + reg |= GP_DIR_0; + reg &= ~GP_IO_0; + } else { + reg |= GP_DIR_2; + reg &= ~GP_IO_2; } + skge_write32(hw, B2_GP_IO, reg); + skge_read32(hw, B2_GP_IO); - skge_xm_write16(hw, port, XM_MMU_CMD, - skge_xm_read16(hw, port, XM_MMU_CMD) + xm_write16(hw, port, XM_MMU_CMD, + xm_read16(hw, port, XM_MMU_CMD) & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); - skge_xm_read16(hw, port, XM_MMU_CMD); + xm_read16(hw, port, XM_MMU_CMD); } @@ -1341,11 +1374,11 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data) int i; unsigned long timeout = jiffies + HZ; - skge_xm_write16(hw, port, + xm_write16(hw, port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC); /* wait for update to complete */ - while (skge_xm_read16(hw, port, XM_STAT_CMD) + while (xm_read16(hw, port, XM_STAT_CMD) & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) { if (time_after(jiffies, timeout)) break; @@ -1353,68 +1386,60 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data) } /* special case for 64 bit octet counter */ - data[0] = (u64) skge_xm_read32(hw, port, XM_TXO_OK_HI) << 32 - | skge_xm_read32(hw, port, XM_TXO_OK_LO); - data[1] = (u64) skge_xm_read32(hw, port, XM_RXO_OK_HI) << 32 - | skge_xm_read32(hw, port, XM_RXO_OK_LO); + data[0] = (u64) xm_read32(hw, port, XM_TXO_OK_HI) << 32 + | xm_read32(hw, port, XM_TXO_OK_LO); + data[1] = (u64) xm_read32(hw, port, XM_RXO_OK_HI) << 32 + | xm_read32(hw, port, XM_RXO_OK_LO); for (i = 2; i < ARRAY_SIZE(skge_stats); i++) - data[i] = skge_xm_read32(hw, port, skge_stats[i].xmac_offset); + data[i] = xm_read32(hw, port, skge_stats[i].xmac_offset); } static void genesis_mac_intr(struct skge_hw *hw, int port) { struct skge_port *skge = netdev_priv(hw->dev[port]); - u16 status = skge_xm_read16(hw, port, XM_ISRC); - - pr_debug("genesis_intr status %x\n", status); - if (hw->phy_type == SK_PHY_XMAC) { - /* LInk down, start polling for state change */ - if (status & XM_IS_INP_ASS) { - skge_xm_write16(hw, port, XM_IMSK, - skge_xm_read16(hw, port, XM_IMSK) | XM_IS_INP_ASS); - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); - } - else if (status & XM_IS_AND) - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); - } + u16 status = xm_read16(hw, port, XM_ISRC); + + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", + skge->netdev->name, status); if (status & XM_IS_TXF_UR) { - skge_xm_write32(hw, port, XM_MODE, XM_MD_FTF); + xm_write32(hw, port, XM_MODE, XM_MD_FTF); ++skge->net_stats.tx_fifo_errors; } if (status & XM_IS_RXF_OV) { - skge_xm_write32(hw, port, XM_MODE, XM_MD_FRF); + xm_write32(hw, port, XM_MODE, XM_MD_FRF); ++skge->net_stats.rx_fifo_errors; } } -static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) +static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) { int i; - skge_gma_write16(hw, port, GM_SMI_DATA, val); - skge_gma_write16(hw, port, GM_SMI_CTRL, + gma_write16(hw, port, GM_SMI_DATA, val); + gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg)); for (i = 0; i < PHY_RETRIES; i++) { udelay(1); - if (!(skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) + if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) break; } } -static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg) +static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg) { int i; - skge_gma_write16(hw, port, GM_SMI_CTRL, + gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); for (i = 0; i < PHY_RETRIES; i++) { udelay(1); - if (skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) + if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) goto ready; } @@ -1422,24 +1447,7 @@ static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg) hw->dev[port]->name); return 0; ready: - return skge_gma_read16(hw, port, GM_SMI_DATA); -} - -static void genesis_link_down(struct skge_port *skge) -{ - struct skge_hw *hw = skge->hw; - int port = skge->port; - - pr_debug("genesis_link_down\n"); - - skge_xm_write16(hw, port, XM_MMU_CMD, - skge_xm_read16(hw, port, XM_MMU_CMD) - & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); - - /* dummy read to ensure writing */ - (void) skge_xm_read16(hw, port, XM_MMU_CMD); - - skge_link_down(skge); + return gma_read16(hw, port, GM_SMI_DATA); } static void genesis_link_up(struct skge_port *skge) @@ -1450,7 +1458,7 @@ static void genesis_link_up(struct skge_port *skge) u32 mode, msk; pr_debug("genesis_link_up\n"); - cmd = skge_xm_read16(hw, port, XM_MMU_CMD); + cmd = xm_read16(hw, port, XM_MMU_CMD); /* * enabling pause frame reception is required for 1000BT @@ -1458,14 +1466,15 @@ static void genesis_link_up(struct skge_port *skge) */ if (skge->flow_control == FLOW_MODE_NONE || skge->flow_control == FLOW_MODE_LOC_SEND) + /* Disable Pause Frame Reception */ cmd |= XM_MMU_IGN_PF; else /* Enable Pause Frame Reception */ cmd &= ~XM_MMU_IGN_PF; - skge_xm_write16(hw, port, XM_MMU_CMD, cmd); + xm_write16(hw, port, XM_MMU_CMD, cmd); - mode = skge_xm_read32(hw, port, XM_MODE); + mode = xm_read32(hw, port, XM_MODE); if (skge->flow_control == FLOW_MODE_SYMMETRIC || skge->flow_control == FLOW_MODE_LOC_SEND) { /* @@ -1479,10 +1488,10 @@ static void genesis_link_up(struct skge_port *skge) /* XM_PAUSE_DA = '010000C28001' (default) */ /* XM_MAC_PTIME = 0xffff (maximum) */ /* remember this value is defined in big endian (!) */ - skge_xm_write16(hw, port, XM_MAC_PTIME, 0xffff); + xm_write16(hw, port, XM_MAC_PTIME, 0xffff); mode |= XM_PAUSE_MODE; - skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE); + skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE); } else { /* * disable pause frame generation is required for 1000BT @@ -1491,125 +1500,68 @@ static void genesis_link_up(struct skge_port *skge) /* Disable Pause Mode in Mode Register */ mode &= ~XM_PAUSE_MODE; - skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE); + skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE); } - skge_xm_write32(hw, port, XM_MODE, mode); + xm_write32(hw, port, XM_MODE, mode); msk = XM_DEF_MSK; - if (hw->phy_type != SK_PHY_XMAC) - msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */ + /* disable GP0 interrupt bit for external Phy */ + msk |= XM_IS_INP_ASS; - skge_xm_write16(hw, port, XM_IMSK, msk); - skge_xm_read16(hw, port, XM_ISRC); + xm_write16(hw, port, XM_IMSK, msk); + xm_read16(hw, port, XM_ISRC); /* get MMU Command Reg. */ - cmd = skge_xm_read16(hw, port, XM_MMU_CMD); - if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL) + cmd = xm_read16(hw, port, XM_MMU_CMD); + if (skge->duplex == DUPLEX_FULL) cmd |= XM_MMU_GMII_FD; - if (hw->phy_type == SK_PHY_BCOM) { - /* - * Workaround BCOM Errata (#10523) for all BCom Phys - * Enable Power Management after link up - */ - skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, - skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) - & ~PHY_B_AC_DIS_PM); - skge_xm_phy_write(hw, port, PHY_BCOM_INT_MASK, - PHY_B_DEF_MSK); - } + /* + * Workaround BCOM Errata (#10523) for all BCom Phys + * Enable Power Management after link up + */ + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, + xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) + & ~PHY_B_AC_DIS_PM); + xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); /* enable Rx/Tx */ - skge_xm_write16(hw, port, XM_MMU_CMD, + xm_write16(hw, port, XM_MMU_CMD, cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX); skge_link_up(skge); } -static void genesis_bcom_intr(struct skge_port *skge) +static inline void bcom_phy_intr(struct skge_port *skge) { struct skge_hw *hw = skge->hw; int port = skge->port; - u16 stat = skge_xm_phy_read(hw, port, PHY_BCOM_INT_STAT); + u16 isrc; + + isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x\n", + skge->netdev->name, isrc); - pr_debug("genesis_bcom intr stat=%x\n", stat); + if (isrc & PHY_B_IS_PSE) + printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n", + hw->dev[port]->name); /* Workaround BCom Errata: * enable and disable loopback mode if "NO HCD" occurs. */ - if (stat & PHY_B_IS_NO_HDCL) { - u16 ctrl = skge_xm_phy_read(hw, port, PHY_BCOM_CTRL); - skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, + if (isrc & PHY_B_IS_NO_HDCL) { + u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL); + xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl | PHY_CT_LOOP); - skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, + xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl & ~PHY_CT_LOOP); } - stat = skge_xm_phy_read(hw, port, PHY_BCOM_STAT); - if (stat & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) { - u16 aux = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); - if ( !(aux & PHY_B_AS_LS) && netif_carrier_ok(skge->netdev)) - genesis_link_down(skge); - - else if (stat & PHY_B_IS_LST_CHANGE) { - if (aux & PHY_B_AS_AN_C) { - switch (aux & PHY_B_AS_AN_RES_MSK) { - case PHY_B_RES_1000FD: - skge->duplex = DUPLEX_FULL; - break; - case PHY_B_RES_1000HD: - skge->duplex = DUPLEX_HALF; - break; - } - - switch (aux & PHY_B_AS_PAUSE_MSK) { - case PHY_B_AS_PAUSE_MSK: - skge->flow_control = FLOW_MODE_SYMMETRIC; - break; - case PHY_B_AS_PRR: - skge->flow_control = FLOW_MODE_REM_SEND; - break; - case PHY_B_AS_PRT: - skge->flow_control = FLOW_MODE_LOC_SEND; - break; - default: - skge->flow_control = FLOW_MODE_NONE; - } - skge->speed = SPEED_1000; - } - genesis_link_up(skge); - } - else - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); - } -} + if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) + bcom_check_link(hw, port); -/* Perodic poll of phy status to check for link transistion */ -static void skge_link_timer(unsigned long __arg) -{ - struct skge_port *skge = (struct skge_port *) __arg; - struct skge_hw *hw = skge->hw; - int port = skge->port; - - if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev)) - return; - - spin_lock_bh(&hw->phy_lock); - if (hw->phy_type == SK_PHY_BCOM) - genesis_bcom_intr(skge); - else { - int i; - for (i = 0; i < 3; i++) - if (skge_xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) - break; - - if (i == 3) - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); - else - genesis_link_up(skge); - } - spin_unlock_bh(&hw->phy_lock); } /* Marvell Phy Initailization */ @@ -1621,31 +1573,27 @@ static void yukon_init(struct skge_hw *hw, int port) pr_debug("yukon_init\n"); if (skge->autoneg == AUTONEG_ENABLE) { - u16 ectrl = skge_gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); + u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | PHY_M_EC_MAC_S_MSK); ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); - /* on PHY 88E1111 there is a change for downshift control */ - if (hw->chip_id == CHIP_ID_YUKON_EC) - ectrl |= PHY_M_EC_M_DSC_2(0) | PHY_M_EC_DOWN_S_ENA; - else - ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); + ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); - skge_gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); + gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); } - ctrl = skge_gm_phy_read(hw, port, PHY_MARV_CTRL); + ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL); if (skge->autoneg == AUTONEG_DISABLE) ctrl &= ~PHY_CT_ANE; ctrl |= PHY_CT_RESET; - skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); + gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); ctrl = 0; ct1000 = 0; - adv = PHY_SEL_TYPE; + adv = PHY_AN_CSMA; if (skge->autoneg == AUTONEG_ENABLE) { if (iscopper(hw)) { @@ -1661,41 +1609,12 @@ static void yukon_init(struct skge_hw *hw, int port) adv |= PHY_M_AN_10_FD; if (skge->advertising & ADVERTISED_10baseT_Half) adv |= PHY_M_AN_10_HD; - - /* Set Flow-control capabilities */ - switch (skge->flow_control) { - case FLOW_MODE_NONE: - adv |= PHY_B_P_NO_PAUSE; - break; - case FLOW_MODE_LOC_SEND: - adv |= PHY_B_P_ASYM_MD; - break; - case FLOW_MODE_SYMMETRIC: - adv |= PHY_B_P_SYM_MD; - break; - case FLOW_MODE_REM_SEND: - adv |= PHY_B_P_BOTH_MD; - break; - } - } else { /* special defines for FIBER (88E1011S only) */ + } else /* special defines for FIBER (88E1011S only) */ adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; - /* Set Flow-control capabilities */ - switch (skge->flow_control) { - case FLOW_MODE_NONE: - adv |= PHY_M_P_NO_PAUSE_X; - break; - case FLOW_MODE_LOC_SEND: - adv |= PHY_M_P_ASYM_MD_X; - break; - case FLOW_MODE_SYMMETRIC: - adv |= PHY_M_P_SYM_MD_X; - break; - case FLOW_MODE_REM_SEND: - adv |= PHY_M_P_BOTH_MD_X; - break; - } - } + /* Set Flow-control capabilities */ + adv |= phy_pause_map[skge->flow_control]; + /* Restart Auto-negotiation */ ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; } else { @@ -1717,36 +1636,23 @@ static void yukon_init(struct skge_hw *hw, int port) ctrl |= PHY_CT_RESET; } - if (hw->chip_id != CHIP_ID_YUKON_FE) - skge_gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); + gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); - skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); - skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); + gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); + gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); /* Setup Phy LED's */ ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS); ledover = 0; - if (hw->chip_id == CHIP_ID_YUKON_FE) { - /* on 88E3082 these bits are at 11..9 (shifted left) */ - ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1; - - skge_gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, - ((skge_gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR) - - & ~PHY_M_FELP_LED1_MSK) - | PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL))); - } else { - /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ - ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; + ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; - /* turn off the Rx LED (LED_RX) */ - ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); - } + /* turn off the Rx LED (LED_RX) */ + ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); /* disable blink mode (LED_DUPLEX) on collisions */ ctrl |= PHY_M_LEDC_DP_CTRL; - skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); + gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) { /* turn on 100 Mbps LED (LED_LINK100) */ @@ -1754,25 +1660,25 @@ static void yukon_init(struct skge_hw *hw, int port) } if (ledover) - skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); + gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); /* Enable phy interrupt on autonegotiation complete (or link up) */ if (skge->autoneg == AUTONEG_ENABLE) - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); + gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); else - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); + gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); } static void yukon_reset(struct skge_hw *hw, int port) { - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */ - skge_gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */ - skge_gma_write16(hw, port, GM_MC_ADDR_H2, 0); - skge_gma_write16(hw, port, GM_MC_ADDR_H3, 0); - skge_gma_write16(hw, port, GM_MC_ADDR_H4, 0); + gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */ + gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */ + gma_write16(hw, port, GM_MC_ADDR_H2, 0); + gma_write16(hw, port, GM_MC_ADDR_H3, 0); + gma_write16(hw, port, GM_MC_ADDR_H4, 0); - skge_gma_write16(hw, port, GM_RX_CTRL, - skge_gma_read16(hw, port, GM_RX_CTRL) + gma_write16(hw, port, GM_RX_CTRL, + gma_read16(hw, port, GM_RX_CTRL) | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); } @@ -1785,17 +1691,17 @@ static void yukon_mac_init(struct skge_hw *hw, int port) /* WA code for COMA mode -- set PHY reset */ if (hw->chip_id == CHIP_ID_YUKON_LITE && - chip_rev(hw) == CHIP_REV_YU_LITE_A3) + hw->chip_rev == CHIP_REV_YU_LITE_A3) skge_write32(hw, B2_GP_IO, (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); /* hard reset */ - skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), GPC_RST_SET); - skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_RST_SET); + skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); + skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); /* WA code for COMA mode -- clear PHY reset */ if (hw->chip_id == CHIP_ID_YUKON_LITE && - chip_rev(hw) == CHIP_REV_YU_LITE_A3) + hw->chip_rev == CHIP_REV_YU_LITE_A3) skge_write32(hw, B2_GP_IO, (skge_read32(hw, B2_GP_IO) | GP_DIR_9) & ~GP_IO_9); @@ -1806,13 +1712,13 @@ static void yukon_mac_init(struct skge_hw *hw, int port) reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB; /* Clear GMC reset */ - skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_SET); - skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); - skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); + skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); + skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); + skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); if (skge->autoneg == AUTONEG_DISABLE) { reg = GM_GPCR_AU_ALL_DIS; - skge_gma_write16(hw, port, GM_GP_CTRL, - skge_gma_read16(hw, port, GM_GP_CTRL) | reg); + gma_write16(hw, port, GM_GP_CTRL, + gma_read16(hw, port, GM_GP_CTRL) | reg); switch (skge->speed) { case SPEED_1000: @@ -1828,7 +1734,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; switch (skge->flow_control) { case FLOW_MODE_NONE: - skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); + skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; break; case FLOW_MODE_LOC_SEND: @@ -1836,7 +1742,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; } - skge_gma_write16(hw, port, GM_GP_CTRL, reg); + gma_write16(hw, port, GM_GP_CTRL, reg); skge_read16(hw, GMAC_IRQ_SRC); spin_lock_bh(&hw->phy_lock); @@ -1844,25 +1750,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port) spin_unlock_bh(&hw->phy_lock); /* MIB clear */ - reg = skge_gma_read16(hw, port, GM_PHY_ADDR); - skge_gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); + reg = gma_read16(hw, port, GM_PHY_ADDR); + gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); for (i = 0; i < GM_MIB_CNT_SIZE; i++) - skge_gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i); - skge_gma_write16(hw, port, GM_PHY_ADDR, reg); + gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i); + gma_write16(hw, port, GM_PHY_ADDR, reg); /* transmit control */ - skge_gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF)); + gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF)); /* receive control reg: unicast + multicast + no FCS */ - skge_gma_write16(hw, port, GM_RX_CTRL, + gma_write16(hw, port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA); /* transmit flow control */ - skge_gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff); + gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff); /* transmit parameter */ - skge_gma_write16(hw, port, GM_TX_PARAM, + gma_write16(hw, port, GM_TX_PARAM, TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) | TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) | TX_IPG_JAM_DATA(TX_IPG_JAM_DEF)); @@ -1872,33 +1778,33 @@ static void yukon_mac_init(struct skge_hw *hw, int port) if (hw->dev[port]->mtu > 1500) reg |= GM_SMOD_JUMBO_ENA; - skge_gma_write16(hw, port, GM_SERIAL_MODE, reg); + gma_write16(hw, port, GM_SERIAL_MODE, reg); /* physical address: used for pause frames */ - skge_gm_set_addr(hw, port, GM_SRC_ADDR_1L, addr); + gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr); /* virtual address for data */ - skge_gm_set_addr(hw, port, GM_SRC_ADDR_2L, addr); + gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr); /* enable interrupt mask for counter overflows */ - skge_gma_write16(hw, port, GM_TX_IRQ_MSK, 0); - skge_gma_write16(hw, port, GM_RX_IRQ_MSK, 0); - skge_gma_write16(hw, port, GM_TR_IRQ_MSK, 0); + gma_write16(hw, port, GM_TX_IRQ_MSK, 0); + gma_write16(hw, port, GM_RX_IRQ_MSK, 0); + gma_write16(hw, port, GM_TR_IRQ_MSK, 0); /* Initialize Mac Fifo */ /* Configure Rx MAC FIFO */ - skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); + skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); reg = GMF_OPER_ON | GMF_RX_F_FL_ON; if (hw->chip_id == CHIP_ID_YUKON_LITE && - chip_rev(hw) == CHIP_REV_YU_LITE_A3) + hw->chip_rev == CHIP_REV_YU_LITE_A3) reg &= ~GMF_RX_F_FL_ON; - skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); - skge_write16(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), reg); - skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); + skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); + skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); + skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); /* Configure Tx MAC FIFO */ - skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); - skge_write16(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); + skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); + skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); } static void yukon_stop(struct skge_port *skge) @@ -1907,19 +1813,19 @@ static void yukon_stop(struct skge_port *skge) int port = skge->port; if (hw->chip_id == CHIP_ID_YUKON_LITE && - chip_rev(hw) == CHIP_REV_YU_LITE_A3) { + hw->chip_rev == CHIP_REV_YU_LITE_A3) { skge_write32(hw, B2_GP_IO, skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); } - skge_gma_write16(hw, port, GM_GP_CTRL, - skge_gma_read16(hw, port, GM_GP_CTRL) + gma_write16(hw, port, GM_GP_CTRL, + gma_read16(hw, port, GM_GP_CTRL) & ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA)); - skge_gma_read16(hw, port, GM_GP_CTRL); + gma_read16(hw, port, GM_GP_CTRL); /* set GPHY Control reset */ - skge_gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET); - skge_gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET); + gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET); + gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET); } static void yukon_get_stats(struct skge_port *skge, u64 *data) @@ -1928,39 +1834,40 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data) int port = skge->port; int i; - data[0] = (u64) skge_gma_read32(hw, port, GM_TXO_OK_HI) << 32 - | skge_gma_read32(hw, port, GM_TXO_OK_LO); - data[1] = (u64) skge_gma_read32(hw, port, GM_RXO_OK_HI) << 32 - | skge_gma_read32(hw, port, GM_RXO_OK_LO); + data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32 + | gma_read32(hw, port, GM_TXO_OK_LO); + data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32 + | gma_read32(hw, port, GM_RXO_OK_LO); for (i = 2; i < ARRAY_SIZE(skge_stats); i++) - data[i] = skge_gma_read32(hw, port, + data[i] = gma_read32(hw, port, skge_stats[i].gma_offset); } static void yukon_mac_intr(struct skge_hw *hw, int port) { - struct skge_port *skge = netdev_priv(hw->dev[port]); - u8 status = skge_read8(hw, SKGEMAC_REG(port, GMAC_IRQ_SRC)); + struct net_device *dev = hw->dev[port]; + struct skge_port *skge = netdev_priv(dev); + u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC)); + + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", + dev->name, status); - pr_debug("yukon_intr status %x\n", status); if (status & GM_IS_RX_FF_OR) { ++skge->net_stats.rx_fifo_errors; - skge_gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); + gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); } if (status & GM_IS_TX_FF_UR) { ++skge->net_stats.tx_fifo_errors; - skge_gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU); + gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU); } } static u16 yukon_speed(const struct skge_hw *hw, u16 aux) { - if (hw->chip_id == CHIP_ID_YUKON_FE) - return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10; - - switch(aux & PHY_M_PS_SPEED_MSK) { + switch (aux & PHY_M_PS_SPEED_MSK) { case PHY_M_PS_SPEED_1000: return SPEED_1000; case PHY_M_PS_SPEED_100: @@ -1981,15 +1888,15 @@ static void yukon_link_up(struct skge_port *skge) /* Enable Transmit FIFO Underrun */ skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK); - reg = skge_gma_read16(hw, port, GM_GP_CTRL); + reg = gma_read16(hw, port, GM_GP_CTRL); if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE) reg |= GM_GPCR_DUP_FULL; /* enable Rx/Tx */ reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; - skge_gma_write16(hw, port, GM_GP_CTRL, reg); + gma_write16(hw, port, GM_GP_CTRL, reg); - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); + gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); skge_link_up(skge); } @@ -1999,16 +1906,15 @@ static void yukon_link_down(struct skge_port *skge) int port = skge->port; pr_debug("yukon_link_down\n"); - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); - skge_gm_phy_write(hw, port, GM_GP_CTRL, - skge_gm_phy_read(hw, port, GM_GP_CTRL) + gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); + gm_phy_write(hw, port, GM_GP_CTRL, + gm_phy_read(hw, port, GM_GP_CTRL) & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); - if (hw->chip_id != CHIP_ID_YUKON_FE && - skge->flow_control == FLOW_MODE_REM_SEND) { + if (skge->flow_control == FLOW_MODE_REM_SEND) { /* restore Asymmetric Pause bit */ - skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, - skge_gm_phy_read(hw, port, + gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, + gm_phy_read(hw, port, PHY_MARV_AUNE_ADV) | PHY_M_AN_ASP); @@ -2027,20 +1933,21 @@ static void yukon_phy_intr(struct skge_port *skge) const char *reason = NULL; u16 istatus, phystat; - istatus = skge_gm_phy_read(hw, port, PHY_MARV_INT_STAT); - phystat = skge_gm_phy_read(hw, port, PHY_MARV_PHY_STAT); - pr_debug("yukon phy intr istat=%x phy_stat=%x\n", istatus, phystat); + istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); + phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); + + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x 0x%x\n", + skge->netdev->name, istatus, phystat); if (istatus & PHY_M_IS_AN_COMPL) { - if (skge_gm_phy_read(hw, port, PHY_MARV_AUNE_LP) + if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP) & PHY_M_AN_RF) { reason = "remote fault"; goto failed; } - if (!(hw->chip_id == CHIP_ID_YUKON_FE || hw->chip_id == CHIP_ID_YUKON_EC) - && (skge_gm_phy_read(hw, port, PHY_MARV_1000T_STAT) - & PHY_B_1000S_MSF)) { + if (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) { reason = "master/slave fault"; goto failed; } @@ -2054,10 +1961,6 @@ static void yukon_phy_intr(struct skge_port *skge) ? DUPLEX_FULL : DUPLEX_HALF; skge->speed = yukon_speed(hw, phystat); - /* Tx & Rx Pause Enabled bits are at 9..8 */ - if (hw->chip_id == CHIP_ID_YUKON_XL) - phystat >>= 6; - /* We are using IEEE 802.3z/D5.0 Table 37-4 */ switch (phystat & PHY_M_PS_PAUSE_MSK) { case PHY_M_PS_PAUSE_MSK: @@ -2075,9 +1978,9 @@ static void yukon_phy_intr(struct skge_port *skge) if (skge->flow_control == FLOW_MODE_NONE || (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF)) - skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); + skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); else - skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON); + skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); yukon_link_up(skge); return; } @@ -2161,6 +2064,12 @@ static int skge_up(struct net_device *dev) if (netif_msg_ifup(skge)) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); + if (dev->mtu > RX_BUF_SIZE) + skge->rx_buf_size = dev->mtu + ETH_HLEN + NET_IP_ALIGN; + else + skge->rx_buf_size = RX_BUF_SIZE; + + rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc); tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc); skge->mem_size = tx_size + rx_size; @@ -2173,7 +2082,8 @@ static int skge_up(struct net_device *dev) if ((err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma))) goto free_pci_mem; - if (skge_rx_fill(skge)) + err = skge_rx_fill(skge); + if (err) goto free_rx_ring; if ((err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size, @@ -2182,6 +2092,10 @@ static int skge_up(struct net_device *dev) skge->tx_avail = skge->tx_ring.count - 1; + /* Enable IRQ from port */ + hw->intr_mask |= portirqmask[port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); + /* Initialze MAC */ if (hw->chip_id == CHIP_ID_GENESIS) genesis_mac_init(hw, port); @@ -2189,7 +2103,7 @@ static int skge_up(struct net_device *dev) yukon_mac_init(hw, port); /* Configure RAMbuffers */ - chunk = hw->ram_size / (isdualport(hw) ? 4 : 2); + chunk = hw->ram_size / ((hw->ports + 1)*2); ram_addr = hw->ram_offset + 2 * chunk * port; skge_ramset(hw, rxqaddr[port], ram_addr, chunk); @@ -2227,7 +2141,6 @@ static int skge_down(struct net_device *dev) netif_stop_queue(dev); del_timer_sync(&skge->led_blink); - del_timer_sync(&skge->link_check); /* Stop transmitter */ skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); @@ -2240,12 +2153,12 @@ static int skge_down(struct net_device *dev) yukon_stop(skge); /* Disable Force Sync bit and Enable Alloc bit */ - skge_write8(hw, SKGEMAC_REG(port, TXA_CTRL), + skge_write8(hw, SK_REG(port, TXA_CTRL), TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); /* Stop Interval Timer and Limit Counter of Tx Arbiter */ - skge_write32(hw, SKGEMAC_REG(port, TXA_ITI_INI), 0L); - skge_write32(hw, SKGEMAC_REG(port, TXA_LIM_INI), 0L); + skge_write32(hw, SK_REG(port, TXA_ITI_INI), 0L); + skge_write32(hw, SK_REG(port, TXA_LIM_INI), 0L); /* Reset PCI FIFO */ skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET); @@ -2260,13 +2173,13 @@ static int skge_down(struct net_device *dev) skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET); if (hw->chip_id == CHIP_ID_GENESIS) { - skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_SET); - skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_SET); - skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_STOP); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_STOP); + skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); + skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET); + skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP); + skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP); } else { - skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); - skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); + skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); + skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); } /* turn off led's */ @@ -2299,10 +2212,10 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) local_irq_save(flags); if (!spin_trylock(&skge->tx_lock)) { - /* Collision - tell upper layer to requeue */ - local_irq_restore(flags); - return NETDEV_TX_LOCKED; - } + /* Collision - tell upper layer to requeue */ + local_irq_restore(flags); + return NETDEV_TX_LOCKED; + } if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) { netif_stop_queue(dev); @@ -2333,7 +2246,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) * does. Looks like hardware is wrong? */ if (ip->protocol == IPPROTO_UDP - && chip_rev(hw) == 0 && hw->chip_id == CHIP_ID_YUKON) + && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON) control = BMU_TCP_CHECK; else control = BMU_UDP_CHECK; @@ -2394,6 +2307,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) static inline void skge_tx_free(struct skge_hw *hw, struct skge_element *e) { + /* This ring element can be skb or fragment */ if (e->skb) { pci_unmap_single(hw->pdev, pci_unmap_addr(e, mapaddr), @@ -2438,16 +2352,17 @@ static void skge_tx_timeout(struct net_device *dev) static int skge_change_mtu(struct net_device *dev, int new_mtu) { int err = 0; + int running = netif_running(dev); - if(new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) + if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) return -EINVAL; - dev->mtu = new_mtu; - if (netif_running(dev)) { + if (running) skge_down(dev); + dev->mtu = new_mtu; + if (running) skge_up(dev); - } return err; } @@ -2462,7 +2377,9 @@ static void genesis_set_multicast(struct net_device *dev) u32 mode; u8 filter[8]; - mode = skge_xm_read32(hw, port, XM_MODE); + pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count); + + mode = xm_read32(hw, port, XM_MODE); mode |= XM_MD_ENA_HASH; if (dev->flags & IFF_PROMISC) mode |= XM_MD_ENA_PROM; @@ -2473,17 +2390,16 @@ static void genesis_set_multicast(struct net_device *dev) memset(filter, 0xff, sizeof(filter)); else { memset(filter, 0, sizeof(filter)); - for(i = 0; list && i < count; i++, list = list->next) { - u32 crc = crc32_le(~0, list->dmi_addr, ETH_ALEN); - u8 bit = 63 - (crc & 63); - + for (i = 0; list && i < count; i++, list = list->next) { + u32 crc, bit; + crc = ether_crc_le(ETH_ALEN, list->dmi_addr); + bit = ~crc & 0x3f; filter[bit/8] |= 1 << (bit%8); } } - skge_xm_outhash(hw, port, XM_HSM, filter); - - skge_xm_write32(hw, port, XM_MODE, mode); + xm_write32(hw, port, XM_MODE, mode); + xm_outhash(hw, port, XM_HSM, filter); } static void yukon_set_multicast(struct net_device *dev) @@ -2497,7 +2413,7 @@ static void yukon_set_multicast(struct net_device *dev) memset(filter, 0, sizeof(filter)); - reg = skge_gma_read16(hw, port, GM_RX_CTRL); + reg = gma_read16(hw, port, GM_RX_CTRL); reg |= GM_RXCR_UCF_ENA; if (dev->flags & IFF_PROMISC) /* promiscious */ @@ -2510,23 +2426,23 @@ static void yukon_set_multicast(struct net_device *dev) int i; reg |= GM_RXCR_MCF_ENA; - for(i = 0; list && i < dev->mc_count; i++, list = list->next) { + for (i = 0; list && i < dev->mc_count; i++, list = list->next) { u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f; filter[bit/8] |= 1 << (bit%8); } } - skge_gma_write16(hw, port, GM_MC_ADDR_H1, + gma_write16(hw, port, GM_MC_ADDR_H1, (u16)filter[0] | ((u16)filter[1] << 8)); - skge_gma_write16(hw, port, GM_MC_ADDR_H2, + gma_write16(hw, port, GM_MC_ADDR_H2, (u16)filter[2] | ((u16)filter[3] << 8)); - skge_gma_write16(hw, port, GM_MC_ADDR_H3, + gma_write16(hw, port, GM_MC_ADDR_H3, (u16)filter[4] | ((u16)filter[5] << 8)); - skge_gma_write16(hw, port, GM_MC_ADDR_H4, + gma_write16(hw, port, GM_MC_ADDR_H4, (u16)filter[6] | ((u16)filter[7] << 8)); - skge_gma_write16(hw, port, GM_RX_CTRL, reg); + gma_write16(hw, port, GM_RX_CTRL, reg); } static inline int bad_phy_status(const struct skge_hw *hw, u32 status) @@ -2545,28 +2461,76 @@ static void skge_rx_error(struct skge_port *skge, int slot, printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n", skge->netdev->name, slot, control, status); - if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) - || (control & BMU_BBC) > skge->netdev->mtu + VLAN_ETH_HLEN) + if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)) skge->net_stats.rx_length_errors++; - else { - if (skge->hw->chip_id == CHIP_ID_GENESIS) { - if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) - skge->net_stats.rx_length_errors++; - if (status & XMR_FS_FRA_ERR) - skge->net_stats.rx_frame_errors++; - if (status & XMR_FS_FCS_ERR) - skge->net_stats.rx_crc_errors++; - } else { - if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE)) - skge->net_stats.rx_length_errors++; - if (status & GMR_FS_FRAGMENT) - skge->net_stats.rx_frame_errors++; - if (status & GMR_FS_CRC_ERR) - skge->net_stats.rx_crc_errors++; + else if (skge->hw->chip_id == CHIP_ID_GENESIS) { + if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) + skge->net_stats.rx_length_errors++; + if (status & XMR_FS_FRA_ERR) + skge->net_stats.rx_frame_errors++; + if (status & XMR_FS_FCS_ERR) + skge->net_stats.rx_crc_errors++; + } else { + if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE)) + skge->net_stats.rx_length_errors++; + if (status & GMR_FS_FRAGMENT) + skge->net_stats.rx_frame_errors++; + if (status & GMR_FS_CRC_ERR) + skge->net_stats.rx_crc_errors++; + } +} + +/* Get receive buffer from descriptor. + * Handles copy of small buffers and reallocation failures + */ +static inline struct sk_buff *skge_rx_get(struct skge_port *skge, + struct skge_element *e, + unsigned int len) +{ + struct sk_buff *nskb, *skb; + + if (len < RX_COPY_THRESHOLD) { + nskb = skge_rx_alloc(skge->netdev, len + NET_IP_ALIGN); + if (unlikely(!nskb)) + return NULL; + + pci_dma_sync_single_for_cpu(skge->hw->pdev, + pci_unmap_addr(e, mapaddr), + len, PCI_DMA_FROMDEVICE); + memcpy(nskb->data, e->skb->data, len); + pci_dma_sync_single_for_device(skge->hw->pdev, + pci_unmap_addr(e, mapaddr), + len, PCI_DMA_FROMDEVICE); + + if (skge->rx_csum) { + struct skge_rx_desc *rd = e->desc; + nskb->csum = le16_to_cpu(rd->csum2); + nskb->ip_summed = CHECKSUM_HW; } + skge_rx_reuse(e, skge->rx_buf_size); + return nskb; + } else { + nskb = skge_rx_alloc(skge->netdev, skge->rx_buf_size); + if (unlikely(!nskb)) + return NULL; + + pci_unmap_single(skge->hw->pdev, + pci_unmap_addr(e, mapaddr), + pci_unmap_len(e, maplen), + PCI_DMA_FROMDEVICE); + skb = e->skb; + if (skge->rx_csum) { + struct skge_rx_desc *rd = e->desc; + skb->csum = le16_to_cpu(rd->csum2); + skb->ip_summed = CHECKSUM_HW; + } + + skge_rx_setup(skge, e, nskb, skge->rx_buf_size); + return skb; } } + static int skge_poll(struct net_device *dev, int *budget) { struct skge_port *skge = netdev_priv(dev); @@ -2575,13 +2539,12 @@ static int skge_poll(struct net_device *dev, int *budget) struct skge_element *e; unsigned int to_do = min(dev->quota, *budget); unsigned int work_done = 0; - int done; - static const u32 irqmask[] = { IS_PORT_1, IS_PORT_2 }; - for (e = ring->to_clean; e != ring->to_use && work_done < to_do; - e = e->next) { + pr_debug("skge_poll\n"); + + for (e = ring->to_clean; work_done < to_do; e = e->next) { struct skge_rx_desc *rd = e->desc; - struct sk_buff *skb = e->skb; + struct sk_buff *skb; u32 control, len, status; rmb(); @@ -2590,19 +2553,12 @@ static int skge_poll(struct net_device *dev, int *budget) break; len = control & BMU_BBC; - e->skb = NULL; - - pci_unmap_single(hw->pdev, - pci_unmap_addr(e, mapaddr), - pci_unmap_len(e, maplen), - PCI_DMA_FROMDEVICE); - status = rd->status; - if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) - || len > dev->mtu + VLAN_ETH_HLEN - || bad_phy_status(hw, status)) { + + if (unlikely((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) + || bad_phy_status(hw, status))) { skge_rx_error(skge, e - ring->start, control, status); - dev_kfree_skb(skb); + skge_rx_reuse(e, skge->rx_buf_size); continue; } @@ -2610,43 +2566,37 @@ static int skge_poll(struct net_device *dev, int *budget) printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n", dev->name, e - ring->start, rd->status, len); - skb_put(skb, len); - skb->protocol = eth_type_trans(skb, dev); - - if (skge->rx_csum) { - skb->csum = le16_to_cpu(rd->csum2); - skb->ip_summed = CHECKSUM_HW; - } + skb = skge_rx_get(skge, e, len); + if (likely(skb)) { + skb_put(skb, len); + skb->protocol = eth_type_trans(skb, dev); - dev->last_rx = jiffies; - netif_receive_skb(skb); + dev->last_rx = jiffies; + netif_receive_skb(skb); - ++work_done; + ++work_done; + } else + skge_rx_reuse(e, skge->rx_buf_size); } ring->to_clean = e; - *budget -= work_done; - dev->quota -= work_done; - done = work_done < to_do; - - if (skge_rx_fill(skge)) - done = 0; - /* restart receiver */ wmb(); skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START | CSR_IRQ_CL_F); - if (done) { - local_irq_disable(); - hw->intr_mask |= irqmask[skge->port]; - /* Order is important since data can get interrupted */ - skge_write32(hw, B0_IMSK, hw->intr_mask); - __netif_rx_complete(dev); - local_irq_enable(); - } + *budget -= work_done; + dev->quota -= work_done; - return !done; + if (work_done >= to_do) + return 1; /* not done */ + + local_irq_disable(); + __netif_rx_complete(dev); + hw->intr_mask |= portirqmask[skge->port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); + local_irq_enable(); + return 0; } static inline void skge_tx_intr(struct net_device *dev) @@ -2657,7 +2607,7 @@ static inline void skge_tx_intr(struct net_device *dev) struct skge_element *e; spin_lock(&skge->tx_lock); - for(e = ring->to_clean; e != ring->to_use; e = e->next) { + for (e = ring->to_clean; e != ring->to_use; e = e->next) { struct skge_tx_desc *td = e->desc; u32 control; @@ -2690,12 +2640,12 @@ static void skge_mac_parity(struct skge_hw *hw, int port) : (port == 0 ? "(port A)": "(port B")); if (hw->chip_id == CHIP_ID_GENESIS) - skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), + skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_PERR); else /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ - skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), - (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0) + skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), + (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE); } @@ -2703,16 +2653,16 @@ static void skge_pci_clear(struct skge_hw *hw) { u16 status; - status = skge_read16(hw, SKGEPCI_REG(PCI_STATUS)); + pci_read_config_word(hw->pdev, PCI_STATUS, &status); skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - skge_write16(hw, SKGEPCI_REG(PCI_STATUS), - status | PCI_STATUS_ERROR_BITS); + pci_write_config_word(hw->pdev, PCI_STATUS, + status | PCI_STATUS_ERROR_BITS); skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } static void skge_mac_intr(struct skge_hw *hw, int port) { - if (hw->chip_id == CHIP_ID_GENESIS) + if (hw->chip_id == CHIP_ID_GENESIS) genesis_mac_intr(hw, port); else yukon_mac_intr(hw, port); @@ -2726,9 +2676,9 @@ static void skge_error_irq(struct skge_hw *hw) if (hw->chip_id == CHIP_ID_GENESIS) { /* clear xmac errors */ if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1)) - skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT); + skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT); if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2)) - skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT); + skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT); } else { /* Timestamp (unused) overflow */ if (hwstatus & IS_IRQ_TIST_OV) @@ -2803,8 +2753,8 @@ static void skge_extirq(unsigned long data) if (hw->chip_id != CHIP_ID_GENESIS) yukon_phy_intr(skge); - else if (hw->phy_type == SK_PHY_BCOM) - genesis_bcom_intr(skge); + else + bcom_phy_intr(skge); } } spin_unlock(&hw->phy_lock); @@ -2824,19 +2774,14 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) return IRQ_NONE; status &= hw->intr_mask; - - if ((status & IS_R1_F) && netif_rx_schedule_prep(hw->dev[0])) { - status &= ~IS_R1_F; + if (status & IS_R1_F) { hw->intr_mask &= ~IS_R1_F; - skge_write32(hw, B0_IMSK, hw->intr_mask); - __netif_rx_schedule(hw->dev[0]); + netif_rx_schedule(hw->dev[0]); } - if ((status & IS_R2_F) && netif_rx_schedule_prep(hw->dev[1])) { - status &= ~IS_R2_F; + if (status & IS_R2_F) { hw->intr_mask &= ~IS_R2_F; - skge_write32(hw, B0_IMSK, hw->intr_mask); - __netif_rx_schedule(hw->dev[1]); + netif_rx_schedule(hw->dev[1]); } if (status & IS_XA1_F) @@ -2845,9 +2790,27 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) if (status & IS_XA2_F) skge_tx_intr(hw->dev[1]); + if (status & IS_PA_TO_RX1) { + struct skge_port *skge = netdev_priv(hw->dev[0]); + ++skge->net_stats.rx_over_errors; + skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX1); + } + + if (status & IS_PA_TO_RX2) { + struct skge_port *skge = netdev_priv(hw->dev[1]); + ++skge->net_stats.rx_over_errors; + skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2); + } + + if (status & IS_PA_TO_TX1) + skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX1); + + if (status & IS_PA_TO_TX2) + skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX2); + if (status & IS_MAC1) skge_mac_intr(hw, 0); - + if (status & IS_MAC2) skge_mac_intr(hw, 1); @@ -2859,8 +2822,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) tasklet_schedule(&hw->ext_tasklet); } - if (status) - skge_write32(hw, B0_IMSK, hw->intr_mask); + skge_write32(hw, B0_IMSK, hw->intr_mask); return IRQ_HANDLED; } @@ -2904,9 +2866,6 @@ static const struct { { CHIP_ID_YUKON, "Yukon" }, { CHIP_ID_YUKON_LITE, "Yukon-Lite"}, { CHIP_ID_YUKON_LP, "Yukon-LP"}, - { CHIP_ID_YUKON_XL, "Yukon-2 XL"}, - { CHIP_ID_YUKON_EC, "YUKON-2 EC"}, - { CHIP_ID_YUKON_FE, "YUKON-2 FE"}, }; static const char *skge_board_name(const struct skge_hw *hw) @@ -2930,8 +2889,8 @@ static const char *skge_board_name(const struct skge_hw *hw) static int skge_reset(struct skge_hw *hw) { u16 ctst; - u8 t8; - int i, ports; + u8 t8, mac_cfg; + int i; ctst = skge_read16(hw, B0_CTST); @@ -2952,12 +2911,9 @@ static int skge_reset(struct skge_hw *hw) hw->phy_type = skge_read8(hw, B2_E_1) & 0xf; hw->pmd_type = skge_read8(hw, B2_PMD_TYP); - switch(hw->chip_id) { + switch (hw->chip_id) { case CHIP_ID_GENESIS: switch (hw->phy_type) { - case SK_PHY_XMAC: - hw->phy_addr = PHY_ADDR_XMAC; - break; case SK_PHY_BCOM: hw->phy_addr = PHY_ADDR_BCOM; break; @@ -2986,8 +2942,9 @@ static int skge_reset(struct skge_hw *hw) return -EOPNOTSUPP; } - hw->mac_cfg = skge_read8(hw, B2_MAC_CFG); - ports = isdualport(hw) ? 2 : 1; + mac_cfg = skge_read8(hw, B2_MAC_CFG); + hw->ports = (mac_cfg & CFG_SNG_MAC) ? 1 : 2; + hw->chip_rev = (mac_cfg & CFG_CHIP_R_MSK) >> 4; /* read the adapters RAM size */ t8 = skge_read8(hw, B2_E_0); @@ -3010,9 +2967,9 @@ static int skge_reset(struct skge_hw *hw) /* switch power to VCC (WA for VAUX problem) */ skge_write8(hw, B0_POWER_CTRL, PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); - for (i = 0; i < ports; i++) { - skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); - skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); + for (i = 0; i < hw->ports; i++) { + skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); + skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); } } @@ -3022,8 +2979,8 @@ static int skge_reset(struct skge_hw *hw) skge_write8(hw, B0_LED, LED_STAT_ON); /* enable the Tx Arbiters */ - for (i = 0; i < ports; i++) - skge_write8(hw, SKGEMAC_REG(i, TXA_CTRL), TXA_ENA_ARB); + for (i = 0; i < hw->ports; i++) + skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB); /* Initialize ram interface */ skge_write16(hw, B3_RI_CTRL, RI_RST_CLR); @@ -3050,16 +3007,14 @@ static int skge_reset(struct skge_hw *hw) skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); skge_write32(hw, B2_IRQM_CTRL, TIM_START); - hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; - if (isdualport(hw)) - hw->intr_mask |= IS_PORT_2; + hw->intr_mask = IS_HW_ERR | IS_EXT_REG; skge_write32(hw, B0_IMSK, hw->intr_mask); if (hw->chip_id != CHIP_ID_GENESIS) skge_write8(hw, GMAC_IRQ_MSK, 0); spin_lock_bh(&hw->phy_lock); - for (i = 0; i < ports; i++) { + for (i = 0; i < hw->ports; i++) { if (hw->chip_id == CHIP_ID_GENESIS) genesis_reset(hw, i); else @@ -3071,7 +3026,8 @@ static int skge_reset(struct skge_hw *hw) } /* Initialize network device */ -static struct net_device *skge_devinit(struct skge_hw *hw, int port) +static struct net_device *skge_devinit(struct skge_hw *hw, int port, + int highmem) { struct skge_port *skge; struct net_device *dev = alloc_etherdev(sizeof(*skge)); @@ -3104,6 +3060,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port) #endif dev->irq = hw->pdev->irq; dev->features = NETIF_F_LLTX; + if (highmem) + dev->features |= NETIF_F_HIGHDMA; skge = netdev_priv(dev); skge->netdev = dev; @@ -3117,7 +3075,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port) skge->flow_control = FLOW_MODE_SYMMETRIC; skge->duplex = -1; skge->speed = -1; - skge->advertising = skge_modes(hw); + skge->advertising = skge_supported_modes(hw); hw->dev[port] = dev; @@ -3125,10 +3083,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port) spin_lock_init(&skge->tx_lock); - init_timer(&skge->link_check); - skge->link_check.function = skge_link_timer; - skge->link_check.data = (unsigned long) skge; - init_timer(&skge->led_blink); skge->led_blink.function = skge_blink_timer; skge->led_blink.data = (unsigned long) skge; @@ -3232,14 +3186,11 @@ static int __devinit skge_probe(struct pci_dev *pdev, printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", pci_resource_start(pdev, 0), pdev->irq, - skge_board_name(hw), chip_rev(hw)); + skge_board_name(hw), hw->chip_rev); - if ((dev = skge_devinit(hw, 0)) == NULL) + if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) goto err_out_led_off; - if (using_dac) - dev->features |= NETIF_F_HIGHDMA; - if ((err = register_netdev(dev))) { printk(KERN_ERR PFX "%s: cannot register net device\n", pci_name(pdev)); @@ -3248,10 +3199,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, skge_show_addr(dev); - if (isdualport(hw) && (dev1 = skge_devinit(hw, 1))) { - if (using_dac) - dev1->features |= NETIF_F_HIGHDMA; - + if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) { if (register_netdev(dev1) == 0) skge_show_addr(dev1); else { @@ -3288,7 +3236,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) struct skge_hw *hw = pci_get_drvdata(pdev); struct net_device *dev0, *dev1; - if(!hw) + if (!hw) return; if ((dev1 = hw->dev[1])) @@ -3316,7 +3264,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state) struct skge_hw *hw = pci_get_drvdata(pdev); int i, wol = 0; - for(i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; if (dev) { @@ -3349,11 +3297,11 @@ static int skge_resume(struct pci_dev *pdev) skge_reset(hw); - for(i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; if (dev) { netif_device_attach(dev); - if(netif_running(dev)) + if (netif_running(dev)) skge_up(dev); } } diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 36c62b68fab4..fced3d2bc072 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -7,31 +7,7 @@ /* PCI config registers */ #define PCI_DEV_REG1 0x40 #define PCI_DEV_REG2 0x44 -#ifndef PCI_VPD -#define PCI_VPD 0x50 -#endif - -/* PCI_OUR_REG_2 32 bit Our Register 2 */ -enum { - PCI_VPD_WR_THR = 0xff<<24, /* Bit 31..24: VPD Write Threshold */ - PCI_DEV_SEL = 0x7f<<17, /* Bit 23..17: EEPROM Device Select */ - PCI_VPD_ROM_SZ = 7 <<14, /* Bit 16..14: VPD ROM Size */ - /* Bit 13..12: reserved */ - PCI_EN_DUMMY_RD = 1<<3, /* Enable Dummy Read */ - PCI_REV_DESC = 1<<2, /* Reverse Desc. Bytes */ - PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */ -}; - -/* PCI_VPD_ADR_REG 16 bit VPD Address Register */ -enum { - PCI_VPD_FLAG = 1<<15, /* starts VPD rd/wr cycle */ - PCI_VPD_ADR_MSK =0x7fffL, /* Bit 14.. 0: VPD Address Mask */ - VPD_RES_ID = 0x82, - VPD_RES_READ = 0x90, - VPD_RES_WRITE = 0x81, - VPD_RES_END = 0x78, -}; - +#define PCI_REV_DESC 0x4 #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ PCI_STATUS_SIG_SYSTEM_ERROR | \ @@ -39,7 +15,6 @@ enum { PCI_STATUS_REC_TARGET_ABORT | \ PCI_STATUS_PARITY) - enum csr_regs { B0_RAP = 0x0000, B0_CTST = 0x0004, @@ -229,8 +204,11 @@ enum { IS_XA2_F = 1<<1, /* Q_XA2 End of Frame */ IS_XA2_C = 1<<0, /* Q_XA2 Encoding Error */ - IS_PORT_1 = IS_XA1_F| IS_R1_F| IS_MAC1, - IS_PORT_2 = IS_XA2_F| IS_R2_F| IS_MAC2, + IS_TO_PORT1 = IS_PA_TO_RX1 | IS_PA_TO_TX1, + IS_TO_PORT2 = IS_PA_TO_RX2 | IS_PA_TO_TX2, + + IS_PORT_1 = IS_XA1_F| IS_R1_F | IS_TO_PORT1 | IS_MAC1, + IS_PORT_2 = IS_XA2_F| IS_R2_F | IS_TO_PORT2 | IS_MAC2, }; @@ -288,14 +266,6 @@ enum { CHIP_REV_YU_LITE_A3 = 7, /* Chip Rev. for YUKON-Lite A3 */ }; -/* B2_LD_TEST 8 bit EPROM loader test register */ -enum { - LD_T_ON = 1<<3, /* Loader Test mode on */ - LD_T_OFF = 1<<2, /* Loader Test mode off */ - LD_T_STEP = 1<<1, /* Decrement FPROM addr. Counter */ - LD_START = 1<<0, /* Start loading FPROM */ -}; - /* B2_TI_CTRL 8 bit Timer control */ /* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */ enum { @@ -313,16 +283,6 @@ enum { TIM_T_STEP = 1<<0, /* Test step */ }; -/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */ -/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */ -/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */ -enum { - DPT_MSK = 0x00ffffffL, /* Bit 23.. 0: Desc Poll Timer Bits */ - - DPT_START = 1<<1, /* Start Descriptor Poll Timer */ - DPT_STOP = 1<<0, /* Stop Descriptor Poll Timer */ -}; - /* B2_GP_IO 32 bit General Purpose I/O Register */ enum { GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */ @@ -348,30 +308,6 @@ enum { GP_IO_0 = 1<<0, /* IO_0 pin */ }; -/* Rx/Tx Path related Arbiter Test Registers */ -/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */ -/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */ -/* B3_PA_TEST 16 bit Packet Arbiter Test Register */ -/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */ -enum { - TX2_T_EV = 1<<15,/* TX2 Timeout/Recv Event occured */ - TX2_T_ON = 1<<14,/* TX2 Timeout/Recv Timer Test On */ - TX2_T_OFF = 1<<13,/* TX2 Timeout/Recv Timer Tst Off */ - TX2_T_STEP = 1<<12,/* TX2 Timeout/Recv Timer Step */ - TX1_T_EV = 1<<11,/* TX1 Timeout/Recv Event occured */ - TX1_T_ON = 1<<10,/* TX1 Timeout/Recv Timer Test On */ - TX1_T_OFF = 1<<9, /* TX1 Timeout/Recv Timer Tst Off */ - TX1_T_STEP = 1<<8, /* TX1 Timeout/Recv Timer Step */ - RX2_T_EV = 1<<7, /* RX2 Timeout/Recv Event occured */ - RX2_T_ON = 1<<6, /* RX2 Timeout/Recv Timer Test On */ - RX2_T_OFF = 1<<5, /* RX2 Timeout/Recv Timer Tst Off */ - RX2_T_STEP = 1<<4, /* RX2 Timeout/Recv Timer Step */ - RX1_T_EV = 1<<3, /* RX1 Timeout/Recv Event occured */ - RX1_T_ON = 1<<2, /* RX1 Timeout/Recv Timer Test On */ - RX1_T_OFF = 1<<1, /* RX1 Timeout/Recv Timer Tst Off */ - RX1_T_STEP = 1<<0, /* RX1 Timeout/Recv Timer Step */ -}; - /* Descriptor Bit Definition */ /* TxCtrl Transmit Buffer Control Field */ /* RxCtrl Receive Buffer Control Field */ @@ -428,14 +364,6 @@ enum { RI_RST_SET = 1<<0, /* Set RAM Interface Reset */ }; -/* B3_RI_TEST 8 bit RAM Iface Test Register */ -enum { - RI_T_EV = 1<<3, /* Timeout Event occured */ - RI_T_ON = 1<<2, /* Timeout Timer Test On */ - RI_T_OFF = 1<<1, /* Timeout Timer Test Off */ - RI_T_STEP = 1<<0, /* Timeout Timer Step */ -}; - /* MAC Arbiter Registers */ /* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */ enum { @@ -452,19 +380,6 @@ enum { #define SK_PKT_TO_MAX 0xffff /* Maximum value */ #define SK_RI_TO_53 36 /* RAM interface timeout */ - -/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */ -enum { - MA_ENA_REC_TX2 = 1<<7, /* Enable Recovery Timer TX2 */ - MA_DIS_REC_TX2 = 1<<6, /* Disable Recovery Timer TX2 */ - MA_ENA_REC_TX1 = 1<<5, /* Enable Recovery Timer TX1 */ - MA_DIS_REC_TX1 = 1<<4, /* Disable Recovery Timer TX1 */ - MA_ENA_REC_RX2 = 1<<3, /* Enable Recovery Timer RX2 */ - MA_DIS_REC_RX2 = 1<<2, /* Disable Recovery Timer RX2 */ - MA_ENA_REC_RX1 = 1<<1, /* Enable Recovery Timer RX1 */ - MA_DIS_REC_RX1 = 1<<0, /* Disable Recovery Timer RX1 */ -}; - /* Packet Arbiter Registers */ /* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ enum { @@ -488,7 +403,7 @@ enum { PA_ENA_TO_TX1 | PA_ENA_TO_TX2) -/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ +/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */ /* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ /* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ /* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ @@ -511,7 +426,7 @@ enum { /* * Bank 4 - 5 */ -/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ +/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */ enum { TXA_ITI_INI = 0x0200,/* 32 bit Tx Arb Interval Timer Init Val*/ TXA_ITI_VAL = 0x0204,/* 32 bit Tx Arb Interval Timer Value */ @@ -537,7 +452,7 @@ enum { /* Queue Register Offsets, use Q_ADDR() to access */ enum { - B8_Q_REGS = 0x0400, /* base of Queue registers */ + B8_Q_REGS = 0x0400, /* base of Queue registers */ Q_D = 0x00, /* 8*32 bit Current Descriptor */ Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */ Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */ @@ -618,8 +533,7 @@ enum { enum { PHY_ADDR_XMAC = 0<<8, PHY_ADDR_BCOM = 1<<8, - PHY_ADDR_LONE = 3<<8, - PHY_ADDR_NAT = 0<<8, + /* GPHY address (bits 15..11 of SMI control reg) */ PHY_ADDR_MARV = 0, }; @@ -986,7 +900,7 @@ enum { LINKLED_BLINK_OFF = 0x10, LINKLED_BLINK_ON = 0x20, }; - + /* GMAC and GPHY Control Registers (YUKON only) */ enum { GMAC_CTRL = 0x0f00,/* 32 bit GMAC Control Reg */ @@ -1151,54 +1065,6 @@ enum { PHY_MARV_FE_SPEC_2 = 0x1c,/* 16 bit r/w Specific Control Reg. 2 */ }; -/* Level One-PHY Registers, indirect addressed over XMAC */ -enum { - PHY_LONE_CTRL = 0x00,/* 16 bit r/w PHY Control Register */ - PHY_LONE_STAT = 0x01,/* 16 bit r/o PHY Status Register */ - PHY_LONE_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */ - PHY_LONE_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */ - PHY_LONE_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ - PHY_LONE_AUNE_LP = 0x05,/* 16 bit r/o Link Part Ability Reg */ - PHY_LONE_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ - PHY_LONE_NEPG = 0x07,/* 16 bit r/w Next Page Register */ - PHY_LONE_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */ - /* Level One-specific registers */ - PHY_LONE_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */ - PHY_LONE_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */ - PHY_LONE_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Reg */ - PHY_LONE_PORT_CFG = 0x10,/* 16 bit r/w Port Configuration Reg*/ - PHY_LONE_Q_STAT = 0x11,/* 16 bit r/o Quick Status Reg */ - PHY_LONE_INT_ENAB = 0x12,/* 16 bit r/w Interrupt Enable Reg */ - PHY_LONE_INT_STAT = 0x13,/* 16 bit r/o Interrupt Status Reg */ - PHY_LONE_LED_CFG = 0x14,/* 16 bit r/w LED Configuration Reg */ - PHY_LONE_PORT_CTRL = 0x15,/* 16 bit r/w Port Control Reg */ - PHY_LONE_CIM = 0x16,/* 16 bit r/o CIM Reg */ -}; - -/* National-PHY Registers, indirect addressed over XMAC */ -enum { - PHY_NAT_CTRL = 0x00,/* 16 bit r/w PHY Control Register */ - PHY_NAT_STAT = 0x01,/* 16 bit r/w PHY Status Register */ - PHY_NAT_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */ - PHY_NAT_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */ - PHY_NAT_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ - PHY_NAT_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Ability Reg */ - PHY_NAT_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ - PHY_NAT_NEPG = 0x07,/* 16 bit r/w Next Page Register */ - PHY_NAT_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner Reg */ - /* National-specific registers */ - PHY_NAT_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */ - PHY_NAT_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */ - PHY_NAT_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Register */ - PHY_NAT_EXT_CTRL1 = 0x10,/* 16 bit r/o Extended Control Reg1 */ - PHY_NAT_Q_STAT1 = 0x11,/* 16 bit r/o Quick Status Reg1 */ - PHY_NAT_10B_OP = 0x12,/* 16 bit r/o 10Base-T Operations Reg */ - PHY_NAT_EXT_CTRL2 = 0x13,/* 16 bit r/o Extended Control Reg1 */ - PHY_NAT_Q_STAT2 = 0x14,/* 16 bit r/o Quick Status Reg2 */ - - PHY_NAT_PHY_ADDR = 0x19,/* 16 bit r/o PHY Address Register */ -}; - enum { PHY_CT_RESET = 1<<15, /* Bit 15: (sc) clear all PHY related regs */ PHY_CT_LOOP = 1<<14, /* Bit 14: enable Loopback over PHY */ @@ -1253,8 +1119,29 @@ enum { PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */ }; +/* Advertisement register bits */ enum { PHY_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */ + PHY_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */ + PHY_AN_RF = 1<<13, /* Bit 13: Remote Fault Bits */ + + PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11: Try for asymmetric */ + PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10: Try for pause */ + PHY_AN_100BASE4 = 1<<9, /* Bit 9: Try for 100mbps 4k packets */ + PHY_AN_100FULL = 1<<8, /* Bit 8: Try for 100mbps full-duplex */ + PHY_AN_100HALF = 1<<7, /* Bit 7: Try for 100mbps half-duplex */ + PHY_AN_10FULL = 1<<6, /* Bit 6: Try for 10mbps full-duplex */ + PHY_AN_10HALF = 1<<5, /* Bit 5: Try for 10mbps half-duplex */ + PHY_AN_CSMA = 1<<0, /* Bit 0: Only selector supported */ + PHY_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ + PHY_AN_FULL = PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA, + PHY_AN_ALL = PHY_AN_10HALF | PHY_AN_10FULL | + PHY_AN_100HALF | PHY_AN_100FULL, +}; + +/* Xmac Specific */ +enum { + PHY_X_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */ PHY_X_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */ PHY_X_AN_RFB = 3<<12,/* Bit 13..12: Remote Fault Bits */ @@ -1263,82 +1150,6 @@ enum { PHY_X_AN_FD = 1<<5, /* Bit 5: Full Duplex */ }; -enum { - PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */ - - PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ - PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */ - PHY_B_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ -}; - -enum { - PHY_L_AN_RF = 1<<13, /* Bit 13: Remote Fault */ - /* Bit 12: reserved */ - PHY_L_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ - PHY_L_AN_PC = 1<<10, /* Bit 10: Pause Capable */ - - PHY_L_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ -}; - -/* PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement */ -/* PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ -/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ -enum { - PHY_N_AN_RF = 1<<13, /* Bit 13: Remote Fault */ - - PHY_N_AN_100F = 1<<11, /* Bit 11: 100Base-T2 FD Support */ - PHY_N_AN_100H = 1<<10, /* Bit 10: 100Base-T2 HD Support */ - - PHY_N_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ -}; - -/* field type definition for PHY_x_AN_SEL */ -enum { - PHY_SEL_TYPE = 1, /* 00001 = Ethernet */ -}; - -enum { - PHY_ANE_LP_NP = 1<<3, /* Bit 3: Link Partner can Next Page */ - PHY_ANE_LOC_NP = 1<<2, /* Bit 2: Local PHY can Next Page */ - PHY_ANE_RX_PG = 1<<1, /* Bit 1: Page Received */ -}; - -enum { - PHY_ANE_PAR_DF = 1<<4, /* Bit 4: Parallel Detection Fault */ - - PHY_ANE_LP_CAP = 1<<0, /* Bit 0: Link Partner Auto-Neg. Cap. */ -}; - -enum { - PHY_NP_MORE = 1<<15, /* Bit 15: More, Next Pages to follow */ - PHY_NP_ACK1 = 1<<14, /* Bit 14: (ro) Ack1, for receiving a message */ - PHY_NP_MSG_VAL = 1<<13, /* Bit 13: Message Page valid */ - PHY_NP_ACK2 = 1<<12, /* Bit 12: Ack2, comply with msg content */ - PHY_NP_TOG = 1<<11, /* Bit 11: Toggle Bit, ensure sync */ - PHY_NP_MSG = 0x07ff, /* Bit 10..0: Message from/to Link Partner */ -}; - -enum { - PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */ - PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */ -}; - -enum { - PHY_X_RS_PAUSE = 3<<7,/* Bit 8..7: selected Pause Mode */ - PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */ - PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */ - PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */ - PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */ -}; - -/** Remote Fault Bits (PHY_X_AN_RFB) encoding */ -enum { - X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */ - X_RFB_LF = 1<<12, /* Bit 13..12 Link Failure */ - X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */ - X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */ -}; - /* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ enum { PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */ @@ -1418,6 +1229,16 @@ enum { PHY_B_PES_MLT3_ER = 1<<0, /* Bit 0: MLT3 code Error */ }; +/* PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ +/* PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ +enum { + PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */ + + PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ + PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */ +}; + + /***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/ enum { PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */ @@ -1478,7 +1299,9 @@ enum { PHY_B_IS_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */ PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */ }; -#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) +#define PHY_B_DEF_MSK \ + (~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \ + PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE)) /* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */ enum { @@ -1495,166 +1318,6 @@ enum { PHY_B_RES_1000HD = 6<<8,/* Bit 10..8: 1000Base-T Half Dup. */ }; -/* - * Level One-Specific - */ -/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -enum { - PHY_L_1000C_TEST = 7<<13,/* Bit 15..13: Test Modes */ - PHY_L_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */ - PHY_L_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */ - PHY_L_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */ - PHY_L_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */ - PHY_L_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */ -}; - -/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ -enum { - PHY_L_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */ - PHY_L_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */ - PHY_L_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */ - PHY_L_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status */ - PHY_L_1000S_LP_FD = 1<<11, /* Bit 11: Link Partner can FD */ - PHY_L_1000S_LP_HD = 1<<10, /* Bit 10: Link Partner can HD */ - - PHY_L_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */ - -/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/ - PHY_L_ES_X_FD_CAP = 1<<15, /* Bit 15: 1000Base-X FD capable */ - PHY_L_ES_X_HD_CAP = 1<<14, /* Bit 14: 1000Base-X HD capable */ - PHY_L_ES_T_FD_CAP = 1<<13, /* Bit 13: 1000Base-T FD capable */ - PHY_L_ES_T_HD_CAP = 1<<12, /* Bit 12: 1000Base-T HD capable */ -}; - -/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/ -enum { - PHY_L_PC_REP_MODE = 1<<15, /* Bit 15: Repeater Mode */ - - PHY_L_PC_TX_DIS = 1<<13, /* Bit 13: Tx output Disabled */ - PHY_L_PC_BY_SCR = 1<<12, /* Bit 12: Bypass Scrambler */ - PHY_L_PC_BY_45 = 1<<11, /* Bit 11: Bypass 4B5B-Decoder */ - PHY_L_PC_JAB_DIS = 1<<10, /* Bit 10: Jabber Disabled */ - PHY_L_PC_SQE = 1<<9, /* Bit 9: Enable Heartbeat */ - PHY_L_PC_TP_LOOP = 1<<8, /* Bit 8: TP Loopback */ - PHY_L_PC_SSS = 1<<7, /* Bit 7: Smart Speed Selection */ - PHY_L_PC_FIFO_SIZE = 1<<6, /* Bit 6: FIFO Size */ - PHY_L_PC_PRE_EN = 1<<5, /* Bit 5: Preamble Enable */ - PHY_L_PC_CIM = 1<<4, /* Bit 4: Carrier Integrity Mon */ - PHY_L_PC_10_SER = 1<<3, /* Bit 3: Use Serial Output */ - PHY_L_PC_ANISOL = 1<<2, /* Bit 2: Unisolate Port */ - PHY_L_PC_TEN_BIT = 1<<1, /* Bit 1: 10bit iface mode on */ - PHY_L_PC_ALTCLOCK = 1<<0, /* Bit 0: (ro) ALTCLOCK Mode on */ -}; - -/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/ -enum { - PHY_L_QS_D_RATE = 3<<14,/* Bit 15..14: Data Rate */ - PHY_L_QS_TX_STAT = 1<<13, /* Bit 13: Transmitting */ - PHY_L_QS_RX_STAT = 1<<12, /* Bit 12: Receiving */ - PHY_L_QS_COL_STAT = 1<<11, /* Bit 11: Collision */ - PHY_L_QS_L_STAT = 1<<10, /* Bit 10: Link is up */ - PHY_L_QS_DUP_MOD = 1<<9, /* Bit 9: Full/Half Duplex */ - PHY_L_QS_AN = 1<<8, /* Bit 8: AutoNeg is On */ - PHY_L_QS_AN_C = 1<<7, /* Bit 7: AN is Complete */ - PHY_L_QS_LLE = 7<<4,/* Bit 6..4: Line Length Estim. */ - PHY_L_QS_PAUSE = 1<<3, /* Bit 3: LP advertised Pause */ - PHY_L_QS_AS_PAUSE = 1<<2, /* Bit 2: LP adv. asym. Pause */ - PHY_L_QS_ISOLATE = 1<<1, /* Bit 1: CIM Isolated */ - PHY_L_QS_EVENT = 1<<0, /* Bit 0: Event has occurred */ -}; - -/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/ -/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/ -enum { - PHY_L_IS_AN_F = 1<<13, /* Bit 13: Auto-Negotiation fault */ - PHY_L_IS_CROSS = 1<<11, /* Bit 11: Crossover used */ - PHY_L_IS_POL = 1<<10, /* Bit 10: Polarity correct. used */ - PHY_L_IS_SS = 1<<9, /* Bit 9: Smart Speed Downgrade */ - PHY_L_IS_CFULL = 1<<8, /* Bit 8: Counter Full */ - PHY_L_IS_AN_C = 1<<7, /* Bit 7: AutoNeg Complete */ - PHY_L_IS_SPEED = 1<<6, /* Bit 6: Speed Changed */ - PHY_L_IS_DUP = 1<<5, /* Bit 5: Duplex Changed */ - PHY_L_IS_LS = 1<<4, /* Bit 4: Link Status Changed */ - PHY_L_IS_ISOL = 1<<3, /* Bit 3: Isolate Occured */ - PHY_L_IS_MDINT = 1<<2, /* Bit 2: (ro) STAT: MII Int Pending */ - PHY_L_IS_INTEN = 1<<1, /* Bit 1: ENAB: Enable IRQs */ - PHY_L_IS_FORCE = 1<<0, /* Bit 0: ENAB: Force Interrupt */ -}; - -/* int. mask */ -#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN) - -/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/ -enum { - PHY_L_LC_LEDC = 3<<14,/* Bit 15..14: Col/Blink/On/Off */ - PHY_L_LC_LEDR = 3<<12,/* Bit 13..12: Rx/Blink/On/Off */ - PHY_L_LC_LEDT = 3<<10,/* Bit 11..10: Tx/Blink/On/Off */ - PHY_L_LC_LEDG = 3<<8,/* Bit 9..8: Giga/Blink/On/Off */ - PHY_L_LC_LEDS = 3<<6,/* Bit 7..6: 10-100/Blink/On/Off */ - PHY_L_LC_LEDL = 3<<4,/* Bit 5..4: Link/Blink/On/Off */ - PHY_L_LC_LEDF = 3<<2,/* Bit 3..2: Duplex/Blink/On/Off */ - PHY_L_LC_PSTRECH= 1<<1, /* Bit 1: Strech LED Pulses */ - PHY_L_LC_FREQ = 1<<0, /* Bit 0: 30/100 ms */ -}; - -/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/ -enum { - PHY_L_PC_TX_TCLK = 1<<15, /* Bit 15: Enable TX_TCLK */ - PHY_L_PC_ALT_NP = 1<<13, /* Bit 14: Alternate Next Page */ - PHY_L_PC_GMII_ALT= 1<<12, /* Bit 13: Alternate GMII driver */ - PHY_L_PC_TEN_CRS = 1<<10, /* Bit 10: Extend CRS*/ -}; - -/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/ -enum { - PHY_L_CIM_ISOL = 0xff<<8,/* Bit 15..8: Isolate Count */ - PHY_L_CIM_FALSE_CAR = 0xff, /* Bit 7..0: False Carrier Count */ -}; - -/* - * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding - */ -enum { - PHY_L_P_NO_PAUSE= 0<<10,/* Bit 11..10: no Pause Mode */ - PHY_L_P_SYM_MD = 1<<10, /* Bit 11..10: symmetric Pause Mode */ - PHY_L_P_ASYM_MD = 2<<10,/* Bit 11..10: asymmetric Pause Mode */ - PHY_L_P_BOTH_MD = 3<<10,/* Bit 11..10: both Pause Mode */ -}; - -/* - * National-Specific - */ -/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -enum { - PHY_N_1000C_TEST= 7<<13,/* Bit 15..13: Test Modes */ - PHY_N_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */ - PHY_N_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */ - PHY_N_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */ - PHY_N_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */ - PHY_N_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */ - PHY_N_1000C_APC = 1<<7, /* Bit 7: Asymmetric Pause Cap. */}; - - -/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ -enum { - PHY_N_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */ - PHY_N_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */ - PHY_N_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */ - PHY_N_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status*/ - PHY_N_1000S_LP_FD= 1<<11, /* Bit 11: Link Partner can FD */ - PHY_N_1000S_LP_HD= 1<<10, /* Bit 10: Link Partner can HD */ - PHY_N_1000C_LP_APC= 1<<9, /* Bit 9: LP Asym. Pause Cap. */ - PHY_N_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */ -}; - -/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/ -enum { - PHY_N_ES_X_FD_CAP= 1<<15, /* Bit 15: 1000Base-X FD capable */ - PHY_N_ES_X_HD_CAP= 1<<14, /* Bit 14: 1000Base-X HD capable */ - PHY_N_ES_T_FD_CAP= 1<<13, /* Bit 13: 1000Base-T FD capable */ - PHY_N_ES_T_HD_CAP= 1<<12, /* Bit 12: 1000Base-T HD capable */ -}; - /** Marvell-Specific */ enum { PHY_M_AN_NXT_PG = 1<<15, /* Request Next Page */ @@ -1718,7 +1381,7 @@ enum { PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */ }; -#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK) +#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK) enum { PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */ @@ -2105,7 +1768,7 @@ enum { GM_GPSR_FC_RX_DIS = 1<<2, /* Bit 2: Rx Flow-Control Mode Disabled */ GM_GPSR_PROM_EN = 1<<1, /* Bit 1: Promiscuous Mode Enabled */ }; - + /* GM_GP_CTRL 16 bit r/w General Purpose Control Register */ enum { GM_GPCR_PROM_ENA = 1<<14, /* Bit 14: Enable Promiscuous Mode */ @@ -2127,7 +1790,7 @@ enum { #define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100) #define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS) - + /* GM_TX_CTRL 16 bit r/w Transmit Control Register */ enum { GM_TXCR_FORCE_JAM = 1<<15, /* Bit 15: Force Jam / Flow-Control */ @@ -2138,7 +1801,7 @@ enum { #define TX_COL_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK) #define TX_COL_DEF 0x04 - + /* GM_RX_CTRL 16 bit r/w Receive Control Register */ enum { GM_RXCR_UCF_ENA = 1<<15, /* Bit 15: Enable Unicast filtering */ @@ -2146,7 +1809,7 @@ enum { GM_RXCR_CRC_DIS = 1<<13, /* Bit 13: Remove 4-byte CRC */ GM_RXCR_PASS_FC = 1<<12, /* Bit 12: Pass FC packets to FIFO */ }; - + /* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */ enum { GM_TXPA_JAMLEN_MSK = 0x03<<14, /* Bit 15..14: Jam Length */ @@ -2171,7 +1834,7 @@ enum { GM_SMOD_JUMBO_ENA = 1<<8, /* Bit 8: Enable Jumbo (Max. Frame Len) */ GM_SMOD_IPG_MSK = 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ }; - + #define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK) #define DATA_BLIND_DEF 0x04 @@ -2186,7 +1849,7 @@ enum { GM_SMI_CT_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */ GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */ }; - + #define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK) #define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK) @@ -2195,7 +1858,7 @@ enum { GM_PAR_MIB_CLR = 1<<5, /* Bit 5: Set MIB Clear Counter Mode */ GM_PAR_MIB_TST = 1<<4, /* Bit 4: MIB Load Counter (Test Mode) */ }; - + /* Receive Frame Status Encoding */ enum { GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */ @@ -2217,12 +1880,12 @@ enum { /* * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR) */ - GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR | - GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | + GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR | + GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_JABBER, /* Rx GMAC FIFO Flush Mask (default) */ RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR | - GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE | + GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE | GMR_FS_JABBER, }; @@ -2540,10 +2203,6 @@ enum { }; -/* XM_PHY_ADDR 16 bit r/w PHY Address Register */ -#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */ - - /* XM_GP_PORT 32 bit r/w General Purpose Port Register */ enum { XM_GP_ANIP = 1<<6, /* Bit 6: (ro) Auto-Neg. in progress */ @@ -2662,8 +2321,8 @@ enum { }; #define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) -#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ - XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA) +#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ + XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA) /* XM_STAT_CMD 16 bit r/w Statistics Command Register */ enum { @@ -2793,28 +2452,20 @@ struct skge_hw { u32 intr_mask; struct net_device *dev[2]; - u8 mac_cfg; u8 chip_id; + u8 chip_rev; u8 phy_type; u8 pmd_type; u16 phy_addr; + u8 ports; u32 ram_size; u32 ram_offset; - + struct tasklet_struct ext_tasklet; spinlock_t phy_lock; }; -static inline int isdualport(const struct skge_hw *hw) -{ - return !(hw->mac_cfg & CFG_SNG_MAC); -} - -static inline u8 chip_rev(const struct skge_hw *hw) -{ - return (hw->mac_cfg & CFG_CHIP_R_MSK) >> 4; -} static inline int iscopper(const struct skge_hw *hw) { @@ -2827,7 +2478,7 @@ enum { FLOW_MODE_REM_SEND = 2, /* Symmetric or just remote */ FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */ }; - + struct skge_port { u32 msg_enable; struct skge_hw *hw; @@ -2853,8 +2504,8 @@ struct skge_port { void *mem; /* PCI memory for rings */ dma_addr_t dma; unsigned long mem_size; + unsigned int rx_buf_size; - struct timer_list link_check; struct timer_list led_blink; }; @@ -2863,7 +2514,6 @@ struct skge_port { static inline u32 skge_read32(const struct skge_hw *hw, int reg) { return readl(hw->regs + reg); - } static inline u16 skge_read16(const struct skge_hw *hw, int reg) @@ -2892,114 +2542,87 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val) } /* MAC Related Registers inside the device. */ -#define SKGEMAC_REG(port,reg) (((port)<<7)+(reg)) - -/* PCI config space can be accessed via memory mapped space */ -#define SKGEPCI_REG(reg) ((reg)+ 0x380) - -#define SKGEXM_REG(port, reg) \ +#define SK_REG(port,reg) (((port)<<7)+(reg)) +#define SK_XMAC_REG(port, reg) \ ((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1) -static inline u32 skge_xm_read32(const struct skge_hw *hw, int port, int reg) -{ - return skge_read32(hw, SKGEXM_REG(port,reg)); -} - -static inline u16 skge_xm_read16(const struct skge_hw *hw, int port, int reg) +static inline u32 xm_read32(const struct skge_hw *hw, int port, int reg) { - return skge_read16(hw, SKGEXM_REG(port,reg)); + u32 v; + v = skge_read16(hw, SK_XMAC_REG(port, reg)); + v |= (u32)skge_read16(hw, SK_XMAC_REG(port, reg+2)) << 16; + return v; } -static inline u8 skge_xm_read8(const struct skge_hw *hw, int port, int reg) +static inline u16 xm_read16(const struct skge_hw *hw, int port, int reg) { - return skge_read8(hw, SKGEXM_REG(port,reg)); + return skge_read16(hw, SK_XMAC_REG(port,reg)); } -static inline void skge_xm_write32(const struct skge_hw *hw, int port, int r, u32 v) +static inline void xm_write32(const struct skge_hw *hw, int port, int r, u32 v) { - skge_write32(hw, SKGEXM_REG(port,r), v); + skge_write16(hw, SK_XMAC_REG(port,r), v & 0xffff); + skge_write16(hw, SK_XMAC_REG(port,r+2), v >> 16); } -static inline void skge_xm_write16(const struct skge_hw *hw, int port, int r, u16 v) +static inline void xm_write16(const struct skge_hw *hw, int port, int r, u16 v) { - skge_write16(hw, SKGEXM_REG(port,r), v); + skge_write16(hw, SK_XMAC_REG(port,r), v); } -static inline void skge_xm_write8(const struct skge_hw *hw, int port, int r, u8 v) -{ - skge_write8(hw, SKGEXM_REG(port,r), v); -} - -static inline void skge_xm_outhash(const struct skge_hw *hw, int port, int reg, +static inline void xm_outhash(const struct skge_hw *hw, int port, int reg, const u8 *hash) { - skge_xm_write16(hw, port, reg, - (u16)hash[0] | ((u16)hash[1] << 8)); - skge_xm_write16(hw, port, reg+2, - (u16)hash[2] | ((u16)hash[3] << 8)); - skge_xm_write16(hw, port, reg+4, - (u16)hash[4] | ((u16)hash[5] << 8)); - skge_xm_write16(hw, port, reg+6, - (u16)hash[6] | ((u16)hash[7] << 8)); + xm_write16(hw, port, reg, (u16)hash[0] | ((u16)hash[1] << 8)); + xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8)); + xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8)); + xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 8)); } -static inline void skge_xm_outaddr(const struct skge_hw *hw, int port, int reg, +static inline void xm_outaddr(const struct skge_hw *hw, int port, int reg, const u8 *addr) { - skge_xm_write16(hw, port, reg, - (u16)addr[0] | ((u16)addr[1] << 8)); - skge_xm_write16(hw, port, reg, - (u16)addr[2] | ((u16)addr[3] << 8)); - skge_xm_write16(hw, port, reg, - (u16)addr[4] | ((u16)addr[5] << 8)); + xm_write16(hw, port, reg, (u16)addr[0] | ((u16)addr[1] << 8)); + xm_write16(hw, port, reg+2, (u16)addr[2] | ((u16)addr[3] << 8)); + xm_write16(hw, port, reg+4, (u16)addr[4] | ((u16)addr[5] << 8)); } +#define SK_GMAC_REG(port,reg) \ + (BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg)) -#define SKGEGMA_REG(port,reg) \ - ((reg) + BASE_GMAC_1 + \ - (port) * (BASE_GMAC_2-BASE_GMAC_1)) - -static inline u16 skge_gma_read16(const struct skge_hw *hw, int port, int reg) +static inline u16 gma_read16(const struct skge_hw *hw, int port, int reg) { - return skge_read16(hw, SKGEGMA_REG(port,reg)); + return skge_read16(hw, SK_GMAC_REG(port,reg)); } -static inline u32 skge_gma_read32(const struct skge_hw *hw, int port, int reg) +static inline u32 gma_read32(const struct skge_hw *hw, int port, int reg) { - return (u32) skge_read16(hw, SKGEGMA_REG(port,reg)) - | ((u32)skge_read16(hw, SKGEGMA_REG(port,reg+4)) << 16); + return (u32) skge_read16(hw, SK_GMAC_REG(port,reg)) + | ((u32)skge_read16(hw, SK_GMAC_REG(port,reg+4)) << 16); } -static inline u8 skge_gma_read8(const struct skge_hw *hw, int port, int reg) +static inline void gma_write16(const struct skge_hw *hw, int port, int r, u16 v) { - return skge_read8(hw, SKGEGMA_REG(port,reg)); + skge_write16(hw, SK_GMAC_REG(port,r), v); } -static inline void skge_gma_write16(const struct skge_hw *hw, int port, int r, u16 v) +static inline void gma_write32(const struct skge_hw *hw, int port, int r, u32 v) { - skge_write16(hw, SKGEGMA_REG(port,r), v); + skge_write16(hw, SK_GMAC_REG(port, r), (u16) v); + skge_write32(hw, SK_GMAC_REG(port, r+4), (u16)(v >> 16)); } -static inline void skge_gma_write32(const struct skge_hw *hw, int port, int r, u32 v) +static inline void gma_write8(const struct skge_hw *hw, int port, int r, u8 v) { - skge_write16(hw, SKGEGMA_REG(port, r), (u16) v); - skge_write32(hw, SKGEGMA_REG(port, r+4), (u16)(v >> 16)); + skge_write8(hw, SK_GMAC_REG(port,r), v); } -static inline void skge_gma_write8(const struct skge_hw *hw, int port, int r, u8 v) -{ - skge_write8(hw, SKGEGMA_REG(port,r), v); -} - -static inline void skge_gm_set_addr(struct skge_hw *hw, int port, int reg, +static inline void gma_set_addr(struct skge_hw *hw, int port, int reg, const u8 *addr) { - skge_gma_write16(hw, port, reg, - (u16) addr[0] | ((u16) addr[1] << 8)); - skge_gma_write16(hw, port, reg+4, - (u16) addr[2] | ((u16) addr[3] << 8)); - skge_gma_write16(hw, port, reg+8, - (u16) addr[4] | ((u16) addr[5] << 8)); + gma_write16(hw, port, reg, (u16) addr[0] | ((u16) addr[1] << 8)); + gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8)); + gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8)); } - + #endif diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 16363b5c6f56..404ea4297e32 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -74,6 +74,7 @@ #include <linux/rtnetlink.h> #include <linux/if_arp.h> #include <linux/if_slip.h> +#include <linux/delay.h> #include <linux/init.h> #include "slip.h" #ifdef CONFIG_INET diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index cfb9d3cdb04a..1438fdd20826 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -1998,7 +1998,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) if (retval) goto err_out; - set_irq_type(dev->irq, IRQT_RISING); + set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE); #ifdef SMC_USE_PXA_DMA { diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 946528e6b742..7089d86e857a 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -182,6 +182,16 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) +#include <asm/mach-types.h> +#include <asm/arch/cpu.h> + +#define SMC_IRQ_TRIGGER_TYPE (( \ + machine_is_omap_h2() \ + || machine_is_omap_h3() \ + || (machine_is_omap_innovator() && !cpu_is_omap150()) \ + ) ? IRQT_FALLING : IRQT_RISING) + + #elif defined(CONFIG_SH_SH4202_MICRODEV) #define SMC_CAN_USE_8BIT 0 @@ -300,6 +310,9 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) #endif +#ifndef SMC_IRQ_TRIGGER_TYPE +#define SMC_IRQ_TRIGGER_TYPE IRQT_RISING +#endif #ifdef SMC_USE_PXA_DMA /* diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 12e2b6826fa3..88b89dc95c77 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -1286,7 +1286,7 @@ static void init_ring(struct net_device *dev) np->rx_info[i].skb = skb; if (skb == NULL) break; - np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); + np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ /* Grrr, we cannot offset to correctly align the IP header. */ np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); @@ -1572,7 +1572,7 @@ static int __netdev_rx(struct net_device *dev, int *quota) pci_dma_sync_single_for_cpu(np->pci_dev, np->rx_info[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0); + eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0); pci_dma_sync_single_for_device(np->pci_dev, np->rx_info[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); @@ -1696,7 +1696,7 @@ static void refill_rx_ring(struct net_device *dev) if (skb == NULL) break; /* Better luck next round. */ np->rx_info[entry].mapping = - pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); + pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ np->rx_ring[entry].rxaddr = cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 08cb7177a175..d500a5771dbc 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1028,7 +1028,7 @@ static void init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ np->rx_ring[i].frag[0].addr = cpu_to_le32( - pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, + pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag); } @@ -1341,7 +1341,7 @@ static void rx_poll(unsigned long data) np->rx_buf_sz, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); + eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0); pci_dma_sync_single_for_device(np->pci_dev, desc->frag[0].addr, np->rx_buf_sz, @@ -1400,7 +1400,7 @@ static void refill_rx (struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ np->rx_ring[entry].frag[0].addr = cpu_to_le32( - pci_map_single(np->pci_dev, skb->tail, + pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); } /* Perhaps we need not reset this field. */ diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 7e371b1209a1..54640686e983 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -66,8 +66,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.32" -#define DRV_MODULE_RELDATE "June 24, 2005" +#define DRV_MODULE_VERSION "3.33" +#define DRV_MODULE_RELDATE "July 5, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -5117,7 +5117,7 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr, } static void __tg3_set_rx_mode(struct net_device *); -static void tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) +static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) { tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs); tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs); @@ -5460,7 +5460,7 @@ static int tg3_reset_hw(struct tg3 *tp) udelay(10); } - tg3_set_coalesce(tp, &tp->coal); + __tg3_set_coalesce(tp, &tp->coal); /* set status block DMA address */ tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, @@ -7821,6 +7821,60 @@ static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) return 0; } +static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) +{ + struct tg3 *tp = netdev_priv(dev); + u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0; + u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0; + + if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { + max_rxcoal_tick_int = MAX_RXCOAL_TICK_INT; + max_txcoal_tick_int = MAX_TXCOAL_TICK_INT; + max_stat_coal_ticks = MAX_STAT_COAL_TICKS; + min_stat_coal_ticks = MIN_STAT_COAL_TICKS; + } + + if ((ec->rx_coalesce_usecs > MAX_RXCOL_TICKS) || + (ec->tx_coalesce_usecs > MAX_TXCOL_TICKS) || + (ec->rx_max_coalesced_frames > MAX_RXMAX_FRAMES) || + (ec->tx_max_coalesced_frames > MAX_TXMAX_FRAMES) || + (ec->rx_coalesce_usecs_irq > max_rxcoal_tick_int) || + (ec->tx_coalesce_usecs_irq > max_txcoal_tick_int) || + (ec->rx_max_coalesced_frames_irq > MAX_RXCOAL_MAXF_INT) || + (ec->tx_max_coalesced_frames_irq > MAX_TXCOAL_MAXF_INT) || + (ec->stats_block_coalesce_usecs > max_stat_coal_ticks) || + (ec->stats_block_coalesce_usecs < min_stat_coal_ticks)) + return -EINVAL; + + /* No rx interrupts will be generated if both are zero */ + if ((ec->rx_coalesce_usecs == 0) && + (ec->rx_max_coalesced_frames == 0)) + return -EINVAL; + + /* No tx interrupts will be generated if both are zero */ + if ((ec->tx_coalesce_usecs == 0) && + (ec->tx_max_coalesced_frames == 0)) + return -EINVAL; + + /* Only copy relevant parameters, ignore all others. */ + tp->coal.rx_coalesce_usecs = ec->rx_coalesce_usecs; + tp->coal.tx_coalesce_usecs = ec->tx_coalesce_usecs; + tp->coal.rx_max_coalesced_frames = ec->rx_max_coalesced_frames; + tp->coal.tx_max_coalesced_frames = ec->tx_max_coalesced_frames; + tp->coal.rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq; + tp->coal.tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq; + tp->coal.rx_max_coalesced_frames_irq = ec->rx_max_coalesced_frames_irq; + tp->coal.tx_max_coalesced_frames_irq = ec->tx_max_coalesced_frames_irq; + tp->coal.stats_block_coalesce_usecs = ec->stats_block_coalesce_usecs; + + if (netif_running(dev)) { + tg3_full_lock(tp, 0); + __tg3_set_coalesce(tp, &tp->coal); + tg3_full_unlock(tp); + } + return 0; +} + static struct ethtool_ops tg3_ethtool_ops = { .get_settings = tg3_get_settings, .set_settings = tg3_set_settings, @@ -7856,6 +7910,7 @@ static struct ethtool_ops tg3_ethtool_ops = { .get_stats_count = tg3_get_stats_count, .get_ethtool_stats = tg3_get_ethtool_stats, .get_coalesce = tg3_get_coalesce, + .set_coalesce = tg3_set_coalesce, }; static void __devinit tg3_get_eeprom_size(struct tg3 *tp) @@ -9800,6 +9855,12 @@ static void __devinit tg3_init_coal(struct tg3 *tp) ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS; ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS; } + + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { + ec->rx_coalesce_usecs_irq = 0; + ec->tx_coalesce_usecs_irq = 0; + ec->stats_block_coalesce_usecs = 0; + } } static int __devinit tg3_init_one(struct pci_dev *pdev, diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 99c5f9675a56..70ad450733e6 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -879,31 +879,41 @@ #define LOW_RXCOL_TICKS_CLRTCKS 0x00000014 #define DEFAULT_RXCOL_TICKS 0x00000048 #define HIGH_RXCOL_TICKS 0x00000096 +#define MAX_RXCOL_TICKS 0x000003ff #define HOSTCC_TXCOL_TICKS 0x00003c0c #define LOW_TXCOL_TICKS 0x00000096 #define LOW_TXCOL_TICKS_CLRTCKS 0x00000048 #define DEFAULT_TXCOL_TICKS 0x0000012c #define HIGH_TXCOL_TICKS 0x00000145 +#define MAX_TXCOL_TICKS 0x000003ff #define HOSTCC_RXMAX_FRAMES 0x00003c10 #define LOW_RXMAX_FRAMES 0x00000005 #define DEFAULT_RXMAX_FRAMES 0x00000008 #define HIGH_RXMAX_FRAMES 0x00000012 +#define MAX_RXMAX_FRAMES 0x000000ff #define HOSTCC_TXMAX_FRAMES 0x00003c14 #define LOW_TXMAX_FRAMES 0x00000035 #define DEFAULT_TXMAX_FRAMES 0x0000004b #define HIGH_TXMAX_FRAMES 0x00000052 +#define MAX_TXMAX_FRAMES 0x000000ff #define HOSTCC_RXCOAL_TICK_INT 0x00003c18 #define DEFAULT_RXCOAL_TICK_INT 0x00000019 #define DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014 +#define MAX_RXCOAL_TICK_INT 0x000003ff #define HOSTCC_TXCOAL_TICK_INT 0x00003c1c #define DEFAULT_TXCOAL_TICK_INT 0x00000019 #define DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014 +#define MAX_TXCOAL_TICK_INT 0x000003ff #define HOSTCC_RXCOAL_MAXF_INT 0x00003c20 #define DEFAULT_RXCOAL_MAXF_INT 0x00000005 +#define MAX_RXCOAL_MAXF_INT 0x000000ff #define HOSTCC_TXCOAL_MAXF_INT 0x00003c24 #define DEFAULT_TXCOAL_MAXF_INT 0x00000005 +#define MAX_TXCOAL_MAXF_INT 0x000000ff #define HOSTCC_STAT_COAL_TICKS 0x00003c28 #define DEFAULT_STAT_COAL_TICKS 0x000f4240 +#define MAX_STAT_COAL_TICKS 0xd693d400 +#define MIN_STAT_COAL_TICKS 0x00000064 /* 0x3c2c --> 0x3c30 unused */ #define HOSTCC_STATS_BLK_HOST_ADDR 0x00003c30 /* 64-bit */ #define HOSTCC_STATUS_BLK_HOST_ADDR 0x00003c38 /* 64-bit */ diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index dd357dd8c370..fc353e348f9a 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -446,13 +446,13 @@ static void de_rx (struct de_private *de) mapping = de->rx_skb[rx_tail].mapping = - pci_map_single(de->pdev, copy_skb->tail, + pci_map_single(de->pdev, copy_skb->data, buflen, PCI_DMA_FROMDEVICE); de->rx_skb[rx_tail].skb = copy_skb; } else { pci_dma_sync_single_for_cpu(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); skb_reserve(copy_skb, RX_OFFSET); - memcpy(skb_put(copy_skb, len), skb->tail, len); + memcpy(skb_put(copy_skb, len), skb->data, len); pci_dma_sync_single_for_device(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); @@ -1269,7 +1269,7 @@ static int de_refill_rx (struct de_private *de) skb->dev = de->dev; de->rx_skb[i].mapping = pci_map_single(de->pdev, - skb->tail, de->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE); de->rx_skb[i].skb = skb; de->rx_ring[i].opts1 = cpu_to_le32(DescOwn); diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 7b899702ceb9..74e9075d9c48 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -945,8 +945,8 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) /* Received Packet CRC check need or not */ if ( (db->dm910x_chk_mode & 1) && - (cal_CRC(skb->tail, rxlen, 1) != - (*(u32 *) (skb->tail+rxlen) ))) { /* FIXME (?) */ + (cal_CRC(skb->data, rxlen, 1) != + (*(u32 *) (skb->data+rxlen) ))) { /* FIXME (?) */ /* Found a error received packet */ dmfe_reuse_skb(db, rxptr->rx_skb_ptr); db->dm910x_chk_mode = 3; @@ -959,7 +959,7 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) /* size less than COPY_SIZE, allocate a rxlen SKB */ skb->dev = dev; skb_reserve(skb, 2); /* 16byte align */ - memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->tail, rxlen); + memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->data, rxlen); dmfe_reuse_skb(db, rxptr->rx_skb_ptr); } else { skb->dev = dev; @@ -1252,7 +1252,7 @@ static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb) if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) { rxptr->rx_skb_ptr = skb; - rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); + rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); wmb(); rxptr->rdes0 = cpu_to_le32(0x80000000); db->rx_avail_cnt++; @@ -1463,7 +1463,7 @@ static void allocate_rx_buffer(struct dmfe_board_info *db) if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL ) break; rxptr->rx_skb_ptr = skb; /* FIXME (?) */ - rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); + rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); wmb(); rxptr->rdes0 = cpu_to_le32(0x80000000); rxptr = rxptr->next_rx_desc; diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index afb5cda9d8e1..bb3558164a5b 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -78,7 +78,7 @@ int tulip_refill_rx(struct net_device *dev) if (skb == NULL) break; - mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ, + mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); tp->rx_buffers[entry].mapping = mapping; @@ -199,12 +199,12 @@ int tulip_poll(struct net_device *dev, int *budget) tp->rx_buffers[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); #if ! defined(__alpha__) - eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, + eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data, pkt_len, 0); skb_put(skb, pkt_len); #else memcpy(skb_put(skb, pkt_len), - tp->rx_buffers[entry].skb->tail, + tp->rx_buffers[entry].skb->data, pkt_len); #endif pci_dma_sync_single_for_device(tp->pdev, @@ -423,12 +423,12 @@ static int tulip_rx(struct net_device *dev) tp->rx_buffers[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); #if ! defined(__alpha__) - eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, + eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data, pkt_len, 0); skb_put(skb, pkt_len); #else memcpy(skb_put(skb, pkt_len), - tp->rx_buffers[entry].skb->tail, + tp->rx_buffers[entry].skb->data, pkt_len); #endif pci_dma_sync_single_for_device(tp->pdev, diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 08e0f80f89d5..d45d8f56e5b4 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -625,7 +625,7 @@ static void tulip_init_ring(struct net_device *dev) tp->rx_buffers[i].skb = skb; if (skb == NULL) break; - mapping = pci_map_single(tp->pdev, skb->tail, + mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); tp->rx_buffers[i].mapping = mapping; skb->dev = dev; /* Mark as being used by this device. */ diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index db4b32c2369a..5b1af3986abf 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -849,7 +849,7 @@ static void init_rxtx_rings(struct net_device *dev) if (skb == NULL) break; skb->dev = dev; /* Mark as being used by this device. */ - np->rx_addr[i] = pci_map_single(np->pci_dev,skb->tail, + np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data, skb->len,PCI_DMA_FROMDEVICE); np->rx_ring[i].buffer1 = np->rx_addr[i]; @@ -1269,7 +1269,7 @@ static int netdev_rx(struct net_device *dev) pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry], np->rx_skbuff[entry]->len, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); + eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry], np->rx_skbuff[entry]->len, @@ -1315,7 +1315,7 @@ static int netdev_rx(struct net_device *dev) break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ np->rx_addr[entry] = pci_map_single(np->pci_dev, - skb->tail, + skb->data, skb->len, PCI_DMA_FROMDEVICE); np->rx_ring[entry].buffer1 = np->rx_addr[entry]; } diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c index b8a9b395c5ea..887d7245fe7b 100644 --- a/drivers/net/tulip/xircom_tulip_cb.c +++ b/drivers/net/tulip/xircom_tulip_cb.c @@ -899,7 +899,7 @@ static void xircom_init_ring(struct net_device *dev) break; skb->dev = dev; /* Mark as being used by this device. */ tp->rx_ring[i].status = Rx0DescOwned; /* Owned by Xircom chip */ - tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail); + tp->rx_ring[i].buffer1 = virt_to_bus(skb->data); } tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1291,7 +1291,7 @@ xircom_rx(struct net_device *dev) if (skb == NULL) break; skb->dev = dev; /* Mark as being used by this device. */ - tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail); + tp->rx_ring[entry].buffer1 = virt_to_bus(skb->data); work_done++; } tp->rx_ring[entry].status = Rx0DescOwned; diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 8f3392989a06..0b5ca2537963 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1661,7 +1661,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx) #endif skb->dev = tp->dev; - dma_addr = pci_map_single(tp->pdev, skb->tail, + dma_addr = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); /* Since no card does 64 bit DAC, the high bits will never @@ -1721,7 +1721,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile u32 * ready, pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0); + eth_copy_and_sum(new_skb, skb->data, pkt_len, 0); pci_dma_sync_single_for_device(tp->pdev, dma_addr, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index be1c1047b9ba..fc7738ffbfff 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -507,7 +507,7 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static struct ethtool_ops netdev_ethtool_ops; static int rhine_close(struct net_device *dev); -static void rhine_shutdown (struct device *gdev); +static void rhine_shutdown (struct pci_dev *pdev); #define RHINE_WAIT_FOR(condition) do { \ int i=1024; \ @@ -990,7 +990,7 @@ static void alloc_rbufs(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ rp->rx_skbuff_dma[i] = - pci_map_single(rp->pdev, skb->tail, rp->rx_buf_sz, + pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz, PCI_DMA_FROMDEVICE); rp->rx_ring[i].addr = cpu_to_le32(rp->rx_skbuff_dma[i]); @@ -1518,7 +1518,7 @@ static void rhine_rx(struct net_device *dev) PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, - rp->rx_skbuff[entry]->tail, + rp->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(rp->pdev, @@ -1561,7 +1561,7 @@ static void rhine_rx(struct net_device *dev) break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ rp->rx_skbuff_dma[entry] = - pci_map_single(rp->pdev, skb->tail, + pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz, PCI_DMA_FROMDEVICE); rp->rx_ring[entry].addr = cpu_to_le32(rp->rx_skbuff_dma[entry]); @@ -1895,9 +1895,8 @@ static void __devexit rhine_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -static void rhine_shutdown (struct device *gendev) +static void rhine_shutdown (struct pci_dev *pdev) { - struct pci_dev *pdev = to_pci_dev(gendev); struct net_device *dev = pci_get_drvdata(pdev); struct rhine_private *rp = netdev_priv(dev); void __iomem *ioaddr = rp->base; @@ -1956,7 +1955,7 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state) pci_save_state(pdev); spin_lock_irqsave(&rp->lock, flags); - rhine_shutdown(&pdev->dev); + rhine_shutdown(pdev); spin_unlock_irqrestore(&rp->lock, flags); free_irq(dev->irq, dev); @@ -2010,9 +2009,7 @@ static struct pci_driver rhine_driver = { .suspend = rhine_suspend, .resume = rhine_resume, #endif /* CONFIG_PM */ - .driver = { - .shutdown = rhine_shutdown, - } + .shutdown = rhine_shutdown, }; diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 15e710283493..abc5cee6eedc 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1335,7 +1335,7 @@ static inline int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size, if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) skb_reserve(new_skb, 2); - memcpy(new_skb->data, rx_skb[0]->tail, pkt_size); + memcpy(new_skb->data, rx_skb[0]->data, pkt_size); *rx_skb = new_skb; ret = 0; } @@ -1456,9 +1456,9 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx) * Do the gymnastics to get the buffer head for data at * 64byte alignment. */ - skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63); + skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63); rd_info->skb->dev = vptr->dev; - rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); + rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); /* * Fill in the descriptor to match diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index c1b6896d7007..87496843681a 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -72,7 +72,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type, } skb_reserve(skb, 4); cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); - data = (cisco_packet*)skb->tail; + data = (cisco_packet*)skb->data; data->type = htonl(type); data->par1 = htonl(par1); diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c index b4f4bd7956a2..9d496703c465 100644 --- a/drivers/net/wireless/airport.c +++ b/drivers/net/wireless/airport.c @@ -184,7 +184,7 @@ static int airport_hard_reset(struct orinoco_private *priv) } static int -airport_attach(struct macio_dev *mdev, const struct of_match *match) +airport_attach(struct macio_dev *mdev, const struct of_device_id *match) { struct orinoco_private *priv; struct net_device *dev; @@ -266,16 +266,16 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); MODULE_DESCRIPTION("Driver for the Apple Airport wireless card."); MODULE_LICENSE("Dual MPL/GPL"); -static struct of_match airport_match[] = +static struct of_device_id airport_match[] = { { .name = "radio", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, airport_match); + static struct macio_driver airport_driver = { .name = DRIVER_NAME, diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 9da925430109..1c2506535f7e 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -786,7 +786,7 @@ static void yellowfin_init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, - skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); } yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1111,7 +1111,7 @@ static int yellowfin_rx(struct net_device *dev) pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr, yp->rx_buf_sz, PCI_DMA_FROMDEVICE); desc_status = le32_to_cpu(desc->result_status) >> 16; - buf_addr = rx_skb->tail; + buf_addr = rx_skb->data; data_size = (le32_to_cpu(desc->dbdma_cmd) - le32_to_cpu(desc->result_status)) & 0xffff; frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2]))); @@ -1185,7 +1185,7 @@ static int yellowfin_rx(struct net_device *dev) break; skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ - eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0); + eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(yp->pci_dev, desc->addr, yp->rx_buf_sz, @@ -1211,7 +1211,7 @@ static int yellowfin_rx(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, - skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); } yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP); yp->rx_ring[entry].result_status = 0; /* Clear complete bit. */ diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index b0d2a73d1d47..2f2dbef2c3b7 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -993,6 +993,7 @@ dino_driver_callback(struct parisc_device *dev) bus = pci_scan_bus_parented(&dev->dev, dino_current_bus, &dino_cfg_ops, NULL); if(bus) { + pci_bus_add_devices(bus); /* This code *depends* on scanning being single threaded * if it isn't, this global bus number count will fail */ diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index dc838804c0dd..7fdd80b7eb47 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1570,6 +1570,8 @@ lba_driver_probe(struct parisc_device *dev) lba_bus = lba_dev->hba.hba_bus = pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, cfg_ops, NULL); + if (lba_bus) + pci_bus_add_devices(lba_bus); /* This is in lieu of calling pci_assign_unassigned_resources() */ if (is_pdc_pat()) { diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 80edfa3abd29..4598c6a9212d 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -3008,7 +3008,7 @@ static int __init parport_pc_init_superio (int autoirq, int autodma) int ret = 0; while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { - id = pci_match_device (parport_pc_pci_tbl, pdev); + id = pci_match_id(parport_pc_pci_tbl, pdev); if (id == NULL || id->driver_data >= last_sio) continue; diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 7dea494c0d7b..3657f6199c48 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ # # Some architectures use the generic PCI setup functions # +obj-$(CONFIG_X86) += setup-bus.o obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o obj-$(CONFIG_PARISC) += setup-bus.o diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index dbd33605cc10..fedae89d8f7d 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -121,10 +121,13 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) * If there is an unattached subordinate bus, attach * it and then scan for unattached PCI devices. */ - if (dev->subordinate && list_empty(&dev->subordinate->node)) { - spin_lock(&pci_bus_lock); - list_add_tail(&dev->subordinate->node, &dev->bus->children); - spin_unlock(&pci_bus_lock); + if (dev->subordinate) { + if (list_empty(&dev->subordinate->node)) { + spin_lock(&pci_bus_lock); + list_add_tail(&dev->subordinate->node, + &dev->bus->children); + spin_unlock(&pci_bus_lock); + } pci_bus_add_devices(dev->subordinate); sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge"); diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c index 3903f8c559b6..b844bc972324 100644 --- a/drivers/pci/hotplug.c +++ b/drivers/pci/hotplug.c @@ -54,7 +54,7 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp, envp[i++] = scratch; length += scnprintf (scratch, buffer_size - length, - "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n", + "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device, (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 93c120ddbd39..3e632ff8c717 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile @@ -36,9 +36,7 @@ ibmphp-objs := ibmphp_core.o \ ibmphp_hpc.o acpiphp-objs := acpiphp_core.o \ - acpiphp_glue.o \ - acpiphp_pci.o \ - acpiphp_res.o + acpiphp_glue.o rpaphp-objs := rpaphp_core.o \ rpaphp_pci.o \ diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index d9499874c8a9..293603e1b7c3 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -7,6 +7,8 @@ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (C) 2002,2003 NEC Corporation + * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) + * Copyright (C) 2003-2005 Hewlett Packard * * All rights reserved. * @@ -52,7 +54,6 @@ struct acpiphp_bridge; struct acpiphp_slot; -struct pci_resource; /* * struct slot - slot information for each *physical* slot @@ -65,15 +66,6 @@ struct slot { struct acpiphp_slot *acpi_slot; }; -/* - * struct pci_resource - describes pci resource (mem, pfmem, io, bus) - */ -struct pci_resource { - struct pci_resource * next; - u64 base; - u32 length; -}; - /** * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters * @cache_line_size in DWORD @@ -101,10 +93,6 @@ struct acpiphp_bridge { int type; int nr_slots; - u8 seg; - u8 bus; - u8 sub; - u32 flags; /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */ @@ -117,12 +105,6 @@ struct acpiphp_bridge { struct hpp_param hpp; spinlock_t res_lock; - - /* available resources on this bus */ - struct pci_resource *mem_head; - struct pci_resource *p_mem_head; - struct pci_resource *io_head; - struct pci_resource *bus_head; }; @@ -163,12 +145,6 @@ struct acpiphp_func { u8 function; /* pci function# */ u32 flags; /* see below */ - - /* resources used for this function */ - struct pci_resource *mem_head; - struct pci_resource *p_mem_head; - struct pci_resource *io_head; - struct pci_resource *bus_head; }; /** @@ -243,25 +219,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); extern u32 acpiphp_get_address (struct acpiphp_slot *slot); -/* acpiphp_pci.c */ -extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn); -extern int acpiphp_configure_slot (struct acpiphp_slot *slot); -extern int acpiphp_configure_function (struct acpiphp_func *func); -extern void acpiphp_unconfigure_function (struct acpiphp_func *func); -extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge); -extern int acpiphp_init_func_resource (struct acpiphp_func *func); - -/* acpiphp_res.c */ -extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size); -extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size); -extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size); -extern int acpiphp_resource_sort_and_combine (struct pci_resource **head); -extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length); -extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to); -extern void acpiphp_free_resource (struct pci_resource **res); -extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */ -extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */ - /* variables */ extern int acpiphp_debug; diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 4539e61a3dc1..60c4c38047a3 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -7,6 +7,8 @@ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (C) 2002,2003 NEC Corporation + * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) + * Copyright (C) 2003-2005 Hewlett Packard * * All rights reserved. * @@ -53,8 +55,8 @@ int acpiphp_debug; static int num_slots; static struct acpiphp_attention_info *attention_info; -#define DRIVER_VERSION "0.4" -#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>" +#define DRIVER_VERSION "0.5" +#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>, Matthew Wilcox <willy@hp.com>" #define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver" MODULE_AUTHOR(DRIVER_AUTHOR); @@ -281,8 +283,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) /** * get_address - get pci address of a slot * @hotplug_slot: slot to get status - * @busdev: pointer to struct pci_busdev (seg, bus, dev) - * + * @value: pointer to struct pci_busdev (seg, bus, dev) */ static int get_address(struct hotplug_slot *hotplug_slot, u32 *value) { diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index e7f41294f811..424e7de181ae 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -4,6 +4,10 @@ * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) * Copyright (C) 2002,2003 NEC Corporation + * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) + * Copyright (C) 2003-2005 Hewlett Packard + * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com) + * Copyright (C) 2005 Intel Corporation * * All rights reserved. * @@ -26,6 +30,16 @@ * */ +/* + * Lifetime rules for pci_dev: + * - The one in acpiphp_func has its refcount elevated by pci_get_slot() + * when the driver is loaded or when an insertion event occurs. It loses + * a refcount when its ejected or the driver unloads. + * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() + * when the bridge is scanned and it loses a refcount when the bridge + * is removed. + */ + #include <linux/init.h> #include <linux/module.h> @@ -178,21 +192,18 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) bridge->nr_slots++; - dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n", - slot->bridge->bus, slot->device, slot->sun); + dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n", + slot->sun, pci_domain_nr(bridge->pci_bus), + bridge->pci_bus->number, slot->device); } newfunc->slot = slot; list_add_tail(&newfunc->sibling, &slot->funcs); /* associate corresponding pci_dev */ - newfunc->pci_dev = pci_find_slot(bridge->bus, + newfunc->pci_dev = pci_get_slot(bridge->pci_bus, PCI_DEVFN(device, function)); if (newfunc->pci_dev) { - if (acpiphp_init_func_resource(newfunc) < 0) { - kfree(newfunc); - return AE_ERROR; - } slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); } @@ -227,62 +238,6 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle) } -/* decode ACPI _CRS data and convert into our internal resource list - * TBD: _TRA, etc. - */ -static acpi_status -decode_acpi_resource(struct acpi_resource *resource, void *context) -{ - struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context; - struct acpi_resource_address64 address; - struct pci_resource *res; - - if (resource->id != ACPI_RSTYPE_ADDRESS16 && - resource->id != ACPI_RSTYPE_ADDRESS32 && - resource->id != ACPI_RSTYPE_ADDRESS64) - return AE_OK; - - acpi_resource_to_address64(resource, &address); - - if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) { - dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type, - (unsigned long long)address.min_address_range, - (unsigned long long)address.max_address_range); - res = acpiphp_make_resource(address.min_address_range, - address.address_length); - if (!res) { - err("out of memory\n"); - return AE_OK; - } - - switch (address.resource_type) { - case ACPI_MEMORY_RANGE: - if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) { - res->next = bridge->p_mem_head; - bridge->p_mem_head = res; - } else { - res->next = bridge->mem_head; - bridge->mem_head = res; - } - break; - case ACPI_IO_RANGE: - res->next = bridge->io_head; - bridge->io_head = res; - break; - case ACPI_BUS_NUMBER_RANGE: - res->next = bridge->bus_head; - bridge->bus_head = res; - break; - default: - /* invalid type */ - kfree(res); - break; - } - } - - return AE_OK; -} - /* decode ACPI 2.0 _HPP hot plug parameters */ static void decode_hpp(struct acpiphp_bridge *bridge) { @@ -346,34 +301,29 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) /* decode ACPI 2.0 _HPP (hot plug parameters) */ decode_hpp(bridge); - /* subtract all resources already allocated */ - acpiphp_detect_pci_resource(bridge); - /* register all slot objects under this bridge */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, register_slot, bridge, NULL); /* install notify handler */ - status = acpi_install_notify_handler(bridge->handle, + if (bridge->type != BRIDGE_TYPE_HOST) { + status = acpi_install_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_bridge, bridge); - if (ACPI_FAILURE(status)) { - err("failed to register interrupt notify handler\n"); + if (ACPI_FAILURE(status)) { + err("failed to register interrupt notify handler\n"); + } } list_add(&bridge->list, &bridge_list); - - dbg("Bridge resource:\n"); - acpiphp_dump_resource(bridge); } /* allocate and initialize host bridge data structure */ -static void add_host_bridge(acpi_handle *handle, int seg, int bus) +static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) { - acpi_status status; struct acpiphp_bridge *bridge; bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); @@ -384,52 +334,19 @@ static void add_host_bridge(acpi_handle *handle, int seg, int bus) bridge->type = BRIDGE_TYPE_HOST; bridge->handle = handle; - bridge->seg = seg; - bridge->bus = bus; - bridge->pci_bus = pci_find_bus(seg, bus); + bridge->pci_bus = pci_bus; spin_lock_init(&bridge->res_lock); - /* to be overridden when we decode _CRS */ - bridge->sub = bridge->bus; - - /* decode resources */ - - status = acpi_walk_resources(handle, METHOD_NAME__CRS, - decode_acpi_resource, bridge); - - if (ACPI_FAILURE(status)) { - err("failed to decode bridge resources\n"); - kfree(bridge); - return; - } - - acpiphp_resource_sort_and_combine(&bridge->io_head); - acpiphp_resource_sort_and_combine(&bridge->mem_head); - acpiphp_resource_sort_and_combine(&bridge->p_mem_head); - acpiphp_resource_sort_and_combine(&bridge->bus_head); - - dbg("ACPI _CRS resource:\n"); - acpiphp_dump_resource(bridge); - - if (bridge->bus_head) { - bridge->bus = bridge->bus_head->base; - bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1; - } - init_bridge_misc(bridge); } /* allocate and initialize PCI-to-PCI bridge data structure */ -static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn) +static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) { struct acpiphp_bridge *bridge; - u8 tmp8; - u16 tmp16; - u64 base64, limit64; - u32 base, limit, base32u, limit32u; bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); if (bridge == NULL) { @@ -441,133 +358,22 @@ static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int f bridge->type = BRIDGE_TYPE_P2P; bridge->handle = handle; - bridge->seg = seg; - - bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn)); - if (!bridge->pci_dev) { - err("Can't get pci_dev\n"); - kfree(bridge); - return; - } - bridge->pci_bus = bridge->pci_dev->subordinate; + bridge->pci_dev = pci_dev_get(pci_dev); + bridge->pci_bus = pci_dev->subordinate; if (!bridge->pci_bus) { err("This is not a PCI-to-PCI bridge!\n"); - kfree(bridge); - return; + goto err; } spin_lock_init(&bridge->res_lock); - bridge->bus = bridge->pci_bus->number; - bridge->sub = bridge->pci_bus->subordinate; - - /* - * decode resources under this P2P bridge - */ - - /* I/O resources */ - pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8); - base = tmp8; - pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8); - limit = tmp8; - - switch (base & PCI_IO_RANGE_TYPE_MASK) { - case PCI_IO_RANGE_TYPE_16: - base = (base << 8) & 0xf000; - limit = ((limit << 8) & 0xf000) + 0xfff; - bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); - if (!bridge->io_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("16bit I/O range: %04x-%04x\n", - (u32)bridge->io_head->base, - (u32)(bridge->io_head->base + bridge->io_head->length - 1)); - break; - case PCI_IO_RANGE_TYPE_32: - pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16); - base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000); - pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16); - limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff; - bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); - if (!bridge->io_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("32bit I/O range: %08x-%08x\n", - (u32)bridge->io_head->base, - (u32)(bridge->io_head->base + bridge->io_head->length - 1)); - break; - case 0x0f: - dbg("I/O space unsupported\n"); - break; - default: - warn("Unknown I/O range type\n"); - } - - /* Memory resources (mandatory for P2P bridge) */ - pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16); - base = (tmp16 & 0xfff0) << 16; - pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16); - limit = ((tmp16 & 0xfff0) << 16) | 0xfffff; - bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1); - if (!bridge->mem_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("32bit Memory range: %08x-%08x\n", - (u32)bridge->mem_head->base, - (u32)(bridge->mem_head->base + bridge->mem_head->length-1)); - - /* Prefetchable Memory resources (optional) */ - pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16); - base = tmp16; - pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16); - limit = tmp16; - - switch (base & PCI_MEMORY_RANGE_TYPE_MASK) { - case PCI_PREF_RANGE_TYPE_32: - base = (base & 0xfff0) << 16; - limit = ((limit & 0xfff0) << 16) | 0xfffff; - bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1); - if (!bridge->p_mem_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("32bit Prefetchable memory range: %08x-%08x\n", - (u32)bridge->p_mem_head->base, - (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1)); - break; - case PCI_PREF_RANGE_TYPE_64: - pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u); - pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u); - base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16); - limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff; - - bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1); - if (!bridge->p_mem_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n", - (u32)(bridge->p_mem_head->base >> 32), - (u32)(bridge->p_mem_head->base & 0xffffffff), - (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32), - (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff)); - break; - case 0x0f: - break; - default: - warn("Unknown prefetchale memory type\n"); - } - init_bridge_misc(bridge); + return; + err: + pci_dev_put(pci_dev); + kfree(bridge); + return; } @@ -577,14 +383,10 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; acpi_handle dummy_handle; - unsigned long *segbus = context; unsigned long tmp; - int seg, bus, device, function; + int device, function; struct pci_dev *dev; - - /* get PCI address */ - seg = (*segbus >> 8) & 0xff; - bus = *segbus & 0xff; + struct pci_bus *pci_bus = context; status = acpi_get_handle(handle, "_ADR", &dummy_handle); if (ACPI_FAILURE(status)) @@ -599,20 +401,19 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) device = (tmp >> 16) & 0xffff; function = tmp & 0xffff; - dev = pci_find_slot(bus, PCI_DEVFN(device, function)); + dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function)); - if (!dev) - return AE_OK; - - if (!dev->subordinate) - return AE_OK; + if (!dev || !dev->subordinate) + goto out; /* check if this bridge has ejectable slots */ if (detect_ejectable_slots(handle) > 0) { dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); - add_p2p_bridge(handle, seg, bus, device, function); + add_p2p_bridge(handle, dev); } + out: + pci_dev_put(dev); return AE_OK; } @@ -624,6 +425,7 @@ static int add_bridge(acpi_handle handle) unsigned long tmp; int seg, bus; acpi_handle dummy_handle; + struct pci_bus *pci_bus; /* if the bridge doesn't have _STA, we assume it is always there */ status = acpi_get_handle(handle, "_STA", &dummy_handle); @@ -653,18 +455,22 @@ static int add_bridge(acpi_handle handle) bus = 0; } + pci_bus = pci_find_bus(seg, bus); + if (!pci_bus) { + err("Can't find bus %04x:%02x\n", seg, bus); + return 0; + } + /* check if this bridge has ejectable slots */ if (detect_ejectable_slots(handle) > 0) { dbg("found PCI host-bus bridge with hot-pluggable slots\n"); - add_host_bridge(handle, seg, bus); + add_host_bridge(handle, pci_bus); return 0; } - tmp = seg << 8 | bus; - /* search P2P bridges under this host bridge */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, - find_p2p_bridge, &tmp, NULL); + find_p2p_bridge, pci_bus, NULL); if (ACPI_FAILURE(status)) warn("find_p2p_bridge faied (error code = 0x%x)\n",status); @@ -672,12 +478,205 @@ static int add_bridge(acpi_handle handle) return 0; } +static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) +{ + struct list_head *head; + list_for_each(head, &bridge_list) { + struct acpiphp_bridge *bridge = list_entry(head, + struct acpiphp_bridge, list); + if (bridge->handle == handle) + return bridge; + } + + return NULL; +} + +static void cleanup_bridge(struct acpiphp_bridge *bridge) +{ + struct list_head *list, *tmp; + struct acpiphp_slot *slot; + acpi_status status; + acpi_handle handle = bridge->handle; + + status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_bridge); + if (ACPI_FAILURE(status)) + err("failed to remove notify handler\n"); + + slot = bridge->slots; + while (slot) { + struct acpiphp_slot *next = slot->next; + list_for_each_safe (list, tmp, &slot->funcs) { + struct acpiphp_func *func; + func = list_entry(list, struct acpiphp_func, sibling); + status = acpi_remove_notify_handler(func->handle, + ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_func); + if (ACPI_FAILURE(status)) + err("failed to remove notify handler\n"); + pci_dev_put(func->pci_dev); + list_del(list); + kfree(func); + } + kfree(slot); + slot = next; + } + + pci_dev_put(bridge->pci_dev); + list_del(&bridge->list); + kfree(bridge); +} + +static acpi_status +cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + struct acpiphp_bridge *bridge; + + if (!(bridge = acpiphp_handle_to_bridge(handle))) + return AE_OK; + cleanup_bridge(bridge); + return AE_OK; +} static void remove_bridge(acpi_handle handle) { - /* No-op for now .. */ + struct acpiphp_bridge *bridge; + + bridge = acpiphp_handle_to_bridge(handle); + if (bridge) { + cleanup_bridge(bridge); + } else { + /* clean-up p2p bridges under this host bridge */ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + (u32)1, cleanup_p2p_bridge, NULL, NULL); + } +} + +static struct pci_dev * get_apic_pci_info(acpi_handle handle) +{ + struct acpi_pci_id id; + struct pci_bus *bus; + struct pci_dev *dev; + + if (ACPI_FAILURE(acpi_get_pci_id(handle, &id))) + return NULL; + + bus = pci_find_bus(id.segment, id.bus); + if (!bus) + return NULL; + + dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function)); + if (!dev) + return NULL; + + if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) && + (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC)) + { + pci_dev_put(dev); + return NULL; + } + + return dev; +} + +static int get_gsi_base(acpi_handle handle, u32 *gsi_base) +{ + acpi_status status; + int result = -1; + unsigned long gsb; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *obj; + void *table; + + status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); + if (ACPI_SUCCESS(status)) { + *gsi_base = (u32)gsb; + return 0; + } + + status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer); + if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer) + return -1; + + obj = buffer.pointer; + if (obj->type != ACPI_TYPE_BUFFER) + goto out; + + table = obj->buffer.pointer; + switch (((acpi_table_entry_header *)table)->type) { + case ACPI_MADT_IOSAPIC: + *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base; + result = 0; + break; + case ACPI_MADT_IOAPIC: + *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base; + result = 0; + break; + default: + break; + } + out: + acpi_os_free(buffer.pointer); + return result; +} + +static acpi_status +ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + acpi_status status; + unsigned long sta; + acpi_handle tmp; + struct pci_dev *pdev; + u32 gsi_base; + u64 phys_addr; + + /* Evaluate _STA if present */ + status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); + if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) + return AE_CTRL_DEPTH; + + /* Scan only PCI bus scope */ + status = acpi_get_handle(handle, "_HID", &tmp); + if (ACPI_SUCCESS(status)) + return AE_CTRL_DEPTH; + + if (get_gsi_base(handle, &gsi_base)) + return AE_OK; + + pdev = get_apic_pci_info(handle); + if (!pdev) + return AE_OK; + + if (pci_enable_device(pdev)) { + pci_dev_put(pdev); + return AE_OK; + } + + pci_set_master(pdev); + + if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) { + pci_disable_device(pdev); + pci_dev_put(pdev); + return AE_OK; + } + + phys_addr = pci_resource_start(pdev, 0); + if (acpi_register_ioapic(handle, phys_addr, gsi_base)) { + pci_release_region(pdev, 0); + pci_disable_device(pdev); + pci_dev_put(pdev); + return AE_OK; + } + + return AE_OK; } +static int acpiphp_configure_ioapics(acpi_handle handle) +{ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + ACPI_UINT32_MAX, ioapic_add, NULL, NULL); + return 0; +} static int power_on_slot(struct acpiphp_slot *slot) { @@ -719,8 +718,6 @@ static int power_off_slot(struct acpiphp_slot *slot) acpi_status status; struct acpiphp_func *func; struct list_head *l; - struct acpi_object_list arg_list; - union acpi_object arg; int retval = 0; @@ -731,7 +728,7 @@ static int power_off_slot(struct acpiphp_slot *slot) list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); - if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) { + if (func->flags & FUNC_HAS_PS3) { status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); if (ACPI_FAILURE(status)) { warn("%s: _PS3 failed\n", __FUNCTION__); @@ -742,27 +739,6 @@ static int power_off_slot(struct acpiphp_slot *slot) } } - list_for_each (l, &slot->funcs) { - func = list_entry(l, struct acpiphp_func, sibling); - - /* We don't want to call _EJ0 on non-existing functions. */ - if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) { - /* _EJ0 method take one argument */ - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - - status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); - if (ACPI_FAILURE(status)) { - warn("%s: _EJ0 failed\n", __FUNCTION__); - retval = -1; - goto err_exit; - } else - break; - } - } - /* TBD: evaluate _STA to check if the slot is disabled */ slot->flags &= (~SLOT_POWEREDON); @@ -782,70 +758,56 @@ static int power_off_slot(struct acpiphp_slot *slot) */ static int enable_device(struct acpiphp_slot *slot) { - u8 bus; struct pci_dev *dev; - struct pci_bus *child; + struct pci_bus *bus = slot->bridge->pci_bus; struct list_head *l; struct acpiphp_func *func; int retval = 0; - int num; + int num, max, pass; if (slot->flags & SLOT_ENABLED) goto err_exit; /* sanity check: dev should be NULL when hot-plugged in */ - dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0)); + dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); if (dev) { /* This case shouldn't happen */ err("pci_dev structure already exists.\n"); + pci_dev_put(dev); retval = -1; goto err_exit; } - /* allocate resources to device */ - retval = acpiphp_configure_slot(slot); - if (retval) - goto err_exit; - - /* returned `dev' is the *first function* only! */ - num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0)); - if (num) - pci_bus_add_devices(slot->bridge->pci_bus); - dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0)); - - if (!dev) { + num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); + if (num == 0) { err("No new device found\n"); retval = -1; goto err_exit; } - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus); - child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus); - pci_do_scan_bus(child); + max = bus->secondary; + for (pass = 0; pass < 2; pass++) { + list_for_each_entry(dev, &bus->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != slot->device) + continue; + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) + max = pci_scan_bridge(bus, dev, max, pass); + } } + pci_bus_assign_resources(bus); + pci_bus_add_devices(bus); + /* associate pci_dev to our representation */ list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); - - func->pci_dev = pci_find_slot(slot->bridge->bus, - PCI_DEVFN(slot->device, + func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device, func->function)); - if (!func->pci_dev) - continue; - - /* configure device */ - retval = acpiphp_configure_function(func); - if (retval) - goto err_exit; } slot->flags |= SLOT_ENABLED; - dbg("Available resources:\n"); - acpiphp_dump_resource(slot->bridge); - err_exit: return retval; } @@ -866,9 +828,12 @@ static int disable_device(struct acpiphp_slot *slot) list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); + if (!func->pci_dev) + continue; - if (func->pci_dev) - acpiphp_unconfigure_function(func); + pci_remove_bus_device(func->pci_dev); + pci_dev_put(func->pci_dev); + func->pci_dev = NULL; } slot->flags &= (~SLOT_ENABLED); @@ -920,6 +885,39 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) } /** + * acpiphp_eject_slot - physically eject the slot + */ +static int acpiphp_eject_slot(struct acpiphp_slot *slot) +{ + acpi_status status; + struct acpiphp_func *func; + struct list_head *l; + struct acpi_object_list arg_list; + union acpi_object arg; + + list_for_each (l, &slot->funcs) { + func = list_entry(l, struct acpiphp_func, sibling); + + /* We don't want to call _EJ0 on non-existing functions. */ + if ((func->flags & FUNC_HAS_EJ0)) { + /* _EJ0 method take one argument */ + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = 1; + + status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); + if (ACPI_FAILURE(status)) { + warn("%s: _EJ0 failed\n", __FUNCTION__); + return -1; + } else + break; + } + } + return 0; +} + +/** * acpiphp_check_bridge - re-enumerate devices * * Iterate over all slots under this bridge and make sure that if a @@ -942,6 +940,8 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) if (retval) { err("Error occurred in disabling\n"); goto err_exit; + } else { + acpiphp_eject_slot(slot); } disabled++; } else { @@ -962,6 +962,144 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) return retval; } +static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) +{ + u16 pci_cmd, pci_bctl; + struct pci_dev *cdev; + + /* Program hpp values for this device */ + if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || + (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) + return; + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, + bridge->hpp.cache_line_size); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, + bridge->hpp.latency_timer); + pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); + if (bridge->hpp.enable_SERR) + pci_cmd |= PCI_COMMAND_SERR; + else + pci_cmd &= ~PCI_COMMAND_SERR; + if (bridge->hpp.enable_PERR) + pci_cmd |= PCI_COMMAND_PARITY; + else + pci_cmd &= ~PCI_COMMAND_PARITY; + pci_write_config_word(dev, PCI_COMMAND, pci_cmd); + + /* Program bridge control value and child devices */ + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, + bridge->hpp.latency_timer); + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); + if (bridge->hpp.enable_SERR) + pci_bctl |= PCI_BRIDGE_CTL_SERR; + else + pci_bctl &= ~PCI_BRIDGE_CTL_SERR; + if (bridge->hpp.enable_PERR) + pci_bctl |= PCI_BRIDGE_CTL_PARITY; + else + pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); + if (dev->subordinate) { + list_for_each_entry(cdev, &dev->subordinate->devices, + bus_list) + program_hpp(cdev, bridge); + } + } +} + +static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus) +{ + struct acpiphp_bridge bridge; + struct pci_dev *dev; + + memset(&bridge, 0, sizeof(bridge)); + bridge.handle = handle; + decode_hpp(&bridge); + list_for_each_entry(dev, &bus->devices, bus_list) + program_hpp(dev, &bridge); + +} + +/* + * Remove devices for which we could not assign resources, call + * arch specific code to fix-up the bus + */ +static void acpiphp_sanitize_bus(struct pci_bus *bus) +{ + struct pci_dev *dev; + int i; + unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; + + list_for_each_entry(dev, &bus->devices, bus_list) { + for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { + struct resource *res = &dev->resource[i]; + if ((res->flags & type_mask) && !res->start && + res->end) { + /* Could not assign a required resources + * for this device, remove it */ + pci_remove_bus_device(dev); + break; + } + } + } +} + +/* Program resources in newly inserted bridge */ +static int acpiphp_configure_bridge (acpi_handle handle) +{ + struct acpi_pci_id pci_id; + struct pci_bus *bus; + + if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) { + err("cannot get PCI domain and bus number for bridge\n"); + return -EINVAL; + } + bus = pci_find_bus(pci_id.segment, pci_id.bus); + if (!bus) { + err("cannot find bus %d:%d\n", + pci_id.segment, pci_id.bus); + return -EINVAL; + } + + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + acpiphp_sanitize_bus(bus); + acpiphp_set_hpp_values(handle, bus); + pci_enable_bridges(bus); + acpiphp_configure_ioapics(handle); + return 0; +} + +static void handle_bridge_insertion(acpi_handle handle, u32 type) +{ + struct acpi_device *device, *pdevice; + acpi_handle phandle; + + if ((type != ACPI_NOTIFY_BUS_CHECK) && + (type != ACPI_NOTIFY_DEVICE_CHECK)) { + err("unexpected notification type %d\n", type); + return; + } + + acpi_get_parent(handle, &phandle); + if (acpi_bus_get_device(phandle, &pdevice)) { + dbg("no parent device, assuming NULL\n"); + pdevice = NULL; + } + if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) { + err("cannot add bridge to acpi list\n"); + return; + } + if (!acpiphp_configure_bridge(handle) && + !acpi_bus_start(device)) + add_bridge(handle); + else + err("cannot configure and start bridge\n"); + +} + /* * ACPI event handlers */ @@ -982,8 +1120,19 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), .pointer = objname }; + struct acpi_device *device; - bridge = (struct acpiphp_bridge *)context; + if (acpi_bus_get_device(handle, &device)) { + /* This bridge must have just been physically inserted */ + handle_bridge_insertion(handle, type); + return; + } + + bridge = acpiphp_handle_to_bridge(handle); + if (!bridge) { + err("cannot get bridge info\n"); + return; + } acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); @@ -1031,7 +1180,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont } } - /** * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) * @@ -1074,7 +1222,8 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); - acpiphp_disable_slot(func->slot); + if (!(acpiphp_disable_slot(func->slot))) + acpiphp_eject_slot(func->slot); break; default: @@ -1083,6 +1232,47 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex } } +static int is_root_bridge(acpi_handle handle) +{ + acpi_status status; + struct acpi_device_info *info; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + int i; + + status = acpi_get_object_info(handle, &buffer); + if (ACPI_SUCCESS(status)) { + info = buffer.pointer; + if ((info->valid & ACPI_VALID_HID) && + !strcmp(PCI_ROOT_HID_STRING, + info->hardware_id.value)) { + acpi_os_free(buffer.pointer); + return 1; + } + if (info->valid & ACPI_VALID_CID) { + for (i=0; i < info->compatibility_id.count; i++) { + if (!strcmp(PCI_ROOT_HID_STRING, + info->compatibility_id.id[i].value)) { + acpi_os_free(buffer.pointer); + return 1; + } + } + } + } + return 0; +} + +static acpi_status +find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + int *count = (int *)context; + + if (is_root_bridge(handle)) { + acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_bridge, NULL); + (*count)++; + } + return AE_OK ; +} static struct acpi_pci_driver acpi_pci_hp_driver = { .add = add_bridge, @@ -1095,15 +1285,15 @@ static struct acpi_pci_driver acpi_pci_hp_driver = { */ int __init acpiphp_glue_init(void) { - int num; - - if (list_empty(&pci_root_buses)) - return -1; + int num = 0; - num = acpi_pci_register_driver(&acpi_pci_hp_driver); + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, find_root_bridges, &num, NULL); if (num <= 0) return -1; + else + acpi_pci_register_driver(&acpi_pci_hp_driver); return 0; } @@ -1116,46 +1306,6 @@ int __init acpiphp_glue_init(void) */ void __exit acpiphp_glue_exit(void) { - struct list_head *l1, *l2, *n1, *n2; - struct acpiphp_bridge *bridge; - struct acpiphp_slot *slot, *next; - struct acpiphp_func *func; - acpi_status status; - - list_for_each_safe (l1, n1, &bridge_list) { - bridge = (struct acpiphp_bridge *)l1; - slot = bridge->slots; - while (slot) { - next = slot->next; - list_for_each_safe (l2, n2, &slot->funcs) { - func = list_entry(l2, struct acpiphp_func, sibling); - acpiphp_free_resource(&func->io_head); - acpiphp_free_resource(&func->mem_head); - acpiphp_free_resource(&func->p_mem_head); - acpiphp_free_resource(&func->bus_head); - status = acpi_remove_notify_handler(func->handle, - ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_func); - if (ACPI_FAILURE(status)) - err("failed to remove notify handler\n"); - kfree(func); - } - kfree(slot); - slot = next; - } - status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_bridge); - if (ACPI_FAILURE(status)) - err("failed to remove notify handler\n"); - - acpiphp_free_resource(&bridge->io_head); - acpiphp_free_resource(&bridge->mem_head); - acpiphp_free_resource(&bridge->p_mem_head); - acpiphp_free_resource(&bridge->bus_head); - - kfree(bridge); - } - acpi_pci_unregister_driver(&acpi_pci_hp_driver); } @@ -1173,11 +1323,14 @@ int __init acpiphp_get_num_slots(void) list_for_each (node, &bridge_list) { bridge = (struct acpiphp_bridge *)node; - dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots); + dbg("Bus %04x:%02x has %d slot%s\n", + pci_domain_nr(bridge->pci_bus), + bridge->pci_bus->number, bridge->nr_slots, + bridge->nr_slots == 1 ? "" : "s"); num_slots += bridge->nr_slots; } - dbg("Total %dslots\n", num_slots); + dbg("Total %d slots\n", num_slots); return num_slots; } @@ -1254,7 +1407,6 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot) return retval; } - /** * acpiphp_disable_slot - power off slot */ @@ -1274,13 +1426,6 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) if (retval) goto err_exit; - acpiphp_resource_sort_and_combine(&slot->bridge->io_head); - acpiphp_resource_sort_and_combine(&slot->bridge->mem_head); - acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head); - acpiphp_resource_sort_and_combine(&slot->bridge->bus_head); - dbg("Available resources:\n"); - acpiphp_dump_resource(slot->bridge); - err_exit: up(&slot->crit_sect); return retval; @@ -1293,11 +1438,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) */ u8 acpiphp_get_power_status(struct acpiphp_slot *slot) { - unsigned int sta; - - sta = get_slot_status(slot); - - return (sta & ACPI_STA_ENABLED) ? 1 : 0; + return (slot->flags & SLOT_POWEREDON); } @@ -1335,9 +1476,10 @@ u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot) u32 acpiphp_get_address(struct acpiphp_slot *slot) { u32 address; + struct pci_bus *pci_bus = slot->bridge->pci_bus; - address = ((slot->bridge->seg) << 16) | - ((slot->bridge->bus) << 8) | + address = (pci_domain_nr(pci_bus) << 16) | + (pci_bus->number << 8) | slot->device; return address; diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c deleted file mode 100644 index 54d97c9d1dff..000000000000 --- a/drivers/pci/hotplug/acpiphp_pci.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * ACPI PCI HotPlug PCI configuration space management - * - * Copyright (C) 1995,2001 Compaq Computer Corporation - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2001,2002 IBM Corp. - * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) - * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (C) 2002 NEC Corporation - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. 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. - * - * Send feedback to <t-kochi@bq.jp.nec.com> - * - */ - -#include <linux/init.h> -#include <linux/module.h> - -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/acpi.h> -#include "../pci.h" -#include "pci_hotplug.h" -#include "acpiphp.h" - -#define MY_NAME "acpiphp_pci" - - -/* allocate mem/pmem/io resource to a new function */ -static int init_config_space (struct acpiphp_func *func) -{ - u32 bar, len; - u32 address[] = { - PCI_BASE_ADDRESS_0, - PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, - PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, - PCI_BASE_ADDRESS_5, - 0 - }; - int count; - struct acpiphp_bridge *bridge; - struct pci_resource *res; - struct pci_bus *pbus; - int bus, device, function; - unsigned int devfn; - u16 tmp; - - bridge = func->slot->bridge; - pbus = bridge->pci_bus; - bus = bridge->bus; - device = func->slot->device; - function = func->function; - devfn = PCI_DEVFN(device, function); - - for (count = 0; address[count]; count++) { /* for 6 BARs */ - pci_bus_write_config_dword(pbus, devfn, - address[count], 0xFFFFFFFF); - pci_bus_read_config_dword(pbus, devfn, address[count], &bar); - - if (!bar) /* This BAR is not implemented */ - continue; - - dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar); - - if (bar & PCI_BASE_ADDRESS_SPACE_IO) { - /* This is IO */ - - len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); - len = len & ~(len - 1); - - dbg("len in IO %x, BAR %d\n", len, count); - - spin_lock(&bridge->res_lock); - res = acpiphp_get_io_resource(&bridge->io_head, len); - spin_unlock(&bridge->res_lock); - - if (!res) { - err("cannot allocate requested io for %02x:%02x.%d len %x\n", - bus, device, function, len); - return -1; - } - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)res->base); - res->next = func->io_head; - func->io_head = res; - - } else { - /* This is Memory */ - if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) { - /* pfmem */ - - len = bar & 0xFFFFFFF0; - len = ~len + 1; - - dbg("len in PFMEM %x, BAR %d\n", len, count); - - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource(&bridge->p_mem_head, len); - spin_unlock(&bridge->res_lock); - - if (!res) { - err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n", - bus, device, function, len); - return -1; - } - - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)res->base); - - if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */ - dbg("inside the pfmem 64 case, count %d\n", count); - count += 1; - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)(res->base >> 32)); - } - - res->next = func->p_mem_head; - func->p_mem_head = res; - - } else { - /* regular memory */ - - len = bar & 0xFFFFFFF0; - len = ~len + 1; - - dbg("len in MEM %x, BAR %d\n", len, count); - - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource(&bridge->mem_head, len); - spin_unlock(&bridge->res_lock); - - if (!res) { - err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n", - bus, device, function, len); - return -1; - } - - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)res->base); - - if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { - /* takes up another dword */ - dbg("inside mem 64 case, reg. mem, count %d\n", count); - count += 1; - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)(res->base >> 32)); - } - - res->next = func->mem_head; - func->mem_head = res; - - } - } - } - - /* disable expansion rom */ - pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000); - - /* set PCI parameters from _HPP */ - pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE, - bridge->hpp.cache_line_size); - pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER, - bridge->hpp.latency_timer); - - pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp); - if (bridge->hpp.enable_SERR) - tmp |= PCI_COMMAND_SERR; - if (bridge->hpp.enable_PERR) - tmp |= PCI_COMMAND_PARITY; - pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp); - - return 0; -} - -/* detect_used_resource - subtract resource under dev from bridge */ -static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev) -{ - int count; - - dbg("Device %s\n", pci_name(dev)); - - for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) { - struct pci_resource *res; - struct pci_resource **head; - unsigned long base = dev->resource[count].start; - unsigned long len = dev->resource[count].end - base + 1; - unsigned long flags = dev->resource[count].flags; - - if (!flags) - continue; - - dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base, - base + len - 1, flags); - - if (flags & IORESOURCE_IO) { - head = &bridge->io_head; - } else if (flags & IORESOURCE_PREFETCH) { - head = &bridge->p_mem_head; - } else { - head = &bridge->mem_head; - } - - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource_with_base(head, base, len); - spin_unlock(&bridge->res_lock); - if (res) - kfree(res); - } - - return 0; -} - - -/** - * acpiphp_detect_pci_resource - detect resources under bridge - * @bridge: detect all resources already used under this bridge - * - * collect all resources already allocated for all devices under a bridge. - */ -int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge) -{ - struct list_head *l; - struct pci_dev *dev; - - list_for_each (l, &bridge->pci_bus->devices) { - dev = pci_dev_b(l); - detect_used_resource(bridge, dev); - } - - return 0; -} - - -/** - * acpiphp_init_slot_resource - gather resource usage information of a slot - * @slot: ACPI slot object to be checked, should have valid pci_dev member - * - * TBD: PCI-to-PCI bridge case - * use pci_dev->resource[] - */ -int acpiphp_init_func_resource (struct acpiphp_func *func) -{ - u64 base; - u32 bar, len; - u32 address[] = { - PCI_BASE_ADDRESS_0, - PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, - PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, - PCI_BASE_ADDRESS_5, - 0 - }; - int count; - struct pci_resource *res; - struct pci_dev *dev; - - dev = func->pci_dev; - dbg("Hot-pluggable device %s\n", pci_name(dev)); - - for (count = 0; address[count]; count++) { /* for 6 BARs */ - pci_read_config_dword(dev, address[count], &bar); - - if (!bar) /* This BAR is not implemented */ - continue; - - pci_write_config_dword(dev, address[count], 0xFFFFFFFF); - pci_read_config_dword(dev, address[count], &len); - - if (len & PCI_BASE_ADDRESS_SPACE_IO) { - /* This is IO */ - base = bar & 0xFFFFFFFC; - len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); - len = len & ~(len - 1); - - dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1); - - res = acpiphp_make_resource(base, len); - if (!res) - goto no_memory; - - res->next = func->io_head; - func->io_head = res; - - } else { - /* This is Memory */ - base = bar & 0xFFFFFFF0; - if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) { - /* pfmem */ - - len &= 0xFFFFFFF0; - len = ~len + 1; - - if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */ - dbg("prefetch mem 64\n"); - count += 1; - } - dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1); - res = acpiphp_make_resource(base, len); - if (!res) - goto no_memory; - - res->next = func->p_mem_head; - func->p_mem_head = res; - - } else { - /* regular memory */ - - len &= 0xFFFFFFF0; - len = ~len + 1; - - if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { - /* takes up another dword */ - dbg("mem 64\n"); - count += 1; - } - dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1); - res = acpiphp_make_resource(base, len); - if (!res) - goto no_memory; - - res->next = func->mem_head; - func->mem_head = res; - - } - } - - pci_write_config_dword(dev, address[count], bar); - } -#if 1 - acpiphp_dump_func_resource(func); -#endif - - return 0; - - no_memory: - err("out of memory\n"); - acpiphp_free_resource(&func->io_head); - acpiphp_free_resource(&func->mem_head); - acpiphp_free_resource(&func->p_mem_head); - - return -1; -} - - -/** - * acpiphp_configure_slot - allocate PCI resources - * @slot: slot to be configured - * - * initializes a PCI functions on a device inserted - * into the slot - * - */ -int acpiphp_configure_slot (struct acpiphp_slot *slot) -{ - struct acpiphp_func *func; - struct list_head *l; - u8 hdr; - u32 dvid; - int retval = 0; - int is_multi = 0; - - pci_bus_read_config_byte(slot->bridge->pci_bus, - PCI_DEVFN(slot->device, 0), - PCI_HEADER_TYPE, &hdr); - - if (hdr & 0x80) - is_multi = 1; - - list_for_each (l, &slot->funcs) { - func = list_entry(l, struct acpiphp_func, sibling); - if (is_multi || func->function == 0) { - pci_bus_read_config_dword(slot->bridge->pci_bus, - PCI_DEVFN(slot->device, - func->function), - PCI_VENDOR_ID, &dvid); - if (dvid != 0xffffffff) { - retval = init_config_space(func); - if (retval) - break; - } - } - } - - return retval; -} - -/** - * acpiphp_configure_function - configure PCI function - * @func: function to be configured - * - * initializes a PCI functions on a device inserted - * into the slot - * - */ -int acpiphp_configure_function (struct acpiphp_func *func) -{ - /* all handled by the pci core now */ - return 0; -} - -/** - * acpiphp_unconfigure_function - unconfigure PCI function - * @func: function to be unconfigured - * - */ -void acpiphp_unconfigure_function (struct acpiphp_func *func) -{ - struct acpiphp_bridge *bridge; - - /* if pci_dev is NULL, ignore it */ - if (!func->pci_dev) - return; - - pci_remove_bus_device(func->pci_dev); - - /* free all resources */ - bridge = func->slot->bridge; - - spin_lock(&bridge->res_lock); - acpiphp_move_resource(&func->io_head, &bridge->io_head); - acpiphp_move_resource(&func->mem_head, &bridge->mem_head); - acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head); - acpiphp_move_resource(&func->bus_head, &bridge->bus_head); - spin_unlock(&bridge->res_lock); -} diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c deleted file mode 100644 index f54b1fa7b75a..000000000000 --- a/drivers/pci/hotplug/acpiphp_res.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * ACPI PCI HotPlug Utility functions - * - * Copyright (C) 1995,2001 Compaq Computer Corporation - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2001 IBM Corp. - * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) - * Copyright (C) 2002 NEC Corporation - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. 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. - * - * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com> - * - */ - -#include <linux/init.h> -#include <linux/module.h> - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/proc_fs.h> -#include <linux/sysctl.h> -#include <linux/pci.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> - -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/timer.h> - -#include <linux/ioctl.h> -#include <linux/fcntl.h> - -#include <linux/list.h> - -#include "pci_hotplug.h" -#include "acpiphp.h" - -#define MY_NAME "acpiphp_res" - - -/* - * sort_by_size - sort nodes by their length, smallest first - */ -static int sort_by_size(struct pci_resource **head) -{ - struct pci_resource *current_res; - struct pci_resource *next_res; - int out_of_order = 1; - - if (!(*head)) - return 1; - - if (!((*head)->next)) - return 0; - - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->length > (*head)->next->length)) { - out_of_order++; - current_res = *head; - *head = (*head)->next; - current_res->next = (*head)->next; - (*head)->next = current_res; - } - - current_res = *head; - - while (current_res->next && current_res->next->next) { - if (current_res->next->length > current_res->next->next->length) { - out_of_order++; - next_res = current_res->next; - current_res->next = current_res->next->next; - current_res = current_res->next; - next_res->next = current_res->next; - current_res->next = next_res; - } else - current_res = current_res->next; - } - } /* End of out_of_order loop */ - - return 0; -} - -#if 0 -/* - * sort_by_max_size - sort nodes by their length, largest first - */ -static int sort_by_max_size(struct pci_resource **head) -{ - struct pci_resource *current_res; - struct pci_resource *next_res; - int out_of_order = 1; - - if (!(*head)) - return 1; - - if (!((*head)->next)) - return 0; - - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->length < (*head)->next->length)) { - out_of_order++; - current_res = *head; - *head = (*head)->next; - current_res->next = (*head)->next; - (*head)->next = current_res; - } - - current_res = *head; - - while (current_res->next && current_res->next->next) { - if (current_res->next->length < current_res->next->next->length) { - out_of_order++; - next_res = current_res->next; - current_res->next = current_res->next->next; - current_res = current_res->next; - next_res->next = current_res->next; - current_res->next = next_res; - } else - current_res = current_res->next; - } - } /* End of out_of_order loop */ - - return 0; -} -#endif - -/** - * get_io_resource - get resource for I/O ports - * - * this function sorts the resource list by size and then - * returns the first node of "size" length that is not in the - * ISA aliasing window. If it finds a node larger than "size" - * it will split it up. - * - * size must be a power of two. - * - * difference from get_resource is handling of ISA aliasing space. - * - */ -struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *prevnode; - struct pci_resource *node; - struct pci_resource *split_node; - u64 temp_qword; - - if (!(*head)) - return NULL; - - if (acpiphp_resource_sort_and_combine(head)) - return NULL; - - if (sort_by_size(head)) - return NULL; - - for (node = *head; node; node = node->next) { - if (node->length < size) - continue; - - if (node->base & (size - 1)) { - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_qword = (node->base | (size-1)) + 1; - - /* Short circuit if adjusted size is too small */ - if ((node->length - (temp_qword - node->base)) < size) - continue; - - split_node = acpiphp_make_resource(node->base, temp_qword - node->base); - - if (!split_node) - return NULL; - - node->base = temp_qword; - node->length -= split_node->length; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of non-aligned base */ - - /* Don't need to check if too small since we already did */ - if (node->length > size) { - /* this one is longer than we need - so we'll make a new entry and split it up */ - split_node = acpiphp_make_resource(node->base + size, node->length - size); - - if (!split_node) - return NULL; - - node->length = size; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of too big on top end */ - - /* For IO make sure it's not in the ISA aliasing space */ - if ((node->base & 0x300L) && !(node->base & 0xfffff000)) - continue; - - /* If we got here, then it is the right size - Now take it out of the list */ - if (*head == node) { - *head = node->next; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - } - node->next = NULL; - /* Stop looping */ - break; - } - - return node; -} - - -#if 0 -/** - * get_max_resource - get the largest resource - * - * Gets the largest node that is at least "size" big from the - * list pointed to by head. It aligns the node on top and bottom - * to "size" alignment before returning it. - */ -static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *max; - struct pci_resource *temp; - struct pci_resource *split_node; - u64 temp_qword; - - if (!(*head)) - return NULL; - - if (acpiphp_resource_sort_and_combine(head)) - return NULL; - - if (sort_by_max_size(head)) - return NULL; - - for (max = *head;max; max = max->next) { - - /* If not big enough we could probably just bail, - instead we'll continue to the next. */ - if (max->length < size) - continue; - - if (max->base & (size - 1)) { - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_qword = (max->base | (size-1)) + 1; - - /* Short circuit if adjusted size is too small */ - if ((max->length - (temp_qword - max->base)) < size) - continue; - - split_node = acpiphp_make_resource(max->base, temp_qword - max->base); - - if (!split_node) - return NULL; - - max->base = temp_qword; - max->length -= split_node->length; - - /* Put it next in the list */ - split_node->next = max->next; - max->next = split_node; - } - - if ((max->base + max->length) & (size - 1)) { - /* this one isn't end aligned properly at the top - so we'll make a new entry and split it up */ - temp_qword = ((max->base + max->length) & ~(size - 1)); - - split_node = acpiphp_make_resource(temp_qword, - max->length + max->base - temp_qword); - - if (!split_node) - return NULL; - - max->length -= split_node->length; - - /* Put it in the list */ - split_node->next = max->next; - max->next = split_node; - } - - /* Make sure it didn't shrink too much when we aligned it */ - if (max->length < size) - continue; - - /* Now take it out of the list */ - temp = (struct pci_resource*) *head; - if (temp == max) { - *head = max->next; - } else { - while (temp && temp->next != max) { - temp = temp->next; - } - - temp->next = max->next; - } - - max->next = NULL; - return max; - } - - /* If we get here, we couldn't find one */ - return NULL; -} -#endif - -/** - * get_resource - get resource (mem, pfmem) - * - * this function sorts the resource list by size and then - * returns the first node of "size" length. If it finds a node - * larger than "size" it will split it up. - * - * size must be a power of two. - * - */ -struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *prevnode; - struct pci_resource *node; - struct pci_resource *split_node; - u64 temp_qword; - - if (!(*head)) - return NULL; - - if (acpiphp_resource_sort_and_combine(head)) - return NULL; - - if (sort_by_size(head)) - return NULL; - - for (node = *head; node; node = node->next) { - dbg("%s: req_size =%x node=%p, base=%x, length=%x\n", - __FUNCTION__, size, node, (u32)node->base, node->length); - if (node->length < size) - continue; - - if (node->base & (size - 1)) { - dbg("%s: not aligned\n", __FUNCTION__); - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_qword = (node->base | (size-1)) + 1; - - /* Short circuit if adjusted size is too small */ - if ((node->length - (temp_qword - node->base)) < size) - continue; - - split_node = acpiphp_make_resource(node->base, temp_qword - node->base); - - if (!split_node) - return NULL; - - node->base = temp_qword; - node->length -= split_node->length; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of non-aligned base */ - - /* Don't need to check if too small since we already did */ - if (node->length > size) { - dbg("%s: too big\n", __FUNCTION__); - /* this one is longer than we need - so we'll make a new entry and split it up */ - split_node = acpiphp_make_resource(node->base + size, node->length - size); - - if (!split_node) - return NULL; - - node->length = size; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of too big on top end */ - - dbg("%s: got one!!!\n", __FUNCTION__); - /* If we got here, then it is the right size - Now take it out of the list */ - if (*head == node) { - *head = node->next; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - } - node->next = NULL; - /* Stop looping */ - break; - } - return node; -} - -/** - * get_resource_with_base - get resource with specific base address - * - * this function - * returns the first node of "size" length located at specified base address. - * If it finds a node larger than "size" it will split it up. - * - * size must be a power of two. - * - */ -struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size) -{ - struct pci_resource *prevnode; - struct pci_resource *node; - struct pci_resource *split_node; - u64 temp_qword; - - if (!(*head)) - return NULL; - - if (acpiphp_resource_sort_and_combine(head)) - return NULL; - - for (node = *head; node; node = node->next) { - dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n", - (u32)base, size, node, (u32)node->base, node->length); - if (node->base > base) - continue; - - if ((node->base + node->length) < (base + size)) - continue; - - if (node->base < base) { - dbg(": split 1\n"); - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_qword = base; - - /* Short circuit if adjusted size is too small */ - if ((node->length - (temp_qword - node->base)) < size) - continue; - - split_node = acpiphp_make_resource(node->base, temp_qword - node->base); - - if (!split_node) - return NULL; - - node->base = temp_qword; - node->length -= split_node->length; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } - - dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n", - (u32)base, size, node, (u32)node->base, node->length); - - /* Don't need to check if too small since we already did */ - if (node->length > size) { - dbg(": split 2\n"); - /* this one is longer than we need - so we'll make a new entry and split it up */ - split_node = acpiphp_make_resource(node->base + size, node->length - size); - - if (!split_node) - return NULL; - - node->length = size; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of too big on top end */ - - dbg(": got one!!!\n"); - /* If we got here, then it is the right size - Now take it out of the list */ - if (*head == node) { - *head = node->next; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - } - node->next = NULL; - /* Stop looping */ - break; - } - return node; -} - - -/** - * acpiphp_resource_sort_and_combine - * - * Sorts all of the nodes in the list in ascending order by - * their base addresses. Also does garbage collection by - * combining adjacent nodes. - * - * returns 0 if success - */ -int acpiphp_resource_sort_and_combine (struct pci_resource **head) -{ - struct pci_resource *node1; - struct pci_resource *node2; - int out_of_order = 1; - - if (!(*head)) - return 1; - - dbg("*head->next = %p\n",(*head)->next); - - if (!(*head)->next) - return 0; /* only one item on the list, already sorted! */ - - dbg("*head->base = 0x%x\n",(u32)(*head)->base); - dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base); - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->base > (*head)->next->base)) { - node1 = *head; - (*head) = (*head)->next; - node1->next = (*head)->next; - (*head)->next = node1; - out_of_order++; - } - - node1 = (*head); - - while (node1->next && node1->next->next) { - if (node1->next->base > node1->next->next->base) { - out_of_order++; - node2 = node1->next; - node1->next = node1->next->next; - node1 = node1->next; - node2->next = node1->next; - node1->next = node2; - } else - node1 = node1->next; - } - } /* End of out_of_order loop */ - - node1 = *head; - - while (node1 && node1->next) { - if ((node1->base + node1->length) == node1->next->base) { - /* Combine */ - dbg("8..\n"); - node1->length += node1->next->length; - node2 = node1->next; - node1->next = node1->next->next; - kfree(node2); - } else - node1 = node1->next; - } - - return 0; -} - - -/** - * acpiphp_make_resource - make resource structure - * @base: base address of a resource - * @length: length of a resource - */ -struct pci_resource *acpiphp_make_resource (u64 base, u32 length) -{ - struct pci_resource *res; - - res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (res) { - memset(res, 0, sizeof(struct pci_resource)); - res->base = base; - res->length = length; - } - - return res; -} - - -/** - * acpiphp_move_resource - move linked resources from one to another - * @from: head of linked resource list - * @to: head of linked resource list - */ -void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to) -{ - struct pci_resource *tmp; - - while (*from) { - tmp = (*from)->next; - (*from)->next = *to; - *to = *from; - *from = tmp; - } - - /* *from = NULL is guaranteed */ -} - - -/** - * acpiphp_free_resource - free all linked resources - * @res: head of linked resource list - */ -void acpiphp_free_resource (struct pci_resource **res) -{ - struct pci_resource *tmp; - - while (*res) { - tmp = (*res)->next; - kfree(*res); - *res = tmp; - } - - /* *res = NULL is guaranteed */ -} - - -/* debug support functions; will go away sometime :) */ -static void dump_resource(struct pci_resource *head) -{ - struct pci_resource *p; - int cnt; - - p = head; - cnt = 0; - - while (p) { - dbg("[%02d] %08x - %08x\n", - cnt++, (u32)p->base, (u32)p->base + p->length - 1); - p = p->next; - } -} - -void acpiphp_dump_resource(struct acpiphp_bridge *bridge) -{ - dbg("I/O resource:\n"); - dump_resource(bridge->io_head); - dbg("MEM resource:\n"); - dump_resource(bridge->mem_head); - dbg("PMEM resource:\n"); - dump_resource(bridge->p_mem_head); - dbg("BUS resource:\n"); - dump_resource(bridge->bus_head); -} - -void acpiphp_dump_func_resource(struct acpiphp_func *func) -{ - dbg("I/O resource:\n"); - dump_resource(func->io_head); - dbg("MEM resource:\n"); - dump_resource(func->mem_head); - dbg("PMEM resource:\n"); - dump_resource(func->p_mem_head); - dbg("BUS resource:\n"); - dump_resource(func->bus_head); -} diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index afbccfa5217d..8c6d3987d461 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -60,6 +60,7 @@ static void __iomem *smbios_start; static void __iomem *cpqhp_rom_start; static int power_mode; static int debug; +static int initialized; #define DRIVER_VERSION "0.9.8" #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>" @@ -1271,7 +1272,6 @@ static int one_time_init(void) { int loop; int retval = 0; - static int initialized = 0; if (initialized) return 0; @@ -1441,7 +1441,8 @@ static void __exit unload_cpqphpd(void) } // Stop the notification mechanism - cpqhp_event_stop_thread(); + if (initialized) + cpqhp_event_stop_thread(); //unmap the rom address if (cpqhp_rom_start) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 30206ac43c44..b5ab9aa6ff7c 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -28,10 +28,10 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; static kmem_cache_t* msi_cachep; static int pci_msi_enable = 1; -static int last_alloc_vector = 0; -static int nr_released_vectors = 0; +static int last_alloc_vector; +static int nr_released_vectors; static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS; -static int nr_msix_devices = 0; +static int nr_msix_devices; #ifndef CONFIG_X86_IO_APIC int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; @@ -170,44 +170,30 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector) return 0; /* never anything pending */ } -static void release_msi(unsigned int vector); -static void shutdown_msi_irq(unsigned int vector) -{ - release_msi(vector); -} - -#define shutdown_msi_irq_wo_maskbit shutdown_msi_irq -static void enable_msi_irq_wo_maskbit(unsigned int vector) {} -static void disable_msi_irq_wo_maskbit(unsigned int vector) {} -static void ack_msi_irq_wo_maskbit(unsigned int vector) {} -static void end_msi_irq_wo_maskbit(unsigned int vector) +static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) { - move_msi(vector); - ack_APIC_irq(); + startup_msi_irq_wo_maskbit(vector); + unmask_MSI_irq(vector); + return 0; /* never anything pending */ } -static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) +static void shutdown_msi_irq(unsigned int vector) { struct msi_desc *entry; unsigned long flags; spin_lock_irqsave(&msi_lock, flags); entry = msi_desc[vector]; - if (!entry || !entry->dev) { - spin_unlock_irqrestore(&msi_lock, flags); - return 0; - } - entry->msi_attrib.state = 1; /* Mark it active */ + if (entry && entry->dev) + entry->msi_attrib.state = 0; /* Mark it not active */ spin_unlock_irqrestore(&msi_lock, flags); - - unmask_MSI_irq(vector); - return 0; /* never anything pending */ } -#define shutdown_msi_irq_w_maskbit shutdown_msi_irq -#define enable_msi_irq_w_maskbit unmask_MSI_irq -#define disable_msi_irq_w_maskbit mask_MSI_irq -#define ack_msi_irq_w_maskbit mask_MSI_irq +static void end_msi_irq_wo_maskbit(unsigned int vector) +{ + move_msi(vector); + ack_APIC_irq(); +} static void end_msi_irq_w_maskbit(unsigned int vector) { @@ -216,6 +202,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector) ack_APIC_irq(); } +static void do_nothing(unsigned int vector) +{ +} + /* * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices, * which implement the MSI-X Capability Structure. @@ -223,10 +213,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector) static struct hw_interrupt_type msix_irq_type = { .typename = "PCI-MSI-X", .startup = startup_msi_irq_w_maskbit, - .shutdown = shutdown_msi_irq_w_maskbit, - .enable = enable_msi_irq_w_maskbit, - .disable = disable_msi_irq_w_maskbit, - .ack = ack_msi_irq_w_maskbit, + .shutdown = shutdown_msi_irq, + .enable = unmask_MSI_irq, + .disable = mask_MSI_irq, + .ack = mask_MSI_irq, .end = end_msi_irq_w_maskbit, .set_affinity = set_msi_irq_affinity }; @@ -239,10 +229,10 @@ static struct hw_interrupt_type msix_irq_type = { static struct hw_interrupt_type msi_irq_w_maskbit_type = { .typename = "PCI-MSI", .startup = startup_msi_irq_w_maskbit, - .shutdown = shutdown_msi_irq_w_maskbit, - .enable = enable_msi_irq_w_maskbit, - .disable = disable_msi_irq_w_maskbit, - .ack = ack_msi_irq_w_maskbit, + .shutdown = shutdown_msi_irq, + .enable = unmask_MSI_irq, + .disable = mask_MSI_irq, + .ack = mask_MSI_irq, .end = end_msi_irq_w_maskbit, .set_affinity = set_msi_irq_affinity }; @@ -255,10 +245,10 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = { static struct hw_interrupt_type msi_irq_wo_maskbit_type = { .typename = "PCI-MSI", .startup = startup_msi_irq_wo_maskbit, - .shutdown = shutdown_msi_irq_wo_maskbit, - .enable = enable_msi_irq_wo_maskbit, - .disable = disable_msi_irq_wo_maskbit, - .ack = ack_msi_irq_wo_maskbit, + .shutdown = shutdown_msi_irq, + .enable = do_nothing, + .disable = do_nothing, + .ack = do_nothing, .end = end_msi_irq_wo_maskbit, .set_affinity = set_msi_irq_affinity }; @@ -407,7 +397,7 @@ static struct msi_desc* alloc_msi_entry(void) { struct msi_desc *entry; - entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL); + entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL); if (!entry) return NULL; @@ -796,18 +786,6 @@ void pci_disable_msi(struct pci_dev* dev) } } -static void release_msi(unsigned int vector) -{ - struct msi_desc *entry; - unsigned long flags; - - spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[vector]; - if (entry && entry->dev) - entry->msi_attrib.state = 0; /* Mark it not active */ - spin_unlock_irqrestore(&msi_lock, flags); -} - static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) { struct msi_desc *entry; @@ -924,7 +902,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec) /** * pci_enable_msix - configure device's MSI-X capability structure * @dev: pointer to the pci_dev data structure of MSI-X device function - * @data: pointer to an array of MSI-X entries + * @entries: pointer to an array of MSI-X entries * @nvec: number of MSI-X vectors requested for allocation by device driver * * Setup the MSI-X capability structure of device function with the number diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index bef21ae3cbd0..390f1851c0f1 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h @@ -41,11 +41,11 @@ static inline void move_msi(int vector) {} #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) #define PCI_MSIX_FLAGS_BITMASK (1 << 0) -#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 -#define PCI_MSIX_ENTRY_DATA_OFFSET 8 -#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12 #define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 +#define PCI_MSIX_ENTRY_DATA_OFFSET 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12 #define msi_control_reg(base) (base + PCI_MSI_FLAGS) #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) @@ -64,7 +64,6 @@ static inline void move_msi(int vector) {} #define msi_enable(control, num) multi_msi_enable(control, num); \ control |= PCI_MSI_FLAGS_ENABLE -#define msix_control_reg msi_control_reg #define msix_table_offset_reg(base) (base + 0x04) #define msix_pba_offset_reg(base) (base + 0x08) #define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e65bf2b395aa..e4115a0d5ba6 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -7,7 +7,6 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/device.h> -#include <linux/pci-dynids.h> #include "pci.h" /* @@ -18,36 +17,12 @@ * Dynamic device IDs are disabled for !CONFIG_HOTPLUG */ -#ifdef CONFIG_HOTPLUG -/** - * pci_device_probe_dynamic() - * - * Walk the dynamic ID list looking for a match. - * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error. - */ -static int -pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev) -{ - int error = -ENODEV; - struct list_head *pos; - struct dynid *dynid; +struct pci_dynid { + struct list_head node; + struct pci_device_id id; +}; - spin_lock(&drv->dynids.lock); - list_for_each(pos, &drv->dynids.list) { - dynid = list_entry(pos, struct dynid, node); - if (pci_match_one_device(&dynid->id, pci_dev)) { - spin_unlock(&drv->dynids.lock); - error = drv->probe(pci_dev, &dynid->id); - if (error >= 0) { - pci_dev->driver = drv; - return 0; - } - return error; - } - } - spin_unlock(&drv->dynids.lock); - return error; -} +#ifdef CONFIG_HOTPLUG /** * store_new_id @@ -58,8 +33,7 @@ pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev) static inline ssize_t store_new_id(struct device_driver *driver, const char *buf, size_t count) { - struct dynid *dynid; - struct bus_type * bus; + struct pci_dynid *dynid; struct pci_driver *pdrv = to_pci_driver(driver); __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID, subdevice=PCI_ANY_ID, class=0, class_mask=0; @@ -91,37 +65,22 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) list_add_tail(&pdrv->dynids.list, &dynid->node); spin_unlock(&pdrv->dynids.lock); - bus = get_bus(pdrv->driver.bus); - if (bus) { - if (get_driver(&pdrv->driver)) { - down_write(&bus->subsys.rwsem); - driver_attach(&pdrv->driver); - up_write(&bus->subsys.rwsem); - put_driver(&pdrv->driver); - } - put_bus(bus); + if (get_driver(&pdrv->driver)) { + driver_attach(&pdrv->driver); + put_driver(&pdrv->driver); } return count; } - static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); -static inline void -pci_init_dynids(struct pci_dynids *dynids) -{ - spin_lock_init(&dynids->lock); - INIT_LIST_HEAD(&dynids->list); -} static void pci_free_dynids(struct pci_driver *drv) { - struct list_head *pos, *n; - struct dynid *dynid; + struct pci_dynid *dynid, *n; spin_lock(&drv->dynids.lock); - list_for_each_safe(pos, n, &drv->dynids.list) { - dynid = list_entry(pos, struct dynid, node); + list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { list_del(&dynid->node); kfree(dynid); } @@ -138,83 +97,70 @@ pci_create_newid_file(struct pci_driver *drv) return error; } -static int -pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv) -{ - struct list_head *pos; - struct dynid *dynid; - - spin_lock(&pci_drv->dynids.lock); - list_for_each(pos, &pci_drv->dynids.list) { - dynid = list_entry(pos, struct dynid, node); - if (pci_match_one_device(&dynid->id, pci_dev)) { - spin_unlock(&pci_drv->dynids.lock); - return 1; - } - } - spin_unlock(&pci_drv->dynids.lock); - return 0; -} - #else /* !CONFIG_HOTPLUG */ -static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev) -{ - return -ENODEV; -} -static inline void pci_init_dynids(struct pci_dynids *dynids) {} static inline void pci_free_dynids(struct pci_driver *drv) {} static inline int pci_create_newid_file(struct pci_driver *drv) { return 0; } -static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv) -{ - return 0; -} #endif /** - * pci_match_device - Tell if a PCI device structure has a matching - * PCI device id structure + * pci_match_id - See if a pci device matches a given pci_id table * @ids: array of PCI device id structures to search in - * @dev: the PCI device structure to match against - * + * @dev: the PCI device structure to match against. + * * Used by a driver to check whether a PCI device present in the - * system is in its list of supported devices.Returns the matching + * system is in its list of supported devices. Returns the matching * pci_device_id structure or %NULL if there is no match. + * + * Depreciated, don't use this as it will not catch any dynamic ids + * that a driver might want to check for. */ -const struct pci_device_id * -pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) +const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, + struct pci_dev *dev) { - while (ids->vendor || ids->subvendor || ids->class_mask) { - if (pci_match_one_device(ids, dev)) - return ids; - ids++; + if (ids) { + while (ids->vendor || ids->subvendor || ids->class_mask) { + if (pci_match_one_device(ids, dev)) + return ids; + ids++; + } } return NULL; } /** - * pci_device_probe_static() - * - * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error. + * pci_match_device - Tell if a PCI device structure has a matching + * PCI device id structure + * @ids: array of PCI device id structures to search in + * @dev: the PCI device structure to match against + * @drv: the PCI driver to match against + * + * Used by a driver to check whether a PCI device present in the + * system is in its list of supported devices. Returns the matching + * pci_device_id structure or %NULL if there is no match. */ -static int -pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev) -{ - int error = -ENODEV; +const struct pci_device_id *pci_match_device(struct pci_driver *drv, + struct pci_dev *dev) +{ const struct pci_device_id *id; + struct pci_dynid *dynid; - if (!drv->id_table) - return error; - id = pci_match_device(drv->id_table, pci_dev); + id = pci_match_id(drv->id_table, dev); if (id) - error = drv->probe(pci_dev, id); - if (error >= 0) { - pci_dev->driver = drv; - error = 0; + return id; + + /* static ids didn't match, lets look at the dynamic ones */ + spin_lock(&drv->dynids.lock); + list_for_each_entry(dynid, &drv->dynids.list, node) { + if (pci_match_one_device(&dynid->id, dev)) { + spin_unlock(&drv->dynids.lock); + return &dynid->id; + } } - return error; + spin_unlock(&drv->dynids.lock); + return NULL; } /** @@ -225,13 +171,20 @@ pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev) */ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) -{ +{ + const struct pci_device_id *id; int error = 0; if (!pci_dev->driver && drv->probe) { - error = pci_device_probe_static(drv, pci_dev); - if (error == -ENODEV) - error = pci_device_probe_dynamic(drv, pci_dev); + error = -ENODEV; + + id = pci_match_device(drv, pci_dev); + if (id) + error = drv->probe(pci_dev, id); + if (error >= 0) { + pci_dev->driver = drv; + error = 0; + } } return error; } @@ -371,12 +324,6 @@ static struct kobj_type pci_driver_kobj_type = { .sysfs_ops = &pci_driver_sysfs_ops, }; -static int -pci_populate_driver_dir(struct pci_driver *drv) -{ - return pci_create_newid_file(drv); -} - /** * pci_register_driver - register a new pci driver * @drv: the driver structure to register @@ -401,13 +348,15 @@ int pci_register_driver(struct pci_driver *drv) drv->driver.shutdown = pci_device_shutdown; drv->driver.owner = drv->owner; drv->driver.kobj.ktype = &pci_driver_kobj_type; - pci_init_dynids(&drv->dynids); + + spin_lock_init(&drv->dynids.lock); + INIT_LIST_HEAD(&drv->dynids.list); /* register with core */ error = driver_register(&drv->driver); if (!error) - pci_populate_driver_dir(drv); + error = pci_create_newid_file(drv); return error; } @@ -463,21 +412,17 @@ pci_dev_driver(const struct pci_dev *dev) * system is in its list of supported devices.Returns the matching * pci_device_id structure or %NULL if there is no match. */ -static int pci_bus_match(struct device * dev, struct device_driver * drv) +static int pci_bus_match(struct device *dev, struct device_driver *drv) { - const struct pci_dev * pci_dev = to_pci_dev(dev); - struct pci_driver * pci_drv = to_pci_driver(drv); - const struct pci_device_id * ids = pci_drv->id_table; + struct pci_dev *pci_dev = to_pci_dev(dev); + struct pci_driver *pci_drv = to_pci_driver(drv); const struct pci_device_id *found_id; - if (!ids) - return 0; - - found_id = pci_match_device(ids, pci_dev); + found_id = pci_match_device(pci_drv, pci_dev); if (found_id) return 1; - return pci_bus_match_dynids(pci_dev, pci_drv); + return 0; } /** @@ -536,6 +481,7 @@ static int __init pci_driver_init(void) postcore_initcall(pci_driver_init); +EXPORT_SYMBOL(pci_match_id); EXPORT_SYMBOL(pci_match_device); EXPORT_SYMBOL(pci_register_driver); EXPORT_SYMBOL(pci_unregister_driver); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index a15f94072a6f..cc9d65388e62 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -60,15 +60,18 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) char * str = buf; int i; int max = 7; + u64 start, end; if (pci_dev->subordinate) max = DEVICE_COUNT_RESOURCE; for (i = 0; i < max; i++) { - str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n", - pci_resource_start(pci_dev,i), - pci_resource_end(pci_dev,i), - pci_resource_flags(pci_dev,i)); + struct resource *res = &pci_dev->resource[i]; + pci_resource_to_user(pci_dev, i, res, &start, &end); + str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n", + (unsigned long long)start, + (unsigned long long)end, + (unsigned long long)res->flags); } return (str - buf); } @@ -313,8 +316,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, struct device, kobj)); struct resource *res = (struct resource *)attr->private; enum pci_mmap_state mmap_type; + u64 start, end; + int i; - vma->vm_pgoff += res->start >> PAGE_SHIFT; + for (i = 0; i < PCI_ROM_RESOURCE; i++) + if (res == &pdev->resource[i]) + break; + if (i >= PCI_ROM_RESOURCE) + return -ENODEV; + + /* pci_mmap_page_range() expects the same kind of entry as coming + * from /proc/bus/pci/ which is a "user visible" value. If this is + * different from the resource itself, arch will do necessary fixup. + */ + pci_resource_to_user(pdev, i, res, &start, &end); + vma->vm_pgoff += start >> PAGE_SHIFT; mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; return pci_mmap_page_range(pdev, vma, mmap_type, 0); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f04b9ffe4153..d382bdb7b560 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -334,10 +334,6 @@ EXPORT_SYMBOL(pci_choose_state); /** * pci_save_state - save the PCI configuration space of a device before suspending * @dev: - PCI device that we're dealing with - * @buffer: - buffer to hold config space context - * - * @buffer must be large enough to hold the entire PCI 2.2 config space - * (>= 64 bytes). */ int pci_save_state(struct pci_dev *dev) @@ -352,8 +348,6 @@ pci_save_state(struct pci_dev *dev) /** * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with - * @buffer: - saved PCI config space - * */ int pci_restore_state(struct pci_dev *dev) diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 537b372dc340..a63bd8f72601 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -27,6 +27,11 @@ #define get_descriptor_id(type, service) (((type - 4) << 4) | service) +struct pcie_port_device_ext { + int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */ + unsigned int saved_msi_config_space[5]; +}; + extern struct bus_type pcie_port_bus_type; extern int pcie_port_device_probe(struct pci_dev *dev); extern int pcie_port_device_register(struct pci_dev *dev); diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index f5c5f10a3d2f..4db69982876e 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -275,10 +275,17 @@ int pcie_port_device_probe(struct pci_dev *dev) int pcie_port_device_register(struct pci_dev *dev) { + struct pcie_port_device_ext *p_ext; int status, type, capabilities, irq_mode, i; int vectors[PCIE_PORT_DEVICE_MAXSERVICES]; u16 reg16; + /* Allocate port device extension */ + if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL))) + return -ENOMEM; + + pci_set_drvdata(dev, p_ext); + /* Get port type */ pci_read_config_word(dev, pci_find_capability(dev, PCI_CAP_ID_EXP) + @@ -288,6 +295,7 @@ int pcie_port_device_register(struct pci_dev *dev) /* Now get port services */ capabilities = get_port_device_capability(dev); irq_mode = assign_interrupt_mode(dev, vectors, capabilities); + p_ext->interrupt_mode = irq_mode; /* Allocate child services if any */ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index e9095ee508e3..30bac7ed7c16 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -29,6 +29,78 @@ MODULE_LICENSE("GPL"); /* global data */ static const char device_name[] = "pcieport-driver"; +static void pci_save_msi_state(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + int i = 0, pos; + u16 control; + + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0) + return; + + pci_read_config_dword(dev, pos, &p_ext->saved_msi_config_space[i++]); + control = p_ext->saved_msi_config_space[0] >> 16; + pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, + &p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_64BIT) { + pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, + &p_ext->saved_msi_config_space[i++]); + pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, + &p_ext->saved_msi_config_space[i++]); + } else + pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, + &p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_MASKBIT) + pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, + &p_ext->saved_msi_config_space[i++]); +} + +static void pci_restore_msi_state(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + int i = 0, pos; + u16 control; + + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0) + return; + + control = p_ext->saved_msi_config_space[i++] >> 16; + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, + p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_64BIT) { + pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, + p_ext->saved_msi_config_space[i++]); + pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, + p_ext->saved_msi_config_space[i++]); + } else + pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, + p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_MASKBIT) + pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, + p_ext->saved_msi_config_space[i++]); +} + +static void pcie_portdrv_save_config(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + + pci_save_state(dev); + if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE) + pci_save_msi_state(dev); +} + +static void pcie_portdrv_restore_config(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + + pci_restore_state(dev); + if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE) + pci_restore_msi_state(dev); + pci_enable_device(dev); + pci_set_master(dev); +} + /* * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed @@ -64,16 +136,21 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, static void pcie_portdrv_remove (struct pci_dev *dev) { pcie_port_device_remove(dev); + kfree(pci_get_drvdata(dev)); } #ifdef CONFIG_PM static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state) { - return pcie_port_device_suspend(dev, state); + int ret = pcie_port_device_suspend(dev, state); + + pcie_portdrv_save_config(dev); + return ret; } static int pcie_portdrv_resume (struct pci_dev *dev) { + pcie_portdrv_restore_config(dev); return pcie_port_device_resume(dev); } #endif diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index fd48b201eb53..df3bdae2040f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -239,9 +239,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) if (dev->transparent) { printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev)); - for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) - child->resource[i] = child->parent->resource[i]; - return; + for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) + child->resource[i] = child->parent->resource[i - 3]; } for(i=0; i<3; i++) @@ -374,8 +373,11 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de struct pci_bus *child; child = pci_alloc_child_bus(parent, dev, busnr); - if (child) + if (child) { + spin_lock(&pci_bus_lock); list_add_tail(&child->node, &parent->children); + spin_unlock(&pci_bus_lock); + } return child; } @@ -395,6 +397,16 @@ static void pci_enable_crs(struct pci_dev *dev) pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl); } +static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) +{ + struct pci_bus *parent = child->parent; + while (parent->parent && parent->subordinate < max) { + parent->subordinate = max; + pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); + parent = parent->parent; + } +} + unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); /* @@ -411,7 +423,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max { struct pci_bus *child; int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); - u32 buses; + u32 buses, i; u16 bctl; pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); @@ -447,7 +459,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max return max; } - child = pci_alloc_child_bus(bus, dev, busnr); + child = pci_add_new_bus(bus, dev, busnr); if (!child) return max; child->primary = buses & 0xFF; @@ -470,7 +482,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max /* Clear errors */ pci_write_config_word(dev, PCI_STATUS, 0xffff); - child = pci_alloc_child_bus(bus, dev, ++max); + /* Prevent assigning a bus number that already exists. + * This can happen when a bridge is hot-plugged */ + if (pci_find_bus(pci_domain_nr(bus), max+1)) + return max; + child = pci_add_new_bus(bus, dev, ++max); buses = (buses & 0xff000000) | ((unsigned int)(child->primary) << 0) | ((unsigned int)(child->secondary) << 8) @@ -492,7 +508,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max if (!is_cardbus) { child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA; - + /* + * Adjust subordinate busnr in parent buses. + * We do this before scanning for children because + * some devices may not be detected if the bios + * was lazy. + */ + pci_fixup_parent_subordinate_busnr(child, max); /* Now we can scan all subordinate buses... */ max = pci_scan_child_bus(child); } else { @@ -501,7 +523,12 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max * as cards with a PCI-to-PCI bridge can be * inserted later. */ - max += CARDBUS_RESERVE_BUSNR; + for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) + if (pci_find_bus(pci_domain_nr(bus), + max+i+1)) + break; + max += i; + pci_fixup_parent_subordinate_busnr(child, max); } /* * Set the subordinate bus number to its real value. @@ -757,7 +784,9 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) * and the bus list for fixup functions, etc. */ INIT_LIST_HEAD(&dev->global_list); + spin_lock(&pci_bus_lock); list_add_tail(&dev->bus_list, &bus->devices); + spin_unlock(&pci_bus_lock); return dev; } @@ -878,7 +907,9 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); goto err_out; } + spin_lock(&pci_bus_lock); list_add_tail(&b->node, &pci_root_buses); + spin_unlock(&pci_bus_lock); memset(dev, 0, sizeof(*dev)); dev->parent = parent; @@ -911,8 +942,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, b->subordinate = pci_scan_child_bus(b); - pci_bus_add_devices(b); - return b; sys_create_link_err: @@ -922,7 +951,9 @@ class_dev_create_file_err: class_dev_reg_err: device_unregister(dev); dev_reg_err: + spin_lock(&pci_bus_lock); list_del(&b->node); + spin_unlock(&pci_bus_lock); err_out: kfree(dev); kfree(b); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index e68bbfb1e7c3..7988fc8df3fd 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -355,14 +355,20 @@ static int show_device(struct seq_file *m, void *v) dev->device, dev->irq); /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ - for(i=0; i<7; i++) + for (i=0; i<7; i++) { + u64 start, end; + pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); seq_printf(m, LONG_FORMAT, - dev->resource[i].start | + ((unsigned long)start) | (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); - for(i=0; i<7; i++) + } + for (i=0; i<7; i++) { + u64 start, end; + pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); seq_printf(m, LONG_FORMAT, dev->resource[i].start < dev->resource[i].end ? - dev->resource[i].end - dev->resource[i].start + 1 : 0); + (unsigned long)(end - start) + 1 : 0); + } seq_putc(m, '\t'); if (drv) seq_printf(m, "%s", drv->name); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 968033fd29f0..1521fd5d95cc 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -767,6 +767,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) { if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB) switch(dev->subsystem_device) { + case 0x8025: /* P4B-LX */ case 0x8070: /* P4B */ case 0x8088: /* P4B533 */ case 0x1626: /* L3C notebook */ diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 96f077f9a659..27a294b6965d 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -18,17 +18,21 @@ static void pci_free_resources(struct pci_dev *dev) static void pci_destroy_dev(struct pci_dev *dev) { - pci_proc_detach_device(dev); - pci_remove_sysfs_dev_files(dev); - device_unregister(&dev->dev); + if (!list_empty(&dev->global_list)) { + pci_proc_detach_device(dev); + pci_remove_sysfs_dev_files(dev); + device_unregister(&dev->dev); + spin_lock(&pci_bus_lock); + list_del(&dev->global_list); + dev->global_list.next = dev->global_list.prev = NULL; + spin_unlock(&pci_bus_lock); + } /* Remove the device from the device lists, and prevent any further * list accesses from this device */ spin_lock(&pci_bus_lock); list_del(&dev->bus_list); - list_del(&dev->global_list); dev->bus_list.next = dev->bus_list.prev = NULL; - dev->global_list.next = dev->global_list.prev = NULL; spin_unlock(&pci_bus_lock); pci_free_resources(dev); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1ba84be0b4c0..9fe48f712be9 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -72,7 +72,11 @@ pbus_assign_resources_sorted(struct pci_bus *bus) for (list = head.next; list;) { res = list->res; idx = res - &list->dev->resource[0]; - pci_assign_resource(list->dev, idx); + if (pci_assign_resource(list->dev, idx)) { + res->start = 0; + res->end = 0; + res->flags = 0; + } tmp = list; list = list->next; kfree(tmp); @@ -270,6 +274,8 @@ find_free_bus_resource(struct pci_bus *bus, unsigned long type) for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { r = bus->resource[i]; + if (r == &ioport_resource || r == &iomem_resource) + continue; if (r && (r->flags & type_mask) == type && !r->parent) return r; } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index cabddd49f6ff..d5afd557fe37 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -847,7 +847,7 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]); pcmcia_device_stringattr(prod_id3, prod_id[2]); pcmcia_device_stringattr(prod_id4, prod_id[3]); -static ssize_t modalias_show(struct device *dev, char *buf) +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); int i; diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index 8f0f46907a81..87302fb14885 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c @@ -79,10 +79,6 @@ struct inst { unsigned char run_length; unsigned char repeat_byte; - - /* These members manage timeouts for programmed delays */ - wait_queue_head_t wait_queue; - struct timer_list timer_list; }; static struct inst instances[BPP_NO]; @@ -297,16 +293,10 @@ static unsigned short get_pins(unsigned minor) #endif /* __sparc__ */ -static void bpp_wake_up(unsigned long val) -{ wake_up(&instances[val].wait_queue); } - static void snooze(unsigned long snooze_time, unsigned minor) { - init_timer(&instances[minor].timer_list); - instances[minor].timer_list.expires = jiffies + snooze_time + 1; - instances[minor].timer_list.data = minor; - add_timer(&instances[minor].timer_list); - sleep_on (&instances[minor].wait_queue); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(snooze_time + 1); } static int wait_for(unsigned short set, unsigned short clr, @@ -880,11 +870,8 @@ static void probeLptPort(unsigned idx) instances[idx].enhanced = 0; instances[idx].direction = 0; instances[idx].mode = COMPATIBILITY; - instances[idx].wait_queue = 0; instances[idx].run_length = 0; instances[idx].run_flag = 0; - init_timer(&instances[idx].timer_list); - instances[idx].timer_list.function = bpp_wake_up; if (!request_region(lpAddr,3, dev_name)) return; /* @@ -977,11 +964,8 @@ static void probeLptPort(unsigned idx) instances[idx].enhanced = 0; instances[idx].direction = 0; instances[idx].mode = COMPATIBILITY; - init_waitqueue_head(&instances[idx].wait_queue); instances[idx].run_length = 0; instances[idx].run_flag = 0; - init_timer(&instances[idx].timer_list); - instances[idx].timer_list.function = bpp_wake_up; if (!rp) return; diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 34dbc37a79d4..bc6e4627c7a1 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1916,9 +1916,9 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev) } /* End __twa_shutdown() */ /* Wrapper for __twa_shutdown */ -static void twa_shutdown(struct device *dev) +static void twa_shutdown(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); + struct Scsi_Host *host = pci_get_drvdata(pdev); TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; __twa_shutdown(tw_dev); @@ -2140,9 +2140,7 @@ static struct pci_driver twa_driver = { .id_table = twa_pci_tbl, .probe = twa_probe, .remove = twa_remove, - .driver = { - .shutdown = twa_shutdown - } + .shutdown = twa_shutdown }; /* This function is called on driver initialization */ diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index b6dc576da430..973c51fb0fe2 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -2264,9 +2264,9 @@ static void __tw_shutdown(TW_Device_Extension *tw_dev) } /* End __tw_shutdown() */ /* Wrapper for __tw_shutdown */ -static void tw_shutdown(struct device *dev) +static void tw_shutdown(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); + struct Scsi_Host *host = pci_get_drvdata(pdev); TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; __tw_shutdown(tw_dev); @@ -2451,9 +2451,7 @@ static struct pci_driver tw_driver = { .id_table = tw_pci_tbl, .probe = tw_probe, .remove = tw_remove, - .driver = { - .shutdown = tw_shutdown - } + .shutdown = tw_shutdown, }; /* This function is called on driver initialization */ diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 9a547ca9c864..c5623694d10f 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -304,26 +304,19 @@ static int ahci_port_start(struct ata_port *ap) struct device *dev = ap->host_set->dev; struct ahci_host_priv *hpriv = ap->host_set->private_data; struct ahci_port_priv *pp; - int rc; void *mem, *mmio = ap->host_set->mmio_base; void *port_mmio = ahci_port_base(mmio, ap->port_no); dma_addr_t mem_dma; - rc = ata_port_start(ap); - if (rc) - return rc; - pp = kmalloc(sizeof(*pp), GFP_KERNEL); - if (!pp) { - rc = -ENOMEM; - goto err_out; - } + if (!pp) + return -ENOMEM; memset(pp, 0, sizeof(*pp)); mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { - rc = -ENOMEM; - goto err_out_kfree; + kfree(pp); + return -ENOMEM; } memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); @@ -373,12 +366,6 @@ static int ahci_port_start(struct ata_port *ap) readl(port_mmio + PORT_CMD); /* flush */ return 0; - -err_out_kfree: - kfree(pp); -err_out: - ata_port_stop(ap); - return rc; } @@ -404,7 +391,6 @@ static void ahci_port_stop(struct ata_port *ap) dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, pp->cmd_slot, pp->cmd_slot_dma); kfree(pp); - ata_port_stop(ap); } static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 80d022625c82..babd48363402 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6012,7 +6012,7 @@ static int __devinit ipr_probe(struct pci_dev *pdev, /** * ipr_shutdown - Shutdown handler. - * @dev: device struct + * @pdev: pci device struct * * This function is invoked upon system shutdown/reboot. It will issue * an adapter shutdown to the adapter to flush the write cache. @@ -6020,9 +6020,9 @@ static int __devinit ipr_probe(struct pci_dev *pdev, * Return value: * none **/ -static void ipr_shutdown(struct device *dev) +static void ipr_shutdown(struct pci_dev *pdev) { - struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(to_pci_dev(dev)); + struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); unsigned long lock_flags = 0; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); @@ -6068,9 +6068,7 @@ static struct pci_driver ipr_driver = { .id_table = ipr_pci_table, .probe = ipr_probe, .remove = ipr_remove, - .driver = { - .shutdown = ipr_shutdown, - }, + .shutdown = ipr_shutdown, }; /** diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 36b401fee1f1..cb535fa185b9 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1408,7 +1408,9 @@ void __sata_phy_reset(struct ata_port *ap) if (ap->flags & ATA_FLAG_SATA_RESET) { /* issue phy wake/reset */ scr_write_flush(ap, SCR_CONTROL, 0x301); - udelay(400); /* FIXME: a guess */ + /* Couldn't find anything in SATA I/II specs, but + * AHCI-1.1 10.4.2 says at least 1 ms. */ + mdelay(1); } scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ @@ -1920,6 +1922,7 @@ static const char * ata_dma_blacklist [] = { "HITACHI CDR-8335", "HITACHI CDR-8435", "Toshiba CD-ROM XM-6202B", + "TOSHIBA CD-ROM XM-1702BC", "CD-532E-A", "E-IDE CD-ROM CR-840", "CD-ROM Drive/F5A", @@ -1927,7 +1930,6 @@ static const char * ata_dma_blacklist [] = { "SAMSUNG CD-ROM SC-148C", "SAMSUNG CD-ROM SC", "SanDisk SDP3B-64", - "SAMSUNG CD-ROM SN-124", "ATAPI CD-ROM DRIVE 40X MAXIMUM", "_NEC DV5800A", }; diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index edd47d1f0b17..932dcf0366eb 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -424,7 +424,7 @@ static struct scsi_host_template mac53c94_template = { .use_clustering = DISABLE_CLUSTERING, }; -static int mac53c94_probe(struct macio_dev *mdev, const struct of_match *match) +static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match) { struct device_node *node = macio_get_of_node(mdev); struct pci_dev *pdev = macio_get_pci_dev(mdev); @@ -544,15 +544,14 @@ static int mac53c94_remove(struct macio_dev *mdev) } -static struct of_match mac53c94_match[] = +static struct of_device_id mac53c94_match[] = { { .name = "53c94", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, mac53c94_match); static struct macio_driver mac53c94_driver = { diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index ec81532eb845..a70cdf31311c 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -5036,9 +5036,9 @@ megaraid_remove_one(struct pci_dev *pdev) } static void -megaraid_shutdown(struct device *dev) +megaraid_shutdown(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); + struct Scsi_Host *host = pci_get_drvdata(pdev); adapter_t *adapter = (adapter_t *)host->hostdata; __megaraid_shutdown(adapter); @@ -5070,9 +5070,7 @@ static struct pci_driver megaraid_pci_driver = { .id_table = megaraid_pci_tbl, .probe = megaraid_probe_one, .remove = __devexit_p(megaraid_remove_one), - .driver = { - .shutdown = megaraid_shutdown, - }, + .shutdown = megaraid_shutdown, }; static int __init megaraid_init(void) diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index b05737ae5eff..ff1933298da6 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -1847,7 +1847,7 @@ static struct scsi_host_template mesh_template = { .use_clustering = DISABLE_CLUSTERING, }; -static int mesh_probe(struct macio_dev *mdev, const struct of_match *match) +static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match) { struct device_node *mesh = macio_get_of_node(mdev); struct pci_dev* pdev = macio_get_pci_dev(mdev); @@ -2012,20 +2012,18 @@ static int mesh_remove(struct macio_dev *mdev) } -static struct of_match mesh_match[] = +static struct of_device_id mesh_match[] = { { .name = "mesh", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, { - .name = OF_ANY_MATCH, .type = "scsi", .compatible = "chrp,mesh0" }, {}, }; +MODULE_DEVICE_TABLE (of, mesh_match); static struct macio_driver mesh_driver = { diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 621dee8b8cb2..10506f9cd0c9 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -632,7 +632,7 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index) { struct scsi_host_sg_pool *sgp; - BUG_ON(index > SG_MEMPOOL_NR); + BUG_ON(index >= SG_MEMPOOL_NR); sgp = scsi_sg_pools + index; mempool_free(sgl, sgp->pool); diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 34e75bc8f4cc..7e8fc7c1d4cc 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -105,7 +105,7 @@ static struct old_serial_port old_serial_port[] = { SERIAL_PORT_DFNS /* defined in asm/serial.h */ }; -#define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS) +#define UART_NR CONFIG_SERIAL_8250_NR_UARTS #ifdef CONFIG_SERIAL_8250_RSA @@ -993,21 +993,24 @@ static void autoconfig_irq(struct uart_8250_port *up) up->port.irq = (irq > 0) ? irq : 0; } +static inline void __stop_tx(struct uart_8250_port *p) +{ + if (p->ier & UART_IER_THRI) { + p->ier &= ~UART_IER_THRI; + serial_out(p, UART_IER, p->ier); + } +} + static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) { struct uart_8250_port *up = (struct uart_8250_port *)port; - if (up->ier & UART_IER_THRI) { - up->ier &= ~UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } + __stop_tx(up); /* - * We only do this from uart_stop - if we run out of - * characters to send, we don't want to prevent the - * FIFO from emptying. + * We really want to stop the transmitter from sending. */ - if (up->port.type == PORT_16C950 && tty_stop) { + if (up->port.type == PORT_16C950) { up->acr |= UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } @@ -1031,10 +1034,11 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start) transmit_chars(up); } } + /* - * We only do this from uart_start + * Re-enable the transmitter if we disabled it. */ - if (tty_start && up->port.type == PORT_16C950) { + if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { up->acr &= ~UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } @@ -1155,7 +1159,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial8250_stop_tx(&up->port, 0); + __stop_tx(up); return; } @@ -1174,7 +1178,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) DEBUG_INTR("THRE..."); if (uart_circ_empty(xmit)) - serial8250_stop_tx(&up->port, 0); + __stop_tx(up); } static _INLINE_ void check_modem_status(struct uart_8250_port *up) @@ -1376,13 +1380,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) static unsigned int serial8250_get_mctrl(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) @@ -2060,7 +2061,8 @@ static void __init serial8250_isa_init_ports(void) up->port.ops = &serial8250_pops; } - for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port); + for (i = 0, up = serial8250_ports; + i < ARRAY_SIZE(old_serial_port) && i < UART_NR; i++, up++) { up->port.iobase = old_serial_port[i].port; up->port.irq = irq_canonicalize(old_serial_port[i].irq); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e879bce160df..e0d0a470ddfc 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -86,7 +86,7 @@ config SERIAL_8250_ACPI namespace, say Y here. If unsure, say N. config SERIAL_8250_NR_UARTS - int "Maximum number of non-legacy 8250/16550 serial ports" + int "Maximum number of 8250/16550 serial ports" depends on SERIAL_8250 default "4" help diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index 5400dc2c087e..6104aeef1243 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c @@ -556,13 +556,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) static unsigned int serial8250_get_mctrl(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index de26cf7b003c..7911912f50c7 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -94,12 +94,42 @@ void smc1_lineif(struct uart_cpm_port *pinfo) ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; } +#ifdef CONFIG_MPC885ADS + /* Enable SMC1 transceivers */ + { + volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4); + uint tmp; + + tmp = in_be32(bcsr1); + tmp &= ~BCSR1_RS232EN_1; + out_be32(bcsr1, tmp); + iounmap(bcsr1); + } +#endif + pinfo->brg = 1; } void smc2_lineif(struct uart_cpm_port *pinfo) { - /* XXX SMC2: insert port configuration here */ +#ifdef CONFIG_MPC885ADS + volatile cpm8xx_t *cp = cpmp; + volatile uint __iomem *bcsr1; + uint tmp; + + cp->cp_pepar |= 0x00000c00; + cp->cp_pedir &= ~0x00000c00; + cp->cp_peso &= ~0x00000400; + cp->cp_peso |= 0x00000800; + + /* Enable SMC2 transceivers */ + bcsr1 = ioremap(BCSR1, 4); + tmp = in_be32(bcsr1); + tmp &= ~BCSR1_RS232EN_2; + out_be32(bcsr1, tmp); + iounmap(bcsr1); +#endif + pinfo->brg = 2; } diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 3ea46c069f6f..ea5bf4d4daa3 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c @@ -518,27 +518,28 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *re static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port) { struct zilog_channel *channel; - unsigned long flags; unsigned char status; - spin_lock_irqsave(&port->lock, flags); - channel = ZILOG_CHANNEL_FROM_PORT(port); status = readb(&channel->control); ZSDELAY(); - spin_unlock_irqrestore(&port->lock, flags); - return status; } /* The port lock is not held. */ static unsigned int ip22zilog_tx_empty(struct uart_port *port) { + unsigned long flags; unsigned char status; unsigned int ret; + spin_lock_irqsave(&port->lock, flags); + status = ip22zilog_read_channel_status(port); + + spin_unlock_irqrestore(&port->lock, flags); + if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; else @@ -547,7 +548,7 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port) return ret; } -/* The port lock is not held. */ +/* The port lock is held and interrupts are disabled. */ static unsigned int ip22zilog_get_mctrl(struct uart_port *port) { unsigned char status; diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index a2a643318002..e43276c6a954 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -1058,12 +1058,9 @@ mpsc_get_mctrl(struct uart_port *port) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; u32 mflags, status; - ulong iflags; - spin_lock_irqsave(&pi->port.lock, iflags); status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m : readl(pi->mpsc_base + MPSC_CHR_10); - spin_unlock_irqrestore(&pi->port.lock, iflags); mflags = 0; if (status & 0x1) diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 85abd8a045e0..7db2f37532cf 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -604,7 +604,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl) /* * Get Modem Control bits (only the input ones, the core will * or that with a cached value of the control ones) - * The port lock is not held. + * The port lock is held and interrupts are disabled. */ static unsigned int pmz_get_mctrl(struct uart_port *port) { @@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct uart_port *port) if (ZS_IS_ASLEEP(uap) || uap->node == NULL) return 0; - status = pmz_peek_status(to_pmz(port)); + status = read_zsreg(uap, R0); ret = 0; if (status & DCD) @@ -1545,7 +1545,7 @@ static void pmz_dispose_port(struct uart_pmac_port *uap) /* * Called upon match with an escc node in the devive-tree. */ -static int pmz_attach(struct macio_dev *mdev, const struct of_match *match) +static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) { int i; @@ -1850,20 +1850,17 @@ err_out: return rc; } -static struct of_match pmz_match[] = +static struct of_device_id pmz_match[] = { { .name = "ch-a", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, { .name = "ch-b", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, pmz_match); static struct macio_driver pmz_driver = { diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 08b08d6ae904..461c81c93207 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -274,14 +274,11 @@ static unsigned int serial_pxa_tx_empty(struct uart_port *port) static unsigned int serial_pxa_get_mctrl(struct uart_port *port) { struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 5c4678478b1d..7365d4b50b95 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -522,14 +522,11 @@ static void s3c24xx_serial_shutdown(struct uart_port *port) static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); - unsigned long flags; int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); - local_irq_save(flags); - rx_enabled(port) = 1; ret = request_irq(RX_IRQ(port), @@ -563,12 +560,10 @@ static int s3c24xx_serial_startup(struct uart_port *port) /* the port reset code should have done the correct * register setup for the port controls */ - local_irq_restore(flags); return ret; err: s3c24xx_serial_shutdown(port); - local_irq_restore(flags); return ret; } diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 36b1ae083fb7..54699c3a00ab 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -182,6 +182,13 @@ static int uart_startup(struct uart_state *state, int init_hw) uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); } + if (info->flags & UIF_CTS_FLOW) { + spin_lock_irq(&port->lock); + if (!(port->ops->get_mctrl(port) & TIOCM_CTS)) + info->tty->hw_stopped = 1; + spin_unlock_irq(&port->lock); + } + info->flags |= UIF_INITIALIZED; clear_bit(TTY_IO_ERROR, &info->tty->flags); @@ -828,7 +835,10 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file) if ((!file || !tty_hung_up_p(file)) && !(tty->flags & (1 << TTY_IO_ERROR))) { result = port->mctrl; + + spin_lock_irq(&port->lock); result |= port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); } up(&state->sem); @@ -1131,6 +1141,16 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios spin_unlock_irqrestore(&state->port->lock, flags); } + /* Handle turning on CRTSCTS */ + if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { + spin_lock_irqsave(&state->port->lock, flags); + if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { + tty->hw_stopped = 1; + state->port->ops->stop_tx(state->port, 0); + } + spin_unlock_irqrestore(&state->port->lock, flags); + } + #if 0 /* * No need to wake up processes in open wait, since they @@ -1369,6 +1389,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) DECLARE_WAITQUEUE(wait, current); struct uart_info *info = state->info; struct uart_port *port = state->port; + unsigned int mctrl; info->blocked_open++; state->count--; @@ -1416,7 +1437,10 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) * and wait for the carrier to indicate that the * modem is ready for us. */ - if (port->ops->get_mctrl(port) & TIOCM_CAR) + spin_lock_irq(&port->lock); + mctrl = port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); + if (mctrl & TIOCM_CAR) break; up(&state->sem); @@ -1618,7 +1642,9 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i) if(capable(CAP_SYS_ADMIN)) { + spin_lock_irq(&port->lock); status = port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); ret += sprintf(buf + ret, " tx:%d rx:%d", port->icount.tx, port->icount.rx); @@ -1782,6 +1808,12 @@ uart_set_options(struct uart_port *port, struct console *co, struct termios termios; int i; + /* + * Ensure that the serial console lock is initialised + * early. + */ + spin_lock_init(&port->lock); + memset(&termios, 0, sizeof(struct termios)); termios.c_cflag = CREAD | HUPCL | CLOCAL; @@ -2170,10 +2202,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) state->port = port; - spin_lock_init(&port->lock); port->cons = drv->cons; port->info = state->info; + /* + * If this port is a console, then the spinlock is already + * initialised. + */ + if (!uart_console(port)) + spin_lock_init(&port->lock); + uart_configure_port(drv, state, port); /* diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 3f1051a4a13f..d085030df70b 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -442,13 +442,10 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port) static unsigned int serial_txx9_get_mctrl(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; - unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); - spin_unlock_irqrestore(&up->port.lock, flags); return ret; } diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 10e2990a40d4..8d198880756a 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -426,18 +426,15 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl) sunsab_tx_idle(up); } -/* port->lock is not held. */ +/* port->lock is held by caller and interrupts are disabled. */ static unsigned int sunsab_get_mctrl(struct uart_port *port) { struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; - unsigned long flags; unsigned char val; unsigned int result; result = 0; - spin_lock_irqsave(&up->port.lock, flags); - val = readb(&up->regs->r.pvr); result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR; @@ -447,8 +444,6 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port) val = readb(&up->regs->r.star); result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - return result; } diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index ddc97c905e14..d57a3553aea3 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -572,13 +572,10 @@ static unsigned int sunsu_tx_empty(struct uart_port *port) static unsigned int sunsu_get_mctrl(struct uart_port *port) { struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 8e65206d3d76..bff42a7b89d0 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -610,27 +610,28 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port) { struct zilog_channel __iomem *channel; - unsigned long flags; unsigned char status; - spin_lock_irqsave(&port->lock, flags); - channel = ZILOG_CHANNEL_FROM_PORT(port); status = sbus_readb(&channel->control); ZSDELAY(); - spin_unlock_irqrestore(&port->lock, flags); - return status; } /* The port lock is not held. */ static unsigned int sunzilog_tx_empty(struct uart_port *port) { + unsigned long flags; unsigned char status; unsigned int ret; + spin_lock_irqsave(&port->lock, flags); + status = sunzilog_read_channel_status(port); + + spin_unlock_irqrestore(&port->lock, flags); + if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; else @@ -639,7 +640,7 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port) return ret; } -/* The port lock is not held. */ +/* The port lock is held and interrupts are disabled. */ static unsigned int sunzilog_get_mctrl(struct uart_port *port) { unsigned char status; diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index b209adbd508a..9dd0fbccf994 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -142,7 +142,6 @@ static int fbcon_set_origin(struct vc_data *); #define CURSOR_DRAW_DELAY (1) /* # VBL ints between cursor state changes */ -#define ARM_CURSOR_BLINK_RATE (10) #define ATARI_CURSOR_BLINK_RATE (42) #define MAC_CURSOR_BLINK_RATE (32) #define DEFAULT_CURSOR_BLINK_RATE (20) @@ -288,7 +287,7 @@ static void fb_flashcursor(void *private) release_console_sem(); } -#if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC) +#if defined(CONFIG_ATARI) || defined(CONFIG_MAC) static int cursor_blink_rate; static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp) { @@ -878,11 +877,6 @@ static const char *fbcon_startup(void) } #endif /* CONFIG_MAC */ -#if defined(__arm__) && defined(IRQ_VSYNCPULSE) - cursor_blink_rate = ARM_CURSOR_BLINK_RATE; - irqres = request_irq(IRQ_VSYNCPULSE, fb_vbl_handler, SA_SHIRQ, - "framebuffer vbl", info); -#endif /* Initialize the work queue. If the driver provides its * own work queue this means it will use something besides * default timer to flash the cursor. */ diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 3dd1de1539d2..b00887e9851c 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -523,7 +523,7 @@ int __init platinumfb_setup(char *options) #define invalidate_cache(addr) #endif -static int __devinit platinumfb_probe(struct of_device* odev, const struct of_match *match) +static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match) { struct device_node *dp = odev->node; struct fb_info *info; @@ -647,12 +647,10 @@ static int __devexit platinumfb_remove(struct of_device* odev) return 0; } -static struct of_match platinumfb_match[] = +static struct of_device_id platinumfb_match[] = { { .name = "platinum", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH, }, {}, }; @@ -58,6 +58,7 @@ static DEFINE_SPINLOCK(fput_lock); static LIST_HEAD(fput_head); static void aio_kick_handler(void *); +static void aio_queue_work(struct kioctx *); /* aio_setup * Creates the slab caches used by the aio routines, panic on @@ -747,6 +748,14 @@ out: * has already been kicked */ if (kiocbIsKicked(iocb)) { __queue_kicked_iocb(iocb); + + /* + * __queue_kicked_iocb will always return 1 here, because + * iocb->ki_run_list is empty at this point so it should + * be safe to unconditionally queue the context into the + * work queue. + */ + aio_queue_work(ctx); } } return ret; diff --git a/fs/buffer.c b/fs/buffer.c index 13e5938a64f6..561e63a14966 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -278,7 +278,7 @@ EXPORT_SYMBOL(thaw_bdev); */ static void do_sync(unsigned long wait) { - wakeup_bdflush(0); + wakeup_pdflush(0); sync_inodes(0); /* All mappings, inodes and their blockdevs */ DQUOT_SYNC(NULL); sync_supers(); /* Write the superblocks */ @@ -497,7 +497,7 @@ static void free_more_memory(void) struct zone **zones; pg_data_t *pgdat; - wakeup_bdflush(1024); + wakeup_pdflush(1024); yield(); for_each_pgdat(pgdat) { diff --git a/fs/char_dev.c b/fs/char_dev.c index e82aac9cc2f5..a69a5d8a406f 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) struct char_device_struct *cd = NULL, **cp; int i = major_to_index(major); - up(&chrdevs_lock); + down(&chrdevs_lock); for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) if ((*cp)->major == major && (*cp)->baseminor == baseminor && diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index ccd632fcc6d8..e463dca008e4 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -749,24 +749,24 @@ fail_access: * to find a free region that is of my size and has not * been reserved. * - * on succeed, it returns the reservation window to be appended to. - * failed, return NULL. */ -static struct ext3_reserve_window_node *find_next_reservable_window( +static int find_next_reservable_window( struct ext3_reserve_window_node *search_head, - unsigned long size, int *start_block, + struct ext3_reserve_window_node *my_rsv, + struct super_block * sb, int start_block, int last_block) { struct rb_node *next; struct ext3_reserve_window_node *rsv, *prev; int cur; + int size = my_rsv->rsv_goal_size; /* TODO: make the start of the reservation window byte-aligned */ /* cur = *start_block & ~7;*/ - cur = *start_block; + cur = start_block; rsv = search_head; if (!rsv) - return NULL; + return -1; while (1) { if (cur <= rsv->rsv_end) @@ -782,11 +782,11 @@ static struct ext3_reserve_window_node *find_next_reservable_window( * space with expected-size (or more)... */ if (cur > last_block) - return NULL; /* fail */ + return -1; /* fail */ prev = rsv; next = rb_next(&rsv->rsv_node); - rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node); + rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node); /* * Reached the last reservation, we can just append to the @@ -813,8 +813,25 @@ static struct ext3_reserve_window_node *find_next_reservable_window( * return the reservation window that we could append to. * succeed. */ - *start_block = cur; - return prev; + + if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window))) + rsv_window_remove(sb, my_rsv); + + /* + * Let's book the whole avaliable window for now. We will check the + * disk bitmap later and then, if there are free blocks then we adjust + * the window size if it's larger than requested. + * Otherwise, we will remove this node from the tree next time + * call find_next_reservable_window. + */ + my_rsv->rsv_start = cur; + my_rsv->rsv_end = cur + size - 1; + my_rsv->rsv_alloc_hit = 0; + + if (prev != my_rsv) + ext3_rsv_window_add(sb, my_rsv); + + return 0; } /** @@ -852,6 +869,7 @@ static struct ext3_reserve_window_node *find_next_reservable_window( * @sb: the super block * @group: the group we are trying to allocate in * @bitmap_bh: the block group block bitmap + * */ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, int goal, struct super_block *sb, @@ -860,10 +878,10 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, struct ext3_reserve_window_node *search_head; int group_first_block, group_end_block, start_block; int first_free_block; - int reservable_space_start; - struct ext3_reserve_window_node *prev_rsv; struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root; unsigned long size; + int ret; + spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock; group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + group * EXT3_BLOCKS_PER_GROUP(sb); @@ -875,6 +893,7 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, start_block = goal + group_first_block; size = my_rsv->rsv_goal_size; + if (!rsv_is_empty(&my_rsv->rsv_window)) { /* * if the old reservation is cross group boundary @@ -908,6 +927,8 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, my_rsv->rsv_goal_size= size; } } + + spin_lock(rsv_lock); /* * shift the search start to the window near the goal block */ @@ -921,11 +942,16 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, * need to check the bitmap after we found a reservable window. */ retry: - prev_rsv = find_next_reservable_window(search_head, size, - &start_block, group_end_block); - if (prev_rsv == NULL) - goto failed; - reservable_space_start = start_block; + ret = find_next_reservable_window(search_head, my_rsv, sb, + start_block, group_end_block); + + if (ret == -1) { + if (!rsv_is_empty(&my_rsv->rsv_window)) + rsv_window_remove(sb, my_rsv); + spin_unlock(rsv_lock); + return -1; + } + /* * On success, find_next_reservable_window() returns the * reservation window where there is a reservable space after it. @@ -937,8 +963,9 @@ retry: * block. Search start from the start block of the reservable space * we just found. */ + spin_unlock(rsv_lock); first_free_block = bitmap_search_next_usable_block( - reservable_space_start - group_first_block, + my_rsv->rsv_start - group_first_block, bitmap_bh, group_end_block - group_first_block + 1); if (first_free_block < 0) { @@ -946,54 +973,29 @@ retry: * no free block left on the bitmap, no point * to reserve the space. return failed. */ - goto failed; + spin_lock(rsv_lock); + if (!rsv_is_empty(&my_rsv->rsv_window)) + rsv_window_remove(sb, my_rsv); + spin_unlock(rsv_lock); + return -1; /* failed */ } + start_block = first_free_block + group_first_block; /* * check if the first free block is within the - * free space we just found + * free space we just reserved */ - if ((start_block >= reservable_space_start) && - (start_block < reservable_space_start + size)) - goto found_rsv_window; + if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) + return 0; /* success */ /* * if the first free bit we found is out of the reservable space - * this means there is no free block on the reservable space - * we should continue search for next reservable space, + * continue search for next reservable space, * start from where the free block is, * we also shift the list head to where we stopped last time */ - search_head = prev_rsv; + search_head = my_rsv; + spin_lock(rsv_lock); goto retry; - -found_rsv_window: - /* - * great! the reservable space contains some free blocks. - * if the search returns that we should add the new - * window just next to where the old window, we don't - * need to remove the old window first then add it to the - * same place, just update the new start and new end. - */ - if (my_rsv != prev_rsv) { - if (!rsv_is_empty(&my_rsv->rsv_window)) - rsv_window_remove(sb, my_rsv); - } - my_rsv->rsv_start = reservable_space_start; - my_rsv->rsv_end = my_rsv->rsv_start + size - 1; - my_rsv->rsv_alloc_hit = 0; - if (my_rsv != prev_rsv) { - ext3_rsv_window_add(sb, my_rsv); - } - return 0; /* succeed */ -failed: - /* - * failed to find a new reservation window in the current - * group, remove the current(stale) reservation window - * if there is any - */ - if (!rsv_is_empty(&my_rsv->rsv_window)) - rsv_window_remove(sb, my_rsv); - return -1; /* failed */ } /* @@ -1023,7 +1025,6 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, int goal, struct ext3_reserve_window_node * my_rsv, int *errp) { - spinlock_t *rsv_lock; unsigned long group_first_block; int ret = 0; int fatal; @@ -1052,7 +1053,6 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL); goto out; } - rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock; /* * goal is a group relative block number (if there is a goal) * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb) @@ -1078,30 +1078,21 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, * then we could go to allocate from the reservation window directly. */ while (1) { - struct ext3_reserve_window rsv_copy; - - rsv_copy._rsv_start = my_rsv->rsv_start; - rsv_copy._rsv_end = my_rsv->rsv_end; - - if (rsv_is_empty(&rsv_copy) || (ret < 0) || - !goal_in_my_reservation(&rsv_copy, goal, group, sb)) { - spin_lock(rsv_lock); + if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) || + !goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) { ret = alloc_new_reservation(my_rsv, goal, sb, group, bitmap_bh); - rsv_copy._rsv_start = my_rsv->rsv_start; - rsv_copy._rsv_end = my_rsv->rsv_end; - spin_unlock(rsv_lock); if (ret < 0) break; /* failed */ - if (!goal_in_my_reservation(&rsv_copy, goal, group, sb)) + if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) goal = -1; } - if ((rsv_copy._rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) - || (rsv_copy._rsv_end < group_first_block)) + if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) + || (my_rsv->rsv_end < group_first_block)) BUG(); ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, - &rsv_copy); + &my_rsv->rsv_window); if (ret >= 0) { my_rsv->rsv_alloc_hit++; break; /* succeed */ diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 5ad8cf0292df..98e78345ead9 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -36,7 +36,11 @@ static int ext3_release_file (struct inode * inode, struct file * filp) /* if we are the last writer on the inode, drop the block reservation */ if ((filp->f_mode & FMODE_WRITE) && (atomic_read(&inode->i_writecount) == 1)) + { + down(&EXT3_I(inode)->truncate_sem); ext3_discard_reservation(inode); + up(&EXT3_I(inode)->truncate_sem); + } if (is_dx(inode) && filp->private_data) ext3_htree_free_dir_info(filp->private_data); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index b4b3e8a39131..a6d1779d7de4 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -944,7 +944,8 @@ clear_qf_name: "for remount\n"); return 0; } - match_int(&args[0], &option); + if (match_int(&args[0], &option) != 0) + return 0; *n_blocks_count = option; break; case Opt_nobh: diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 7c52e465a619..77c24fcf712a 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c @@ -56,7 +56,7 @@ int __init fat_cache_init(void) return 0; } -void __exit fat_cache_destroy(void) +void fat_cache_destroy(void) { if (kmem_cache_destroy(fat_cache_cachep)) printk(KERN_INFO "fat_cache: not all structures were freed\n"); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 8ccee8415488..96ae85b67eba 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1327,16 +1327,25 @@ out_fail: EXPORT_SYMBOL(fat_fill_super); int __init fat_cache_init(void); -void __exit fat_cache_destroy(void); +void fat_cache_destroy(void); static int __init init_fat_fs(void) { - int ret; + int err; - ret = fat_cache_init(); - if (ret < 0) - return ret; - return fat_init_inodecache(); + err = fat_cache_init(); + if (err) + return err; + + err = fat_init_inodecache(); + if (err) + goto failed; + + return 0; + +failed: + fat_cache_destroy(); + return err; } static void __exit exit_fat_fs(void) diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h index 8da0252642a4..583bd78086d8 100644 --- a/fs/freevxfs/vxfs.h +++ b/fs/freevxfs/vxfs.h @@ -37,7 +37,6 @@ * superblocks of the Veritas Filesystem. */ #include <linux/types.h> -#include "vxfs_kcompat.h" /* diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c index bc4b57da306a..d3f6b2835bc8 100644 --- a/fs/freevxfs/vxfs_bmap.c +++ b/fs/freevxfs/vxfs_bmap.c @@ -101,7 +101,7 @@ vxfs_bmap_ext4(struct inode *ip, long bn) return 0; fail_size: - printk("vxfs: indirect extent to big!\n"); + printk("vxfs: indirect extent too big!\n"); fail_buf: return 0; } diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c index 05b19f70bf97..6dee109aeea4 100644 --- a/fs/freevxfs/vxfs_fshead.c +++ b/fs/freevxfs/vxfs_fshead.c @@ -78,17 +78,18 @@ vxfs_getfsh(struct inode *ip, int which) struct buffer_head *bp; bp = vxfs_bread(ip, which); - if (buffer_mapped(bp)) { + if (bp) { struct vxfs_fsh *fhp; - if (!(fhp = kmalloc(sizeof(*fhp), SLAB_KERNEL))) - return NULL; + if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL))) + goto out; memcpy(fhp, bp->b_data, sizeof(*fhp)); - brelse(bp); + put_bh(bp); return (fhp); } - +out: + brelse(bp); return NULL; } diff --git a/fs/freevxfs/vxfs_kcompat.h b/fs/freevxfs/vxfs_kcompat.h deleted file mode 100644 index 342a4cc860f4..000000000000 --- a/fs/freevxfs/vxfs_kcompat.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _VXFS_KCOMPAT_H -#define _VXFS_KCOMPAT_H - -#include <linux/version.h> - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - -#include <linux/blkdev.h> - -typedef long sector_t; - -/* From include/linux/fs.h (Linux 2.5.2-pre3) */ -static inline struct buffer_head * sb_bread(struct super_block *sb, int block) -{ - return bread(sb->s_dev, block, sb->s_blocksize); -} - -/* Dito. */ -static inline void map_bh(struct buffer_head *bh, struct super_block *sb, int block) -{ - bh->b_state |= 1 << BH_Mapped; - bh->b_dev = sb->s_dev; - bh->b_blocknr = block; -} - -/* From fs/block_dev.c (Linux 2.5.2-pre2) */ -static inline int sb_set_blocksize(struct super_block *sb, int size) -{ - int bits; - if (set_blocksize(sb->s_dev, size) < 0) - return 0; - sb->s_blocksize = size; - for (bits = 9, size >>= 9; size >>= 1; bits++) - ; - sb->s_blocksize_bits = bits; - return sb->s_blocksize; -} - -/* Dito. */ -static inline int sb_min_blocksize(struct super_block *sb, int size) -{ - int minsize = get_hardsect_size(sb->s_dev); - if (size < minsize) - size = minsize; - return sb_set_blocksize(sb, size); -} - -#endif /* Kernel 2.4 */ -#endif /* _VXFS_KCOMPAT_H */ diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c index 506ae251d2c0..554eb455722c 100644 --- a/fs/freevxfs/vxfs_lookup.c +++ b/fs/freevxfs/vxfs_lookup.c @@ -61,13 +61,13 @@ struct file_operations vxfs_dir_operations = { }; -static __inline__ u_long +static inline u_long dir_pages(struct inode *inode) { return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; } -static __inline__ u_long +static inline u_long dir_blocks(struct inode *ip) { u_long bsize = ip->i_sb->s_blocksize; @@ -79,7 +79,7 @@ dir_blocks(struct inode *ip) * * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller. */ -static __inline__ int +static inline int vxfs_match(int len, const char * const name, struct vxfs_direct *de) { if (len != de->d_namelen) @@ -89,7 +89,7 @@ vxfs_match(int len, const char * const name, struct vxfs_direct *de) return !memcmp(name, de->d_name, len); } -static __inline__ struct vxfs_direct * +static inline struct vxfs_direct * vxfs_next_entry(struct vxfs_direct *de) { return ((struct vxfs_direct *)((char*)de + de->d_reclen)); diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c index 7a204e31aad9..133476201d84 100644 --- a/fs/freevxfs/vxfs_olt.c +++ b/fs/freevxfs/vxfs_olt.c @@ -38,7 +38,7 @@ #include "vxfs_olt.h" -static __inline__ void +static inline void vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) { if (infp->vsi_fshino) @@ -46,7 +46,7 @@ vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) infp->vsi_fshino = fshp->olt_fsino[0]; } -static __inline__ void +static inline void vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) { if (infp->vsi_iext) @@ -54,7 +54,7 @@ vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) infp->vsi_iext = ilistp->olt_iext[0]; } -static __inline__ u_long +static inline u_long vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize) { if (sbp->s_blocksize % bsize) @@ -104,8 +104,8 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize) goto fail; } - oaddr = (char *)bp->b_data + op->olt_size; - eaddr = (char *)bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize); + oaddr = bp->b_data + op->olt_size; + eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize); while (oaddr < eaddr) { struct vxfs_oltcommon *ocp = diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c index 5e305612054a..50aae77651b2 100644 --- a/fs/freevxfs/vxfs_subr.c +++ b/fs/freevxfs/vxfs_subr.c @@ -36,7 +36,6 @@ #include <linux/slab.h> #include <linux/pagemap.h> -#include "vxfs_kcompat.h" #include "vxfs_extern.h" diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index 0ae2c7b8182a..27f66d3e8a04 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c @@ -155,12 +155,11 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) sbp->s_flags |= MS_RDONLY; - infp = kmalloc(sizeof(*infp), GFP_KERNEL); + infp = kcalloc(1, sizeof(*infp), GFP_KERNEL); if (!infp) { printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n"); return -ENOMEM; } - memset(infp, 0, sizeof(*infp)); bsize = sb_min_blocksize(sbp, BLOCK_SIZE); if (!bsize) { @@ -196,7 +195,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) #endif sbp->s_magic = rsbp->vs_magic; - sbp->s_fs_info = (void *)infp; + sbp->s_fs_info = infp; infp->vsi_raw = rsbp; infp->vsi_bp = bp; @@ -263,7 +262,7 @@ vxfs_init(void) sizeof(struct vxfs_inode_info), 0, SLAB_RECLAIM_ACCOUNT, NULL, NULL); if (vxfs_inode_cachep) - return (register_filesystem(&vxfs_fs_type)); + return register_filesystem(&vxfs_fs_type); return -ENOMEM; } diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index ee3536fc84a3..1b7a3ef2f813 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c @@ -2,7 +2,7 @@ #include <linux/nfs.h> #include <linux/nfs3.h> #include <linux/nfs_fs.h> -#include <linux/xattr_acl.h> +#include <linux/posix_acl_xattr.h> #include <linux/nfsacl.h> #define NFSDBG_FACILITY NFSDBG_PROC @@ -53,9 +53,9 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name, struct posix_acl *acl; int type, error = 0; - if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) + if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) type = ACL_TYPE_ACCESS; - else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) + else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) type = ACL_TYPE_DEFAULT; else return -EOPNOTSUPP; @@ -82,9 +82,9 @@ int nfs3_setxattr(struct dentry *dentry, const char *name, struct posix_acl *acl; int type, error; - if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) + if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) type = ACL_TYPE_ACCESS; - else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) + else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) type = ACL_TYPE_DEFAULT; else return -EOPNOTSUPP; @@ -103,9 +103,9 @@ int nfs3_removexattr(struct dentry *dentry, const char *name) struct inode *inode = dentry->d_inode; int type; - if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) + if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) type = ACL_TYPE_ACCESS; - else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) + else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) type = ACL_TYPE_DEFAULT; else return -EOPNOTSUPP; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index de340ffd33c3..be24ead89d94 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -46,10 +46,9 @@ #include <linux/nfsd/nfsfh.h> #include <linux/quotaops.h> #include <linux/dnotify.h> -#include <linux/xattr_acl.h> #include <linux/posix_acl.h> -#ifdef CONFIG_NFSD_V4 #include <linux/posix_acl_xattr.h> +#ifdef CONFIG_NFSD_V4 #include <linux/xattr.h> #include <linux/nfs4.h> #include <linux/nfs4_acl.h> @@ -1872,10 +1871,10 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type) return ERR_PTR(-EOPNOTSUPP); switch(type) { case ACL_TYPE_ACCESS: - name = XATTR_NAME_ACL_ACCESS; + name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: - name = XATTR_NAME_ACL_DEFAULT; + name = POSIX_ACL_XATTR_DEFAULT; break; default: return ERR_PTR(-EOPNOTSUPP); @@ -1919,17 +1918,17 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) return -EOPNOTSUPP; switch(type) { case ACL_TYPE_ACCESS: - name = XATTR_NAME_ACL_ACCESS; + name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: - name = XATTR_NAME_ACL_DEFAULT; + name = POSIX_ACL_XATTR_DEFAULT; break; default: return -EOPNOTSUPP; } if (acl && acl->a_count) { - size = xattr_acl_size(acl->a_count); + size = posix_acl_xattr_size(acl->a_count); value = kmalloc(size, GFP_KERNEL); if (!value) return -ENOMEM; diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 94dc42475a04..76caedf737f2 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -36,10 +36,16 @@ int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, /* following two cases are taken from fs/ext2/ioctl.c by Remy Card (card@masi.ibp.fr) */ case REISERFS_IOC_GETFLAGS: + if (!reiserfs_attrs (inode->i_sb)) + return -ENOTTY; + flags = REISERFS_I(inode) -> i_attrs; i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags ); return put_user(flags, (int __user *) arg); case REISERFS_IOC_SETFLAGS: { + if (!reiserfs_attrs (inode->i_sb)) + return -ENOTTY; + if (IS_RDONLY(inode)) return -EROFS; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 660aefca1fd2..4b80ab95d338 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1053,10 +1053,9 @@ static void handle_barrier_mode(struct super_block *s, unsigned long bits) { static void handle_attrs( struct super_block *s ) { - struct reiserfs_super_block * rs; + struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); if( reiserfs_attrs( s ) ) { - rs = SB_DISK_SUPER_BLOCK (s); if( old_format_only(s) ) { reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format" ); REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS ); @@ -1066,6 +1065,8 @@ static void handle_attrs( struct super_block *s ) reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block" ); REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS ); } + } else if (le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared) { + REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS; } } diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 3f6dc7112bc6..ac191ed7df0a 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -159,14 +159,12 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, char *nameptr; uint8_t lfi; uint16_t liu; - loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; + loff_t size; kernel_lb_addr bloc, eloc; uint32_t extoffset, elen, offset; struct buffer_head *bh = NULL; - if (!dir) - return NULL; - + size = (udf_ext0_offset(dir) + dir->i_size) >> 2; f_pos = (udf_ext0_offset(dir) >> 2); fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c627bc408a6b..9ad142476f33 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -108,6 +108,21 @@ typedef int (*acpi_op_unbind) (struct acpi_device *device); typedef int (*acpi_op_match) (struct acpi_device *device, struct acpi_driver *driver); +struct acpi_bus_ops { + u32 acpi_op_add:1; + u32 acpi_op_remove:1; + u32 acpi_op_lock:1; + u32 acpi_op_start:1; + u32 acpi_op_stop:1; + u32 acpi_op_suspend:1; + u32 acpi_op_resume:1; + u32 acpi_op_scan:1; + u32 acpi_op_bind:1; + u32 acpi_op_unbind:1; + u32 acpi_op_match:1; + u32 reserved:21; +}; + struct acpi_device_ops { acpi_op_add add; acpi_op_remove remove; @@ -327,9 +342,9 @@ int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data); int acpi_bus_receive_event (struct acpi_bus_event *event); int acpi_bus_register_driver (struct acpi_driver *driver); int acpi_bus_unregister_driver (struct acpi_driver *driver); -int acpi_bus_scan (struct acpi_device *start); int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent, acpi_handle handle, int type); +int acpi_bus_start (struct acpi_device *device); int acpi_match_ids (struct acpi_device *device, char *ids); diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index c62e92ec43b2..4ec722d73381 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -68,6 +68,7 @@ void acpi_pci_irq_del_prt (int segment, int bus); struct pci_bus; +acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id); int acpi_pci_bind (struct acpi_device *device); int acpi_pci_unbind (struct acpi_device *device); int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus); diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index 0c7b57bc043a..b7806aa3785c 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -223,6 +223,25 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, /* Nothing to do. */ } +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_BOUNDARY; + *strategy_parameter = cacheline_size; +} +#endif + /* TODO: integrate with include/asm-generic/pci.h ? */ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { diff --git a/include/asm-alpha/serial.h b/include/asm-alpha/serial.h index 7b2d9ee95a44..7e4b2987d453 100644 --- a/include/asm-alpha/serial.h +++ b/include/asm-alpha/serial.h @@ -22,54 +22,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#endif - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h index c27b9d3079a7..7495026e2c18 100644 --- a/include/asm-arm/arch-ixp4xx/io.h +++ b/include/asm-arm/arch-ixp4xx/io.h @@ -3,7 +3,7 @@ * * Author: Deepak Saxena <dsaxena@plexity.net> * - * Copyright (C) 2002-2004 MontaVista Software, Inc. + * Copyright (C) 2002-2005 MontaVista Software, Inc. * * 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 @@ -383,6 +383,180 @@ __ixp4xx_insl(u32 io_addr, u32 *vaddr, u32 count) *vaddr++ = inl(io_addr); } +#define __is_io_address(p) (((unsigned long)p >= 0x0) && \ + ((unsigned long)p <= 0x0000ffff)) +static inline unsigned int +__ixp4xx_ioread8(void __iomem *port) +{ + if (__is_io_address(port)) + return (unsigned int)__ixp4xx_inb((unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + return (unsigned int)__raw_readb((u32)port); +#else + return (unsigned int)__ixp4xx_readb((u32)port); +#endif +} + +static inline void +__ixp4xx_ioread8_rep(u32 port, u8 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_insb(port, vaddr, count); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsb((void __iomem *)port, vaddr, count); +#else + __ixp4xx_readsb(port, vaddr, count); +#endif +} + +static inline unsigned int +__ixp4xx_ioread16(void __iomem *port) +{ + if (__is_io_address(port)) + return (unsigned int)__ixp4xx_inw((unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + return le16_to_cpu(__raw_readw((u32)port)); +#else + return (unsigned int)__ixp4xx_readw((u32)port); +#endif +} + +static inline void +__ixp4xx_ioread16_rep(u32 port, u16 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_insw(port, vaddr, count); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsw((void __iomem *)port, vaddr, count); +#else + __ixp4xx_readsw(port, vaddr, count); +#endif +} + +static inline unsigned int +__ixp4xx_ioread32(void __iomem *port) +{ + if (__is_io_address(port)) + return (unsigned int)__ixp4xx_inl((unsigned int)port); + else { +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + return le32_to_cpu(__raw_readl((u32)port)); +#else + return (unsigned int)__ixp4xx_readl((u32)port); +#endif + } +} + +static inline void +__ixp4xx_ioread32_rep(u32 port, u32 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_insl(port, vaddr, count); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsl((void __iomem *)port, vaddr, count); +#else + __ixp4xx_readsl(port, vaddr, count); +#endif +} + +static inline void +__ixp4xx_iowrite8(u8 value, void __iomem *port) +{ + if (__is_io_address(port)) + __ixp4xx_outb(value, (unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_writeb(value, (u32)port); +#else + __ixp4xx_writeb(value, (u32)port); +#endif +} + +static inline void +__ixp4xx_iowrite8_rep(u32 port, u8 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_outsb(port, vaddr, count); +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_writesb((void __iomem *)port, vaddr, count); +#else + __ixp4xx_writesb(port, vaddr, count); +#endif +} + +static inline void +__ixp4xx_iowrite16(u16 value, void __iomem *port) +{ + if (__is_io_address(port)) + __ixp4xx_outw(value, (unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_writew(cpu_to_le16(value), (u32)port); +#else + __ixp4xx_writew(value, (u32)port); +#endif +} + +static inline void +__ixp4xx_iowrite16_rep(u32 port, u16 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_outsw(port, vaddr, count); +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsw((void __iomem *)port, vaddr, count); +#else + __ixp4xx_writesw(port, vaddr, count); +#endif +} + +static inline void +__ixp4xx_iowrite32(u32 value, void __iomem *port) +{ + if (__is_io_address(port)) + __ixp4xx_outl(value, (unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_writel(cpu_to_le32(value), (u32)port); +#else + __ixp4xx_writel(value, (u32)port); +#endif +} + +static inline void +__ixp4xx_iowrite32_rep(u32 port, u32 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_outsl(port, vaddr, count); +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsl((void __iomem *)port, vaddr, count); +#else + __ixp4xx_outsl(port, vaddr, count); +#endif +} + +#define ioread8(p) __ixp4xx_ioread8(p) +#define ioread16(p) __ixp4xx_ioread16(p) +#define ioread32(p) __ixp4xx_ioread32(p) + +#define ioread8_rep(p, v, c) __ixp4xx_ioread8_rep(p, v, c) +#define ioread16_rep(p, v, c) __ixp4xx_ioread16_rep(p, v, c) +#define ioread32_rep(p, v, c) __ixp4xx_ioread32_rep(p, v, c) + +#define iowrite8(v,p) __ixp4xx_iowrite8(v,p) +#define iowrite16(v,p) __ixp4xx_iowrite16(v,p) +#define iowrite32(v,p) __ixp4xx_iowrite32(v,p) + +#define iowrite8_rep(p, v, c) __ixp4xx_iowrite8_rep(p, v, c) +#define iowrite16_rep(p, v, c) __ixp4xx_iowrite16_rep(p, v, c) +#define iowrite32_rep(p, v, c) __ixp4xx_iowrite32_rep(p, v, c) + +#define ioport_map(port, nr) ((void __iomem*)port) +#define ioport_unmap(addr) #endif // __ASM_ARM_ARCH_IO_H diff --git a/include/asm-arm/arch-pxa/debug-macro.S b/include/asm-arm/arch-pxa/debug-macro.S index f288e74b67c2..b6ec68879176 100644 --- a/include/asm-arm/arch-pxa/debug-macro.S +++ b/include/asm-arm/arch-pxa/debug-macro.S @@ -11,6 +11,8 @@ * */ +#include "hardware.h" + .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index b5e54a9e9fa7..51f0fe0ac165 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1505,6 +1505,7 @@ #define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */ #define PSSR_RDH (1 << 5) /* Read Disable Hold */ #define PSSR_PH (1 << 4) /* Peripheral Control Hold */ +#define PSSR_STS (1 << 3) /* Standby Mode Status */ #define PSSR_VFS (1 << 2) /* VDD Fault Status */ #define PSSR_BFS (1 << 1) /* Battery Fault Status */ #define PSSR_SSS (1 << 0) /* Software Sleep Status */ @@ -1965,6 +1966,7 @@ #define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */ #define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */ +#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */ #define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ #define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ #define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ diff --git a/include/asm-arm/arch-s3c2410/audio.h b/include/asm-arm/arch-s3c2410/audio.h new file mode 100644 index 000000000000..0d276e67f2fb --- /dev/null +++ b/include/asm-arm/arch-s3c2410/audio.h @@ -0,0 +1,49 @@ +/* linux/include/asm-arm/arch-s3c2410/audio.h + * + * (c) 2004-2005 Simtec Electronics + * http://www.simtec.co.uk/products/SWLINUX/ + * Ben Dooks <ben@simtec.co.uk> + * + * S3C24XX - Audio platfrom_device info + * + * 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. + * + * Changelog: + * 20-Nov-2004 BJD Created file + * 07-Mar-2005 BJD Added suspend/resume calls +*/ + +#ifndef __ASM_ARCH_AUDIO_H +#define __ASM_ARCH_AUDIO_H __FILE__ + +/* struct s3c24xx_iis_ops + * + * called from the s3c24xx audio core to deal with the architecture + * or the codec's setup and control. + * + * the pointer to itself is passed through in case the caller wants to + * embed this in an larger structure for easy reference to it's context. +*/ + +struct s3c24xx_iis_ops { + struct module *owner; + + int (*startup)(struct s3c24xx_iis_ops *me); + void (*shutdown)(struct s3c24xx_iis_ops *me); + int (*suspend)(struct s3c24xx_iis_ops *me); + int (*resume)(struct s3c24xx_iis_ops *me); + + int (*open)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm); + int (*close)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm); + int (*prepare)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm, snd_pcm_runtime_t *rt); +}; + +struct s3c24xx_platdata_iis { + const char *codec_clk; + struct s3c24xx_iis_ops *ops; + int (*match_dev)(struct device *dev); +}; + +#endif /* __ASM_ARCH_AUDIO_H */ diff --git a/include/asm-arm/hardware/arm_timer.h b/include/asm-arm/hardware/arm_timer.h new file mode 100644 index 000000000000..04be3bdf46b8 --- /dev/null +++ b/include/asm-arm/hardware/arm_timer.h @@ -0,0 +1,21 @@ +#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H +#define __ASM_ARM_HARDWARE_ARM_TIMER_H + +#define TIMER_LOAD 0x00 +#define TIMER_VALUE 0x04 +#define TIMER_CTRL 0x08 +#define TIMER_CTRL_ONESHOT (1 << 0) +#define TIMER_CTRL_32BIT (1 << 1) +#define TIMER_CTRL_DIV1 (0 << 2) +#define TIMER_CTRL_DIV16 (1 << 2) +#define TIMER_CTRL_DIV256 (2 << 2) +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ +#define TIMER_CTRL_PERIODIC (1 << 6) +#define TIMER_CTRL_ENABLE (1 << 7) + +#define TIMER_INTCLR 0x0c +#define TIMER_RIS 0x10 +#define TIMER_MIS 0x14 +#define TIMER_BGLOAD 0x18 + +#endif diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h index 3a32e929ec8c..56c6bf4ab0c3 100644 --- a/include/asm-arm/mach/arch.h +++ b/include/asm-arm/mach/arch.h @@ -26,7 +26,7 @@ struct machine_desc { * page tabe entry */ const char *name; /* architecture name */ - unsigned int param_offset; /* parameter page */ + unsigned long boot_params; /* tagged list */ unsigned int video_start; /* start of video RAM */ unsigned int video_end; /* end of video RAM */ @@ -54,38 +54,6 @@ const struct machine_desc __mach_desc_##_type \ .nr = MACH_TYPE_##_type, \ .name = _name, -#define MAINTAINER(n) - -#define BOOT_MEM(_pram,_pio,_vio) \ - .phys_ram = _pram, \ - .phys_io = _pio, \ - .io_pg_offst = ((_vio)>>18)&0xfffc, - -#define BOOT_PARAMS(_params) \ - .param_offset = _params, - -#define VIDEO(_start,_end) \ - .video_start = _start, \ - .video_end = _end, - -#define DISABLE_PARPORT(_n) \ - .reserve_lp##_n = 1, - -#define SOFT_REBOOT \ - .soft_reboot = 1, - -#define FIXUP(_func) \ - .fixup = _func, - -#define MAPIO(_func) \ - .map_io = _func, - -#define INITIRQ(_func) \ - .init_irq = _func, - -#define INIT_MACHINE(_func) \ - .init_machine = _func, - #define MACHINE_END \ }; diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h index 40ffaefbeb1a..e300646fe650 100644 --- a/include/asm-arm/pci.h +++ b/include/asm-arm/pci.h @@ -42,6 +42,16 @@ static inline void pcibios_penalize_isa_irq(int irq) #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + #define HAVE_PCI_MMAP extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); diff --git a/include/asm-arm/stat.h b/include/asm-arm/stat.h index ca8e7a8436da..ec4e2c2e3b47 100644 --- a/include/asm-arm/stat.h +++ b/include/asm-arm/stat.h @@ -89,6 +89,6 @@ struct stat64 { unsigned long st_ctime_nsec; unsigned long long st_ino; -}; +} __attribute__((packed)); #endif diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 3d0d2860b6db..2f44b2044214 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -85,7 +85,9 @@ struct pt_regs; void die(const char *msg, struct pt_regs *regs, int err) __attribute__((noreturn)); -void die_if_kernel(const char *str, struct pt_regs *regs, int err); +struct siginfo; +void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, + unsigned long err, unsigned long trap); void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), @@ -290,7 +292,6 @@ do { \ }) #ifdef CONFIG_SMP -#error SMP not supported #define smp_mb() mb() #define smp_rmb() rmb() @@ -304,6 +305,8 @@ do { \ #define smp_wmb() barrier() #define smp_read_barrier_depends() do { } while(0) +#endif /* CONFIG_SMP */ + #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) /* * On the StrongARM, "swp" is terminally broken since it bypasses the @@ -316,9 +319,16 @@ do { \ * * We choose (1) since its the "easiest" to achieve here and is not * dependent on the processor type. + * + * NOTE that this solution won't work on an SMP system, so explcitly + * forbid it here. */ +#ifdef CONFIG_SMP +#error SMP is not supported on SA1100/SA110 +#else #define swp_is_buggy #endif +#endif static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) { @@ -361,8 +371,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size return ret; } -#endif /* CONFIG_SMP */ - #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x) diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h index 8a864b118569..9387a5e1ffe0 100644 --- a/include/asm-arm/tlbflush.h +++ b/include/asm-arm/tlbflush.h @@ -235,7 +235,7 @@ extern struct cpu_tlb_fns cpu_tlb; #define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) -static inline void flush_tlb_all(void) +static inline void local_flush_tlb_all(void) { const int zero = 0; const unsigned int __tlb_flag = __cpu_tlb_flags; @@ -253,7 +253,7 @@ static inline void flush_tlb_all(void) asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); } -static inline void flush_tlb_mm(struct mm_struct *mm) +static inline void local_flush_tlb_mm(struct mm_struct *mm) { const int zero = 0; const int asid = ASID(mm); @@ -282,7 +282,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm) } static inline void -flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) { const int zero = 0; const unsigned int __tlb_flag = __cpu_tlb_flags; @@ -313,7 +313,7 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr)); } -static inline void flush_tlb_kernel_page(unsigned long kaddr) +static inline void local_flush_tlb_kernel_page(unsigned long kaddr) { const int zero = 0; const unsigned int __tlb_flag = __cpu_tlb_flags; @@ -384,8 +384,24 @@ static inline void clean_pmd_entry(pmd_t *pmd) /* * Convert calls to our calling convention. */ -#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) -#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) +#define local_flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) +#define local_flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) + +#ifndef CONFIG_SMP +#define flush_tlb_all local_flush_tlb_all +#define flush_tlb_mm local_flush_tlb_mm +#define flush_tlb_page local_flush_tlb_page +#define flush_tlb_kernel_page local_flush_tlb_kernel_page +#define flush_tlb_range local_flush_tlb_range +#define flush_tlb_kernel_range local_flush_tlb_kernel_range +#else +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *mm); +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr); +extern void flush_tlb_kernel_page(unsigned long kaddr); +extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); +#endif /* * if PG_dcache_dirty is set for the page, we need to ensure that any diff --git a/include/asm-arm26/serial.h b/include/asm-arm26/serial.h index 21e1df31f086..5fc747d1b501 100644 --- a/include/asm-arm26/serial.h +++ b/include/asm-arm26/serial.h @@ -30,34 +30,16 @@ #if defined(CONFIG_ARCH_A5K) /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS }, /* ttyS1 */ #else -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS1 */ #endif -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS - #endif diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h index a6a469231f62..b4efe5e3591a 100644 --- a/include/asm-frv/pci.h +++ b/include/asm-frv/pci.h @@ -57,6 +57,16 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, */ #define PCI_DMA_BUS_IS_PHYS (1) +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + /* * These are pretty much arbitary with the CoMEM implementation. * We have the whole address space to ourselves. diff --git a/include/asm-i386/i8253.h b/include/asm-i386/i8253.h new file mode 100644 index 000000000000..015d8df07690 --- /dev/null +++ b/include/asm-i386/i8253.h @@ -0,0 +1,6 @@ +#ifndef __ASM_I8253_H__ +#define __ASM_I8253_H__ + +extern spinlock_t i8253_lock; + +#endif /* __ASM_I8253_H__ */ diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h index 03dd13a48a8c..56211414fc95 100644 --- a/include/asm-i386/mach-default/do_timer.h +++ b/include/asm-i386/mach-default/do_timer.h @@ -1,6 +1,7 @@ /* defines for inline arch setup functions */ #include <asm/apic.h> +#include <asm/i8259.h> /** * do_timer_interrupt_hook - hook into timer tick diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index fb749b85a739..3561899eb826 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h @@ -99,6 +99,16 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev) { } +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + #endif /* __KERNEL__ */ /* implement the pci_ DMA API in terms of the generic device dma_ one */ diff --git a/include/asm-i386/serial.h b/include/asm-i386/serial.h index 21ddecc77c77..e1ecfccb743b 100644 --- a/include/asm-i386/serial.h +++ b/include/asm-i386/serial.h @@ -22,109 +22,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#endif - -#define MCA_COM_FLAGS (STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA) - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS -#endif - -#ifdef CONFIG_MCA -#define MCA_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS }, -#else -#define MCA_SERIAL_PORT_DFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ - MCA_SERIAL_PORT_DFNS - diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h index 38a7a72791cc..1093f35b3b90 100644 --- a/include/asm-ia64/iosapic.h +++ b/include/asm-ia64/iosapic.h @@ -71,8 +71,11 @@ static inline void iosapic_eoi(char __iomem *iosapic, u32 vector) } extern void __init iosapic_system_init (int pcat_compat); -extern void __init iosapic_init (unsigned long address, +extern int __devinit iosapic_init (unsigned long address, unsigned int gsi_base); +#ifdef CONFIG_HOTPLUG +extern int iosapic_remove (unsigned int gsi_base); +#endif /* CONFIG_HOTPLUG */ extern int gsi_to_vector (unsigned int gsi); extern int gsi_to_irq (unsigned int gsi); extern void iosapic_enable_intr (unsigned int vector); @@ -94,11 +97,14 @@ extern unsigned int iosapic_version (char __iomem *addr); extern void iosapic_pci_fixup (int); #ifdef CONFIG_NUMA -extern void __init map_iosapic_to_node (unsigned int, int); +extern void __devinit map_iosapic_to_node (unsigned int, int); #endif #else #define iosapic_system_init(pcat_compat) do { } while (0) -#define iosapic_init(address,gsi_base) do { } while (0) +#define iosapic_init(address,gsi_base) (-EINVAL) +#ifdef CONFIG_HOTPLUG +#define iosapic_remove(gsi_base) (-ENODEV) +#endif /* CONFIG_HOTPLUG */ #define iosapic_register_intr(gsi,polarity,trigger) (gsi) #define iosapic_unregister_intr(irq) do { } while (0) #define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger) do { } while (0) diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h index 0096e7e05012..e3e5fededb04 100644 --- a/include/asm-ia64/mmu_context.h +++ b/include/asm-ia64/mmu_context.h @@ -132,6 +132,9 @@ reload_context (mm_context_t context) ia64_srlz_i(); /* srlz.i implies srlz.d */ } +/* + * Must be called with preemption off + */ static inline void activate_context (struct mm_struct *mm) { diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index a8314ee4e7d2..0c4c5d801d3f 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h @@ -82,6 +82,25 @@ extern int pcibios_prep_mwi (struct pci_dev *); #define sg_dma_len(sg) ((sg)->dma_length) #define sg_dma_address(sg) ((sg)->dma_address) +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_MULTIPLE; + *strategy_parameter = cacheline_size; +} +#endif + #define HAVE_PCI_MMAP extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); diff --git a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h index 1bfdfb4d7b01..103d745dc5f2 100644 --- a/include/asm-ia64/sn/addrs.h +++ b/include/asm-ia64/sn/addrs.h @@ -216,6 +216,10 @@ #define TIO_SWIN_WIDGETNUM(x) (((x) >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK) +#define TIO_IOSPACE_ADDR(n,x) \ + /* Move in the Chiplet ID for TIO Local Block MMR */ \ + (REMOTE_ADDR(n,x) | 1UL << (NASID_SHIFT - 2)) + /* * The following macros produce the correct base virtual address for * the hub registers. The REMOTE_HUB_* macro produce @@ -233,13 +237,16 @@ #define REMOTE_HUB_ADDR(n,x) \ ((n & 1) ? \ /* TIO: */ \ - ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x))) \ - : /* SHUB: */ \ - (((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))\ + (is_shub2() ? \ + /* TIO on Shub2 */ \ + (volatile u64 *)(TIO_IOSPACE_ADDR(n,x)) \ + : /* TIO on shub1 */ \ + (volatile u64 *)(GLOBAL_MMR_ADDR(n,x))) \ + \ + : /* SHUB1 and SHUB2 MMRs: */ \ + (((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x))) \ : ((volatile u64 *)(NODE_SWIN_BASE(n,1) + 0x800000 + (x))))) - - #define HUB_L(x) (*((volatile typeof(*x) *)x)) #define HUB_S(x,d) (*((volatile typeof(*x) *)x) = (d)) diff --git a/include/asm-ia64/sn/l1.h b/include/asm-ia64/sn/l1.h index 08050d37b662..2e5f0aa38889 100644 --- a/include/asm-ia64/sn/l1.h +++ b/include/asm-ia64/sn/l1.h @@ -33,5 +33,6 @@ #define L1_BRICKTYPE_PA 0x6a /* j */ #define L1_BRICKTYPE_IA 0x6b /* k */ #define L1_BRICKTYPE_ATHENA 0x2b /* + */ +#define L1_BRICKTYPE_DAYTONA 0x7a /* z */ #endif /* _ASM_IA64_SN_L1_H */ diff --git a/include/asm-ia64/sn/shub_mmr.h b/include/asm-ia64/sn/shub_mmr.h index 323fa0cd8d83..7de1d1d4b71a 100644 --- a/include/asm-ia64/sn/shub_mmr.h +++ b/include/asm-ia64/sn/shub_mmr.h @@ -14,96 +14,98 @@ /* Register "SH_IPI_INT" */ /* SHub Inter-Processor Interrupt Registers */ /* ==================================================================== */ -#define SH1_IPI_INT 0x0000000110000380 -#define SH2_IPI_INT 0x0000000010000380 +#define SH1_IPI_INT __IA64_UL_CONST(0x0000000110000380) +#define SH2_IPI_INT __IA64_UL_CONST(0x0000000010000380) /* SH_IPI_INT_TYPE */ /* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ -#define SH_IPI_INT_TYPE_SHFT 0 -#define SH_IPI_INT_TYPE_MASK 0x0000000000000007 +#define SH_IPI_INT_TYPE_SHFT 0 +#define SH_IPI_INT_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) /* SH_IPI_INT_AGT */ /* Description: Agent, must be 0 for SHub */ -#define SH_IPI_INT_AGT_SHFT 3 -#define SH_IPI_INT_AGT_MASK 0x0000000000000008 +#define SH_IPI_INT_AGT_SHFT 3 +#define SH_IPI_INT_AGT_MASK __IA64_UL_CONST(0x0000000000000008) /* SH_IPI_INT_PID */ /* Description: Processor ID, same setting as on targeted McKinley */ -#define SH_IPI_INT_PID_SHFT 4 -#define SH_IPI_INT_PID_MASK 0x00000000000ffff0 +#define SH_IPI_INT_PID_SHFT 4 +#define SH_IPI_INT_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) /* SH_IPI_INT_BASE */ /* Description: Optional interrupt vector area, 2MB aligned */ -#define SH_IPI_INT_BASE_SHFT 21 -#define SH_IPI_INT_BASE_MASK 0x0003ffffffe00000 +#define SH_IPI_INT_BASE_SHFT 21 +#define SH_IPI_INT_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) /* SH_IPI_INT_IDX */ /* Description: Targeted McKinley interrupt vector */ -#define SH_IPI_INT_IDX_SHFT 52 -#define SH_IPI_INT_IDX_MASK 0x0ff0000000000000 +#define SH_IPI_INT_IDX_SHFT 52 +#define SH_IPI_INT_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) /* SH_IPI_INT_SEND */ /* Description: Send Interrupt Message to PI, This generates a puls */ -#define SH_IPI_INT_SEND_SHFT 63 -#define SH_IPI_INT_SEND_MASK 0x8000000000000000 +#define SH_IPI_INT_SEND_SHFT 63 +#define SH_IPI_INT_SEND_MASK __IA64_UL_CONST(0x8000000000000000) /* ==================================================================== */ /* Register "SH_EVENT_OCCURRED" */ /* SHub Interrupt Event Occurred */ /* ==================================================================== */ -#define SH1_EVENT_OCCURRED 0x0000000110010000 -#define SH1_EVENT_OCCURRED_ALIAS 0x0000000110010008 -#define SH2_EVENT_OCCURRED 0x0000000010010000 -#define SH2_EVENT_OCCURRED_ALIAS 0x0000000010010008 +#define SH1_EVENT_OCCURRED __IA64_UL_CONST(0x0000000110010000) +#define SH1_EVENT_OCCURRED_ALIAS __IA64_UL_CONST(0x0000000110010008) +#define SH2_EVENT_OCCURRED __IA64_UL_CONST(0x0000000010010000) +#define SH2_EVENT_OCCURRED_ALIAS __IA64_UL_CONST(0x0000000010010008) /* ==================================================================== */ /* Register "SH_PI_CAM_CONTROL" */ /* CRB CAM MMR Access Control */ /* ==================================================================== */ -#define SH1_PI_CAM_CONTROL 0x0000000120050300 +#define SH1_PI_CAM_CONTROL __IA64_UL_CONST(0x0000000120050300) /* ==================================================================== */ /* Register "SH_SHUB_ID" */ /* SHub ID Number */ /* ==================================================================== */ -#define SH1_SHUB_ID 0x0000000110060580 -#define SH1_SHUB_ID_REVISION_SHFT 28 -#define SH1_SHUB_ID_REVISION_MASK 0x00000000f0000000 +#define SH1_SHUB_ID __IA64_UL_CONST(0x0000000110060580) +#define SH1_SHUB_ID_REVISION_SHFT 28 +#define SH1_SHUB_ID_REVISION_MASK __IA64_UL_CONST(0x00000000f0000000) /* ==================================================================== */ /* Register "SH_RTC" */ /* Real-time Clock */ /* ==================================================================== */ -#define SH1_RTC 0x00000001101c0000 -#define SH2_RTC 0x00000002101c0000 -#define SH_RTC_MASK 0x007fffffffffffff +#define SH1_RTC __IA64_UL_CONST(0x00000001101c0000) +#define SH2_RTC __IA64_UL_CONST(0x00000002101c0000) +#define SH_RTC_MASK __IA64_UL_CONST(0x007fffffffffffff) /* ==================================================================== */ /* Register "SH_PIO_WRITE_STATUS_0|1" */ /* PIO Write Status for CPU 0 & 1 */ /* ==================================================================== */ -#define SH1_PIO_WRITE_STATUS_0 0x0000000120070200 -#define SH1_PIO_WRITE_STATUS_1 0x0000000120070280 -#define SH2_PIO_WRITE_STATUS_0 0x0000000020070200 -#define SH2_PIO_WRITE_STATUS_1 0x0000000020070280 -#define SH2_PIO_WRITE_STATUS_2 0x0000000020070300 -#define SH2_PIO_WRITE_STATUS_3 0x0000000020070380 +#define SH1_PIO_WRITE_STATUS_0 __IA64_UL_CONST(0x0000000120070200) +#define SH1_PIO_WRITE_STATUS_1 __IA64_UL_CONST(0x0000000120070280) +#define SH2_PIO_WRITE_STATUS_0 __IA64_UL_CONST(0x0000000020070200) +#define SH2_PIO_WRITE_STATUS_1 __IA64_UL_CONST(0x0000000020070280) +#define SH2_PIO_WRITE_STATUS_2 __IA64_UL_CONST(0x0000000020070300) +#define SH2_PIO_WRITE_STATUS_3 __IA64_UL_CONST(0x0000000020070380) /* SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK */ /* Description: Deadlock response detected */ -#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT 1 -#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK 0x0000000000000002 +#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT 1 +#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK \ + __IA64_UL_CONST(0x0000000000000002) /* SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT */ /* Description: Count of currently pending PIO writes */ -#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT 56 -#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK 0x3f00000000000000 +#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT 56 +#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK \ + __IA64_UL_CONST(0x3f00000000000000) /* ==================================================================== */ /* Register "SH_PIO_WRITE_STATUS_0_ALIAS" */ /* ==================================================================== */ -#define SH1_PIO_WRITE_STATUS_0_ALIAS 0x0000000120070208 -#define SH2_PIO_WRITE_STATUS_0_ALIAS 0x0000000020070208 +#define SH1_PIO_WRITE_STATUS_0_ALIAS __IA64_UL_CONST(0x0000000120070208) +#define SH2_PIO_WRITE_STATUS_0_ALIAS __IA64_UL_CONST(0x0000000020070208) /* ==================================================================== */ /* Register "SH_EVENT_OCCURRED" */ @@ -111,33 +113,33 @@ /* ==================================================================== */ /* SH_EVENT_OCCURRED_UART_INT */ /* Description: Pending Junk Bus UART Interrupt */ -#define SH_EVENT_OCCURRED_UART_INT_SHFT 20 -#define SH_EVENT_OCCURRED_UART_INT_MASK 0x0000000000100000 +#define SH_EVENT_OCCURRED_UART_INT_SHFT 20 +#define SH_EVENT_OCCURRED_UART_INT_MASK __IA64_UL_CONST(0x0000000000100000) /* SH_EVENT_OCCURRED_IPI_INT */ /* Description: Pending IPI Interrupt */ -#define SH_EVENT_OCCURRED_IPI_INT_SHFT 28 -#define SH_EVENT_OCCURRED_IPI_INT_MASK 0x0000000010000000 +#define SH_EVENT_OCCURRED_IPI_INT_SHFT 28 +#define SH_EVENT_OCCURRED_IPI_INT_MASK __IA64_UL_CONST(0x0000000010000000) /* SH_EVENT_OCCURRED_II_INT0 */ /* Description: Pending II 0 Interrupt */ -#define SH_EVENT_OCCURRED_II_INT0_SHFT 29 -#define SH_EVENT_OCCURRED_II_INT0_MASK 0x0000000020000000 +#define SH_EVENT_OCCURRED_II_INT0_SHFT 29 +#define SH_EVENT_OCCURRED_II_INT0_MASK __IA64_UL_CONST(0x0000000020000000) /* SH_EVENT_OCCURRED_II_INT1 */ /* Description: Pending II 1 Interrupt */ -#define SH_EVENT_OCCURRED_II_INT1_SHFT 30 -#define SH_EVENT_OCCURRED_II_INT1_MASK 0x0000000040000000 +#define SH_EVENT_OCCURRED_II_INT1_SHFT 30 +#define SH_EVENT_OCCURRED_II_INT1_MASK __IA64_UL_CONST(0x0000000040000000) /* SH2_EVENT_OCCURRED_EXTIO_INT2 */ /* Description: Pending SHUB 2 EXT IO INT2 */ -#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT 33 -#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK 0x0000000200000000 +#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT 33 +#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK __IA64_UL_CONST(0x0000000200000000) /* SH2_EVENT_OCCURRED_EXTIO_INT3 */ /* Description: Pending SHUB 2 EXT IO INT3 */ -#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT 34 -#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK 0x0000000400000000 +#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT 34 +#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK __IA64_UL_CONST(0x0000000400000000) #define SH_ALL_INT_MASK \ (SH_EVENT_OCCURRED_UART_INT_MASK | SH_EVENT_OCCURRED_IPI_INT_MASK | \ @@ -149,310 +151,310 @@ /* ==================================================================== */ /* LEDS */ /* ==================================================================== */ -#define SH1_REAL_JUNK_BUS_LED0 0x7fed00000UL -#define SH1_REAL_JUNK_BUS_LED1 0x7fed10000UL -#define SH1_REAL_JUNK_BUS_LED2 0x7fed20000UL -#define SH1_REAL_JUNK_BUS_LED3 0x7fed30000UL +#define SH1_REAL_JUNK_BUS_LED0 0x7fed00000UL +#define SH1_REAL_JUNK_BUS_LED1 0x7fed10000UL +#define SH1_REAL_JUNK_BUS_LED2 0x7fed20000UL +#define SH1_REAL_JUNK_BUS_LED3 0x7fed30000UL -#define SH2_REAL_JUNK_BUS_LED0 0xf0000000UL -#define SH2_REAL_JUNK_BUS_LED1 0xf0010000UL -#define SH2_REAL_JUNK_BUS_LED2 0xf0020000UL -#define SH2_REAL_JUNK_BUS_LED3 0xf0030000UL +#define SH2_REAL_JUNK_BUS_LED0 0xf0000000UL +#define SH2_REAL_JUNK_BUS_LED1 0xf0010000UL +#define SH2_REAL_JUNK_BUS_LED2 0xf0020000UL +#define SH2_REAL_JUNK_BUS_LED3 0xf0030000UL /* ==================================================================== */ /* Register "SH1_PTC_0" */ /* Puge Translation Cache Message Configuration Information */ /* ==================================================================== */ -#define SH1_PTC_0 0x00000001101a0000 +#define SH1_PTC_0 __IA64_UL_CONST(0x00000001101a0000) /* SH1_PTC_0_A */ /* Description: Type */ -#define SH1_PTC_0_A_SHFT 0 +#define SH1_PTC_0_A_SHFT 0 /* SH1_PTC_0_PS */ /* Description: Page Size */ -#define SH1_PTC_0_PS_SHFT 2 +#define SH1_PTC_0_PS_SHFT 2 /* SH1_PTC_0_RID */ /* Description: Region ID */ -#define SH1_PTC_0_RID_SHFT 8 +#define SH1_PTC_0_RID_SHFT 8 /* SH1_PTC_0_START */ /* Description: Start */ -#define SH1_PTC_0_START_SHFT 63 +#define SH1_PTC_0_START_SHFT 63 /* ==================================================================== */ /* Register "SH1_PTC_1" */ /* Puge Translation Cache Message Configuration Information */ /* ==================================================================== */ -#define SH1_PTC_1 0x00000001101a0080 +#define SH1_PTC_1 __IA64_UL_CONST(0x00000001101a0080) /* SH1_PTC_1_START */ /* Description: PTC_1 Start */ -#define SH1_PTC_1_START_SHFT 63 - +#define SH1_PTC_1_START_SHFT 63 /* ==================================================================== */ /* Register "SH2_PTC" */ /* Puge Translation Cache Message Configuration Information */ /* ==================================================================== */ -#define SH2_PTC 0x0000000170000000 +#define SH2_PTC __IA64_UL_CONST(0x0000000170000000) /* SH2_PTC_A */ /* Description: Type */ -#define SH2_PTC_A_SHFT 0 +#define SH2_PTC_A_SHFT 0 /* SH2_PTC_PS */ /* Description: Page Size */ -#define SH2_PTC_PS_SHFT 2 +#define SH2_PTC_PS_SHFT 2 /* SH2_PTC_RID */ /* Description: Region ID */ -#define SH2_PTC_RID_SHFT 4 +#define SH2_PTC_RID_SHFT 4 /* SH2_PTC_START */ /* Description: Start */ -#define SH2_PTC_START_SHFT 63 +#define SH2_PTC_START_SHFT 63 /* SH2_PTC_ADDR_RID */ /* Description: Region ID */ -#define SH2_PTC_ADDR_SHFT 4 -#define SH2_PTC_ADDR_MASK 0x1ffffffffffff000 +#define SH2_PTC_ADDR_SHFT 4 +#define SH2_PTC_ADDR_MASK __IA64_UL_CONST(0x1ffffffffffff000) /* ==================================================================== */ /* Register "SH_RTC1_INT_CONFIG" */ /* SHub RTC 1 Interrupt Config Registers */ /* ==================================================================== */ -#define SH1_RTC1_INT_CONFIG 0x0000000110001480 -#define SH2_RTC1_INT_CONFIG 0x0000000010001480 -#define SH_RTC1_INT_CONFIG_MASK 0x0ff3ffffffefffff -#define SH_RTC1_INT_CONFIG_INIT 0x0000000000000000 +#define SH1_RTC1_INT_CONFIG __IA64_UL_CONST(0x0000000110001480) +#define SH2_RTC1_INT_CONFIG __IA64_UL_CONST(0x0000000010001480) +#define SH_RTC1_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC1_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC1_INT_CONFIG_TYPE */ /* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ -#define SH_RTC1_INT_CONFIG_TYPE_SHFT 0 -#define SH_RTC1_INT_CONFIG_TYPE_MASK 0x0000000000000007 +#define SH_RTC1_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC1_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) /* SH_RTC1_INT_CONFIG_AGT */ /* Description: Agent, must be 0 for SHub */ -#define SH_RTC1_INT_CONFIG_AGT_SHFT 3 -#define SH_RTC1_INT_CONFIG_AGT_MASK 0x0000000000000008 +#define SH_RTC1_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC1_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) /* SH_RTC1_INT_CONFIG_PID */ /* Description: Processor ID, same setting as on targeted McKinley */ -#define SH_RTC1_INT_CONFIG_PID_SHFT 4 -#define SH_RTC1_INT_CONFIG_PID_MASK 0x00000000000ffff0 +#define SH_RTC1_INT_CONFIG_PID_SHFT 4 +#define SH_RTC1_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) /* SH_RTC1_INT_CONFIG_BASE */ /* Description: Optional interrupt vector area, 2MB aligned */ -#define SH_RTC1_INT_CONFIG_BASE_SHFT 21 -#define SH_RTC1_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 +#define SH_RTC1_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC1_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) /* SH_RTC1_INT_CONFIG_IDX */ /* Description: Targeted McKinley interrupt vector */ -#define SH_RTC1_INT_CONFIG_IDX_SHFT 52 -#define SH_RTC1_INT_CONFIG_IDX_MASK 0x0ff0000000000000 +#define SH_RTC1_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC1_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) /* ==================================================================== */ /* Register "SH_RTC1_INT_ENABLE" */ /* SHub RTC 1 Interrupt Enable Registers */ /* ==================================================================== */ -#define SH1_RTC1_INT_ENABLE 0x0000000110001500 -#define SH2_RTC1_INT_ENABLE 0x0000000010001500 -#define SH_RTC1_INT_ENABLE_MASK 0x0000000000000001 -#define SH_RTC1_INT_ENABLE_INIT 0x0000000000000000 +#define SH1_RTC1_INT_ENABLE __IA64_UL_CONST(0x0000000110001500) +#define SH2_RTC1_INT_ENABLE __IA64_UL_CONST(0x0000000010001500) +#define SH_RTC1_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC1_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC1_INT_ENABLE_RTC1_ENABLE */ /* Description: Enable RTC 1 Interrupt */ -#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT 0 -#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK 0x0000000000000001 +#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT 0 +#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) /* ==================================================================== */ /* Register "SH_RTC2_INT_CONFIG" */ /* SHub RTC 2 Interrupt Config Registers */ /* ==================================================================== */ -#define SH1_RTC2_INT_CONFIG 0x0000000110001580 -#define SH2_RTC2_INT_CONFIG 0x0000000010001580 -#define SH_RTC2_INT_CONFIG_MASK 0x0ff3ffffffefffff -#define SH_RTC2_INT_CONFIG_INIT 0x0000000000000000 +#define SH1_RTC2_INT_CONFIG __IA64_UL_CONST(0x0000000110001580) +#define SH2_RTC2_INT_CONFIG __IA64_UL_CONST(0x0000000010001580) +#define SH_RTC2_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC2_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC2_INT_CONFIG_TYPE */ /* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ -#define SH_RTC2_INT_CONFIG_TYPE_SHFT 0 -#define SH_RTC2_INT_CONFIG_TYPE_MASK 0x0000000000000007 +#define SH_RTC2_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC2_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) /* SH_RTC2_INT_CONFIG_AGT */ /* Description: Agent, must be 0 for SHub */ -#define SH_RTC2_INT_CONFIG_AGT_SHFT 3 -#define SH_RTC2_INT_CONFIG_AGT_MASK 0x0000000000000008 +#define SH_RTC2_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC2_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) /* SH_RTC2_INT_CONFIG_PID */ /* Description: Processor ID, same setting as on targeted McKinley */ -#define SH_RTC2_INT_CONFIG_PID_SHFT 4 -#define SH_RTC2_INT_CONFIG_PID_MASK 0x00000000000ffff0 +#define SH_RTC2_INT_CONFIG_PID_SHFT 4 +#define SH_RTC2_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) /* SH_RTC2_INT_CONFIG_BASE */ /* Description: Optional interrupt vector area, 2MB aligned */ -#define SH_RTC2_INT_CONFIG_BASE_SHFT 21 -#define SH_RTC2_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 +#define SH_RTC2_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC2_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) /* SH_RTC2_INT_CONFIG_IDX */ /* Description: Targeted McKinley interrupt vector */ -#define SH_RTC2_INT_CONFIG_IDX_SHFT 52 -#define SH_RTC2_INT_CONFIG_IDX_MASK 0x0ff0000000000000 +#define SH_RTC2_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC2_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) /* ==================================================================== */ /* Register "SH_RTC2_INT_ENABLE" */ /* SHub RTC 2 Interrupt Enable Registers */ /* ==================================================================== */ -#define SH1_RTC2_INT_ENABLE 0x0000000110001600 -#define SH2_RTC2_INT_ENABLE 0x0000000010001600 -#define SH_RTC2_INT_ENABLE_MASK 0x0000000000000001 -#define SH_RTC2_INT_ENABLE_INIT 0x0000000000000000 +#define SH1_RTC2_INT_ENABLE __IA64_UL_CONST(0x0000000110001600) +#define SH2_RTC2_INT_ENABLE __IA64_UL_CONST(0x0000000010001600) +#define SH_RTC2_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC2_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC2_INT_ENABLE_RTC2_ENABLE */ /* Description: Enable RTC 2 Interrupt */ -#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT 0 -#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK 0x0000000000000001 +#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT 0 +#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) /* ==================================================================== */ /* Register "SH_RTC3_INT_CONFIG" */ /* SHub RTC 3 Interrupt Config Registers */ /* ==================================================================== */ -#define SH1_RTC3_INT_CONFIG 0x0000000110001680 -#define SH2_RTC3_INT_CONFIG 0x0000000010001680 -#define SH_RTC3_INT_CONFIG_MASK 0x0ff3ffffffefffff -#define SH_RTC3_INT_CONFIG_INIT 0x0000000000000000 +#define SH1_RTC3_INT_CONFIG __IA64_UL_CONST(0x0000000110001680) +#define SH2_RTC3_INT_CONFIG __IA64_UL_CONST(0x0000000010001680) +#define SH_RTC3_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC3_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC3_INT_CONFIG_TYPE */ /* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ -#define SH_RTC3_INT_CONFIG_TYPE_SHFT 0 -#define SH_RTC3_INT_CONFIG_TYPE_MASK 0x0000000000000007 +#define SH_RTC3_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC3_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) /* SH_RTC3_INT_CONFIG_AGT */ /* Description: Agent, must be 0 for SHub */ -#define SH_RTC3_INT_CONFIG_AGT_SHFT 3 -#define SH_RTC3_INT_CONFIG_AGT_MASK 0x0000000000000008 +#define SH_RTC3_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC3_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) /* SH_RTC3_INT_CONFIG_PID */ /* Description: Processor ID, same setting as on targeted McKinley */ -#define SH_RTC3_INT_CONFIG_PID_SHFT 4 -#define SH_RTC3_INT_CONFIG_PID_MASK 0x00000000000ffff0 +#define SH_RTC3_INT_CONFIG_PID_SHFT 4 +#define SH_RTC3_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) /* SH_RTC3_INT_CONFIG_BASE */ /* Description: Optional interrupt vector area, 2MB aligned */ -#define SH_RTC3_INT_CONFIG_BASE_SHFT 21 -#define SH_RTC3_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 +#define SH_RTC3_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC3_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) /* SH_RTC3_INT_CONFIG_IDX */ /* Description: Targeted McKinley interrupt vector */ -#define SH_RTC3_INT_CONFIG_IDX_SHFT 52 -#define SH_RTC3_INT_CONFIG_IDX_MASK 0x0ff0000000000000 +#define SH_RTC3_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC3_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) /* ==================================================================== */ /* Register "SH_RTC3_INT_ENABLE" */ /* SHub RTC 3 Interrupt Enable Registers */ /* ==================================================================== */ -#define SH1_RTC3_INT_ENABLE 0x0000000110001700 -#define SH2_RTC3_INT_ENABLE 0x0000000010001700 -#define SH_RTC3_INT_ENABLE_MASK 0x0000000000000001 -#define SH_RTC3_INT_ENABLE_INIT 0x0000000000000000 +#define SH1_RTC3_INT_ENABLE __IA64_UL_CONST(0x0000000110001700) +#define SH2_RTC3_INT_ENABLE __IA64_UL_CONST(0x0000000010001700) +#define SH_RTC3_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC3_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC3_INT_ENABLE_RTC3_ENABLE */ /* Description: Enable RTC 3 Interrupt */ -#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT 0 -#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK 0x0000000000000001 +#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT 0 +#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) /* SH_EVENT_OCCURRED_RTC1_INT */ /* Description: Pending RTC 1 Interrupt */ -#define SH_EVENT_OCCURRED_RTC1_INT_SHFT 24 -#define SH_EVENT_OCCURRED_RTC1_INT_MASK 0x0000000001000000 +#define SH_EVENT_OCCURRED_RTC1_INT_SHFT 24 +#define SH_EVENT_OCCURRED_RTC1_INT_MASK __IA64_UL_CONST(0x0000000001000000) /* SH_EVENT_OCCURRED_RTC2_INT */ /* Description: Pending RTC 2 Interrupt */ -#define SH_EVENT_OCCURRED_RTC2_INT_SHFT 25 -#define SH_EVENT_OCCURRED_RTC2_INT_MASK 0x0000000002000000 +#define SH_EVENT_OCCURRED_RTC2_INT_SHFT 25 +#define SH_EVENT_OCCURRED_RTC2_INT_MASK __IA64_UL_CONST(0x0000000002000000) /* SH_EVENT_OCCURRED_RTC3_INT */ /* Description: Pending RTC 3 Interrupt */ -#define SH_EVENT_OCCURRED_RTC3_INT_SHFT 26 -#define SH_EVENT_OCCURRED_RTC3_INT_MASK 0x0000000004000000 +#define SH_EVENT_OCCURRED_RTC3_INT_SHFT 26 +#define SH_EVENT_OCCURRED_RTC3_INT_MASK __IA64_UL_CONST(0x0000000004000000) /* ==================================================================== */ /* Register "SH_IPI_ACCESS" */ /* CPU interrupt Access Permission Bits */ /* ==================================================================== */ -#define SH1_IPI_ACCESS 0x0000000110060480 -#define SH2_IPI_ACCESS0 0x0000000010060c00 -#define SH2_IPI_ACCESS1 0x0000000010060c80 -#define SH2_IPI_ACCESS2 0x0000000010060d00 -#define SH2_IPI_ACCESS3 0x0000000010060d80 +#define SH1_IPI_ACCESS __IA64_UL_CONST(0x0000000110060480) +#define SH2_IPI_ACCESS0 __IA64_UL_CONST(0x0000000010060c00) +#define SH2_IPI_ACCESS1 __IA64_UL_CONST(0x0000000010060c80) +#define SH2_IPI_ACCESS2 __IA64_UL_CONST(0x0000000010060d00) +#define SH2_IPI_ACCESS3 __IA64_UL_CONST(0x0000000010060d80) /* ==================================================================== */ /* Register "SH_INT_CMPB" */ /* RTC Compare Value for Processor B */ /* ==================================================================== */ -#define SH1_INT_CMPB 0x00000001101b0080 -#define SH2_INT_CMPB 0x00000000101b0080 -#define SH_INT_CMPB_MASK 0x007fffffffffffff -#define SH_INT_CMPB_INIT 0x0000000000000000 +#define SH1_INT_CMPB __IA64_UL_CONST(0x00000001101b0080) +#define SH2_INT_CMPB __IA64_UL_CONST(0x00000000101b0080) +#define SH_INT_CMPB_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPB_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_INT_CMPB_REAL_TIME_CMPB */ /* Description: Real Time Clock Compare */ -#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT 0 -#define SH_INT_CMPB_REAL_TIME_CMPB_MASK 0x007fffffffffffff +#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT 0 +#define SH_INT_CMPB_REAL_TIME_CMPB_MASK __IA64_UL_CONST(0x007fffffffffffff) /* ==================================================================== */ /* Register "SH_INT_CMPC" */ /* RTC Compare Value for Processor C */ /* ==================================================================== */ -#define SH1_INT_CMPC 0x00000001101b0100 -#define SH2_INT_CMPC 0x00000000101b0100 -#define SH_INT_CMPC_MASK 0x007fffffffffffff -#define SH_INT_CMPC_INIT 0x0000000000000000 +#define SH1_INT_CMPC __IA64_UL_CONST(0x00000001101b0100) +#define SH2_INT_CMPC __IA64_UL_CONST(0x00000000101b0100) +#define SH_INT_CMPC_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPC_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_INT_CMPC_REAL_TIME_CMPC */ /* Description: Real Time Clock Compare */ -#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 -#define SH_INT_CMPC_REAL_TIME_CMPC_MASK 0x007fffffffffffff +#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 +#define SH_INT_CMPC_REAL_TIME_CMPC_MASK __IA64_UL_CONST(0x007fffffffffffff) /* ==================================================================== */ /* Register "SH_INT_CMPD" */ /* RTC Compare Value for Processor D */ /* ==================================================================== */ -#define SH1_INT_CMPD 0x00000001101b0180 -#define SH2_INT_CMPD 0x00000000101b0180 -#define SH_INT_CMPD_MASK 0x007fffffffffffff -#define SH_INT_CMPD_INIT 0x0000000000000000 +#define SH1_INT_CMPD __IA64_UL_CONST(0x00000001101b0180) +#define SH2_INT_CMPD __IA64_UL_CONST(0x00000000101b0180) +#define SH_INT_CMPD_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPD_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_INT_CMPD_REAL_TIME_CMPD */ /* Description: Real Time Clock Compare */ -#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 -#define SH_INT_CMPD_REAL_TIME_CMPD_MASK 0x007fffffffffffff +#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 +#define SH_INT_CMPD_REAL_TIME_CMPD_MASK __IA64_UL_CONST(0x007fffffffffffff) /* ==================================================================== */ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC0" */ /* privilege vector for acc=0 */ /* ==================================================================== */ - -#define SH1_MD_DQLP_MMR_DIR_PRIVEC0 0x0000000100030300 +#define SH1_MD_DQLP_MMR_DIR_PRIVEC0 __IA64_UL_CONST(0x0000000100030300) /* ==================================================================== */ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC0" */ /* privilege vector for acc=0 */ /* ==================================================================== */ - -#define SH1_MD_DQRP_MMR_DIR_PRIVEC0 0x0000000100050300 +#define SH1_MD_DQRP_MMR_DIR_PRIVEC0 __IA64_UL_CONST(0x0000000100050300) /* ==================================================================== */ /* Some MMRs are functionally identical (or close enough) on both SHUB1 */ @@ -484,17 +486,17 @@ /* Engine 0 Control and Status Register */ /* ========================================================================== */ -#define SH2_BT_ENG_CSR_0 0x0000000030040000 -#define SH2_BT_ENG_SRC_ADDR_0 0x0000000030040080 -#define SH2_BT_ENG_DEST_ADDR_0 0x0000000030040100 -#define SH2_BT_ENG_NOTIF_ADDR_0 0x0000000030040180 +#define SH2_BT_ENG_CSR_0 __IA64_UL_CONST(0x0000000030040000) +#define SH2_BT_ENG_SRC_ADDR_0 __IA64_UL_CONST(0x0000000030040080) +#define SH2_BT_ENG_DEST_ADDR_0 __IA64_UL_CONST(0x0000000030040100) +#define SH2_BT_ENG_NOTIF_ADDR_0 __IA64_UL_CONST(0x0000000030040180) /* ========================================================================== */ /* BTE interfaces 1-3 */ /* ========================================================================== */ -#define SH2_BT_ENG_CSR_1 0x0000000030050000 -#define SH2_BT_ENG_CSR_2 0x0000000030060000 -#define SH2_BT_ENG_CSR_3 0x0000000030070000 +#define SH2_BT_ENG_CSR_1 __IA64_UL_CONST(0x0000000030050000) +#define SH2_BT_ENG_CSR_2 __IA64_UL_CONST(0x0000000030060000) +#define SH2_BT_ENG_CSR_3 __IA64_UL_CONST(0x0000000030070000) #endif /* _ASM_IA64_SN_SHUB_MMR_H */ diff --git a/include/asm-ia64/sn/simulator.h b/include/asm-ia64/sn/simulator.h index 78eb4f869c8b..cf770e246af5 100644 --- a/include/asm-ia64/sn/simulator.h +++ b/include/asm-ia64/sn/simulator.h @@ -10,16 +10,17 @@ #include <linux/config.h> -#ifdef CONFIG_IA64_SGI_SN_SIM - #define SNMAGIC 0xaeeeeeee8badbeefL -#define IS_RUNNING_ON_SIMULATOR() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;}) - -#define SIMULATOR_SLEEP() asm("nop.i 0x8beef") +#define IS_MEDUSA() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;}) +#ifdef CONFIG_IA64_SGI_SN_SIM +#define SIMULATOR_SLEEP() asm("nop.i 0x8beef") +#define IS_RUNNING_ON_SIMULATOR() (sn_prom_type) +#define IS_RUNNING_ON_FAKE_PROM() (sn_prom_type == 2) +extern int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ #else - #define IS_RUNNING_ON_SIMULATOR() (0) +#define IS_RUNNING_ON_FAKE_PROM() (0) #define SIMULATOR_SLEEP() #endif diff --git a/include/asm-ia64/sn/sn2/sn_hwperf.h b/include/asm-ia64/sn/sn2/sn_hwperf.h index b0c4d6dd77ba..df75f4c4aec3 100644 --- a/include/asm-ia64/sn/sn2/sn_hwperf.h +++ b/include/asm-ia64/sn/sn2/sn_hwperf.h @@ -223,4 +223,6 @@ struct sn_hwperf_ioctl_args { #define SN_HWPERF_OP_RECONFIGURE 253 #define SN_HWPERF_OP_INVAL 254 +int sn_topology_open(struct inode *inode, struct file *file); +int sn_topology_release(struct inode *inode, struct file *file); #endif /* SN_HWPERF_H */ diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index eb0395ad0d6a..1455375d2ce4 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -132,6 +132,8 @@ #define SALRET_INVALID_ARG (-2) #define SALRET_ERROR (-3) +#define SN_SAL_FAKE_PROM 0x02009999 + /** * sn_sal_rev_major - get the major SGI SAL revision number @@ -1105,4 +1107,12 @@ ia64_sn_bte_recovery(nasid_t nasid) return (int) rv.status; } +static inline int +ia64_sn_is_fake_prom(void) +{ + struct ia64_sal_retval rv; + SAL_CALL_NOLOCK(rv, SN_SAL_FAKE_PROM, 0, 0, 0, 0, 0, 0, 0); + return (rv.status == 0); +} + #endif /* _ASM_IA64_SN_SN_SAL_H */ diff --git a/include/asm-ia64/sn/tioca_provider.h b/include/asm-ia64/sn/tioca_provider.h index b6acc22ab239..5ccec608d325 100644 --- a/include/asm-ia64/sn/tioca_provider.h +++ b/include/asm-ia64/sn/tioca_provider.h @@ -201,6 +201,7 @@ tioca_tlbflush(struct tioca_kernel *tioca_kernel) } extern uint32_t tioca_gart_found; +extern struct list_head tioca_list; extern int tioca_init_provider(void); extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern); #endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */ diff --git a/include/asm-ia64/vga.h b/include/asm-ia64/vga.h index 1f446d6841f6..bc3349ffc505 100644 --- a/include/asm-ia64/vga.h +++ b/include/asm-ia64/vga.h @@ -14,7 +14,10 @@ * videoram directly without any black magic. */ -#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0)) +extern unsigned long vga_console_iobase; +extern unsigned long vga_console_membase; + +#define VGA_MAP_MEM(x) ((unsigned long) ioremap(vga_console_membase + (x), 0)) #define vga_readb(x) (*(x)) #define vga_writeb(x,y) (*(y) = (x)) diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h index 9f5bcdc105fc..3fe29f8b0194 100644 --- a/include/asm-m68k/serial.h +++ b/include/asm-m68k/serial.h @@ -26,54 +26,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#endif - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index c9c576b48556..2d323b6e147d 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -130,6 +130,16 @@ extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction); +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index 8a70ff58f760..4eed8e2acdc3 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -29,32 +29,6 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#define RS_TABLE_SIZE 64 -#else -#define RS_TABLE_SIZE -#endif - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - #ifdef CONFIG_MACH_JAZZ #include <asm/jazz.h> @@ -240,66 +214,10 @@ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else /* CONFIG_SERIAL_MANY_PORTS */ -#define EXTRA_SERIAL_PORT_DEFNS -#endif /* CONFIG_SERIAL_MANY_PORTS */ - #else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */ #define STD_SERIAL_PORT_DEFNS -#define EXTRA_SERIAL_PORT_DEFNS #endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */ -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS -#endif - #ifdef CONFIG_MOMENCO_JAGUAR_ATX /* Ordinary NS16552 duart with a 20MHz crystal. */ #define JAGUAR_ATX_UART_CLK 20000000 @@ -427,8 +345,6 @@ COBALT_SERIAL_PORT_DEFNS \ DDB5477_SERIAL_PORT_DEFNS \ EV96100_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ IP32_SERIAL_PORT_DEFNS \ ITE_SERIAL_PORT_DEFNS \ IVR_SERIAL_PORT_DEFNS \ diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index 0763c2982fb0..ee741c150176 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -230,6 +230,25 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x) /* export the pci_ DMA API in terms of the dma_ one */ #include <asm-generic/pci-dma-compat.h> +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_MULTIPLE; + *strategy_parameter = cacheline_size; +} +#endif + extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); diff --git a/include/asm-parisc/serial.h b/include/asm-parisc/serial.h index 239c5dcab7e6..82fd820d684f 100644 --- a/include/asm-parisc/serial.h +++ b/include/asm-parisc/serial.h @@ -19,18 +19,4 @@ * A500 w/ PCI serial cards: 5 + 4 * card ~= 17 */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, }, /* ttyS0 */ \ - { 0, }, /* ttyS1 */ \ - { 0, }, /* ttyS2 */ \ - { 0, }, /* ttyS3 */ \ - { 0, }, /* ttyS4 */ \ - { 0, }, /* ttyS5 */ \ - { 0, }, /* ttyS6 */ \ - { 0, }, /* ttyS7 */ \ - { 0, }, /* ttyS8 */ - - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS - +#define SERIAL_PORT_DFNS diff --git a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h index 2cafc9978607..a481b772d154 100644 --- a/include/asm-ppc/macio.h +++ b/include/asm-ppc/macio.h @@ -1,6 +1,7 @@ #ifndef __MACIO_ASIC_H__ #define __MACIO_ASIC_H__ +#include <linux/mod_devicetable.h> #include <asm/of_device.h> extern struct bus_type macio_bus_type; @@ -120,10 +121,10 @@ static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev) struct macio_driver { char *name; - struct of_match *match_table; + struct of_device_id *match_table; struct module *owner; - int (*probe)(struct macio_dev* dev, const struct of_match *match); + int (*probe)(struct macio_dev* dev, const struct of_device_id *match); int (*remove)(struct macio_dev* dev); int (*suspend)(struct macio_dev* dev, pm_message_t state); diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h index 714d69c819d3..7c31f2d564a1 100644 --- a/include/asm-ppc/mpc8xx.h +++ b/include/asm-ppc/mpc8xx.h @@ -68,6 +68,10 @@ #include <platforms/lantec.h> #endif +#if defined(CONFIG_MPC885ADS) +#include <platforms/mpc885ads.h> +#endif + /* Currently, all 8xx boards that support a processor to PCI/ISA bridge * use the same memory map. */ diff --git a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h index 7229735a7c18..4b264cfd3998 100644 --- a/include/asm-ppc/of_device.h +++ b/include/asm-ppc/of_device.h @@ -24,20 +24,8 @@ struct of_device }; #define to_of_device(d) container_of(d, struct of_device, dev) -/* - * Struct used for matching a device - */ -struct of_match -{ - char *name; - char *type; - char *compatible; - void *data; -}; -#define OF_ANY_MATCH ((char *)-1L) - -extern const struct of_match *of_match_device( - const struct of_match *matches, const struct of_device *dev); +extern const struct of_device_id *of_match_device( + const struct of_device_id *matches, const struct of_device *dev); extern struct of_device *of_dev_get(struct of_device *dev); extern void of_dev_put(struct of_device *dev); @@ -49,10 +37,10 @@ extern void of_dev_put(struct of_device *dev); struct of_platform_driver { char *name; - struct of_match *match_table; + struct of_device_id *match_table; struct module *owner; - int (*probe)(struct of_device* dev, const struct of_match *match); + int (*probe)(struct of_device* dev, const struct of_device_id *match); int (*remove)(struct of_device* dev); int (*suspend)(struct of_device* dev, pm_message_t state); diff --git a/include/asm-ppc/pc_serial.h b/include/asm-ppc/pc_serial.h index fa9cbb67ce3e..8f994f9f8857 100644 --- a/include/asm-ppc/pc_serial.h +++ b/include/asm-ppc/pc_serial.h @@ -35,93 +35,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#endif - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index ce5ae6d048f5..db0a2a0ec74d 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -69,6 +69,16 @@ extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr); #define pci_unmap_len(PTR, LEN_NAME) (0) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + /* * At present there are very few 32-bit PPC machines that can have * memory above the 4GB point, and we don't support that. @@ -103,6 +113,12 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, unsigned long size, pgprot_t prot); +#define HAVE_ARCH_PCI_RESOURCE_TO_USER +extern void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end); + + #endif /* __KERNEL__ */ #endif /* __PPC_PCI_H */ diff --git a/include/asm-ppc64/byteorder.h b/include/asm-ppc64/byteorder.h index 80327532de64..8b57da62b674 100644 --- a/include/asm-ppc64/byteorder.h +++ b/include/asm-ppc64/byteorder.h @@ -40,7 +40,6 @@ static __inline__ void st_le32(volatile __u32 *addr, const __u32 val) __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -#if 0 static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) { __u16 result; @@ -63,17 +62,8 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) return result; } -static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value) -{ - __u64 result; -#error implement me -} - #define __arch__swab16(x) ___arch__swab16(x) #define __arch__swab32(x) ___arch__swab32(x) -#define __arch__swab64(x) ___arch__swab64(x) - -#endif /* The same, but returns converted value from the location pointer by addr. */ #define __arch__swab16p(addr) ld_le16(addr) diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index 393299e04d7f..69b26ad74135 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -41,7 +41,7 @@ struct HvLpEvent; #define LpEventMaxSize 256 #define LpEventAlign 64 -struct ItLpQueue { +struct hvlpevent_queue { /* * The xSlicCurEventPtr is the pointer to the next event stack entry * that will become valid. The OS must peek at this entry to determine @@ -69,16 +69,13 @@ struct ItLpQueue { char *xSlicEventStackPtr; // 0x20 u8 xIndex; // 0x28 unique sequential index. u8 xSlicRsvd[3]; // 0x29-2b - u32 xInUseWord; // 0x2C - u64 xLpIntCount; // 0x30 Total Lp Int msgs processed - u64 xLpIntCountByType[9]; // 0x38-0x7F Event counts by type + spinlock_t lock; }; -extern struct ItLpQueue xItLpQueue; +extern struct hvlpevent_queue hvlpevent_queue; -extern struct HvLpEvent *ItLpQueue_getNextLpEvent(struct ItLpQueue *); -extern int ItLpQueue_isLpIntPending(struct ItLpQueue *); -extern unsigned ItLpQueue_process(struct ItLpQueue *, struct pt_regs *); -extern void ItLpQueue_clearValid(struct HvLpEvent *); +extern int hvlpevent_is_pending(void); +extern void process_hvlpevents(struct pt_regs *); +extern void setup_hvlpevent_queue(void); #endif /* _ITLPQUEUE_H */ diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h index ae76cae1483f..2f0f36f73d38 100644 --- a/include/asm-ppc64/paca.h +++ b/include/asm-ppc64/paca.h @@ -20,7 +20,6 @@ #include <asm/types.h> #include <asm/lppaca.h> #include <asm/iSeries/ItLpRegSave.h> -#include <asm/iSeries/ItLpQueue.h> #include <asm/mmu.h> register struct paca_struct *local_paca asm("r13"); @@ -62,7 +61,6 @@ struct paca_struct { u16 paca_index; /* Logical processor number */ u32 default_decr; /* Default decrementer value */ - struct ItLpQueue *lpqueue_ptr; /* LpQueue handled by this CPU */ u64 kernel_toc; /* Kernel TOC address */ u64 stab_real; /* Absolute address of segment table */ u64 stab_addr; /* Virtual address of segment table */ @@ -91,7 +89,6 @@ struct paca_struct { u64 next_jiffy_update_tb; /* TB value for next jiffy update */ u64 saved_r1; /* r1 save for RTAS calls */ u64 saved_msr; /* MSR saved here by enter_rtas */ - u32 lpevent_count; /* lpevents processed */ u8 proc_enabled; /* irq soft-enable flag */ /* not yet used */ diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h index 6cd593f660a0..d12dfce21e20 100644 --- a/include/asm-ppc64/pci.h +++ b/include/asm-ppc64/pci.h @@ -78,6 +78,25 @@ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) return 0; } +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_MULTIPLE; + *strategy_parameter = cacheline_size; +} +#endif + extern int pci_domain_nr(struct pci_bus *bus); /* Decide whether to display the domain number in /proc */ @@ -136,6 +155,13 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, unsigned long size, pgprot_t prot); +#ifdef CONFIG_PPC_MULTIPLATFORM +#define HAVE_ARCH_PCI_RESOURCE_TO_USER +extern void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end); +#endif /* CONFIG_PPC_MULTIPLATFORM */ + #endif /* __KERNEL__ */ diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index b4a9f05a93d6..864cae7e1fd6 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -107,11 +107,9 @@ static inline void restore_access_regs(unsigned int *acrs) #ifdef CONFIG_VIRT_CPU_ACCOUNTING extern void account_user_vtime(struct task_struct *); extern void account_system_vtime(struct task_struct *); -#else -#define account_system_vtime(prev) do { } while (0) #endif -#define finish_arch_switch(rq, prev) do { \ +#define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ account_system_vtime(prev); \ } while (0) diff --git a/include/asm-sh/bigsur/serial.h b/include/asm-sh/bigsur/serial.h index 540f12205923..7233af42f755 100644 --- a/include/asm-sh/bigsur/serial.h +++ b/include/asm-sh/bigsur/serial.h @@ -14,13 +14,10 @@ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */ - -#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS - /* XXX: This should be moved ino irq.h */ #define irq_cannonicalize(x) (x) diff --git a/include/asm-sh/ec3104/serial.h b/include/asm-sh/ec3104/serial.h index f8eb16312ed9..cfe4d78ec1ee 100644 --- a/include/asm-sh/ec3104/serial.h +++ b/include/asm-sh/ec3104/serial.h @@ -10,13 +10,11 @@ * it's got the keyboard controller behind it so we can't really use it * (without moving the keyboard driver to userspace, which doesn't sound * like a very good idea) */ -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x11C00, EC3104_IRQBASE+7, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x12000, EC3104_IRQBASE+8, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x12400, EC3104_IRQBASE+9, STD_COM_FLAGS }, /* ttyS2 */ -#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS - /* XXX: This should be moved ino irq.h */ #define irq_cannonicalize(x) (x) diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h index 9c3b63d0105e..26044889c770 100644 --- a/include/asm-sh/pci.h +++ b/include/asm-sh/pci.h @@ -96,6 +96,16 @@ static inline void pcibios_penalize_isa_irq(int irq) #define sg_dma_address(sg) (virt_to_bus((sg)->dma_address)) #define sg_dma_len(sg) ((sg)->length) +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + /* Board-specific fixup routines. */ extern void pcibios_fixup(void); extern void pcibios_fixup_irqs(void); diff --git a/include/asm-sh/serial.h b/include/asm-sh/serial.h index 5474dbdbaa86..f51e232d5cd9 100644 --- a/include/asm-sh/serial.h +++ b/include/asm-sh/serial.h @@ -29,20 +29,18 @@ #ifdef CONFIG_HD64465 #include <asm/hd64465.h> -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */ #else -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS } /* ttyS1 */ #endif -#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS - #endif #endif /* _ASM_SERIAL_H */ diff --git a/include/asm-sh64/pci.h b/include/asm-sh64/pci.h index 8cc14e139750..c68870e02d91 100644 --- a/include/asm-sh64/pci.h +++ b/include/asm-sh64/pci.h @@ -86,6 +86,16 @@ static inline void pcibios_penalize_isa_irq(int irq) #define sg_dma_address(sg) ((sg)->dma_address) #define sg_dma_len(sg) ((sg)->length) +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + /* Board-specific fixup routines. */ extern void pcibios_fixup(void); extern void pcibios_fixup_irqs(void); diff --git a/include/asm-sh64/serial.h b/include/asm-sh64/serial.h index 8e39b4e90c76..29c9be15112b 100644 --- a/include/asm-sh64/serial.h +++ b/include/asm-sh64/serial.h @@ -20,13 +20,11 @@ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS } /* ttyS1 */ -#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS - /* XXX: This should be moved ino irq.h */ #define irq_cannonicalize(x) (x) diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h index d200a25a7373..44bb38758c96 100644 --- a/include/asm-sparc/pci.h +++ b/include/asm-sparc/pci.h @@ -144,6 +144,16 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) #define pci_dac_dma_supported(dev, mask) (0) +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + static inline void pcibios_add_platform_entries(struct pci_dev *dev) { } diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 018e2e46082b..8b70edcb80dc 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -16,6 +16,18 @@ #include <asm/pil.h> #include <asm/ptrace.h> +struct ino_bucket; + +#define MAX_IRQ_DESC_ACTION 4 + +struct irq_desc { + void (*pre_handler)(struct ino_bucket *, void *, void *); + void *pre_handler_arg1; + void *pre_handler_arg2; + u32 action_active_mask; + struct irqaction action[MAX_IRQ_DESC_ACTION]; +}; + /* You should not mess with this directly. That's the job of irq.c. * * If you make changes here, please update hand coded assembler of @@ -42,24 +54,11 @@ struct ino_bucket { /* Miscellaneous flags. */ /*0x06*/unsigned char flags; - /* This is used to deal with IBF_DMA_SYNC on - * Sabre systems. - */ -/*0x07*/unsigned char synctab_ent; - - /* Reference to handler for this IRQ. If this is - * non-NULL this means it is active and should be - * serviced. Else the pending member is set to one - * and later registry of the interrupt checks for - * this condition. - * - * Normally this is just an irq_action structure. - * But, on PCI, if multiple interrupt sources behind - * a bridge have multiple interrupt sources that share - * the same INO bucket, this points to an array of - * pointers to four IRQ action structures. - */ -/*0x08*/void *irq_info; + /* Currently unused. */ +/*0x07*/unsigned char __pad; + + /* Reference to IRQ descriptor for this bucket. */ +/*0x08*/struct irq_desc *irq_info; /* Sun5 Interrupt Clear Register. */ /*0x10*/unsigned long iclr; @@ -69,12 +68,6 @@ struct ino_bucket { }; -#ifdef CONFIG_PCI -extern unsigned long pci_dma_wsync; -extern unsigned long dma_sync_reg_table[256]; -extern unsigned char dma_sync_reg_table_entry; -#endif - /* IMAP/ICLR register defines */ #define IMAP_VALID 0x80000000 /* IRQ Enabled */ #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ @@ -90,11 +83,9 @@ extern unsigned char dma_sync_reg_table_entry; #define ICLR_PENDING 0x00000003 /* Pending state */ /* Only 8-bits are available, be careful. -DaveM */ -#define IBF_DMA_SYNC 0x01 /* DMA synchronization behind PCI bridge needed. */ -#define IBF_PCI 0x02 /* Indicates PSYCHO/SABRE/SCHIZO PCI interrupt. */ -#define IBF_ACTIVE 0x04 /* This interrupt is active and has a handler. */ -#define IBF_MULTI 0x08 /* On PCI, indicates shared bucket. */ -#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */ +#define IBF_PCI 0x02 /* PSYCHO/SABRE/SCHIZO PCI interrupt. */ +#define IBF_ACTIVE 0x04 /* Interrupt is active and has a handler.*/ +#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */ #define NUM_IVECS (IMAP_INR + 1) extern struct ino_bucket ivector_table[NUM_IVECS]; diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h index b7e635544cec..56b5197d7898 100644 --- a/include/asm-sparc64/parport.h +++ b/include/asm-sparc64/parport.h @@ -27,12 +27,12 @@ static struct sparc_ebus_info { static __inline__ void enable_dma(unsigned int dmanr) { + ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1); + if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info, sparc_ebus_dmas[dmanr].addr, sparc_ebus_dmas[dmanr].count)) BUG(); - - ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1); } static __inline__ void disable_dma(unsigned int dmanr) diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index 4c15610a2bac..38bbbccb4068 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h @@ -145,6 +145,9 @@ struct pci_pbm_info { /* Physical address base of PBM registers. */ unsigned long pbm_regs; + /* Physical address of DMA sync register, if any. */ + unsigned long sync_reg; + /* Opaque 32-bit system bus Port ID. */ u32 portid; diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 2a0c85cd1c11..84e41c1ef3f8 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h @@ -220,6 +220,25 @@ static inline int pci_dma_mapping_error(dma_addr_t dma_addr) return (dma_addr == PCI_DMA_ERROR_CODE); } +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_BOUNDARY; + *strategy_parameter = cacheline_size; +} +#endif + /* Return the index of the PCI controller for device PDEV. */ extern int pci_domain_nr(struct pci_bus *bus); diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h index becdf1bc5924..e3059bb4a465 100644 --- a/include/asm-sparc64/signal.h +++ b/include/asm-sparc64/signal.h @@ -162,21 +162,6 @@ struct sigstack { #define MINSIGSTKSZ 4096 #define SIGSTKSZ 16384 -#ifdef __KERNEL__ -/* - * DJHR - * SA_STATIC_ALLOC is used for the SPARC system to indicate that this - * interrupt handler's irq structure should be statically allocated - * by the request_irq routine. - * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge - * of interrupt usage and that sucks. Also without a flag like this - * it may be possible for the free_irq routine to attempt to free - * statically allocated data.. which is NOT GOOD. - * - */ -#define SA_STATIC_ALLOC 0x80 -#endif - #include <asm-generic/signal.h> struct __new_sigaction { diff --git a/include/asm-v850/pci.h b/include/asm-v850/pci.h index e41941447b49..8e79be0fe99d 100644 --- a/include/asm-v850/pci.h +++ b/include/asm-v850/pci.h @@ -81,6 +81,16 @@ extern void pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr, dma_addr_t dma_addr); +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + static inline void pcibios_add_platform_entries(struct pci_dev *dev) { } diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h index 32573749004c..a8babd2bbe84 100644 --- a/include/asm-x86_64/io_apic.h +++ b/include/asm-x86_64/io_apic.h @@ -217,4 +217,6 @@ extern int assign_irq_vector(int irq); void enable_NMI_through_LVT0 (void * dummy); +extern spinlock_t i8259A_lock; + #endif diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h index 8712520ca47f..c1961db88fac 100644 --- a/include/asm-x86_64/pci.h +++ b/include/asm-x86_64/pci.h @@ -123,6 +123,16 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, flush_write_buffers(); } +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + #define HAVE_PCI_MMAP extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); diff --git a/include/asm-x86_64/serial.h b/include/asm-x86_64/serial.h index dbab232044cd..dc752eafa681 100644 --- a/include/asm-x86_64/serial.h +++ b/include/asm-x86_64/serial.h @@ -22,109 +22,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#endif - -#define MCA_COM_FLAGS (STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA) - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS -#endif - -#ifdef CONFIG_MCA -#define MCA_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS }, -#else -#define MCA_SERIAL_PORT_DFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ - MCA_SERIAL_PORT_DFNS - diff --git a/include/asm-xtensa/delay.h b/include/asm-xtensa/delay.h index 6359c55e77a8..0a123d53a636 100644 --- a/include/asm-xtensa/delay.h +++ b/include/asm-xtensa/delay.h @@ -21,7 +21,7 @@ extern unsigned long loops_per_jiffy; extern __inline__ void __delay(unsigned long loops) { /* 2 cycles per loop. */ - __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 1, 1b" + __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" : "=r" (loops) : "0" (loops)); } diff --git a/include/asm-xtensa/errno.h b/include/asm-xtensa/errno.h index ced5194d2750..a0f3b96b79b4 100644 --- a/include/asm-xtensa/errno.h +++ b/include/asm-xtensa/errno.h @@ -11,132 +11,6 @@ #ifndef _XTENSA_ERRNO_H #define _XTENSA_ERRNO_H -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ -#define EDEADLK 35 /* Resource deadlock would occur */ -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOLCK 37 /* No record locks available */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ -#define ELOOP 40 /* Too many symbolic links encountered */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define ENOMSG 42 /* No message of desired type */ -#define EIDRM 43 /* Identifier removed */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ - -#define EDEADLOCK EDEADLK - -#define EBFONT 59 /* Bad font file format */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data available */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* Object is remote */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EBADMSG 74 /* Not a data message */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define EILSEQ 84 /* Illegal byte sequence */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ -#define EUSERS 87 /* Too many users */ -#define ENOTSOCK 88 /* Socket operation on non-socket */ -#define EDESTADDRREQ 89 /* Destination address required */ -#define EMSGSIZE 90 /* Message too long */ -#define EPROTOTYPE 91 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EPROTONOSUPPORT 93 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ENETRESET 102 /* Network dropped connection because of reset */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EISCONN 106 /* Transport endpoint is already connected */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ -#define ETOOMANYREFS 109 /* Too many references: cannot splice */ -#define ETIMEDOUT 110 /* Connection timed out */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EHOSTDOWN 112 /* Host is down */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ESTALE 116 /* Stale NFS file handle */ -#define EUCLEAN 117 /* Structure needs cleaning */ -#define ENOTNAM 118 /* Not a XENIX named type file */ -#define ENAVAIL 119 /* No XENIX semaphores available */ -#define EISNAM 120 /* Is a named type file */ -#define EREMOTEIO 121 /* Remote I/O error */ -#define EDQUOT 122 /* Quota exceeded */ - -#define ENOMEDIUM 123 /* No medium found */ -#define EMEDIUMTYPE 124 /* Wrong medium type */ +#include <asm-generic/errno.h> #endif /* _XTENSA_ERRNO_H */ diff --git a/include/asm-xtensa/ipc.h b/include/asm-xtensa/ipc.h index d37bdb4d4c9c..a9eed4e21cb9 100644 --- a/include/asm-xtensa/ipc.h +++ b/include/asm-xtensa/ipc.h @@ -11,24 +11,6 @@ #ifndef _XTENSA_IPC_H #define _XTENSA_IPC_H -struct ipc_kludge { - struct msgbuf __user *msgp; - long msgtyp; -}; - -#define SEMOP 1 -#define SEMGET 2 -#define SEMCTL 3 -#define SEMTIMEDOP 4 -#define MSGSND 11 -#define MSGRCV 12 -#define MSGGET 13 -#define MSGCTL 14 -#define SHMAT 21 -#define SHMDT 22 -#define SHMGET 23 -#define SHMCTL 24 - -#define IPCCALL(version,op) ((version)<<16 | (op)) +#include <asm-generic/ipc.h> #endif /* _XTENSA_IPC_H */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b123cc08773d..ef8483673aa3 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -342,11 +342,19 @@ struct acpi_table_ecdt { /* PCI MMCONFIG */ +/* Defined in PCI Firmware Specification 3.0 */ +struct acpi_table_mcfg_config { + u32 base_address; + u32 base_reserved; + u16 pci_segment_group_number; + u8 start_bus_number; + u8 end_bus_number; + u8 reserved[4]; +} __attribute__ ((packed)); struct acpi_table_mcfg { struct acpi_table_header header; u8 reserved[8]; - u32 base_address; - u32 base_reserved; + struct acpi_table_mcfg_config config[0]; } __attribute__ ((packed)); /* Table Handlers */ @@ -391,6 +399,7 @@ int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler); int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); +int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size); void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); void acpi_table_print_madt_entry (acpi_table_entry_header *madt); void acpi_table_print_srat_entry (acpi_table_entry_header *srat); @@ -407,9 +416,13 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu); int acpi_unmap_lsapic(int cpu); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); +int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); + extern int acpi_mp_config; -extern u32 pci_mmcfg_base_addr; +extern struct acpi_table_mcfg_config *pci_mmcfg_config; +extern int pci_mmcfg_config_num; extern int sbf_port ; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 21a8674cd149..0881b5cdee3d 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -96,6 +96,7 @@ struct io_context { void put_io_context(struct io_context *ioc); void exit_io_context(void); +struct io_context *current_io_context(int gfp_flags); struct io_context *get_io_context(int gfp_flags); void copy_io_context(struct io_context **pdst, struct io_context **psrc); void swap_io_context(struct io_context **ioc1, struct io_context **ioc2); diff --git a/include/linux/byteorder/swabb.h b/include/linux/byteorder/swabb.h index d28d9a804d3b..d5f2a3205109 100644 --- a/include/linux/byteorder/swabb.h +++ b/include/linux/byteorder/swabb.h @@ -92,29 +92,32 @@ #endif /* OPTIMIZE */ -static __inline__ __const__ __u32 __fswahw32(__u32 x) +static inline __u32 __fswahw32(__u32 x) { return __arch__swahw32(x); } -static __inline__ __u32 __swahw32p(__u32 *x) + +static inline __u32 __swahw32p(__u32 *x) { return __arch__swahw32p(x); } -static __inline__ void __swahw32s(__u32 *addr) + +static inline void __swahw32s(__u32 *addr) { __arch__swahw32s(addr); } - -static __inline__ __const__ __u32 __fswahb32(__u32 x) +static inline __u32 __fswahb32(__u32 x) { return __arch__swahb32(x); } -static __inline__ __u32 __swahb32p(__u32 *x) + +static inline __u32 __swahb32p(__u32 *x) { return __arch__swahb32p(x); } -static __inline__ void __swahb32s(__u32 *addr) + +static inline void __swahb32s(__u32 *addr) { __arch__swahb32s(addr); } diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index 70a4ebb5d964..ecb0d39c0798 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h @@ -346,10 +346,27 @@ COMPATIBLE_IOCTL(PPPOEIOCDFWD) /* LP */ COMPATIBLE_IOCTL(LPGETSTATUS) /* ppdev */ +COMPATIBLE_IOCTL(PPSETMODE) +COMPATIBLE_IOCTL(PPRSTATUS) +COMPATIBLE_IOCTL(PPRCONTROL) +COMPATIBLE_IOCTL(PPWCONTROL) +COMPATIBLE_IOCTL(PPFCONTROL) +COMPATIBLE_IOCTL(PPRDATA) +COMPATIBLE_IOCTL(PPWDATA) COMPATIBLE_IOCTL(PPCLAIM) COMPATIBLE_IOCTL(PPRELEASE) -COMPATIBLE_IOCTL(PPEXCL) COMPATIBLE_IOCTL(PPYIELD) +COMPATIBLE_IOCTL(PPEXCL) +COMPATIBLE_IOCTL(PPDATADIR) +COMPATIBLE_IOCTL(PPNEGOT) +COMPATIBLE_IOCTL(PPWCTLONIRQ) +COMPATIBLE_IOCTL(PPCLRIRQ) +COMPATIBLE_IOCTL(PPSETPHASE) +COMPATIBLE_IOCTL(PPGETMODES) +COMPATIBLE_IOCTL(PPGETMODE) +COMPATIBLE_IOCTL(PPGETPHASE) +COMPATIBLE_IOCTL(PPGETFLAGS) +COMPATIBLE_IOCTL(PPSETFLAGS) /* CDROM stuff */ COMPATIBLE_IOCTL(CDROMPAUSE) COMPATIBLE_IOCTL(CDROMRESUME) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 387da6a3e58c..5e2bcc636a02 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -61,6 +61,15 @@ #define CRYPTO_DIR_DECRYPT 0 struct scatterlist; +struct crypto_tfm; + +struct cipher_desc { + struct crypto_tfm *tfm; + void (*crfn)(void *ctx, u8 *dst, const u8 *src); + unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst, + const u8 *src, unsigned int nbytes); + void *info; +}; /* * Algorithms: modular crypto algorithm implementations, managed @@ -73,6 +82,19 @@ struct cipher_alg { unsigned int keylen, u32 *flags); void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); + + unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); }; struct digest_alg { @@ -102,6 +124,7 @@ struct crypto_alg { u32 cra_flags; unsigned int cra_blocksize; unsigned int cra_ctxsize; + unsigned int cra_alignmask; const char cra_name[CRYPTO_MAX_ALG_NAME]; union { @@ -136,7 +159,6 @@ static inline int crypto_alg_available(const char *name, u32 flags) * and core processing logic. Managed via crypto_alloc_tfm() and * crypto_free_tfm(), as well as the various helpers below. */ -struct crypto_tfm; struct cipher_tfm { void *cit_iv; @@ -266,6 +288,16 @@ static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) return tfm->__crt_alg->cra_digest.dia_digestsize; } +static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm) +{ + return tfm->__crt_alg->cra_alignmask; +} + +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) +{ + return (void *)&tfm[1]; +} + /* * API wrappers. */ diff --git a/include/linux/device.h b/include/linux/device.h index 7b781a72b293..f378c846e6d5 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -69,7 +69,7 @@ struct bus_type { extern int bus_register(struct bus_type * bus); extern void bus_unregister(struct bus_type * bus); -extern int bus_rescan_devices(struct bus_type * bus); +extern void bus_rescan_devices(struct bus_type * bus); extern struct bus_type * get_bus(struct bus_type * bus); extern void put_bus(struct bus_type * bus); @@ -80,6 +80,8 @@ extern struct bus_type * find_bus(char * name); int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, int (*fn)(struct device *, void *)); +struct device * bus_find_device(struct bus_type *bus, struct device *start, + void *data, int (*match)(struct device *, void *)); int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, void * data, int (*fn)(struct device_driver *, void *)); @@ -142,6 +144,9 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute * extern int driver_for_each_device(struct device_driver * drv, struct device * start, void * data, int (*fn)(struct device *, void *)); +struct device * driver_find_device(struct device_driver *drv, + struct device *start, void *data, + int (*match)(struct device *, void *)); /* diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index a1478258d002..cf3847edc50f 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -25,6 +25,7 @@ #define _LINUX_ETHERDEVICE_H #include <linux/if_ether.h> +#include <linux/netdevice.h> #include <linux/random.h> #ifdef __KERNEL__ @@ -65,7 +66,7 @@ static inline int is_zero_ether_addr(const u8 *addr) */ static inline int is_multicast_ether_addr(const u8 *addr) { - return addr[0] & 0x01; + return ((addr[0] != 0xff) && (0x01 & addr[0])); } /** diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h index d228230ffe5d..541695679762 100644 --- a/include/linux/i2c-dev.h +++ b/include/linux/i2c-dev.h @@ -25,6 +25,7 @@ #define _LINUX_I2C_DEV_H #include <linux/types.h> +#include <linux/compiler.h> /* Some IOCTL commands are defined in <linux/i2c.h> */ /* Note: 10-bit addresses are NOT supported! */ diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index 004e6f09a6e2..68c896a36a34 100644 --- a/include/linux/if_shaper.h +++ b/include/linux/if_shaper.h @@ -23,7 +23,7 @@ struct shaper __u32 shapeclock; unsigned long recovery; /* Time we can next clock a packet out on an empty queue */ - struct semaphore sem; + spinlock_t lock; struct net_device_stats stats; struct net_device *dev; int (*hard_start_xmit) (struct sk_buff *skb, diff --git a/include/linux/in6.h b/include/linux/in6.h index f8256c582845..dcf5720ffcbb 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -156,7 +156,7 @@ struct in6_flowlabel_req #define IPV6_CHECKSUM 7 #define IPV6_HOPLIMIT 8 #define IPV6_NEXTHOP 9 -#define IPV6_AUTHHDR 10 +#define IPV6_AUTHHDR 10 /* obsolete */ #define IPV6_FLOWINFO 11 #define IPV6_UNICAST_HOPS 16 diff --git a/include/linux/irq.h b/include/linux/irq.h index 12277799c007..069d3b84d311 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -85,9 +85,10 @@ extern int no_irq_affinity; extern int noirqdebug_setup(char *str); extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, - struct irqaction *action); + struct irqaction *action); extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); -extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret); +extern void note_interrupt(unsigned int irq, irq_desc_t *desc, + int action_ret, struct pt_regs *regs); extern int can_request_irq(unsigned int irq, unsigned long irqflags); extern void init_irq_proc(void); diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index b7a194c4362a..e050fc2d4c26 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -155,7 +155,7 @@ extern void arch_copy_kprobe(struct kprobe *p); extern void arch_arm_kprobe(struct kprobe *p); extern void arch_disarm_kprobe(struct kprobe *p); extern void arch_remove_kprobe(struct kprobe *p); -extern int arch_init(void); +extern int arch_init_kprobes(void); extern void show_registers(struct pt_regs *regs); extern kprobe_opcode_t *get_insn_slot(void); extern void free_insn_slot(kprobe_opcode_t *slot); diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 9b6d05172ed4..dce53ac1625d 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -174,6 +174,17 @@ struct serio_device_id { __u8 proto; }; +/* + * Struct used for matching a device + */ +struct of_device_id +{ + char name[32]; + char type[32]; + char compatible[128]; + void *data; +}; + /* PCMCIA */ diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 3029cad63a01..27e4d164a108 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -168,6 +168,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags) nlh->nlmsg_flags = flags; nlh->nlmsg_pid = pid; nlh->nlmsg_seq = seq; + memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size); return nlh; } diff --git a/include/linux/pci-dynids.h b/include/linux/pci-dynids.h deleted file mode 100644 index 183b6b0de81c..000000000000 --- a/include/linux/pci-dynids.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * PCI defines and function prototypes - * Copyright 2003 Dell Inc. - * by Matt Domsch <Matt_Domsch@dell.com> - */ - -#ifndef LINUX_PCI_DYNIDS_H -#define LINUX_PCI_DYNIDS_H - -#include <linux/list.h> -#include <linux/mod_devicetable.h> - -struct dynid { - struct list_head node; - struct pci_device_id id; -}; - -#endif diff --git a/include/linux/pci.h b/include/linux/pci.h index b5238bd18830..7ac14961ba22 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -586,7 +586,7 @@ struct pci_dev { #define PCI_NUM_RESOURCES 11 #ifndef PCI_BUS_NUM_RESOURCES -#define PCI_BUS_NUM_RESOURCES 4 +#define PCI_BUS_NUM_RESOURCES 8 #endif #define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */ @@ -734,16 +734,20 @@ void pcibios_update_irq(struct pci_dev *, int irq); /* Generic PCI functions used internally */ extern struct pci_bus *pci_find_bus(int domain, int busnr); +void pci_bus_add_devices(struct pci_bus *bus); struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) { - return pci_scan_bus_parented(NULL, bus, ops, sysdata); + struct pci_bus *root_bus; + root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); + if (root_bus) + pci_bus_add_devices(root_bus); + return root_bus; } int pci_scan_slot(struct pci_bus *bus, int devfn); struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); unsigned int pci_scan_child_bus(struct pci_bus *bus); void pci_bus_add_device(struct pci_dev *dev); -void pci_bus_add_devices(struct pci_bus *bus); void pci_name_device(struct pci_dev *dev); char *pci_class_name(u32 class); void pci_read_bridge_bases(struct pci_bus *child); @@ -856,7 +860,8 @@ int pci_register_driver(struct pci_driver *); void pci_unregister_driver(struct pci_driver *); void pci_remove_behind_bridge(struct pci_dev *); struct pci_driver *pci_dev_driver(const struct pci_dev *); -const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev); +const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev); +const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev); int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); /* kmem_cache style wrapper around pci_alloc_consistent() */ @@ -870,6 +875,15 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass #define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle) #define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr) +enum pci_dma_burst_strategy { + PCI_DMA_BURST_INFINITY, /* make bursts as large as possible, + strategy_parameter is N/A */ + PCI_DMA_BURST_BOUNDARY, /* disconnect at every strategy_parameter + byte boundaries */ + PCI_DMA_BURST_MULTIPLE, /* disconnect at some multiple of + strategy_parameter byte boundaries */ +}; + #if defined(CONFIG_ISA) || defined(CONFIG_EISA) extern struct pci_dev *isa_bridge; #endif @@ -972,6 +986,8 @@ static inline int pci_proc_domain(struct pci_bus *bus) } #endif +#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) + #endif /* !CONFIG_PCI */ /* these helpers provide future and backwards compatibility @@ -1016,6 +1032,20 @@ static inline char *pci_name(struct pci_dev *pdev) #define pci_pretty_name(dev) "" #endif + +/* Some archs don't want to expose struct resource to userland as-is + * in sysfs and /proc + */ +#ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER +static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, u64 *start, u64 *end) +{ + *start = rsrc->start; + *end = rsrc->end; +} +#endif /* HAVE_ARCH_PCI_RESOURCE_TO_USER */ + + /* * The world is not perfect and supplies us with broken PCI devices. * For at least a part of these bugs we need a work-around, so both diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1e0bc6a8d653..27348c22dacb 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -62,6 +62,8 @@ #define PCI_BASE_CLASS_SYSTEM 0x08 #define PCI_CLASS_SYSTEM_PIC 0x0800 +#define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010 +#define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020 #define PCI_CLASS_SYSTEM_DMA 0x0801 #define PCI_CLASS_SYSTEM_TIMER 0x0802 #define PCI_CLASS_SYSTEM_RTC 0x0803 @@ -1236,6 +1238,7 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E #define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 #define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 #define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 25d2d67c1faf..bd2c5a2bbbf5 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -276,6 +276,7 @@ struct tc_rsvp_pinfo __u8 protocol; __u8 tunnelid; __u8 tunnelhdr; + __u8 pad; }; /* ROUTE filter */ diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 1d9da36eb9db..60ffcb9c5791 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -221,9 +221,11 @@ struct tc_gred_qopt /* gred setup */ struct tc_gred_sopt { - __u32 DPs; - __u32 def_DP; - __u8 grio; + __u32 DPs; + __u32 def_DP; + __u8 grio; + __u8 pad1; + __u16 pad2; }; /* HTB section */ @@ -351,6 +353,7 @@ struct tc_cbq_ovl #define TC_CBQ_OVL_DROP 3 #define TC_CBQ_OVL_RCLASSIC 4 unsigned char priority2; + __u16 pad; __u32 penalty; }; diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d021888b58f1..657c05ab8f9e 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -363,6 +363,8 @@ enum struct rta_session { __u8 proto; + __u8 pad1; + __u16 pad2; union { struct { @@ -635,10 +637,13 @@ struct ifinfomsg struct prefixmsg { unsigned char prefix_family; + unsigned char prefix_pad1; + unsigned short prefix_pad2; int prefix_ifindex; unsigned char prefix_type; unsigned char prefix_len; unsigned char prefix_flags; + unsigned char prefix_pad3; }; enum @@ -898,7 +903,9 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi memcpy(skb_put(skb, attrlen), data, attrlen); }) #define RTA_PUT_NOHDR(skb, attrlen, data) \ - RTA_APPEND(skb, RTA_ALIGN(attrlen), data) +({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \ + memset(skb->tail - (RTA_ALIGN(attrlen) - attrlen), 0, \ + RTA_ALIGN(attrlen) - attrlen); }) #define RTA_PUT_U8(skb, attrtype, value) \ ({ u8 _tmp = (value); \ @@ -978,6 +985,7 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); rta->rta_type = attrtype; rta->rta_len = size; + memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); return rta; } diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 416a2e4024b2..14b950413495 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -183,7 +183,6 @@ struct skb_shared_info { * @priority: Packet queueing priority * @users: User count - see {datagram,tcp}.c * @protocol: Packet protocol from driver - * @security: Security level of packet * @truesize: Buffer size * @head: Head of buffer * @data: Data head pointer @@ -249,18 +248,18 @@ struct sk_buff { data_len, mac_len, csum; - unsigned char local_df, - cloned:1, - nohdr:1, - pkt_type, - ip_summed; __u32 priority; - unsigned short protocol, - security; + __u8 local_df:1, + cloned:1, + ip_summed:2, + nohdr:1; + /* 3 bits spare */ + __u8 pkt_type; + __u16 protocol; void (*destructor)(struct sk_buff *skb); #ifdef CONFIG_NETFILTER - unsigned long nfmark; + unsigned long nfmark; __u32 nfcache; __u32 nfctinfo; struct nf_conntrack *nfct; @@ -1211,7 +1210,7 @@ static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, { int hlen = skb_headlen(skb); - if (offset + len <= hlen) + if (hlen - offset >= len) return skb->data + offset; if (skb_copy_bits(skb, offset, buffer, len) < 0) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index ebfe1250f0a4..5b5f434ac9a0 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -641,6 +641,7 @@ enum { NET_SCTP_ADDIP_ENABLE = 13, NET_SCTP_PRSCTP_ENABLE = 14, NET_SCTP_SNDBUF_POLICY = 15, + NET_SCTP_SACK_TIMEOUT = 16, }; /* /proc/sys/net/bridge */ diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index a6b2cc530af5..bcb762d93123 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h @@ -45,7 +45,7 @@ enum TCF_META_ID_REALDEV, TCF_META_ID_PRIORITY, TCF_META_ID_PROTOCOL, - TCF_META_ID_SECURITY, + TCF_META_ID_SECURITY, /* obsolete */ TCF_META_ID_PKTTYPE, TCF_META_ID_PKTLEN, TCF_META_ID_DATALEN, diff --git a/include/linux/tcp.h b/include/linux/tcp.h index dfd93d03f5d2..e4fd82e42104 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -286,7 +286,7 @@ struct tcp_sock { __u32 max_window; /* Maximal window ever seen from peer */ __u32 pmtu_cookie; /* Last pmtu seen by socket */ __u32 mss_cache; /* Cached effective mss, not including SACKS */ - __u16 mss_cache_std; /* Like mss_cache, but without TSO */ + __u16 xmit_size_goal; /* Goal for segmenting output packets */ __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */ __u8 ca_state; /* State of fast-retransmit machine */ __u8 retransmits; /* Number of unrecovered RTO timeouts. */ diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h index 39e7ff4ffd28..ee21e6bf3867 100644 --- a/include/linux/usb_ch9.h +++ b/include/linux/usb_ch9.h @@ -19,7 +19,7 @@ #ifndef __LINUX_USB_CH9_H #define __LINUX_USB_CH9_H -#include <asm/types.h> /* __u8 etc */ +#include <linux/types.h> /* __u8 etc */ /*-------------------------------------------------------------------------*/ @@ -294,8 +294,8 @@ struct usb_endpoint_descriptor { __le16 wMaxPacketSize; __u8 bInterval; - // NOTE: these two are _only_ in audio endpoints. - // use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. + /* NOTE: these two are _only_ in audio endpoints. */ + /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ __u8 bRefresh; __u8 bSynchAddress; } __attribute__ ((packed)); diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 4e0edce53760..acbfc525576d 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -221,6 +221,8 @@ struct v4l2_pix_format /* Vendor-specific formats */ #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */ #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */ +#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */ +#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */ /* * F O R M A T E N U M E R A T I O N diff --git a/include/linux/writeback.h b/include/linux/writeback.h index d5c3fe1bf33d..542dbaee6512 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -85,7 +85,7 @@ static inline void wait_on_inode(struct inode *inode) /* * mm/page-writeback.c */ -int wakeup_bdflush(long nr_pages); +int wakeup_pdflush(long nr_pages); void laptop_io_completion(void); void laptop_sync_completion(void); void throttle_vm_writeout(void); diff --git a/include/linux/xattr_acl.h b/include/linux/xattr_acl.h deleted file mode 100644 index 7a1f9b93a45f..000000000000 --- a/include/linux/xattr_acl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - File: linux/xattr_acl.h - - (extended attribute representation of access control lists) - - (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org> -*/ - -#ifndef _LINUX_XATTR_ACL_H -#define _LINUX_XATTR_ACL_H - -#include <linux/posix_acl.h> - -#define XATTR_NAME_ACL_ACCESS "system.posix_acl_access" -#define XATTR_NAME_ACL_DEFAULT "system.posix_acl_default" - -#define XATTR_ACL_VERSION 0x0002 - -typedef struct { - __u16 e_tag; - __u16 e_perm; - __u32 e_id; -} xattr_acl_entry; - -typedef struct { - __u32 a_version; - xattr_acl_entry a_entries[0]; -} xattr_acl_header; - -static inline size_t xattr_acl_size(int count) -{ - return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry); -} - -static inline int xattr_acl_count(size_t size) -{ - if (size < sizeof(xattr_acl_header)) - return -1; - size -= sizeof(xattr_acl_header); - if (size % sizeof(xattr_acl_entry)) - return -1; - return size / sizeof(xattr_acl_entry); -} - -struct posix_acl * posix_acl_from_xattr(const void *value, size_t size); -int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size); - - - -#endif /* _LINUX_XATTR_ACL_H */ diff --git a/include/media/tuner.h b/include/media/tuner.h index 2dd8310901e8..4794c5632360 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -1,5 +1,6 @@ -/* +/* $Id: tuner.h,v 1.33 2005/06/21 14:58:08 mkrufky Exp $ + * tuner.h - definition for different tuners Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de) @@ -23,6 +24,8 @@ #ifndef _TUNER_H #define _TUNER_H +#include <linux/videodev2.h> + #include "id.h" #define ADDR_UNSET (255) @@ -88,7 +91,7 @@ #define TUNER_LG_NTSC_TAPE 47 #define TUNER_TNF_8831BGFF 48 -#define TUNER_MICROTUNE_4042FI5 49 /* FusionHDTV 3 Gold - 4042 FI5 (3X 8147) */ +#define TUNER_MICROTUNE_4042FI5 49 /* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */ #define TUNER_TCL_2002N 50 #define TUNER_PHILIPS_FM1256_IH3 51 @@ -98,18 +101,18 @@ #define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */ #define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ -#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ +#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ #define TUNER_YMEC_TVF_8531MF 58 #define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ -#define TUNER_THOMSON_DTT7611 60 +#define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */ #define TUNER_TENA_9533_DI 61 + #define TUNER_TEA5767 62 /* Only FM Radio Tuner */ +#define TUNER_PHILIPS_FMD1216ME_MK3 63 #define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio" -#define TUNER_THOMSON_DTT7611 60 - #define NOTUNER 0 #define PAL 1 /* PAL_BG */ #define PAL_I 2 @@ -194,11 +197,15 @@ struct tuner { unsigned char i2c_easy_mode[2]; unsigned char i2c_set_freq[8]; + /* used to keep track of audmode */ + unsigned int audmode; + /* function ptrs */ void (*tv_freq)(struct i2c_client *c, unsigned int freq); void (*radio_freq)(struct i2c_client *c, unsigned int freq); int (*has_signal)(struct i2c_client *c); int (*is_stereo)(struct i2c_client *c); + int (*set_tuner)(struct i2c_client *c, struct v4l2_tuner *v); }; extern unsigned int tuner_debug; @@ -206,6 +213,7 @@ extern unsigned const int tuner_count; extern int microtune_init(struct i2c_client *c); extern int tda8290_init(struct i2c_client *c); +extern int tea5767_tuner_init(struct i2c_client *c); extern int default_tuner_init(struct i2c_client *c); #define tuner_warn(fmt, arg...) \ diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index 7fe57f957a51..db09580ad14b 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -94,6 +94,8 @@ struct eapol { u16 length; } __attribute__ ((packed)); +#define IEEE80211_1ADDR_LEN 10 +#define IEEE80211_2ADDR_LEN 16 #define IEEE80211_3ADDR_LEN 24 #define IEEE80211_4ADDR_LEN 30 #define IEEE80211_FCS_LEN 4 @@ -300,23 +302,6 @@ struct ieee80211_snap_hdr { #define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 -/* Information Element IDs */ -#define WLAN_EID_SSID 0 -#define WLAN_EID_SUPP_RATES 1 -#define WLAN_EID_FH_PARAMS 2 -#define WLAN_EID_DS_PARAMS 3 -#define WLAN_EID_CF_PARAMS 4 -#define WLAN_EID_TIM 5 -#define WLAN_EID_IBSS_PARAMS 6 -#define WLAN_EID_CHALLENGE 16 -#define WLAN_EID_RSN 48 -#define WLAN_EID_GENERIC 221 - -#define IEEE80211_MGMT_HDR_LEN 24 -#define IEEE80211_DATA_HDR3_LEN 24 -#define IEEE80211_DATA_HDR4_LEN 30 - - #define IEEE80211_STATMASK_SIGNAL (1<<0) #define IEEE80211_STATMASK_RSSI (1<<1) #define IEEE80211_STATMASK_NOISE (1<<2) @@ -441,6 +426,10 @@ struct ieee80211_stats { struct ieee80211_device; +#if 0 /* for later */ +#include "ieee80211_crypt.h" +#endif + #define SEC_KEY_1 (1<<0) #define SEC_KEY_2 (1<<1) #define SEC_KEY_3 (1<<2) @@ -488,15 +477,6 @@ Total: 28-2340 bytes */ -struct ieee80211_header_data { - u16 frame_ctl; - u16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - u16 seq_ctrl; -}; - #define BEACON_PROBE_SSID_ID_POSITION 12 /* Management Frame Information Element Types */ @@ -541,7 +521,7 @@ struct ieee80211_info_element { */ struct ieee80211_authentication { - struct ieee80211_header_data header; + struct ieee80211_hdr_3addr header; u16 algorithm; u16 transaction; u16 status; @@ -550,7 +530,7 @@ struct ieee80211_authentication { struct ieee80211_probe_response { - struct ieee80211_header_data header; + struct ieee80211_hdr_3addr header; u32 time_stamp[2]; u16 beacon_interval; u16 capability; @@ -648,12 +628,6 @@ enum ieee80211_state { #define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] -extern inline int is_broadcast_ether_addr(const u8 *addr) -{ - return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ - (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); -} - #define CFG_IEEE80211_RESERVE_FCS (1<<0) #define CFG_IEEE80211_COMPUTE_FCS (1<<1) @@ -787,21 +761,21 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod extern inline int ieee80211_get_hdrlen(u16 fc) { - int hdrlen = 24; + int hdrlen = IEEE80211_3ADDR_LEN; switch (WLAN_FC_GET_TYPE(fc)) { case IEEE80211_FTYPE_DATA: if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) - hdrlen = 30; /* Addr4 */ + hdrlen = IEEE80211_4ADDR_LEN; break; case IEEE80211_FTYPE_CTL: switch (WLAN_FC_GET_STYPE(fc)) { case IEEE80211_STYPE_CTS: case IEEE80211_STYPE_ACK: - hdrlen = 10; + hdrlen = IEEE80211_1ADDR_LEN; break; default: - hdrlen = 16; + hdrlen = IEEE80211_2ADDR_LEN; break; } break; diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 771b47e30f86..69324465e8b3 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -183,7 +183,6 @@ struct ipv6_txoptions struct ipv6_opt_hdr *hopopt; struct ipv6_opt_hdr *dst0opt; struct ipv6_rt_hdr *srcrt; /* Routing Header */ - struct ipv6_opt_hdr *auth; struct ipv6_opt_hdr *dst1opt; /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index fcb05a387dbe..6492e7363d84 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -13,13 +13,12 @@ struct qdisc_walker extern rwlock_t qdisc_tree_lock; -#define QDISC_ALIGN 32 -#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) +#define QDISC_ALIGNTO 32 +#define QDISC_ALIGN(len) (((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1)) static inline void *qdisc_priv(struct Qdisc *q) { - return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) - & ~QDISC_ALIGN_CONST); + return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc)); } /* @@ -207,8 +206,6 @@ psched_tod_diff(int delta_sec, int bound) #endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ -extern struct Qdisc noop_qdisc; -extern struct Qdisc_ops noop_qdisc_ops; extern struct Qdisc_ops pfifo_qdisc_ops; extern struct Qdisc_ops bfifo_qdisc_ops; @@ -216,14 +213,6 @@ extern int register_qdisc(struct Qdisc_ops *qops); extern int unregister_qdisc(struct Qdisc_ops *qops); extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle); extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle); -extern void dev_init_scheduler(struct net_device *dev); -extern void dev_shutdown(struct net_device *dev); -extern void dev_activate(struct net_device *dev); -extern void dev_deactivate(struct net_device *dev); -extern void qdisc_reset(struct Qdisc *qdisc); -extern void qdisc_destroy(struct Qdisc *qdisc); -extern struct Qdisc * qdisc_create_dflt(struct net_device *dev, - struct Qdisc_ops *ops); extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab); extern void qdisc_put_rtab(struct qdisc_rate_table *tab); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 7b97405e2dbf..7b6ec9986715 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -164,6 +164,19 @@ extern void qdisc_unlock_tree(struct net_device *dev); #define tcf_tree_lock(tp) qdisc_lock_tree((tp)->q->dev) #define tcf_tree_unlock(tp) qdisc_unlock_tree((tp)->q->dev) +extern struct Qdisc noop_qdisc; +extern struct Qdisc_ops noop_qdisc_ops; + +extern void dev_init_scheduler(struct net_device *dev); +extern void dev_shutdown(struct net_device *dev); +extern void dev_activate(struct net_device *dev); +extern void dev_deactivate(struct net_device *dev); +extern void qdisc_reset(struct Qdisc *qdisc); +extern void qdisc_destroy(struct Qdisc *qdisc); +extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops); +extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, + struct Qdisc_ops *ops); + static inline void tcf_destroy(struct tcf_proto *tp) { diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 4868c7f7749d..5999e5684bbf 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -263,23 +263,11 @@ enum { SCTP_MIN_PMTU = 576 }; enum { SCTP_MAX_DUP_TSNS = 16 }; enum { SCTP_MAX_GABS = 16 }; -/* Here we define the default timers. */ +/* Heartbeat interval - 30 secs */ +#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30 * HZ) -/* cookie timer def = ? seconds */ -#define SCTP_DEFAULT_TIMEOUT_T1_COOKIE (3 * HZ) - -/* init timer def = 3 seconds */ -#define SCTP_DEFAULT_TIMEOUT_T1_INIT (3 * HZ) - -/* shutdown timer def = 300 ms */ -#define SCTP_DEFAULT_TIMEOUT_T2_SHUTDOWN ((300 * HZ) / 1000) - -/* 0 seconds + RTO */ -#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (10 * HZ) - -/* recv timer def = 200ms (in usec) */ +/* Delayed sack timer - 200ms */ #define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000) -#define SCTP_DEFAULT_TIMEOUT_SACK_MAX ((500 * HZ) / 1000) /* 500 ms */ /* RTO.Initial - 3 seconds * RTO.Min - 1 second diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index dfad4d3c581c..47727c7cc628 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -161,6 +161,9 @@ extern struct sctp_globals { */ int sndbuf_policy; + /* Delayed SACK timeout 200ms default*/ + int sack_timeout; + /* HB.interval - 30 seconds */ int hb_interval; @@ -217,6 +220,7 @@ extern struct sctp_globals { #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) #define sctp_max_retrans_path (sctp_globals.max_retrans_path) #define sctp_max_retrans_init (sctp_globals.max_retrans_init) +#define sctp_sack_timeout (sctp_globals.sack_timeout) #define sctp_hb_interval (sctp_globals.hb_interval) #define sctp_max_instreams (sctp_globals.max_instreams) #define sctp_max_outstreams (sctp_globals.max_outstreams) diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h index 0b2c2784f333..8716d5942b65 100644 --- a/include/net/slhc_vj.h +++ b/include/net/slhc_vj.h @@ -170,19 +170,14 @@ struct slcompress { }; #define NULLSLCOMPR (struct slcompress *)0 -#define __ARGS(x) x - /* In slhc.c: */ -struct slcompress *slhc_init __ARGS((int rslots, int tslots)); -void slhc_free __ARGS((struct slcompress *comp)); - -int slhc_compress __ARGS((struct slcompress *comp, unsigned char *icp, - int isize, unsigned char *ocp, unsigned char **cpp, - int compress_cid)); -int slhc_uncompress __ARGS((struct slcompress *comp, unsigned char *icp, - int isize)); -int slhc_remember __ARGS((struct slcompress *comp, unsigned char *icp, - int isize)); -int slhc_toss __ARGS((struct slcompress *comp)); +struct slcompress *slhc_init(int rslots, int tslots); +void slhc_free(struct slcompress *comp); + +int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid); +int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_toss(struct slcompress *comp); #endif /* _SLHC_H */ diff --git a/include/net/sock.h b/include/net/sock.h index e593af5b1ecc..7b76f891ae2d 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1134,13 +1134,16 @@ static inline void sk_stream_moderate_sndbuf(struct sock *sk) static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk, int size, int mem, int gfp) { - struct sk_buff *skb = alloc_skb(size + sk->sk_prot->max_header, gfp); + struct sk_buff *skb; + int hdr_len; + hdr_len = SKB_DATA_ALIGN(sk->sk_prot->max_header); + skb = alloc_skb(size + hdr_len, gfp); if (skb) { skb->truesize += mem; if (sk->sk_forward_alloc >= (int)skb->truesize || sk_stream_mem_schedule(sk, skb->truesize, 0)) { - skb_reserve(skb, sk->sk_prot->max_header); + skb_reserve(skb, hdr_len); return skb; } __kfree_skb(skb); diff --git a/include/net/tcp.h b/include/net/tcp.h index ec9e20c27179..a166918ca56d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -721,11 +721,16 @@ static inline int tcp_ack_scheduled(struct tcp_sock *tp) return tp->ack.pending&TCP_ACK_SCHED; } -static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp) +static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp, unsigned int pkts) { - if (tp->ack.quick && --tp->ack.quick == 0) { - /* Leaving quickack mode we deflate ATO. */ - tp->ack.ato = TCP_ATO_MIN; + if (tp->ack.quick) { + if (pkts >= tp->ack.quick) { + tp->ack.quick = 0; + + /* Leaving quickack mode we deflate ATO. */ + tp->ack.ato = TCP_ATO_MIN; + } else + tp->ack.quick -= pkts; } } @@ -843,7 +848,9 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, /* tcp_output.c */ -extern int tcp_write_xmit(struct sock *, int nonagle); +extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, + unsigned int cur_mss, int nonagle); +extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp); extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); extern void tcp_xmit_retransmit_queue(struct sock *); extern void tcp_simple_retransmit(struct sock *); @@ -855,10 +862,13 @@ extern int tcp_write_wakeup(struct sock *); extern void tcp_send_fin(struct sock *sk); extern void tcp_send_active_reset(struct sock *sk, int priority); extern int tcp_send_synack(struct sock *); -extern void tcp_push_one(struct sock *, unsigned mss_now); +extern void tcp_push_one(struct sock *, unsigned int mss_now); extern void tcp_send_ack(struct sock *sk); extern void tcp_send_delayed_ack(struct sock *sk); +/* tcp_input.c */ +extern void tcp_cwnd_application_limited(struct sock *sk); + /* tcp_timer.c */ extern void tcp_init_xmit_timers(struct sock *); extern void tcp_clear_xmit_timers(struct sock *); @@ -958,7 +968,7 @@ static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long static inline void tcp_initialize_rcv_mss(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); - unsigned int hint = min(tp->advmss, tp->mss_cache_std); + unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache); hint = min(hint, tp->rcv_wnd/2); hint = min(hint, TCP_MIN_RCVMSS); @@ -1225,28 +1235,6 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp) tp->left_out = tp->sacked_out + tp->lost_out; } -extern void tcp_cwnd_application_limited(struct sock *sk); - -/* Congestion window validation. (RFC2861) */ - -static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) -{ - __u32 packets_out = tp->packets_out; - - if (packets_out >= tp->snd_cwnd) { - /* Network is feed fully. */ - tp->snd_cwnd_used = 0; - tp->snd_cwnd_stamp = tcp_time_stamp; - } else { - /* Network starves. */ - if (tp->packets_out > tp->snd_cwnd_used) - tp->snd_cwnd_used = tp->packets_out; - - if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto) - tcp_cwnd_application_limited(sk); - } -} - /* Set slow start threshould and cwnd not falling to slow start */ static inline void __tcp_enter_cwr(struct tcp_sock *tp) { @@ -1279,12 +1267,6 @@ static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp) return 3; } -static __inline__ int tcp_minshall_check(const struct tcp_sock *tp) -{ - return after(tp->snd_sml,tp->snd_una) && - !after(tp->snd_sml, tp->snd_nxt); -} - static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, const struct sk_buff *skb) { @@ -1292,122 +1274,18 @@ static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, tp->snd_sml = TCP_SKB_CB(skb)->end_seq; } -/* Return 0, if packet can be sent now without violation Nagle's rules: - 1. It is full sized. - 2. Or it contains FIN. - 3. Or TCP_NODELAY was set. - 4. Or TCP_CORK is not set, and all sent packets are ACKed. - With Minshall's modification: all sent small packets are ACKed. - */ - -static __inline__ int -tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, - unsigned mss_now, int nonagle) -{ - return (skb->len < mss_now && - !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && - ((nonagle&TCP_NAGLE_CORK) || - (!nonagle && - tp->packets_out && - tcp_minshall_check(tp)))); -} - -extern void tcp_set_skb_tso_segs(struct sock *, struct sk_buff *); - -/* This checks if the data bearing packet SKB (usually sk->sk_send_head) - * should be put on the wire right now. - */ -static __inline__ int tcp_snd_test(struct sock *sk, - struct sk_buff *skb, - unsigned cur_mss, int nonagle) -{ - struct tcp_sock *tp = tcp_sk(sk); - int pkts = tcp_skb_pcount(skb); - - if (!pkts) { - tcp_set_skb_tso_segs(sk, skb); - pkts = tcp_skb_pcount(skb); - } - - /* RFC 1122 - section 4.2.3.4 - * - * We must queue if - * - * a) The right edge of this frame exceeds the window - * b) There are packets in flight and we have a small segment - * [SWS avoidance and Nagle algorithm] - * (part of SWS is done on packetization) - * Minshall version sounds: there are no _small_ - * segments in flight. (tcp_nagle_check) - * c) We have too many packets 'in flight' - * - * Don't use the nagle rule for urgent data (or - * for the final FIN -DaveM). - * - * Also, Nagle rule does not apply to frames, which - * sit in the middle of queue (they have no chances - * to get new data) and if room at tail of skb is - * not enough to save something seriously (<32 for now). - */ - - /* Don't be strict about the congestion window for the - * final FIN frame. -DaveM - */ - return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode - || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) && - (((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) || - (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) && - !after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd)); -} - static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp) { if (!tp->packets_out && !tp->pending) tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto); } -static __inline__ int tcp_skb_is_last(const struct sock *sk, - const struct sk_buff *skb) -{ - return skb->next == (struct sk_buff *)&sk->sk_write_queue; -} - -/* Push out any pending frames which were held back due to - * TCP_CORK or attempt at coalescing tiny packets. - * The socket must be locked by the caller. - */ -static __inline__ void __tcp_push_pending_frames(struct sock *sk, - struct tcp_sock *tp, - unsigned cur_mss, - int nonagle) -{ - struct sk_buff *skb = sk->sk_send_head; - - if (skb) { - if (!tcp_skb_is_last(sk, skb)) - nonagle = TCP_NAGLE_PUSH; - if (!tcp_snd_test(sk, skb, cur_mss, nonagle) || - tcp_write_xmit(sk, nonagle)) - tcp_check_probe_timer(sk, tp); - } - tcp_cwnd_validate(sk, tp); -} - static __inline__ void tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp) { __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle); } -static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) -{ - struct sk_buff *skb = sk->sk_send_head; - - return (skb && - tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), - tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle)); -} - static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq) { tp->snd_wl1 = seq; diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 4def882d0b31..a05cabd0fd10 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -86,7 +86,10 @@ static void __init handle_initrd(void) printk("okay\n"); else { int fd = sys_open("/dev/root.old", O_RDWR, 0); - printk("failed\n"); + if (error == -ENOENT) + printk("/initrd does not exist. Ignored.\n"); + else + printk("failed\n"); printk(KERN_NOTICE "Unmounting old root\n"); sys_umount("/old", MNT_DETACH); printk(KERN_NOTICE "Trying to free ramdisk memory ... "); diff --git a/init/main.c b/init/main.c index d324801729ba..b5e421e39ede 100644 --- a/init/main.c +++ b/init/main.c @@ -383,6 +383,13 @@ static void noinline rest_init(void) numa_default_policy(); unlock_kernel(); preempt_enable_no_resched(); + + /* + * The boot idle thread must execute schedule() + * at least one to get things moving: + */ + schedule(); + cpu_idle(); } diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 98d62d8efeaf..3467097ca61a 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c @@ -9,6 +9,7 @@ #include <linux/irq.h> #include <linux/module.h> #include <linux/interrupt.h> +#include <linux/delay.h> /* * Autodetection depends on the fact that any interrupt that @@ -26,7 +27,7 @@ static DECLARE_MUTEX(probe_sem); */ unsigned long probe_irq_on(void) { - unsigned long val, delay; + unsigned long val; irq_desc_t *desc; unsigned int i; @@ -45,8 +46,7 @@ unsigned long probe_irq_on(void) } /* Wait for longstanding interrupts to trigger. */ - for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) - /* about 20ms delay */ barrier(); + msleep(20); /* * enable any unassigned irqs @@ -68,8 +68,7 @@ unsigned long probe_irq_on(void) /* * Wait for spurious interrupts to trigger */ - for (delay = jiffies + HZ/10; time_after(delay, jiffies); ) - /* about 100ms delay */ barrier(); + msleep(100); /* * Now filter out any obviously spurious interrupts diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 436c7d93c00a..c29f83c16497 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -172,7 +172,7 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) spin_lock(&desc->lock); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index ba039e827d58..7df9abd5ec86 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c @@ -11,6 +11,83 @@ #include <linux/kallsyms.h> #include <linux/interrupt.h> +static int irqfixup; + +/* + * Recovery handler for misrouted interrupts. + */ + +static int misrouted_irq(int irq, struct pt_regs *regs) +{ + int i; + irq_desc_t *desc; + int ok = 0; + int work = 0; /* Did we do work for a real IRQ */ + + for(i = 1; i < NR_IRQS; i++) { + struct irqaction *action; + + if (i == irq) /* Already tried */ + continue; + desc = &irq_desc[i]; + spin_lock(&desc->lock); + action = desc->action; + /* Already running on another processor */ + if (desc->status & IRQ_INPROGRESS) { + /* + * Already running: If it is shared get the other + * CPU to go looking for our mystery interrupt too + */ + if (desc->action && (desc->action->flags & SA_SHIRQ)) + desc->status |= IRQ_PENDING; + spin_unlock(&desc->lock); + continue; + } + /* Honour the normal IRQ locking */ + desc->status |= IRQ_INPROGRESS; + spin_unlock(&desc->lock); + while (action) { + /* Only shared IRQ handlers are safe to call */ + if (action->flags & SA_SHIRQ) { + if (action->handler(i, action->dev_id, regs) == + IRQ_HANDLED) + ok = 1; + } + action = action->next; + } + local_irq_disable(); + /* Now clean up the flags */ + spin_lock(&desc->lock); + action = desc->action; + + /* + * While we were looking for a fixup someone queued a real + * IRQ clashing with our walk + */ + + while ((desc->status & IRQ_PENDING) && action) { + /* + * Perform real IRQ processing for the IRQ we deferred + */ + work = 1; + spin_unlock(&desc->lock); + handle_IRQ_event(i, regs, action); + spin_lock(&desc->lock); + desc->status &= ~IRQ_PENDING; + } + desc->status &= ~IRQ_INPROGRESS; + /* + * If we did actual work for the real IRQ line we must let the + * IRQ controller clean up too + */ + if(work) + desc->handler->end(i); + spin_unlock(&desc->lock); + } + /* So the caller can adjust the irq error counts */ + return ok; +} + /* * If 99,900 of the previous 100,000 interrupts have not been handled * then assume that the IRQ is stuck in some manner. Drop a diagnostic @@ -31,7 +108,8 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) printk(KERN_ERR "irq event %d: bogus return value %x\n", irq, action_ret); } else { - printk(KERN_ERR "irq %d: nobody cared!\n", irq); + printk(KERN_ERR "irq %d: nobody cared (try booting with " + "the \"irqpoll\" option)\n", irq); } dump_stack(); printk(KERN_ERR "handlers:\n"); @@ -55,7 +133,8 @@ static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t actio } } -void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) +void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, + struct pt_regs *regs) { if (action_ret != IRQ_HANDLED) { desc->irqs_unhandled++; @@ -63,6 +142,15 @@ void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) report_bad_irq(irq, desc, action_ret); } + if (unlikely(irqfixup)) { + /* Don't punish working computers */ + if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) { + int ok = misrouted_irq(irq, regs); + if (action_ret == IRQ_NONE) + desc->irqs_unhandled -= ok; + } + } + desc->irq_count++; if (desc->irq_count < 100000) return; @@ -94,3 +182,24 @@ int __init noirqdebug_setup(char *str) __setup("noirqdebug", noirqdebug_setup); +static int __init irqfixup_setup(char *str) +{ + irqfixup = 1; + printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); + printk(KERN_WARNING "This may impact system performance.\n"); + return 1; +} + +__setup("irqfixup", irqfixup_setup); + +static int __init irqpoll_setup(char *str) +{ + irqfixup = 2; + printk(KERN_WARNING "Misrouted IRQ fixup and polling support " + "enabled\n"); + printk(KERN_WARNING "This may significantly impact system " + "performance\n"); + return 1; +} + +__setup("irqpoll", irqpoll_setup); diff --git a/kernel/itimer.c b/kernel/itimer.c index 1dc988e0d2c7..a72cb0e5aa4b 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -153,11 +153,15 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) switch (which) { case ITIMER_REAL: +again: spin_lock_irq(&tsk->sighand->siglock); interval = tsk->signal->it_real_incr; val = it_real_value(tsk->signal); - if (val) - del_timer_sync(&tsk->signal->real_timer); + /* We are sharing ->siglock with it_real_fn() */ + if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) { + spin_unlock_irq(&tsk->sighand->siglock); + goto again; + } tsk->signal->it_real_incr = timeval_to_jiffies(&value->it_interval); it_real_arm(tsk, timeval_to_jiffies(&value->it_value)); diff --git a/kernel/kexec.c b/kernel/kexec.c index 7843548cf2d9..cdd4dcd8fb63 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -241,7 +241,7 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, unsigned long nr_segments, - struct kexec_segment *segments) + struct kexec_segment __user *segments) { int result; struct kimage *image; @@ -650,7 +650,7 @@ static kimage_entry_t *kimage_dst_used(struct kimage *image, } } - return 0; + return NULL; } static struct page *kimage_alloc_page(struct kimage *image, @@ -696,7 +696,7 @@ static struct page *kimage_alloc_page(struct kimage *image, /* Allocate a page, if we run out of memory give up */ page = kimage_alloc_pages(gfp_mask, 0); if (!page) - return 0; + return NULL; /* If the page cannot be used file it away */ if (page_to_pfn(page) > (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) { @@ -754,7 +754,7 @@ static int kimage_load_normal_segment(struct kimage *image, unsigned long maddr; unsigned long ubytes, mbytes; int result; - unsigned char *buf; + unsigned char __user *buf; result = 0; buf = segment->buf; @@ -818,7 +818,7 @@ static int kimage_load_crash_segment(struct kimage *image, unsigned long maddr; unsigned long ubytes, mbytes; int result; - unsigned char *buf; + unsigned char __user *buf; result = 0; buf = segment->buf; diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 90c0e82b650c..b0237122b24e 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -574,7 +574,7 @@ static int __init init_kprobes(void) INIT_HLIST_HEAD(&kretprobe_inst_table[i]); } - err = arch_init(); + err = arch_init_kprobes(); if (!err) err = register_die_notifier(&kprobe_exceptions_nb); diff --git a/kernel/sched.c b/kernel/sched.c index e2b0d3e4dd06..5f2182d42241 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4166,6 +4166,14 @@ void show_state(void) read_unlock(&tasklist_lock); } +/** + * init_idle - set up an idle thread for a given CPU + * @idle: task in question + * @cpu: cpu the idle task belongs to + * + * NOTE: this function does not set the idle thread's NEED_RESCHED + * flag, to make booting more robust. + */ void __devinit init_idle(task_t *idle, int cpu) { runqueue_t *rq = cpu_rq(cpu); @@ -4183,7 +4191,6 @@ void __devinit init_idle(task_t *idle, int cpu) #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) idle->oncpu = 1; #endif - set_tsk_need_resched(idle); spin_unlock_irqrestore(&rq->lock, flags); /* Set the preempt count _outside_ the spinlocks! */ diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 613b99a55917..a6329fa8f862 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -354,7 +354,7 @@ static void background_writeout(unsigned long _min_pages) * the whole world. Returns 0 if a pdflush thread was dispatched. Returns * -1 if all pdflush threads were busy. */ -int wakeup_bdflush(long nr_pages) +int wakeup_pdflush(long nr_pages) { if (nr_pages == 0) { struct writeback_state wbs; diff --git a/mm/slab.c b/mm/slab.c index 122d031baab2..e57abd45eede 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2372,6 +2372,9 @@ void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid) struct slab *slabp; kmem_bufctl_t next; + if (nodeid == -1) + return kmem_cache_alloc(cachep, flags); + for (loop = 0;;loop++) { struct list_head *q; diff --git a/mm/vmscan.c b/mm/vmscan.c index 1fa312a8db77..cfffe5098d53 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -972,7 +972,7 @@ int try_to_free_pages(struct zone **zones, unsigned int gfp_mask) * writeout. So in laptop mode, write out the whole world. */ if (total_scanned > sc.swap_cluster_max + sc.swap_cluster_max/2) { - wakeup_bdflush(laptop_mode ? 0 : total_scanned); + wakeup_pdflush(laptop_mode ? 0 : total_scanned); sc.may_writepage = 1; } diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 03ae4edddac3..2d52fee63a8c 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -844,7 +844,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, * doesn't use the bridge parent of the indev by using * the BRNF_DONT_TAKE_PARENT mask. */ if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { - nf_bridge->mask &= BRNF_DONT_TAKE_PARENT; + nf_bridge->mask |= BRNF_DONT_TAKE_PARENT; nf_bridge->physindev = (struct net_device *)in; } #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index e4ae34b88925..662975be3d1d 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -61,8 +61,6 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, { struct ebt_log_info *info = (struct ebt_log_info *)data; char level_string[4] = "< >"; - union {struct iphdr iph; struct tcpudphdr ports; - struct arphdr arph; struct arppayload arpp;} u; level_string[1] = '0' + info->loglevel; spin_lock_bh(&ebt_log_lock); @@ -88,7 +86,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, } printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); - printk(" IP tos=0x%02X, IP proto=%d", u.iph.tos, + printk(" IP tos=0x%02X, IP proto=%d", ih->tos, ih->protocol); if (ih->protocol == IPPROTO_TCP || ih->protocol == IPPROTO_UDP) { @@ -127,7 +125,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, ah->ar_pln == sizeof(uint32_t)) { struct arppayload _arpp, *ap; - ap = skb_header_pointer(skb, sizeof(u.arph), + ap = skb_header_pointer(skb, sizeof(_arph), sizeof(_arpp), &_arpp); if (ap == NULL) { printk(" INCOMPLETE ARP payload"); diff --git a/net/core/dev.c b/net/core/dev.c index 7016e0c36b3d..7f5f62c65115 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2089,10 +2089,11 @@ void dev_set_promiscuity(struct net_device *dev, int inc) { unsigned short old_flags = dev->flags; - dev->flags |= IFF_PROMISC; if ((dev->promiscuity += inc) == 0) dev->flags &= ~IFF_PROMISC; - if (dev->flags ^ old_flags) { + else + dev->flags |= IFF_PROMISC; + if (dev->flags != old_flags) { dev_mc_upload(dev); printk(KERN_INFO "device %s %s promiscuous mode\n", dev->name, (dev->flags & IFF_PROMISC) ? "entered" : diff --git a/net/core/filter.c b/net/core/filter.c index f3b88205ace2..cd91a24f9720 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -36,7 +36,7 @@ #include <linux/filter.h> /* No hurry in this branch */ -static u8 *load_pointer(struct sk_buff *skb, int k) +static void *__load_pointer(struct sk_buff *skb, int k) { u8 *ptr = NULL; @@ -50,6 +50,18 @@ static u8 *load_pointer(struct sk_buff *skb, int k) return NULL; } +static inline void *load_pointer(struct sk_buff *skb, int k, + unsigned int size, void *buffer) +{ + if (k >= 0) + return skb_header_pointer(skb, k, size, buffer); + else { + if (k >= SKF_AD_OFF) + return NULL; + return __load_pointer(skb, k); + } +} + /** * sk_run_filter - run a filter on a socket * @skb: buffer to run the filter on @@ -64,15 +76,12 @@ static u8 *load_pointer(struct sk_buff *skb, int k) int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) { - unsigned char *data = skb->data; - /* len is UNSIGNED. Byte wide insns relies only on implicit - type casts to prevent reading arbitrary memory locations. - */ - unsigned int len = skb->len-skb->data_len; struct sock_filter *fentry; /* We walk down these */ + void *ptr; u32 A = 0; /* Accumulator */ u32 X = 0; /* Index Register */ u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ + u32 tmp; int k; int pc; @@ -168,86 +177,35 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) case BPF_LD|BPF_W|BPF_ABS: k = fentry->k; load_w: - if (k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) { - A = ntohl(*(u32*)&data[k]); + ptr = load_pointer(skb, k, 4, &tmp); + if (ptr != NULL) { + A = ntohl(*(u32 *)ptr); continue; } - if (k < 0) { - u8 *ptr; - - if (k >= SKF_AD_OFF) - break; - ptr = load_pointer(skb, k); - if (ptr) { - A = ntohl(*(u32*)ptr); - continue; - } - } else { - u32 _tmp, *p; - p = skb_header_pointer(skb, k, 4, &_tmp); - if (p != NULL) { - A = ntohl(*p); - continue; - } - } return 0; case BPF_LD|BPF_H|BPF_ABS: k = fentry->k; load_h: - if (k >= 0 && (unsigned int)(k + sizeof(u16)) <= len) { - A = ntohs(*(u16*)&data[k]); + ptr = load_pointer(skb, k, 2, &tmp); + if (ptr != NULL) { + A = ntohs(*(u16 *)ptr); continue; } - if (k < 0) { - u8 *ptr; - - if (k >= SKF_AD_OFF) - break; - ptr = load_pointer(skb, k); - if (ptr) { - A = ntohs(*(u16*)ptr); - continue; - } - } else { - u16 _tmp, *p; - p = skb_header_pointer(skb, k, 2, &_tmp); - if (p != NULL) { - A = ntohs(*p); - continue; - } - } return 0; case BPF_LD|BPF_B|BPF_ABS: k = fentry->k; load_b: - if (k >= 0 && (unsigned int)k < len) { - A = data[k]; + ptr = load_pointer(skb, k, 1, &tmp); + if (ptr != NULL) { + A = *(u8 *)ptr; continue; } - if (k < 0) { - u8 *ptr; - - if (k >= SKF_AD_OFF) - break; - ptr = load_pointer(skb, k); - if (ptr) { - A = *ptr; - continue; - } - } else { - u8 _tmp, *p; - p = skb_header_pointer(skb, k, 1, &_tmp); - if (p != NULL) { - A = *p; - continue; - } - } return 0; case BPF_LD|BPF_W|BPF_LEN: - A = len; + A = skb->len; continue; case BPF_LDX|BPF_W|BPF_LEN: - X = len; + X = skb->len; continue; case BPF_LD|BPF_W|BPF_IND: k = X + fentry->k; @@ -259,10 +217,12 @@ load_b: k = X + fentry->k; goto load_b; case BPF_LDX|BPF_B|BPF_MSH: - if (fentry->k >= len) - return 0; - X = (data[fentry->k] & 0xf) << 2; - continue; + ptr = load_pointer(skb, fentry->k, 1, &tmp); + if (ptr != NULL) { + X = (*(u8 *)ptr & 0xf) << 2; + continue; + } + return 0; case BPF_LD|BPF_IMM: A = fentry->k; continue; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 851eb927ed97..1beb782ac41b 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1598,6 +1598,8 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, read_lock_bh(&tbl->lock); ndtmsg->ndtm_family = tbl->family; + ndtmsg->ndtm_pad1 = 0; + ndtmsg->ndtm_pad2 = 0; RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); @@ -1683,6 +1685,8 @@ static int neightbl_fill_param_info(struct neigh_table *tbl, read_lock_bh(&tbl->lock); ndtmsg->ndtm_family = tbl->family; + ndtmsg->ndtm_pad1 = 0; + ndtmsg->ndtm_pad2 = 0; RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); if (neightbl_fill_parms(skb, parms) < 0) @@ -1872,6 +1876,8 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, struct ndmsg *ndm = NLMSG_DATA(nlh); ndm->ndm_family = n->ops->family; + ndm->ndm_pad1 = 0; + ndm->ndm_pad2 = 0; ndm->ndm_flags = n->flags; ndm->ndm_type = n->type; ndm->ndm_ifindex = n->dev->ifindex; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e013d836a7ab..4b1bb30e6381 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -126,6 +126,7 @@ void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data rta->rta_type = attrtype; rta->rta_len = size; memcpy(RTA_DATA(rta), data, attrlen); + memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); } size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) @@ -188,6 +189,7 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); r = NLMSG_DATA(nlh); r->ifi_family = AF_UNSPEC; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev_get_flags(dev); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index bb73b2190ec7..733deee24b9f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -357,7 +357,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) C(ip_summed); C(priority); C(protocol); - C(security); n->destructor = NULL; #ifdef CONFIG_NETFILTER C(nfmark); @@ -422,7 +421,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->pkt_type = old->pkt_type; new->stamp = old->stamp; new->destructor = NULL; - new->security = old->security; #ifdef CONFIG_NETFILTER new->nfmark = old->nfmark; new->nfcache = old->nfcache; diff --git a/net/core/wireless.c b/net/core/wireless.c index b2fe378dfbf8..3ff5639c0b78 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c @@ -1102,6 +1102,7 @@ static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb, nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r)); r = NLMSG_DATA(nlh); r->ifi_family = AF_UNSPEC; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev->flags; diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 9934b25720e4..99bc061759c3 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -551,7 +551,8 @@ int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb) if (t < s_t) continue; if (t > s_t) - memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(int)); + memset(&cb->args[1], 0, + sizeof(cb->args) - sizeof(cb->args[0])); tb = dn_fib_get_table(t, 0); if (tb == NULL) continue; diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 6617ea47d365..ab60ea63688e 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -92,10 +92,9 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, * Set the source hardware address. */ - if(saddr) - memcpy(eth->h_source,saddr,dev->addr_len); - else - memcpy(eth->h_source,dev->dev_addr,dev->addr_len); + if(!saddr) + saddr = dev->dev_addr; + memcpy(eth->h_source,saddr,dev->addr_len); /* * Anyway, the loopback-device should never use this function... diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 658e7977924d..ef7468376ae6 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1009,6 +1009,15 @@ static int __init init_ipv4_mibs(void) static int ipv4_proc_init(void); extern void ipfrag_init(void); +/* + * IP protocol layer initialiser + */ + +static struct packet_type ip_packet_type = { + .type = __constant_htons(ETH_P_IP), + .func = ip_rcv, +}; + static int __init inet_init(void) { struct sk_buff *dummy_skb; @@ -1102,6 +1111,8 @@ static int __init inet_init(void) ipfrag_init(); + dev_add_pack(&ip_packet_type); + rc = 0; out: return rc; diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 0671569ee6f0..4be234c7d8c3 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -43,7 +43,7 @@ * 2 of the License, or (at your option) any later version. */ -#define VERSION "0.323" +#define VERSION "0.325" #include <linux/config.h> #include <asm/uaccess.h> @@ -136,6 +136,7 @@ struct trie_use_stats { unsigned int semantic_match_passed; unsigned int semantic_match_miss; unsigned int null_node_hit; + unsigned int resize_node_skipped; }; #endif @@ -164,8 +165,8 @@ static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n); static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull); static int tnode_child_length(struct tnode *tn); static struct node *resize(struct trie *t, struct tnode *tn); -static struct tnode *inflate(struct trie *t, struct tnode *tn); -static struct tnode *halve(struct trie *t, struct tnode *tn); +static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err); +static struct tnode *halve(struct trie *t, struct tnode *tn, int *err); static void tnode_free(struct tnode *tn); static void trie_dump_seq(struct seq_file *seq, struct trie *t); extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio); @@ -341,8 +342,10 @@ static struct leaf *leaf_new(void) static struct leaf_info *leaf_info_new(int plen) { struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); - li->plen = plen; - INIT_LIST_HEAD(&li->falh); + if(li) { + li->plen = plen; + INIT_LIST_HEAD(&li->falh); + } return li; } @@ -356,11 +359,32 @@ static inline void free_leaf_info(struct leaf_info *li) kfree(li); } +static struct tnode *tnode_alloc(unsigned int size) +{ + if (size <= PAGE_SIZE) { + return kmalloc(size, GFP_KERNEL); + } else { + return (struct tnode *) + __get_free_pages(GFP_KERNEL, get_order(size)); + } +} + +static void __tnode_free(struct tnode *tn) +{ + unsigned int size = sizeof(struct tnode) + + (1<<tn->bits) * sizeof(struct node *); + + if (size <= PAGE_SIZE) + kfree(tn); + else + free_pages((unsigned long)tn, get_order(size)); +} + static struct tnode* tnode_new(t_key key, int pos, int bits) { int nchildren = 1<<bits; int sz = sizeof(struct tnode) + nchildren * sizeof(struct node *); - struct tnode *tn = kmalloc(sz, GFP_KERNEL); + struct tnode *tn = tnode_alloc(sz); if(tn) { memset(tn, 0, sz); @@ -388,7 +412,7 @@ static void tnode_free(struct tnode *tn) printk("FL %p \n", tn); } else if(IS_TNODE(tn)) { - kfree(tn); + __tnode_free(tn); if(trie_debug > 0 ) printk("FT %p \n", tn); } @@ -458,6 +482,7 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int w static struct node *resize(struct trie *t, struct tnode *tn) { int i; + int err = 0; if (!tn) return NULL; @@ -554,12 +579,20 @@ static struct node *resize(struct trie *t, struct tnode *tn) */ check_tnode(tn); - + + err = 0; while ((tn->full_children > 0 && 50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >= inflate_threshold * tnode_child_length(tn))) { - tn = inflate(t, tn); + tn = inflate(t, tn, &err); + + if(err) { +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.resize_node_skipped++; +#endif + break; + } } check_tnode(tn); @@ -568,11 +601,22 @@ static struct node *resize(struct trie *t, struct tnode *tn) * Halve as long as the number of empty children in this * node is above threshold. */ + + err = 0; while (tn->bits > 1 && 100 * (tnode_child_length(tn) - tn->empty_children) < - halve_threshold * tnode_child_length(tn)) + halve_threshold * tnode_child_length(tn)) { + + tn = halve(t, tn, &err); + + if(err) { +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.resize_node_skipped++; +#endif + break; + } + } - tn = halve(t, tn); /* Only one child remains */ @@ -597,7 +641,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) return (struct node *) tn; } -static struct tnode *inflate(struct trie *t, struct tnode *tn) +static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err) { struct tnode *inode; struct tnode *oldtnode = tn; @@ -609,8 +653,63 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1); - if (!tn) - trie_bug("tnode_new failed"); + if (!tn) { + *err = -ENOMEM; + return oldtnode; + } + + /* + * Preallocate and store tnodes before the actual work so we + * don't get into an inconsistent state if memory allocation + * fails. In case of failure we return the oldnode and inflate + * of tnode is ignored. + */ + + for(i = 0; i < olen; i++) { + struct tnode *inode = (struct tnode *) tnode_get_child(oldtnode, i); + + if (inode && + IS_TNODE(inode) && + inode->pos == oldtnode->pos + oldtnode->bits && + inode->bits > 1) { + struct tnode *left, *right; + + t_key m = TKEY_GET_MASK(inode->pos, 1); + + left = tnode_new(inode->key&(~m), inode->pos + 1, + inode->bits - 1); + + if(!left) { + *err = -ENOMEM; + break; + } + + right = tnode_new(inode->key|m, inode->pos + 1, + inode->bits - 1); + + if(!right) { + *err = -ENOMEM; + break; + } + + put_child(t, tn, 2*i, (struct node *) left); + put_child(t, tn, 2*i+1, (struct node *) right); + } + } + + if(*err) { + int size = tnode_child_length(tn); + int j; + + for(j = 0; j < size; j++) + if( tn->child[j]) + tnode_free((struct tnode *)tn->child[j]); + + tnode_free(tn); + + *err = -ENOMEM; + return oldtnode; + } for(i = 0; i < olen; i++) { struct node *node = tnode_get_child(oldtnode, i); @@ -623,7 +722,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) if(IS_LEAF(node) || ((struct tnode *) node)->pos > tn->pos + tn->bits - 1) { - if(tkey_extract_bits(node->key, tn->pos + tn->bits - 1, + if(tkey_extract_bits(node->key, oldtnode->pos + oldtnode->bits, 1) == 0) put_child(t, tn, 2*i, node); else @@ -663,27 +762,22 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) * the position (inode->pos) */ - t_key m = TKEY_GET_MASK(inode->pos, 1); - /* Use the old key, but set the new significant * bit to zero. */ - left = tnode_new(inode->key&(~m), inode->pos + 1, - inode->bits - 1); - if(!left) - trie_bug("tnode_new failed"); - - - /* Use the old key, but set the new significant - * bit to one. - */ - right = tnode_new(inode->key|m, inode->pos + 1, - inode->bits - 1); + left = (struct tnode *) tnode_get_child(tn, 2*i); + put_child(t, tn, 2*i, NULL); + + if(!left) + BUG(); + + right = (struct tnode *) tnode_get_child(tn, 2*i+1); + put_child(t, tn, 2*i+1, NULL); + + if(!right) + BUG(); - if(!right) - trie_bug("tnode_new failed"); - size = tnode_child_length(left); for(j = 0; j < size; j++) { put_child(t, left, j, inode->child[j]); @@ -699,7 +793,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) return tn; } -static struct tnode *halve(struct trie *t, struct tnode *tn) +static struct tnode *halve(struct trie *t, struct tnode *tn, int *err) { struct tnode *oldtnode = tn; struct node *left, *right; @@ -710,8 +804,48 @@ static struct tnode *halve(struct trie *t, struct tnode *tn) tn=tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1); - if(!tn) - trie_bug("tnode_new failed"); + if (!tn) { + *err = -ENOMEM; + return oldtnode; + } + + /* + * Preallocate and store tnodes before the actual work so we + * don't get into an inconsistent state if memory allocation + * fails. In case of failure we return the oldnode and halve + * of tnode is ignored. + */ + + for(i = 0; i < olen; i += 2) { + left = tnode_get_child(oldtnode, i); + right = tnode_get_child(oldtnode, i+1); + + /* Two nonempty children */ + if( left && right) { + struct tnode *newBinNode = + tnode_new(left->key, tn->pos + tn->bits, 1); + + if(!newBinNode) { + *err = -ENOMEM; + break; + } + put_child(t, tn, i/2, (struct node *)newBinNode); + } + } + + if(*err) { + int size = tnode_child_length(tn); + int j; + + for(j = 0; j < size; j++) + if( tn->child[j]) + tnode_free((struct tnode *)tn->child[j]); + + tnode_free(tn); + + *err = -ENOMEM; + return oldtnode; + } for(i = 0; i < olen; i += 2) { left = tnode_get_child(oldtnode, i); @@ -728,10 +862,11 @@ static struct tnode *halve(struct trie *t, struct tnode *tn) /* Two nonempty children */ else { struct tnode *newBinNode = - tnode_new(left->key, tn->pos + tn->bits, 1); + (struct tnode *) tnode_get_child(tn, i/2); + put_child(t, tn, i/2, NULL); if(!newBinNode) - trie_bug("tnode_new failed"); + BUG(); put_child(t, newBinNode, 0, left); put_child(t, newBinNode, 1, right); @@ -879,8 +1014,8 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn) return (struct node*) tn; } -static struct list_head * -fib_insert_node(struct trie *t, u32 key, int plen) +static struct list_head * +fib_insert_node(struct trie *t, int *err, u32 key, int plen) { int pos, newpos; struct tnode *tp = NULL, *tn = NULL; @@ -940,7 +1075,6 @@ fib_insert_node(struct trie *t, u32 key, int plen) if(tp && IS_LEAF(tp)) BUG(); - t->revision++; /* Case 1: n is a leaf. Compare prefixes */ @@ -949,8 +1083,10 @@ fib_insert_node(struct trie *t, u32 key, int plen) li = leaf_info_new(plen); - if(! li) - BUG(); + if(! li) { + *err = -ENOMEM; + goto err; + } fa_head = &li->falh; insert_leaf_info(&l->list, li); @@ -959,14 +1095,19 @@ fib_insert_node(struct trie *t, u32 key, int plen) t->size++; l = leaf_new(); - if(! l) - BUG(); + if(! l) { + *err = -ENOMEM; + goto err; + } l->key = key; li = leaf_info_new(plen); - if(! li) - BUG(); + if(! li) { + tnode_free((struct tnode *) l); + *err = -ENOMEM; + goto err; + } fa_head = &li->falh; insert_leaf_info(&l->list, li); @@ -1003,9 +1144,14 @@ fib_insert_node(struct trie *t, u32 key, int plen) newpos = 0; tn = tnode_new(key, newpos, 1); /* First tnode */ } - if(!tn) - trie_bug("tnode_pfx_new failed"); + if(!tn) { + free_leaf_info(li); + tnode_free((struct tnode *) l); + *err = -ENOMEM; + goto err; + } + NODE_SET_PARENT(tn, tp); missbit=tkey_extract_bits(key, newpos, 1); @@ -1027,7 +1173,9 @@ fib_insert_node(struct trie *t, u32 key, int plen) } /* Rebalance the trie */ t->trie = trie_rebalance(t, tp); -done:; +done: + t->revision++; +err:; return fa_head; } @@ -1156,8 +1304,12 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, * Insert new entry to the list. */ - if(!fa_head) - fa_head = fib_insert_node(t, key, plen); + if(!fa_head) { + fa_head = fib_insert_node(t, &err, key, plen); + err = 0; + if(err) + goto out_free_new_fa; + } write_lock_bh(&fib_lock); @@ -1170,6 +1322,9 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req); succeeded: return 0; + +out_free_new_fa: + kmem_cache_free(fn_alias_kmem, new_fa); out: fib_release_info(fi); err:; @@ -2279,6 +2434,7 @@ static void collect_and_show(struct trie *t, struct seq_file *seq) seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed); seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss); seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit); + seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped); #ifdef CLEAR_STATS memset(&(t->stats), 0, sizeof(t->stats)); #endif diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index af2ec88bbb2f..c703528e0bcd 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -283,14 +283,18 @@ static inline int ip_rcv_finish(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct iphdr *iph = skb->nh.iph; + int err; /* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ if (skb->dst == NULL) { - if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) + if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { + if (err == -EHOSTUNREACH) + IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); goto drop; + } } #ifdef CONFIG_NET_CLS_ROUTE diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ee07aec215a0..9de83e6e0f1d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -188,7 +188,13 @@ static inline int ip_finish_output2(struct sk_buff *skb) skb = skb2; } - nf_reset(skb); +#ifdef CONFIG_BRIDGE_NETFILTER + /* bridge-netfilter defers calling some IP hooks to the bridge layer + * and still needs the conntrack reference. + */ + if (skb->nf_bridge == NULL) +#endif + nf_reset(skb); if (hh) { int hh_alen; @@ -383,7 +389,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->pkt_type = from->pkt_type; to->priority = from->priority; to->protocol = from->protocol; - to->security = from->security; dst_release(to->dst); to->dst = dst_clone(from->dst); to->dev = from->dev; @@ -1323,23 +1328,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar ip_rt_put(rt); } -/* - * IP protocol layer initialiser - */ - -static struct packet_type ip_packet_type = { - .type = __constant_htons(ETH_P_IP), - .func = ip_rcv, -}; - -/* - * IP registers the packet type and then calls the subprotocol initialisers - */ - void __init ip_init(void) { - dev_add_pack(&ip_packet_type); - ip_rt_init(); inet_initpeers(); diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f2509034ce72..d2bf8e1930a3 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1149,8 +1149,10 @@ static int __init ic_dynamic(void) ic_rarp_cleanup(); #endif - if (!ic_got_reply) + if (!ic_got_reply) { + ic_myaddr = INADDR_NONE; return -1; + } printk("IP-Config: Got %s answer from %u.%u.%u.%u, ", ((ic_got_reply & IC_RARP) ? "RARP" diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index e4f809a93f47..7833d920bdba 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -297,6 +297,7 @@ static int vif_delete(int vifi) static void ipmr_destroy_unres(struct mfc_cache *c) { struct sk_buff *skb; + struct nlmsgerr *e; atomic_dec(&cache_resolve_queue_len); @@ -306,7 +307,9 @@ static void ipmr_destroy_unres(struct mfc_cache *c) nlh->nlmsg_type = NLMSG_ERROR; nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); skb_trim(skb, nlh->nlmsg_len); - ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT; + e = NLMSG_DATA(nlh); + e->error = -ETIMEDOUT; + memset(&e->msg, 0, sizeof(e->msg)); netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); } else kfree_skb(skb); @@ -499,6 +502,7 @@ static struct mfc_cache *ipmr_cache_alloc_unres(void) static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) { struct sk_buff *skb; + struct nlmsgerr *e; /* * Play the pending entries through our router @@ -515,7 +519,9 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) nlh->nlmsg_type = NLMSG_ERROR; nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); skb_trim(skb, nlh->nlmsg_len); - ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE; + e = NLMSG_DATA(nlh); + e->error = -EMSGSIZE; + memset(&e->msg, 0, sizeof(e->msg)); } err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); } else diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index fd6feb5499fe..9f16ab309106 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c @@ -548,7 +548,6 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp) { if (del_timer(&cp->timer)) mod_timer(&cp->timer, jiffies); - __ip_vs_conn_put(cp); } @@ -764,7 +763,6 @@ void ip_vs_random_dropentry(void) { int idx; struct ip_vs_conn *cp; - struct ip_vs_conn *ct; /* * Randomly scan 1/32 of the whole table every second @@ -801,21 +799,12 @@ void ip_vs_random_dropentry(void) continue; } - /* - * Drop the entry, and drop its ct if not referenced - */ - atomic_inc(&cp->refcnt); - ct_write_unlock(hash); - - if ((ct = cp->control)) - atomic_inc(&ct->refcnt); IP_VS_DBG(4, "del connection\n"); ip_vs_conn_expire_now(cp); - if (ct) { + if (cp->control) { IP_VS_DBG(4, "del conn template\n"); - ip_vs_conn_expire_now(ct); + ip_vs_conn_expire_now(cp->control); } - ct_write_lock(hash); } ct_write_unlock(hash); } @@ -829,7 +818,6 @@ static void ip_vs_conn_flush(void) { int idx; struct ip_vs_conn *cp; - struct ip_vs_conn *ct; flush_again: for (idx=0; idx<IP_VS_CONN_TAB_SIZE; idx++) { @@ -839,18 +827,13 @@ static void ip_vs_conn_flush(void) ct_write_lock_bh(idx); list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { - atomic_inc(&cp->refcnt); - ct_write_unlock(idx); - if ((ct = cp->control)) - atomic_inc(&ct->refcnt); IP_VS_DBG(4, "del connection\n"); ip_vs_conn_expire_now(cp); - if (ct) { + if (cp->control) { IP_VS_DBG(4, "del conn template\n"); - ip_vs_conn_expire_now(ct); + ip_vs_conn_expire_now(cp->control); } - ct_write_lock(idx); } ct_write_unlock_bh(idx); } diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 9cde8c61f525..6706d3a1bc4f 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -30,7 +30,7 @@ #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h> #include <linux/netfilter_ipv4/ip_conntrack.h> -#define CLUSTERIP_VERSION "0.6" +#define CLUSTERIP_VERSION "0.7" #define DEBUG_CLUSTERIP @@ -524,8 +524,9 @@ arp_mangle(unsigned int hook, || arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN) return NF_ACCEPT; - /* we only want to mangle arp replies */ - if (arp->ar_op != htons(ARPOP_REPLY)) + /* we only want to mangle arp requests and replies */ + if (arp->ar_op != htons(ARPOP_REPLY) + && arp->ar_op != htons(ARPOP_REQUEST)) return NF_ACCEPT; payload = (void *)(arp+1); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 80cf633d9f4a..726ea5e8180a 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -54,6 +54,7 @@ * Marc Boucher : routing by fwmark * Robert Olsson : Added rt_cache statistics * Arnaldo C. Melo : Convert proc stuff to seq_file + * Eric Dumazet : hashed spinlocks and rt_check_expire() fixes. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -70,6 +71,7 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/bootmem.h> #include <linux/string.h> #include <linux/socket.h> #include <linux/sockios.h> @@ -201,8 +203,37 @@ __u8 ip_tos2prio[16] = { struct rt_hash_bucket { struct rtable *chain; - spinlock_t lock; -} __attribute__((__aligned__(8))); +}; +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +/* + * Instead of using one spinlock for each rt_hash_bucket, we use a table of spinlocks + * The size of this table is a power of two and depends on the number of CPUS. + */ +#if NR_CPUS >= 32 +#define RT_HASH_LOCK_SZ 4096 +#elif NR_CPUS >= 16 +#define RT_HASH_LOCK_SZ 2048 +#elif NR_CPUS >= 8 +#define RT_HASH_LOCK_SZ 1024 +#elif NR_CPUS >= 4 +#define RT_HASH_LOCK_SZ 512 +#else +#define RT_HASH_LOCK_SZ 256 +#endif + +static spinlock_t *rt_hash_locks; +# define rt_hash_lock_addr(slot) &rt_hash_locks[(slot) & (RT_HASH_LOCK_SZ - 1)] +# define rt_hash_lock_init() { \ + int i; \ + rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ, GFP_KERNEL); \ + if (!rt_hash_locks) panic("IP: failed to allocate rt_hash_locks\n"); \ + for (i = 0; i < RT_HASH_LOCK_SZ; i++) \ + spin_lock_init(&rt_hash_locks[i]); \ + } +#else +# define rt_hash_lock_addr(slot) NULL +# define rt_hash_lock_init() +#endif static struct rt_hash_bucket *rt_hash_table; static unsigned rt_hash_mask; @@ -575,19 +606,26 @@ static struct rtable **rt_remove_balanced_route(struct rtable **chain_head, /* This runs via a timer and thus is always in BH context. */ static void rt_check_expire(unsigned long dummy) { - static int rover; - int i = rover, t; + static unsigned int rover; + unsigned int i = rover, goal; struct rtable *rth, **rthp; unsigned long now = jiffies; - - for (t = ip_rt_gc_interval << rt_hash_log; t >= 0; - t -= ip_rt_gc_timeout) { + u64 mult; + + mult = ((u64)ip_rt_gc_interval) << rt_hash_log; + if (ip_rt_gc_timeout > 1) + do_div(mult, ip_rt_gc_timeout); + goal = (unsigned int)mult; + if (goal > rt_hash_mask) goal = rt_hash_mask + 1; + for (; goal > 0; goal--) { unsigned long tmo = ip_rt_gc_timeout; i = (i + 1) & rt_hash_mask; rthp = &rt_hash_table[i].chain; - spin_lock(&rt_hash_table[i].lock); + if (*rthp == 0) + continue; + spin_lock(rt_hash_lock_addr(i)); while ((rth = *rthp) != NULL) { if (rth->u.dst.expires) { /* Entry is expired even if it is in use */ @@ -620,14 +658,14 @@ static void rt_check_expire(unsigned long dummy) rt_free(rth); #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ } - spin_unlock(&rt_hash_table[i].lock); + spin_unlock(rt_hash_lock_addr(i)); /* Fallback loop breaker. */ if (time_after(jiffies, now)) break; } rover = i; - mod_timer(&rt_periodic_timer, now + ip_rt_gc_interval); + mod_timer(&rt_periodic_timer, jiffies + ip_rt_gc_interval); } /* This can run from both BH and non-BH contexts, the latter @@ -643,11 +681,11 @@ static void rt_run_flush(unsigned long dummy) get_random_bytes(&rt_hash_rnd, 4); for (i = rt_hash_mask; i >= 0; i--) { - spin_lock_bh(&rt_hash_table[i].lock); + spin_lock_bh(rt_hash_lock_addr(i)); rth = rt_hash_table[i].chain; if (rth) rt_hash_table[i].chain = NULL; - spin_unlock_bh(&rt_hash_table[i].lock); + spin_unlock_bh(rt_hash_lock_addr(i)); for (; rth; rth = next) { next = rth->u.rt_next; @@ -780,7 +818,7 @@ static int rt_garbage_collect(void) k = (k + 1) & rt_hash_mask; rthp = &rt_hash_table[k].chain; - spin_lock_bh(&rt_hash_table[k].lock); + spin_lock_bh(rt_hash_lock_addr(k)); while ((rth = *rthp) != NULL) { if (!rt_may_expire(rth, tmo, expire)) { tmo >>= 1; @@ -812,7 +850,7 @@ static int rt_garbage_collect(void) goal--; #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ } - spin_unlock_bh(&rt_hash_table[k].lock); + spin_unlock_bh(rt_hash_lock_addr(k)); if (goal <= 0) break; } @@ -882,7 +920,7 @@ restart: rthp = &rt_hash_table[hash].chain; - spin_lock_bh(&rt_hash_table[hash].lock); + spin_lock_bh(rt_hash_lock_addr(hash)); while ((rth = *rthp) != NULL) { #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED if (!(rth->u.dst.flags & DST_BALANCED) && @@ -908,7 +946,7 @@ restart: rth->u.dst.__use++; dst_hold(&rth->u.dst); rth->u.dst.lastuse = now; - spin_unlock_bh(&rt_hash_table[hash].lock); + spin_unlock_bh(rt_hash_lock_addr(hash)); rt_drop(rt); *rp = rth; @@ -949,7 +987,7 @@ restart: if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { int err = arp_bind_neighbour(&rt->u.dst); if (err) { - spin_unlock_bh(&rt_hash_table[hash].lock); + spin_unlock_bh(rt_hash_lock_addr(hash)); if (err != -ENOBUFS) { rt_drop(rt); @@ -990,7 +1028,7 @@ restart: } #endif rt_hash_table[hash].chain = rt; - spin_unlock_bh(&rt_hash_table[hash].lock); + spin_unlock_bh(rt_hash_lock_addr(hash)); *rp = rt; return 0; } @@ -1058,7 +1096,7 @@ static void rt_del(unsigned hash, struct rtable *rt) { struct rtable **rthp; - spin_lock_bh(&rt_hash_table[hash].lock); + spin_lock_bh(rt_hash_lock_addr(hash)); ip_rt_put(rt); for (rthp = &rt_hash_table[hash].chain; *rthp; rthp = &(*rthp)->u.rt_next) @@ -1067,7 +1105,7 @@ static void rt_del(unsigned hash, struct rtable *rt) rt_free(rt); break; } - spin_unlock_bh(&rt_hash_table[hash].lock); + spin_unlock_bh(rt_hash_lock_addr(hash)); } void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, @@ -1909,7 +1947,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, */ if ((err = fib_lookup(&fl, &res)) != 0) { if (!IN_DEV_FORWARD(in_dev)) - goto e_inval; + goto e_hostunreach; goto no_route; } free_res = 1; @@ -1933,7 +1971,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, } if (!IN_DEV_FORWARD(in_dev)) - goto e_inval; + goto e_hostunreach; if (res.type != RTN_UNICAST) goto martian_destination; @@ -2025,6 +2063,11 @@ martian_destination: "%u.%u.%u.%u, dev %s\n", NIPQUAD(daddr), NIPQUAD(saddr), dev->name); #endif + +e_hostunreach: + err = -EHOSTUNREACH; + goto done; + e_inval: err = -EINVAL; goto done; @@ -3068,12 +3111,14 @@ __setup("rhash_entries=", set_rhash_entries); int __init ip_rt_init(void) { - int i, order, goal, rc = 0; + int rc = 0; rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^ (jiffies ^ (jiffies >> 7))); #ifdef CONFIG_NET_CLS_ROUTE + { + int order; for (order = 0; (PAGE_SIZE << order) < 256 * sizeof(struct ip_rt_acct) * NR_CPUS; order++) /* NOTHING */; @@ -3081,6 +3126,7 @@ int __init ip_rt_init(void) if (!ip_rt_acct) panic("IP: failed to allocate ip_rt_acct\n"); memset(ip_rt_acct, 0, PAGE_SIZE << order); + } #endif ipv4_dst_ops.kmem_cachep = kmem_cache_create("ip_dst_cache", @@ -3091,36 +3137,19 @@ int __init ip_rt_init(void) if (!ipv4_dst_ops.kmem_cachep) panic("IP: failed to allocate ip_dst_cache\n"); - goal = num_physpages >> (26 - PAGE_SHIFT); - if (rhash_entries) - goal = (rhash_entries * sizeof(struct rt_hash_bucket)) >> PAGE_SHIFT; - for (order = 0; (1UL << order) < goal; order++) - /* NOTHING */; - - do { - rt_hash_mask = (1UL << order) * PAGE_SIZE / - sizeof(struct rt_hash_bucket); - while (rt_hash_mask & (rt_hash_mask - 1)) - rt_hash_mask--; - rt_hash_table = (struct rt_hash_bucket *) - __get_free_pages(GFP_ATOMIC, order); - } while (rt_hash_table == NULL && --order > 0); - - if (!rt_hash_table) - panic("Failed to allocate IP route cache hash table\n"); - - printk(KERN_INFO "IP: routing cache hash table of %u buckets, %ldKbytes\n", - rt_hash_mask, - (long) (rt_hash_mask * sizeof(struct rt_hash_bucket)) / 1024); - - for (rt_hash_log = 0; (1 << rt_hash_log) != rt_hash_mask; rt_hash_log++) - /* NOTHING */; - - rt_hash_mask--; - for (i = 0; i <= rt_hash_mask; i++) { - spin_lock_init(&rt_hash_table[i].lock); - rt_hash_table[i].chain = NULL; - } + rt_hash_table = (struct rt_hash_bucket *) + alloc_large_system_hash("IP route cache", + sizeof(struct rt_hash_bucket), + rhash_entries, + (num_physpages >= 128 * 1024) ? + (27 - PAGE_SHIFT) : + (29 - PAGE_SHIFT), + HASH_HIGHMEM, + &rt_hash_log, + &rt_hash_mask, + 0); + memset(rt_hash_table, 0, (rt_hash_mask + 1) * sizeof(struct rt_hash_bucket)); + rt_hash_lock_init(); ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1); ip_rt_max_size = (rt_hash_mask + 1) * 16; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 882436da9a3a..29894c749163 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -615,7 +615,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse size_t psize, int flags) { struct tcp_sock *tp = tcp_sk(sk); - int mss_now; + int mss_now, size_goal; int err; ssize_t copied; long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); @@ -628,6 +628,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); + size_goal = tp->xmit_size_goal; copied = 0; err = -EPIPE; @@ -641,7 +642,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse int offset = poffset % PAGE_SIZE; int size = min_t(size_t, psize, PAGE_SIZE - offset); - if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) { + if (!sk->sk_send_head || (copy = size_goal - skb->len) <= 0) { new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; @@ -652,7 +653,7 @@ new_segment: goto wait_for_memory; skb_entail(sk, tp, skb); - copy = mss_now; + copy = size_goal; } if (copy > size) @@ -693,7 +694,7 @@ new_segment: if (!(psize -= copy)) goto out; - if (skb->len != mss_now || (flags & MSG_OOB)) + if (skb->len < mss_now || (flags & MSG_OOB)) continue; if (forced_push(tp)) { @@ -713,6 +714,7 @@ wait_for_memory: goto do_error; mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); + size_goal = tp->xmit_size_goal; } out: @@ -754,15 +756,20 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, static inline int select_size(struct sock *sk, struct tcp_sock *tp) { - int tmp = tp->mss_cache_std; + int tmp = tp->mss_cache; if (sk->sk_route_caps & NETIF_F_SG) { - int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); + if (sk->sk_route_caps & NETIF_F_TSO) + tmp = 0; + else { + int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); - if (tmp >= pgbreak && - tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) - tmp = pgbreak; + if (tmp >= pgbreak && + tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) + tmp = pgbreak; + } } + return tmp; } @@ -773,7 +780,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; int iovlen, flags; - int mss_now; + int mss_now, size_goal; int err, copied; long timeo; @@ -792,6 +799,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); + size_goal = tp->xmit_size_goal; /* Ok commence sending. */ iovlen = msg->msg_iovlen; @@ -814,7 +822,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, skb = sk->sk_write_queue.prev; if (!sk->sk_send_head || - (copy = mss_now - skb->len) <= 0) { + (copy = size_goal - skb->len) <= 0) { new_segment: /* Allocate new segment. If the interface is SG, @@ -837,7 +845,7 @@ new_segment: skb->ip_summed = CHECKSUM_HW; skb_entail(sk, tp, skb); - copy = mss_now; + copy = size_goal; } /* Try to append data to the end of skb. */ @@ -872,11 +880,6 @@ new_segment: tcp_mark_push(tp, skb); goto new_segment; } else if (page) { - /* If page is cached, align - * offset to L1 cache boundary - */ - off = (off + L1_CACHE_BYTES - 1) & - ~(L1_CACHE_BYTES - 1); if (off == PAGE_SIZE) { put_page(page); TCP_PAGE(sk) = page = NULL; @@ -937,7 +940,7 @@ new_segment: if ((seglen -= copy) == 0 && iovlen == 0) goto out; - if (skb->len != mss_now || (flags & MSG_OOB)) + if (skb->len < mss_now || (flags & MSG_OOB)) continue; if (forced_push(tp)) { @@ -957,6 +960,7 @@ wait_for_memory: goto do_error; mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); + size_goal = tp->xmit_size_goal; } } @@ -2128,7 +2132,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) info->tcpi_rto = jiffies_to_usecs(tp->rto); info->tcpi_ato = jiffies_to_usecs(tp->ack.ato); - info->tcpi_snd_mss = tp->mss_cache_std; + info->tcpi_snd_mss = tp->mss_cache; info->tcpi_rcv_mss = tp->ack.rcv_mss; info->tcpi_unacked = tp->packets_out; @@ -2178,7 +2182,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, switch (optname) { case TCP_MAXSEG: - val = tp->mss_cache_std; + val = tp->mss_cache; if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) val = tp->rx_opt.user_mss; break; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 7bbbbc33eb4b..8de2f1071c2b 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -740,10 +740,10 @@ __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); if (!cwnd) { - if (tp->mss_cache_std > 1460) + if (tp->mss_cache > 1460) cwnd = 2; else - cwnd = (tp->mss_cache_std > 1095) ? 3 : 4; + cwnd = (tp->mss_cache > 1095) ? 3 : 4; } return min_t(__u32, cwnd, tp->snd_cwnd_clamp); } @@ -914,7 +914,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (sk->sk_route_caps & NETIF_F_TSO) { sk->sk_route_caps &= ~NETIF_F_TSO; sock_set_flag(sk, SOCK_NO_LARGESEND); - tp->mss_cache = tp->mss_cache_std; + tp->mss_cache = tp->mss_cache; } if (!tp->sacked_out) @@ -1077,7 +1077,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ (IsFack(tp) || !before(lost_retrans, TCP_SKB_CB(skb)->ack_seq + tp->reordering * - tp->mss_cache_std))) { + tp->mss_cache))) { TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; tp->retrans_out -= tcp_skb_pcount(skb); @@ -1957,15 +1957,6 @@ static inline void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp) } } -/* There is one downside to this scheme. Although we keep the - * ACK clock ticking, adjusting packet counters and advancing - * congestion window, we do not liberate socket send buffer - * space. - * - * Mucking with skb->truesize and sk->sk_wmem_alloc et al. - * then making a write space wakeup callback is a possible - * future enhancement. WARNING: it is not trivial to make. - */ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, __u32 now, __s32 *seq_rtt) { @@ -2047,7 +2038,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt * the other end. */ if (after(scb->end_seq, tp->snd_una)) { - if (tcp_skb_pcount(skb) > 1) + if (tcp_skb_pcount(skb) > 1 && + after(tp->snd_una, scb->seq)) acked |= tcp_tso_acked(sk, skb, now, &seq_rtt); break; @@ -3308,6 +3300,28 @@ void tcp_cwnd_application_limited(struct sock *sk) tp->snd_cwnd_stamp = tcp_time_stamp; } +static inline int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp) +{ + /* If the user specified a specific send buffer setting, do + * not modify it. + */ + if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) + return 0; + + /* If we are under global TCP memory pressure, do not expand. */ + if (tcp_memory_pressure) + return 0; + + /* If we are under soft global TCP memory pressure, do not expand. */ + if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) + return 0; + + /* If we filled the congestion window, do not expand. */ + if (tp->packets_out >= tp->snd_cwnd) + return 0; + + return 1; +} /* When incoming ACK allowed to free some skb from write_queue, * we remember this event in flag SOCK_QUEUE_SHRUNK and wake up socket @@ -3319,11 +3333,8 @@ static void tcp_new_space(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); - if (tp->packets_out < tp->snd_cwnd && - !(sk->sk_userlocks & SOCK_SNDBUF_LOCK) && - !tcp_memory_pressure && - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { - int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache_std) + + if (tcp_should_expand_sndbuf(sk, tp)) { + int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff), demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering + 1); @@ -3346,22 +3357,9 @@ static inline void tcp_check_space(struct sock *sk) } } -static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_sock *tp = tcp_sk(sk); - - if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || - tcp_packets_in_flight(tp) >= tp->snd_cwnd || - tcp_write_xmit(sk, tp->nonagle)) - tcp_check_probe_timer(sk, tp); -} - -static __inline__ void tcp_data_snd_check(struct sock *sk) +static __inline__ void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp) { - struct sk_buff *skb = sk->sk_send_head; - - if (skb != NULL) - __tcp_data_snd_check(sk, skb); + tcp_push_pending_frames(sk, tp); tcp_check_space(sk); } @@ -3655,7 +3653,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, */ tcp_ack(sk, skb, 0); __kfree_skb(skb); - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); return 0; } else { /* Header too small */ TCP_INC_STATS_BH(TCP_MIB_INERRS); @@ -3721,7 +3719,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, if (TCP_SKB_CB(skb)->ack_seq != tp->snd_una) { /* Well, only one small jumplet in fast path... */ tcp_ack(sk, skb, FLAG_DATA); - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); if (!tcp_ack_scheduled(tp)) goto no_ack; } @@ -3799,7 +3797,7 @@ step5: /* step 7: process the segment text */ tcp_data_queue(sk, skb); - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); tcp_ack_snd_check(sk); return 0; @@ -4109,7 +4107,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, /* Do step6 onward by hand. */ tcp_urg(sk, skb, th); __kfree_skb(skb); - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); return 0; } @@ -4300,7 +4298,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, /* tcp_data could move socket to TIME-WAIT */ if (sk->sk_state != TCP_CLOSE) { - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); tcp_ack_snd_check(sk); } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ebf112347a97..62f62bb05c2a 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2045,7 +2045,7 @@ static int tcp_v4_init_sock(struct sock *sk) */ tp->snd_ssthresh = 0x7fffffff; /* Infinity */ tp->snd_cwnd_clamp = ~0; - tp->mss_cache_std = tp->mss_cache = 536; + tp->mss_cache = 536; tp->reordering = sysctl_tcp_reordering; tp->ca_ops = &tcp_init_congestion_ops; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0e17c244875c..e041d057ec86 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -49,7 +49,7 @@ int sysctl_tcp_retrans_collapse = 1; * will allow a single TSO frame to consume. Building TSO frames * which are too large can cause TCP streams to be bursty. */ -int sysctl_tcp_tso_win_divisor = 8; +int sysctl_tcp_tso_win_divisor = 3; static inline void update_send_head(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb) @@ -140,11 +140,11 @@ static inline void tcp_event_data_sent(struct tcp_sock *tp, tp->ack.pingpong = 1; } -static __inline__ void tcp_event_ack_sent(struct sock *sk) +static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts) { struct tcp_sock *tp = tcp_sk(sk); - tcp_dec_quickack_mode(tp); + tcp_dec_quickack_mode(tp, pkts); tcp_clear_xmit_timer(sk, TCP_TIME_DACK); } @@ -355,7 +355,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb) tp->af_specific->send_check(sk, th, skb->len, skb); if (tcb->flags & TCPCB_FLAG_ACK) - tcp_event_ack_sent(sk); + tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); if (skb->len != tcp_header_size) tcp_event_data_sent(tp, skb, sk); @@ -403,42 +403,11 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) sk->sk_send_head = skb; } -static inline void tcp_tso_set_push(struct sk_buff *skb) -{ - /* Force push to be on for any TSO frames to workaround - * problems with busted implementations like Mac OS-X that - * hold off socket receive wakeups until push is seen. - */ - if (tcp_skb_pcount(skb) > 1) - TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; -} - -/* Send _single_ skb sitting at the send head. This function requires - * true push pending frames to setup probe timer etc. - */ -void tcp_push_one(struct sock *sk, unsigned cur_mss) +static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *skb = sk->sk_send_head; - if (tcp_snd_test(sk, skb, cur_mss, TCP_NAGLE_PUSH)) { - /* Send it out now. */ - TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); - if (!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation))) { - sk->sk_send_head = NULL; - tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; - tcp_packets_out_inc(sk, tp, skb); - return; - } - } -} - -void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_sock *tp = tcp_sk(sk); - - if (skb->len <= tp->mss_cache_std || + if (skb->len <= tp->mss_cache || !(sk->sk_route_caps & NETIF_F_TSO)) { /* Avoid the costly divide in the normal * non-TSO case. @@ -448,10 +417,10 @@ void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb) } else { unsigned int factor; - factor = skb->len + (tp->mss_cache_std - 1); - factor /= tp->mss_cache_std; + factor = skb->len + (tp->mss_cache - 1); + factor /= tp->mss_cache; skb_shinfo(skb)->tso_segs = factor; - skb_shinfo(skb)->tso_size = tp->mss_cache_std; + skb_shinfo(skb)->tso_size = tp->mss_cache; } } @@ -537,6 +506,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) } /* Link BUFF into the send queue. */ + skb_header_release(buff); __skb_append(skb, buff); return 0; @@ -657,7 +627,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) /* And store cached results */ tp->pmtu_cookie = pmtu; - tp->mss_cache = tp->mss_cache_std = mss_now; + tp->mss_cache = mss_now; return mss_now; } @@ -669,57 +639,316 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) * cannot be large. However, taking into account rare use of URG, this * is not a big flaw. */ - -unsigned int tcp_current_mss(struct sock *sk, int large) +unsigned int tcp_current_mss(struct sock *sk, int large_allowed) { struct tcp_sock *tp = tcp_sk(sk); struct dst_entry *dst = __sk_dst_get(sk); - unsigned int do_large, mss_now; + u32 mss_now; + u16 xmit_size_goal; + int doing_tso = 0; + + mss_now = tp->mss_cache; + + if (large_allowed && + (sk->sk_route_caps & NETIF_F_TSO) && + !tp->urg_mode) + doing_tso = 1; - mss_now = tp->mss_cache_std; if (dst) { u32 mtu = dst_mtu(dst); if (mtu != tp->pmtu_cookie) mss_now = tcp_sync_mss(sk, mtu); } - do_large = (large && - (sk->sk_route_caps & NETIF_F_TSO) && - !tp->urg_mode); + if (tp->rx_opt.eff_sacks) + mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + + (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); - if (do_large) { - unsigned int large_mss, factor, limit; + xmit_size_goal = mss_now; - large_mss = 65535 - tp->af_specific->net_header_len - + if (doing_tso) { + xmit_size_goal = 65535 - + tp->af_specific->net_header_len - tp->ext_header_len - tp->tcp_header_len; - if (tp->max_window && large_mss > (tp->max_window>>1)) - large_mss = max((tp->max_window>>1), - 68U - tp->tcp_header_len); + if (tp->max_window && + (xmit_size_goal > (tp->max_window >> 1))) + xmit_size_goal = max((tp->max_window >> 1), + 68U - tp->tcp_header_len); + + xmit_size_goal -= (xmit_size_goal % mss_now); + } + tp->xmit_size_goal = xmit_size_goal; - factor = large_mss / mss_now; + return mss_now; +} - /* Always keep large mss multiple of real mss, but - * do not exceed 1/tso_win_divisor of the congestion window - * so we can keep the ACK clock ticking and minimize - * bursting. - */ - limit = tp->snd_cwnd; - if (sysctl_tcp_tso_win_divisor) - limit /= sysctl_tcp_tso_win_divisor; - limit = max(1U, limit); - if (factor > limit) - factor = limit; +/* Congestion window validation. (RFC2861) */ - tp->mss_cache = mss_now * factor; +static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) +{ + __u32 packets_out = tp->packets_out; + + if (packets_out >= tp->snd_cwnd) { + /* Network is feed fully. */ + tp->snd_cwnd_used = 0; + tp->snd_cwnd_stamp = tcp_time_stamp; + } else { + /* Network starves. */ + if (tp->packets_out > tp->snd_cwnd_used) + tp->snd_cwnd_used = tp->packets_out; - mss_now = tp->mss_cache; + if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto) + tcp_cwnd_application_limited(sk); } +} - if (tp->rx_opt.eff_sacks) - mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + - (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); - return mss_now; +static unsigned int tcp_window_allows(struct tcp_sock *tp, struct sk_buff *skb, unsigned int mss_now, unsigned int cwnd) +{ + u32 window, cwnd_len; + + window = (tp->snd_una + tp->snd_wnd - TCP_SKB_CB(skb)->seq); + cwnd_len = mss_now * cwnd; + return min(window, cwnd_len); +} + +/* Can at least one segment of SKB be sent right now, according to the + * congestion window rules? If so, return how many segments are allowed. + */ +static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *skb) +{ + u32 in_flight, cwnd; + + /* Don't be strict about the congestion window for the final FIN. */ + if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) + return 1; + + in_flight = tcp_packets_in_flight(tp); + cwnd = tp->snd_cwnd; + if (in_flight < cwnd) + return (cwnd - in_flight); + + return 0; +} + +/* This must be invoked the first time we consider transmitting + * SKB onto the wire. + */ +static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb) +{ + int tso_segs = tcp_skb_pcount(skb); + + if (!tso_segs) { + tcp_set_skb_tso_segs(sk, skb); + tso_segs = tcp_skb_pcount(skb); + } + return tso_segs; +} + +static inline int tcp_minshall_check(const struct tcp_sock *tp) +{ + return after(tp->snd_sml,tp->snd_una) && + !after(tp->snd_sml, tp->snd_nxt); +} + +/* Return 0, if packet can be sent now without violation Nagle's rules: + * 1. It is full sized. + * 2. Or it contains FIN. (already checked by caller) + * 3. Or TCP_NODELAY was set. + * 4. Or TCP_CORK is not set, and all sent packets are ACKed. + * With Minshall's modification: all sent small packets are ACKed. + */ + +static inline int tcp_nagle_check(const struct tcp_sock *tp, + const struct sk_buff *skb, + unsigned mss_now, int nonagle) +{ + return (skb->len < mss_now && + ((nonagle&TCP_NAGLE_CORK) || + (!nonagle && + tp->packets_out && + tcp_minshall_check(tp)))); +} + +/* Return non-zero if the Nagle test allows this packet to be + * sent now. + */ +static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb, + unsigned int cur_mss, int nonagle) +{ + /* Nagle rule does not apply to frames, which sit in the middle of the + * write_queue (they have no chances to get new data). + * + * This is implemented in the callers, where they modify the 'nonagle' + * argument based upon the location of SKB in the send queue. + */ + if (nonagle & TCP_NAGLE_PUSH) + return 1; + + /* Don't use the nagle rule for urgent data (or for the final FIN). */ + if (tp->urg_mode || + (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) + return 1; + + if (!tcp_nagle_check(tp, skb, cur_mss, nonagle)) + return 1; + + return 0; +} + +/* Does at least the first segment of SKB fit into the send window? */ +static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb, unsigned int cur_mss) +{ + u32 end_seq = TCP_SKB_CB(skb)->end_seq; + + if (skb->len > cur_mss) + end_seq = TCP_SKB_CB(skb)->seq + cur_mss; + + return !after(end_seq, tp->snd_una + tp->snd_wnd); +} + +/* This checks if the data bearing packet SKB (usually sk->sk_send_head) + * should be put on the wire right now. If so, it returns the number of + * packets allowed by the congestion window. + */ +static unsigned int tcp_snd_test(struct sock *sk, struct sk_buff *skb, + unsigned int cur_mss, int nonagle) +{ + struct tcp_sock *tp = tcp_sk(sk); + unsigned int cwnd_quota; + + tcp_init_tso_segs(sk, skb); + + if (!tcp_nagle_test(tp, skb, cur_mss, nonagle)) + return 0; + + cwnd_quota = tcp_cwnd_test(tp, skb); + if (cwnd_quota && + !tcp_snd_wnd_test(tp, skb, cur_mss)) + cwnd_quota = 0; + + return cwnd_quota; +} + +static inline int tcp_skb_is_last(const struct sock *sk, + const struct sk_buff *skb) +{ + return skb->next == (struct sk_buff *)&sk->sk_write_queue; +} + +int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) +{ + struct sk_buff *skb = sk->sk_send_head; + + return (skb && + tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), + (tcp_skb_is_last(sk, skb) ? + TCP_NAGLE_PUSH : + tp->nonagle))); +} + +/* Trim TSO SKB to LEN bytes, put the remaining data into a new packet + * which is put after SKB on the list. It is very much like + * tcp_fragment() except that it may make several kinds of assumptions + * in order to speed up the splitting operation. In particular, we + * know that all the data is in scatter-gather pages, and that the + * packet has never been sent out before (and thus is not cloned). + */ +static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len) +{ + struct sk_buff *buff; + int nlen = skb->len - len; + u16 flags; + + /* All of a TSO frame must be composed of paged data. */ + BUG_ON(skb->len != skb->data_len); + + buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC); + if (unlikely(buff == NULL)) + return -ENOMEM; + + buff->truesize = nlen; + skb->truesize -= nlen; + + /* Correct the sequence numbers. */ + TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; + TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; + + /* PSH and FIN should only be set in the second packet. */ + flags = TCP_SKB_CB(skb)->flags; + TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH); + TCP_SKB_CB(buff)->flags = flags; + + /* This packet was never sent out yet, so no SACK bits. */ + TCP_SKB_CB(buff)->sacked = 0; + + buff->ip_summed = skb->ip_summed = CHECKSUM_HW; + skb_split(skb, buff, len); + + /* Fix up tso_factor for both original and new SKB. */ + tcp_set_skb_tso_segs(sk, skb); + tcp_set_skb_tso_segs(sk, buff); + + /* Link BUFF into the send queue. */ + skb_header_release(buff); + __skb_append(skb, buff); + + return 0; +} + +/* Try to defer sending, if possible, in order to minimize the amount + * of TSO splitting we do. View it as a kind of TSO Nagle test. + * + * This algorithm is from John Heffner. + */ +static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb) +{ + u32 send_win, cong_win, limit, in_flight; + + if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) + return 0; + + if (tp->ca_state != TCP_CA_Open) + return 0; + + in_flight = tcp_packets_in_flight(tp); + + BUG_ON(tcp_skb_pcount(skb) <= 1 || + (tp->snd_cwnd <= in_flight)); + + send_win = (tp->snd_una + tp->snd_wnd) - TCP_SKB_CB(skb)->seq; + + /* From in_flight test above, we know that cwnd > in_flight. */ + cong_win = (tp->snd_cwnd - in_flight) * tp->mss_cache; + + limit = min(send_win, cong_win); + + /* If sk_send_head can be sent fully now, just do it. */ + if (skb->len <= limit) + return 0; + + if (sysctl_tcp_tso_win_divisor) { + u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); + + /* If at least some fraction of a window is available, + * just use it. + */ + chunk /= sysctl_tcp_tso_win_divisor; + if (limit >= chunk) + return 0; + } else { + /* Different approach, try not to defer past a single + * ACK. Receiver should ACK every other full sized + * frame, so if we have space for more than 3 frames + * then send now. + */ + if (limit > tcp_max_burst(tp) * tp->mss_cache) + return 0; + } + + /* Ok, it looks like it is advisable to defer. */ + return 1; } /* This routine writes packets to the network. It advances the @@ -729,57 +958,158 @@ unsigned int tcp_current_mss(struct sock *sk, int large) * Returns 1, if no segments are in flight and we have queued segments, but * cannot send anything now because of SWS or another problem. */ -int tcp_write_xmit(struct sock *sk, int nonagle) +static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) { struct tcp_sock *tp = tcp_sk(sk); - unsigned int mss_now; + struct sk_buff *skb; + unsigned int tso_segs, sent_pkts; + int cwnd_quota; /* If we are closed, the bytes will have to remain here. * In time closedown will finish, we empty the write queue and all * will be happy. */ - if (sk->sk_state != TCP_CLOSE) { - struct sk_buff *skb; - int sent_pkts = 0; + if (unlikely(sk->sk_state == TCP_CLOSE)) + return 0; + + skb = sk->sk_send_head; + if (unlikely(!skb)) + return 0; + + tso_segs = tcp_init_tso_segs(sk, skb); + cwnd_quota = tcp_cwnd_test(tp, skb); + if (unlikely(!cwnd_quota)) + goto out; + + sent_pkts = 0; + while (likely(tcp_snd_wnd_test(tp, skb, mss_now))) { + BUG_ON(!tso_segs); + + if (tso_segs == 1) { + if (unlikely(!tcp_nagle_test(tp, skb, mss_now, + (tcp_skb_is_last(sk, skb) ? + nonagle : TCP_NAGLE_PUSH)))) + break; + } else { + if (tcp_tso_should_defer(sk, tp, skb)) + break; + } - /* Account for SACKS, we may need to fragment due to this. - * It is just like the real MSS changing on us midstream. - * We also handle things correctly when the user adds some - * IP options mid-stream. Silly to do, but cover it. - */ - mss_now = tcp_current_mss(sk, 1); - - while ((skb = sk->sk_send_head) && - tcp_snd_test(sk, skb, mss_now, - tcp_skb_is_last(sk, skb) ? nonagle : - TCP_NAGLE_PUSH)) { - if (skb->len > mss_now) { - if (tcp_fragment(sk, skb, mss_now)) + if (tso_segs > 1) { + u32 limit = tcp_window_allows(tp, skb, + mss_now, cwnd_quota); + + if (skb->len < limit) { + unsigned int trim = skb->len % mss_now; + + if (trim) + limit = skb->len - trim; + } + if (skb->len > limit) { + if (tso_fragment(sk, skb, limit)) break; } - - TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); - if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))) + } else if (unlikely(skb->len > mss_now)) { + if (unlikely(tcp_fragment(sk, skb, mss_now))) break; + } - /* Advance the send_head. This one is sent out. - * This call will increment packets_out. - */ - update_send_head(sk, tp, skb); + TCP_SKB_CB(skb)->when = tcp_time_stamp; + + if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))) + break; + + /* Advance the send_head. This one is sent out. + * This call will increment packets_out. + */ + update_send_head(sk, tp, skb); + + tcp_minshall_update(tp, mss_now, skb); + sent_pkts++; + + /* Do not optimize this to use tso_segs. If we chopped up + * the packet above, tso_segs will no longer be valid. + */ + cwnd_quota -= tcp_skb_pcount(skb); + + BUG_ON(cwnd_quota < 0); + if (!cwnd_quota) + break; + + skb = sk->sk_send_head; + if (!skb) + break; + tso_segs = tcp_init_tso_segs(sk, skb); + } + + if (likely(sent_pkts)) { + tcp_cwnd_validate(sk, tp); + return 0; + } +out: + return !tp->packets_out && sk->sk_send_head; +} + +/* Push out any pending frames which were held back due to + * TCP_CORK or attempt at coalescing tiny packets. + * The socket must be locked by the caller. + */ +void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, + unsigned int cur_mss, int nonagle) +{ + struct sk_buff *skb = sk->sk_send_head; - tcp_minshall_update(tp, mss_now, skb); - sent_pkts = 1; + if (skb) { + if (tcp_write_xmit(sk, cur_mss, nonagle)) + tcp_check_probe_timer(sk, tp); + } +} + +/* Send _single_ skb sitting at the send head. This function requires + * true push pending frames to setup probe timer etc. + */ +void tcp_push_one(struct sock *sk, unsigned int mss_now) +{ + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb = sk->sk_send_head; + unsigned int tso_segs, cwnd_quota; + + BUG_ON(!skb || skb->len < mss_now); + + tso_segs = tcp_init_tso_segs(sk, skb); + cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH); + + if (likely(cwnd_quota)) { + BUG_ON(!tso_segs); + + if (tso_segs > 1) { + u32 limit = tcp_window_allows(tp, skb, + mss_now, cwnd_quota); + + if (skb->len < limit) { + unsigned int trim = skb->len % mss_now; + + if (trim) + limit = skb->len - trim; + } + if (skb->len > limit) { + if (unlikely(tso_fragment(sk, skb, limit))) + return; + } + } else if (unlikely(skb->len > mss_now)) { + if (unlikely(tcp_fragment(sk, skb, mss_now))) + return; } - if (sent_pkts) { + /* Send it out now. */ + TCP_SKB_CB(skb)->when = tcp_time_stamp; + + if (likely(!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation)))) { + update_send_head(sk, tp, skb); tcp_cwnd_validate(sk, tp); - return 0; + return; } - - return !tp->packets_out && sk->sk_send_head; } - return 0; } /* This function returns the amount that we can raise the @@ -1039,7 +1369,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) if (sk->sk_route_caps & NETIF_F_TSO) { sk->sk_route_caps &= ~NETIF_F_TSO; sock_set_flag(sk, SOCK_NO_LARGESEND); - tp->mss_cache = tp->mss_cache_std; } if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq)) @@ -1101,7 +1430,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) * is still in somebody's hands, else make a clone. */ TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); err = tcp_transmit_skb(sk, (skb_cloned(skb) ? pskb_copy(skb, GFP_ATOMIC): @@ -1670,14 +1998,12 @@ int tcp_write_wakeup(struct sock *sk) if (sk->sk_route_caps & NETIF_F_TSO) { sock_set_flag(sk, SOCK_NO_LARGESEND); sk->sk_route_caps &= ~NETIF_F_TSO; - tp->mss_cache = tp->mss_cache_std; } } else if (!tcp_skb_pcount(skb)) tcp_set_skb_tso_segs(sk, skb); TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); if (!err) { update_send_head(sk, tp, skb); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a54d4ef3fd35..77004b9456c0 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2777,7 +2777,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, read_lock_bh(&idev->lock); switch (type) { case UNICAST_ADDR: - /* unicast address */ + /* unicast address incl. temp addr */ for (ifa = idev->addr_list; ifa; ifa = ifa->if_next, ip_idx++) { if (ip_idx < s_ip_idx) @@ -2788,19 +2788,6 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, NLM_F_MULTI)) <= 0) goto done; } - /* temp addr */ -#ifdef CONFIG_IPV6_PRIVACY - for (ifa = idev->tempaddr_list; ifa; - ifa = ifa->tmp_next, ip_idx++) { - if (ip_idx < s_ip_idx) - continue; - if ((err = inet6_fill_ifaddr(skb, ifa, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, RTM_NEWADDR, - NLM_F_MULTI)) <= 0) - goto done; - } -#endif break; case MULTICAST_ADDR: /* multicast address */ @@ -2923,6 +2910,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); r = NLMSG_DATA(nlh); r->ifi_family = AF_INET6; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev_get_flags(dev); @@ -3030,9 +3018,12 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); pmsg = NLMSG_DATA(nlh); pmsg->prefix_family = AF_INET6; + pmsg->prefix_pad1 = 0; + pmsg->prefix_pad2 = 0; pmsg->prefix_ifindex = idev->dev->ifindex; pmsg->prefix_len = pinfo->prefix_len; pmsg->prefix_type = pinfo->type; + pmsg->prefix_pad3 = 0; pmsg->prefix_flags = 0; if (pinfo->onlink) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 2b193e3df49a..28d9bcab0970 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -774,7 +774,6 @@ static int __init inet6_init(void) if (if6_proc_init()) goto proc_if6_fail; #endif - ipv6_packet_init(); ip6_route_init(); ip6_flowlabel_init(); err = addrconf_init(); @@ -791,6 +790,8 @@ static int __init inet6_init(void) /* Init v6 transport protocols. */ udpv6_init(); tcpv6_init(); + + ipv6_packet_init(); err = 0; out: return err; @@ -798,7 +799,6 @@ out: addrconf_fail: ip6_flowlabel_cleanup(); ip6_route_cleanup(); - ipv6_packet_cleanup(); #ifdef CONFIG_PROC_FS if6_proc_exit(); proc_if6_fail: diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 0e5f7499debb..b6c73da5ff35 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -244,7 +244,6 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, opt_space->opt_nflen = 0; } opt_space->dst1opt = fopt->dst1opt; - opt_space->auth = fopt->auth; opt_space->opt_flen = fopt->opt_flen; return opt_space; } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 06e7cdaeedc5..1f2c2f9e353f 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -465,7 +465,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->pkt_type = from->pkt_type; to->priority = from->priority; to->protocol = from->protocol; - to->security = from->security; dst_release(to->dst); to->dst = dst_clone(from->dst); to->dev = from->dev; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9dac7fdf4726..f6e288dc116e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -2018,7 +2018,7 @@ static int tcp_v6_init_sock(struct sock *sk) */ tp->snd_ssthresh = 0x7fffffff; tp->snd_cwnd_clamp = ~0; - tp->mss_cache_std = tp->mss_cache = 536; + tp->mss_cache = 536; tp->reordering = sysctl_tcp_reordering; diff --git a/net/sched/Makefile b/net/sched/Makefile index 8f58cecd6266..e48d0d456b3e 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -4,7 +4,7 @@ obj-y := sch_generic.o -obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o +obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o sch_blackhole.o obj-$(CONFIG_NET_CLS) += cls_api.o obj-$(CONFIG_NET_CLS_ACT) += act_api.o obj-$(CONFIG_NET_ACT_POLICE) += police.o diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 9594206e6035..249c61936ea0 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -439,6 +439,8 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr*) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -580,6 +582,8 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t)); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr *) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -687,7 +691,9 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; - + t->tca__pad1 = 0; + t->tca__pad2 = 0; + x = (struct rtattr*) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -842,6 +848,8 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) cb->nlh->nlmsg_type, sizeof(*t)); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr *) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 1616bf5c9627..3b5714ef4d1a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -331,6 +331,8 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); tcm = NLMSG_DATA(nlh); tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad1 = 0; tcm->tcm_ifindex = tp->q->dev->ifindex; tcm->tcm_parent = tp->classid; tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 232fb9196810..006168d69376 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -618,6 +618,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, pinfo.protocol = s->protocol; pinfo.tunnelid = s->tunnelid; pinfo.tunnelhdr = f->tunnelhdr; + pinfo.pad = 0; RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo); if (f->res.classid) RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid); diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 48bb23c2a35a..53d98f8d3d80 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -205,11 +205,6 @@ META_COLLECTOR(int_protocol) dst->value = skb->protocol; } -META_COLLECTOR(int_security) -{ - dst->value = skb->security; -} - META_COLLECTOR(int_pkttype) { dst->value = skb->pkt_type; @@ -524,7 +519,6 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [META_ID(REALDEV)] = META_FUNC(int_realdev), [META_ID(PRIORITY)] = META_FUNC(int_priority), [META_ID(PROTOCOL)] = META_FUNC(int_protocol), - [META_ID(SECURITY)] = META_FUNC(int_security), [META_ID(PKTTYPE)] = META_FUNC(int_pkttype), [META_ID(PKTLEN)] = META_FUNC(int_pktlen), [META_ID(DATALEN)] = META_FUNC(int_datalen), diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 97c1c75d5c78..b9a069af4a02 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -399,10 +399,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) { int err; struct rtattr *kind = tca[TCA_KIND-1]; - void *p = NULL; struct Qdisc *sch; struct Qdisc_ops *ops; - int size; ops = qdisc_lookup_ops(kind); #ifdef CONFIG_KMOD @@ -437,64 +435,55 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) if (ops == NULL) goto err_out; - /* ensure that the Qdisc and the private data are 32-byte aligned */ - size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); - size += ops->priv_size + QDISC_ALIGN_CONST; - - p = kmalloc(size, GFP_KERNEL); - err = -ENOBUFS; - if (!p) + sch = qdisc_alloc(dev, ops); + if (IS_ERR(sch)) { + err = PTR_ERR(sch); goto err_out2; - memset(p, 0, size); - sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) - & ~QDISC_ALIGN_CONST); - sch->padded = (char *)sch - (char *)p; - - INIT_LIST_HEAD(&sch->list); - skb_queue_head_init(&sch->q); + } - if (handle == TC_H_INGRESS) + if (handle == TC_H_INGRESS) { sch->flags |= TCQ_F_INGRESS; - - sch->ops = ops; - sch->enqueue = ops->enqueue; - sch->dequeue = ops->dequeue; - sch->dev = dev; - dev_hold(dev); - atomic_set(&sch->refcnt, 1); - sch->stats_lock = &dev->queue_lock; - if (handle == 0) { + handle = TC_H_MAKE(TC_H_INGRESS, 0); + } else if (handle == 0) { handle = qdisc_alloc_handle(dev); err = -ENOMEM; if (handle == 0) goto err_out3; } - if (handle == TC_H_INGRESS) - sch->handle =TC_H_MAKE(TC_H_INGRESS, 0); - else - sch->handle = handle; + sch->handle = handle; if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { +#ifdef CONFIG_NET_ESTIMATOR + if (tca[TCA_RATE-1]) { + err = gen_new_estimator(&sch->bstats, &sch->rate_est, + sch->stats_lock, + tca[TCA_RATE-1]); + if (err) { + /* + * Any broken qdiscs that would require + * a ops->reset() here? The qdisc was never + * in action so it shouldn't be necessary. + */ + if (ops->destroy) + ops->destroy(sch); + goto err_out3; + } + } +#endif qdisc_lock_tree(dev); list_add_tail(&sch->list, &dev->qdisc_list); qdisc_unlock_tree(dev); -#ifdef CONFIG_NET_ESTIMATOR - if (tca[TCA_RATE-1]) - gen_new_estimator(&sch->bstats, &sch->rate_est, - sch->stats_lock, tca[TCA_RATE-1]); -#endif return sch; } err_out3: dev_put(dev); + kfree((char *) sch - sch->padded); err_out2: module_put(ops->owner); err_out: *errp = err; - if (p) - kfree(p); return NULL; } @@ -770,6 +759,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); tcm = NLMSG_DATA(nlh); tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad2 = 0; tcm->tcm_ifindex = q->dev->ifindex; tcm->tcm_parent = clid; tcm->tcm_handle = q->handle; diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c new file mode 100644 index 000000000000..81f0b8346d17 --- /dev/null +++ b/net/sched/sch_blackhole.c @@ -0,0 +1,54 @@ +/* + * net/sched/sch_blackhole.c Black hole queue + * + * 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. + * + * Authors: Thomas Graf <tgraf@suug.ch> + * + * Note: Quantum tunneling is not supported. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <net/pkt_sched.h> + +static int blackhole_enqueue(struct sk_buff *skb, struct Qdisc *sch) +{ + qdisc_drop(skb, sch); + return NET_XMIT_SUCCESS; +} + +static struct sk_buff *blackhole_dequeue(struct Qdisc *sch) +{ + return NULL; +} + +static struct Qdisc_ops blackhole_qdisc_ops = { + .id = "blackhole", + .priv_size = 0, + .enqueue = blackhole_enqueue, + .dequeue = blackhole_dequeue, + .owner = THIS_MODULE, +}; + +static int __init blackhole_module_init(void) +{ + return register_qdisc(&blackhole_qdisc_ops); +} + +static void __exit blackhole_module_exit(void) +{ + unregister_qdisc(&blackhole_qdisc_ops); +} + +module_init(blackhole_module_init) +module_exit(blackhole_module_exit) + +MODULE_LICENSE("GPL"); diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index d43e3b8cbf6a..09453f997d8c 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1528,6 +1528,7 @@ static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl) opt.strategy = cl->ovl_strategy; opt.priority2 = cl->priority2+1; + opt.pad = 0; opt.penalty = (cl->penalty*1000)/HZ; RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt); return skb->len; @@ -1563,6 +1564,8 @@ static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl) if (cl->police) { opt.police = cl->police; + opt.__res1 = 0; + opt.__res2 = 0; RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt); } return skb->len; diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 7683b34dc6a9..73e218e646ac 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -395,24 +395,23 @@ static struct Qdisc_ops pfifo_fast_ops = { .owner = THIS_MODULE, }; -struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) +struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) { void *p; struct Qdisc *sch; - int size; + unsigned int size; + int err = -ENOBUFS; /* ensure that the Qdisc and the private data are 32-byte aligned */ - size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); - size += ops->priv_size + QDISC_ALIGN_CONST; + size = QDISC_ALIGN(sizeof(*sch)); + size += ops->priv_size + (QDISC_ALIGNTO - 1); p = kmalloc(size, GFP_KERNEL); if (!p) - return NULL; + goto errout; memset(p, 0, size); - - sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) - & ~QDISC_ALIGN_CONST); - sch->padded = (char *)sch - (char *)p; + sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); + sch->padded = (char *) sch - (char *) p; INIT_LIST_HEAD(&sch->list); skb_queue_head_init(&sch->q); @@ -423,11 +422,24 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) dev_hold(dev); sch->stats_lock = &dev->queue_lock; atomic_set(&sch->refcnt, 1); + + return sch; +errout: + return ERR_PTR(-err); +} + +struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) +{ + struct Qdisc *sch; + + sch = qdisc_alloc(dev, ops); + if (IS_ERR(sch)) + goto errout; + if (!ops->init || ops->init(sch, NULL) == 0) return sch; - dev_put(dev); - kfree(p); +errout: return NULL; } @@ -591,6 +603,7 @@ EXPORT_SYMBOL(__netdev_watchdog_up); EXPORT_SYMBOL(noop_qdisc); EXPORT_SYMBOL(noop_qdisc_ops); EXPORT_SYMBOL(qdisc_create_dflt); +EXPORT_SYMBOL(qdisc_alloc); EXPORT_SYMBOL(qdisc_destroy); EXPORT_SYMBOL(qdisc_reset); EXPORT_SYMBOL(qdisc_restart); diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 2ec0320fac3b..c44bf4165c6e 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -102,9 +102,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, /* Set up the base timeout information. */ ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = - SCTP_DEFAULT_TIMEOUT_T1_COOKIE; + msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = - SCTP_DEFAULT_TIMEOUT_T1_INIT; + msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; @@ -117,12 +117,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD] = 5 * msecs_to_jiffies(sp->rtoinfo.srto_max); - ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = - SCTP_DEFAULT_TIMEOUT_HEARTBEAT; - ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = - SCTP_DEFAULT_TIMEOUT_SACK; - ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = - sp->autoclose * HZ; + ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; + ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = sctp_sack_timeout; + ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; /* Use SCTP specific send buffer space queues. */ ep->sndbuf_policy = sctp_sndbuf_policy; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5135e1a25d25..e7f37faba7c0 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1050,7 +1050,10 @@ SCTP_STATIC __init int sctp_init(void) sctp_sndbuf_policy = 0; /* HB.interval - 30 seconds */ - sctp_hb_interval = 30 * HZ; + sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; + + /* delayed SACK timeout */ + sctp_sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK; /* Implementation specific variables. */ diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 7fc31849312b..dc4893474f18 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -47,6 +47,8 @@ static ctl_handler sctp_sysctl_jiffies_ms; static long rto_timer_min = 1; static long rto_timer_max = 86400000; /* One day */ +static long sack_timer_min = 1; +static long sack_timer_max = 500; static ctl_table sctp_table[] = { { @@ -187,6 +189,17 @@ static ctl_table sctp_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, + { + .ctl_name = NET_SCTP_SACK_TIMEOUT, + .procname = "sack_timeout", + .data = &sctp_sack_timeout, + .maxlen = sizeof(long), + .mode = 0644, + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &sack_timer_min, + .extra2 = &sack_timer_max, + }, { .ctl_name = 0 } }; diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 0ec0fde6e6c5..a63b69179607 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -103,7 +103,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, /* Set up the heartbeat timer. */ init_timer(&peer->hb_timer); - peer->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; peer->hb_timer.function = sctp_generate_heartbeat_event; peer->hb_timer.data = (unsigned long)peer; diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 908bff6d1eef..5180405c1a84 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -25,6 +25,8 @@ typedef Elf64_Addr kernel_ulong_t; #include <stdint.h> #endif +#include <ctype.h> + typedef uint32_t __u32; typedef uint16_t __u16; typedef unsigned char __u8; @@ -323,6 +325,22 @@ static int do_pcmcia_entry(const char *filename, +static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) +{ + char *tmp; + sprintf (alias, "of:N%sT%sC%s", + of->name[0] ? of->name : "*", + of->type[0] ? of->type : "*", + of->compatible[0] ? of->compatible : "*"); + + /* Replace all whitespace with underscores */ + for (tmp = alias; tmp && *tmp; tmp++) + if (isspace (*tmp)) + *tmp = '_'; + + return 1; +} + /* Ignore any prefix, eg. v850 prepends _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -401,6 +419,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, else if (sym_is(symname, "__mod_pcmcia_device_table")) do_table(symval, sym->st_size, sizeof(struct pcmcia_device_id), do_pcmcia_entry, mod); + else if (sym_is(symname, "__mod_of_device_table")) + do_table(symval, sym->st_size, sizeof(struct of_device_id), + do_of_entry, mod); + } /* Now add out buffered information to the generated C source */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 17a1189f1ff8..6be273851144 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -68,6 +68,7 @@ #include <linux/personality.h> #include <linux/sysctl.h> #include <linux/audit.h> +#include <linux/string.h> #include "avc.h" #include "objsec.h" @@ -1943,7 +1944,7 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void } } while (*in_end++); - copy_page(in_save, nosec_save); + strcpy(in_save, nosec_save); free_page((unsigned long)nosec_save); out: return rc; diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index defdc5a459f0..c5557eaf3e2e 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -798,13 +798,15 @@ static struct { {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */ }; +static struct pci_driver driver; + /* return the rate of the card, or a negative value if it's blacklisted */ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) { int i; const struct pci_device_id *supported; - supported = pci_match_device(snd_bt87x_ids, pci); + supported = pci_match_device(&driver, pci); if (supported) return supported->driver_data; |