Merge /spare/repo/netdev-2.6 branch 'ieee80211'

This commit is contained in:
Jeff Garzik 2005-06-30 00:49:38 -04:00
commit e9dd256179
309 changed files with 4417 additions and 4651 deletions

View file

@ -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>

View file

@ -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.

View file

@ -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."

View file

@ -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.

View file

@ -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)

View file

@ -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>&nbsp;</TD><TD>Bit 6:</TD><TD>Corrected bit. Indicates that
an error was corrected for this data block.</TD></TR>
<TR><TD>&nbsp;</TD><TD>Bits 5-3:</TD><TD>Received Offset. Indicates the
offset received by the sync system.</TD></TR>
<TR><TD>&nbsp;</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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
=======

View file

@ -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
@ -2632,10 +2632,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

View file

@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 12
EXTRAVERSION =
SUBLEVEL = 13
EXTRAVERSION =-rc1
NAME=Woozy Numbat
# *DOCUMENTATION*

View file

@ -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)

View file

@ -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);
@ -134,9 +131,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);

View file

@ -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)

View file

@ -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);
}

View file

@ -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)

View file

@ -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)

View file

@ -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;
}

View file

@ -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

View file

@ -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();
}
/*

View file

@ -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();

View file

@ -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

View file

@ -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

View file

@ -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
}
};

View file

@ -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);

View file

@ -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,13 @@ 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,
.map_io = bast_map_io,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END

View file

@ -371,16 +371,12 @@ 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)
.map_io = vr1000_map_io,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END

View file

@ -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);

View file

@ -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;
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);
timer0->TimerLoad = TIMER_RELOAD;
timer0->TimerValue = TIMER_RELOAD;
timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */
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

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -32,6 +32,8 @@
*/
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <asm/div64.h>
#include <asm/ptrace.h>
#include <asm/vfp.h>

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
@ -188,6 +189,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

View file

@ -57,6 +57,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;
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);
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 = pirq_check_routing_table(addr);
if (rt)
return rt;
}
}
return NULL;
}

View file

@ -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();

View file

@ -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 inline void pci_exp_set_dev_base(int bus, int devfn)
static u32 get_base_addr(unsigned int seg, int bus)
{
u32 dev_base = pci_mmcfg_base_addr | (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_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(unsigned int seg, int bus, int devfn)
{
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

View file

@ -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)

View file

@ -27,6 +27,7 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern unsigned int pci_probe;
extern unsigned long pirq_table_addr;
/* pci-i386.c */

View file

@ -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
#

View file

@ -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
#
#
@ -856,6 +871,10 @@ CONFIG_USB_HIDINPUT=y
#
# CONFIG_INFINIBAND is not set
#
# SN Devices
#
#
# File systems
#
@ -863,6 +882,7 @@ 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

View file

@ -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
#
@ -146,10 +168,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)
@ -564,18 +583,6 @@ CONFIG_INPUT_JOYDEV=y
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
#
@ -585,6 +592,16 @@ CONFIG_SERIO=y
# CONFIG_INPUT_TOUCHSCREEN is not set
# 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
#
@ -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
#
#
@ -1040,6 +1095,15 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_MMC is not set
#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
# SN Devices
#
#
# File systems
#
@ -1047,6 +1111,7 @@ 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

View file

@ -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

View file

@ -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;
}

View file

@ -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 */

View file

@ -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
;;
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
;;
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 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 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr
ld8.fill r1=[r3],16 // load r1
(pUStk) mov r17=1
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
nop 0
;;
srlz.d // M0 ensure interruption collection is off
ld8.fill r13=[r3],16
mov f7=f0 // clear f7
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.fill r12=[r2] // restore r12 (sp)
mov.m ar.ssd=r0 // M2 clear ar.ssd
mov r22=r0 // clear r22
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) // M0|1 load ar.fpsr
ld8.fill r1=[r3],16 // M0|1 load r1
(pUStk) mov r17=1 // A
;;
(pUStk) st1 [r14]=r17 // M2|3
ld8.fill r13=[r3],16 // M0|1
mov f8=f0 // F clear f8
;;
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
;;
(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
;;
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
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
mov.m ar.ccv=r0 // clear ar.ccv
(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
br.cond.sptk.many rbs_switch
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=[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.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.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

View file

@ -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
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
;;
mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS
movl r8=PSR_ONE_BITS // X
;;
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
;;
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
// ensure previous insn group is issued before we stall for srlz.i:
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
;;
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.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
;;
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
;;
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
;;
mov rp=r2 // set the real return addr
and r3=_TIF_SYSCALL_TRACEAUDIT,r3
;;
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

View file

@ -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)
rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
LOAD_FSYSCALL_TABLE(r14) // X
;;
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
;;
(p8) ssm psr.i
(p6) mov b7=r18 // I0
(p8) br.dptk.many b7 // B
mov r16=IA64_KR(CURRENT) // 12 cycle read latency
tnat.nz p10,p9=r15
mov r19=NR_syscalls-1
;;
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 r29=psr // read psr (12 cyc load latency)
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

View file

@ -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);

View file

@ -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;
addr = ioremap(phys_addr, 0);
ver = iosapic_version(addr);
spin_lock_irqsave(&iosapic_lock, flags);
{
addr = ioremap(phys_addr, 0);
ver = iosapic_version(addr);
/*
* 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;
if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
iounmap(addr);
spin_unlock_irqrestore(&iosapic_lock, flags);
return err;
}
iosapic_lists[num_iosapic].addr = addr;
iosapic_lists[num_iosapic].gsi_base = gsi_base;
iosapic_lists[num_iosapic].num_rte = num_rte;
/*
* 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;
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;

View file

@ -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 = &current_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
;;
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
;;
invala
/* adjust return address so we skip over the break instruction: */
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
;;
// 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
adds r15=-1024,r15 // A subtract 1024 from syscall number
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
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
adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024
movl r2=ia64_ret_from_syscall
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?
;;
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
;;
(p6) ld8 r20=[r20] // load address of syscall entry point
(p7) movl r20=sys_ni_syscall
add r2=TI_FLAGS+IA64_TASK_SIZE,r13
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?
mov.m ar.bspstore=r22 // M2 switch to kernel RBS
cmp.eq p8,p9=2,r8 // A isr.ei==2?
;;
ld4 r2=[r2] // r2 = current_thread_info()->flags
(p8) mov r8=0 // A clear ei to 0
(p7) movl r30=sys_ni_syscall // X
(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
;;
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
;;
cmp.eq p8,p0=r2,r0
mov b6=r20
.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
;;
(p8) br.call.sptk.many b6=b6 // ignore this return addr
br.cond.sptk ia64_trace_syscall
ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection
movl r3=ia64_ret_from_syscall // X
;;
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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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], &region);
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);

View file

@ -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;
/*

View file

@ -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;

View file

@ -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 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 defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
if (conswitchp == &vga_con) {
/*
* If there was a primary vga adapter identified through the
* EFI PCDP table, make it the preferred console. Otherwise
* zero out conswitchp.
*/
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;

View file

@ -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

View file

@ -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);
/************************************************************************

View file

@ -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 @@ tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size)
* 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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -245,7 +245,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;

View file

@ -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 */

View file

@ -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"

View file

@ -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;

View file

@ -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);
}

View file

@ -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",

View file

@ -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 (

View file

@ -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)

View file

@ -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 @@ acpi_bus_add (
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);

View file

@ -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);
}

View file

@ -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;

View file

@ -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 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
if (unlikely(rl->count[rw] == 0))
rl->starved[rw] = 1;
spin_unlock_irq(q->queue_lock);
goto out;
}
@ -1951,21 +1958,23 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
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 @@ static int __make_request(request_queue_t *q, struct bio *bio)
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. This is might sleep but can not fail.
* Returns with the queue unlocked.
*/
req = get_request_wait(q, rw, bio);
/*
* 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.
* 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 @@ static int __make_request(request_queue_t *q, struct bio *bio)
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,27 +3303,27 @@ struct io_context *get_io_context(int gfp_flags)
ret->nr_batch_requests = 0; /* because this is 0 */
ret->aic = NULL;
ret->cic = NULL;
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;
}
out:
atomic_inc(&ret->refcount);
local_irq_restore(flags);
tsk->io_context = ret;
}
return ret;
}
EXPORT_SYMBOL(current_io_context);
/*
* 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);
return ret;
}
EXPORT_SYMBOL(get_io_context);
void copy_io_context(struct io_context **pdst, struct io_context **psrc)

View file

@ -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,
},
{ }
};

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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 @@ static int __init rtc_init(void)
/* 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

View file

@ -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);

View file

@ -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:

View file

@ -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;
}

View file

@ -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");
}

View file

@ -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");
}

View file

@ -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);
}
}
}

View file

@ -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));

Some files were not shown because too many files have changed in this diff Show more