mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
Auto merge with /home/aegl/GIT/linus
This commit is contained in:
commit
d18bfacff2
@ -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>
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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."
|
||||
|
||||
|
@ -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.
|
||||
|
@ -1,399 +1,16 @@
|
||||
<HTML><HEAD>
|
||||
<TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE>
|
||||
</HEAD>
|
||||
<! Revision History: >
|
||||
<! 4/30/1999 - Fred Gleason (fredg@wava.com)>
|
||||
<! Documented extensions for the Radio Data System (RDS) extensions >
|
||||
<BODY bgcolor="#ffffff">
|
||||
<H3>Devices</H3>
|
||||
Video4Linux provides the following sets of device files. These live on the
|
||||
character device formerly known as "/dev/bttv". /dev/bttv should be a
|
||||
symlink to /dev/video0 for most people.
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TH>Device Name</TH><TH>Minor Range</TH><TH>Function</TH>
|
||||
<TR><TD>/dev/video</TD><TD>0-63</TD><TD>Video Capture Interface</TD>
|
||||
<TR><TD>/dev/radio</TD><TD>64-127</TD><TD>AM/FM Radio Devices</TD>
|
||||
<TR><TD>/dev/vtx</TD><TD>192-223</TD><TD>Teletext Interface Chips</TD>
|
||||
<TR><TD>/dev/vbi</TD><TD>224-239</TD><TD>Raw VBI Data (Intercast/teletext)</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
Video4Linux programs open and scan the devices to find what they are looking
|
||||
for. Capability queries define what each interface supports. The
|
||||
described API is only defined for video capture cards. The relevant subset
|
||||
applies to radio cards. Teletext interfaces talk the existing VTX API.
|
||||
<P>
|
||||
<H3>Capability Query Ioctl</H3>
|
||||
The <B>VIDIOCGCAP</B> ioctl call is used to obtain the capability
|
||||
information for a video device. The <b>struct video_capability</b> object
|
||||
passed to the ioctl is completed and returned. It contains the following
|
||||
information
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>name[32]</b><TD>Canonical name for this interface</TD>
|
||||
<TR><TD><b>type</b><TD>Type of interface</TD>
|
||||
<TR><TD><b>channels</b><TD>Number of radio/tv channels if appropriate</TD>
|
||||
<TR><TD><b>audios</b><TD>Number of audio devices if appropriate</TD>
|
||||
<TR><TD><b>maxwidth</b><TD>Maximum capture width in pixels</TD>
|
||||
<TR><TD><b>maxheight</b><TD>Maximum capture height in pixels</TD>
|
||||
<TR><TD><b>minwidth</b><TD>Minimum capture width in pixels</TD>
|
||||
<TR><TD><b>minheight</b><TD>Minimum capture height in pixels</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The type field lists the capability flags for the device. These are
|
||||
as follows
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TH>Name</TH><TH>Description</TH>
|
||||
<TR><TD><b>VID_TYPE_CAPTURE</b><TD>Can capture to memory</TD>
|
||||
<TR><TD><b>VID_TYPE_TUNER</b><TD>Has a tuner of some form</TD>
|
||||
<TR><TD><b>VID_TYPE_TELETEXT</b><TD>Has teletext capability</TD>
|
||||
<TR><TD><b>VID_TYPE_OVERLAY</b><TD>Can overlay its image onto the frame buffer</TD>
|
||||
<TR><TD><b>VID_TYPE_CHROMAKEY</b><TD>Overlay is Chromakeyed</TD>
|
||||
<TR><TD><b>VID_TYPE_CLIPPING</b><TD>Overlay clipping is supported</TD>
|
||||
<TR><TD><b>VID_TYPE_FRAMERAM</b><TD>Overlay overwrites frame buffer memory</TD>
|
||||
<TR><TD><b>VID_TYPE_SCALES</b><TD>The hardware supports image scaling</TD>
|
||||
<TR><TD><b>VID_TYPE_MONOCHROME</b><TD>Image capture is grey scale only</TD>
|
||||
<TR><TD><b>VID_TYPE_SUBCAPTURE</b><TD>Capture can be of only part of the image</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The minimum and maximum sizes listed for a capture device do not imply all
|
||||
that all height/width ratios or sizes within the range are possible. A
|
||||
request to set a size will be honoured by the largest available capture
|
||||
size whose capture is no large than the requested rectangle in either
|
||||
direction. For example the quickcam has 3 fixed settings.
|
||||
<P>
|
||||
<H3>Frame Buffer</H3>
|
||||
Capture cards that drop data directly onto the frame buffer must be told the
|
||||
base address of the frame buffer, its size and organisation. This is a
|
||||
privileged ioctl and one that eventually X itself should set.
|
||||
<P>
|
||||
The <b>VIDIOCSFBUF</b> ioctl sets the frame buffer parameters for a capture
|
||||
card. If the card does not do direct writes to the frame buffer then this
|
||||
ioctl will be unsupported. The <b>VIDIOCGFBUF</b> ioctl returns the
|
||||
currently used parameters. The structure used in both cases is a
|
||||
<b>struct video_buffer</b>.
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>void *base</b></TD><TD>Base physical address of the buffer</TD>
|
||||
<TR><TD><b>int height</b></TD><TD>Height of the frame buffer</TD>
|
||||
<TR><TD><b>int width</b></TD><TD>Width of the frame buffer</TD>
|
||||
<TR><TD><b>int depth</b></TD><TD>Depth of the frame buffer</TD>
|
||||
<TR><TD><b>int bytesperline</b></TD><TD>Number of bytes of memory between the start of two adjacent lines</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
Note that these values reflect the physical layout of the frame buffer.
|
||||
The visible area may be smaller. In fact under XFree86 this is commonly the
|
||||
case. XFree86 DGA can provide the parameters required to set up this ioctl.
|
||||
Setting the base address to NULL indicates there is no physical frame buffer
|
||||
access.
|
||||
<P>
|
||||
<H3>Capture Windows</H3>
|
||||
The capture area is described by a <b>struct video_window</b>. This defines
|
||||
a capture area and the clipping information if relevant. The
|
||||
<b>VIDIOCGWIN</b> ioctl recovers the current settings and the
|
||||
<b>VIDIOCSWIN</b> sets new values. A successful call to <b>VIDIOCSWIN</b>
|
||||
indicates that a suitable set of parameters have been chosen. They do not
|
||||
indicate that exactly what was requested was granted. The program should
|
||||
call <b>VIDIOCGWIN</b> to check if the nearest match was suitable. The
|
||||
<b>struct video_window</b> contains the following fields.
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>x</b><TD>The X co-ordinate specified in X windows format.</TD>
|
||||
<TR><TD><b>y</b><TD>The Y co-ordinate specified in X windows format.</TD>
|
||||
<TR><TD><b>width</b><TD>The width of the image capture.</TD>
|
||||
<TR><TD><b>height</b><TD>The height of the image capture.</TD>
|
||||
<TR><TD><b>chromakey</b><TD>A host order RGB32 value for the chroma key.</TD>
|
||||
<TR><TD><b>flags</b><TD>Additional capture flags.</TD>
|
||||
<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em></TD>
|
||||
<TR><TD><b>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
Clipping rectangles are passed as an array. Each clip consists of the following
|
||||
fields available to the user.
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>x</b></TD><TD>X co-ordinate of rectangle to skip</TD>
|
||||
<TR><TD><b>y</b></TD><TD>Y co-ordinate of rectangle to skip</TD>
|
||||
<TR><TD><b>width</b></TD><TD>Width of rectangle to skip</TD>
|
||||
<TR><TD><b>height</b></TD><TD>Height of rectangle to skip</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
Merely setting the window does not enable capturing. Overlay capturing
|
||||
(i.e. PCI-PCI transfer to the frame buffer of the video card)
|
||||
is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
|
||||
disabled by passing it a value of 0.
|
||||
<P>
|
||||
Some capture devices can capture a subfield of the image they actually see.
|
||||
This is indicated when VIDEO_TYPE_SUBCAPTURE is defined.
|
||||
The video_capture describes the time and special subfields to capture.
|
||||
The video_capture structure contains the following fields.
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>x</b></TD><TD>X co-ordinate of source rectangle to grab</TD>
|
||||
<TR><TD><b>y</b></TD><TD>Y co-ordinate of source rectangle to grab</TD>
|
||||
<TR><TD><b>width</b></TD><TD>Width of source rectangle to grab</TD>
|
||||
<TR><TD><b>height</b></TD><TD>Height of source rectangle to grab</TD>
|
||||
<TR><TD><b>decimation</b></TD><TD>Decimation to apply</TD>
|
||||
<TR><TD><b>flags</b></TD><TD>Flag settings for grabbing</TD>
|
||||
</TABLE>
|
||||
The available flags are
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TH>Name</TH><TH>Description</TH>
|
||||
<TR><TD><b>VIDEO_CAPTURE_ODD</b><TD>Capture only odd frames</TD>
|
||||
<TR><TD><b>VIDEO_CAPTURE_EVEN</b><TD>Capture only even frames</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
<H3>Video Sources</H3>
|
||||
Each video4linux video or audio device captures from one or more
|
||||
source <b>channels</b>. Each channel can be queries with the
|
||||
<b>VDIOCGCHAN</b> ioctl call. Before invoking this function the caller
|
||||
must set the channel field to the channel that is being queried. On return
|
||||
the <b>struct video_channel</b> is filled in with information about the
|
||||
nature of the channel itself.
|
||||
<P>
|
||||
The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the
|
||||
capture to this input. It is not defined whether parameters such as colour
|
||||
settings or tuning are maintained across a channel switch. The caller should
|
||||
maintain settings as desired for each channel. (This is reasonable as
|
||||
different video inputs may have different properties).
|
||||
<P>
|
||||
The <b>struct video_channel</b> consists of the following
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>channel</b></TD><TD>The channel number</TD>
|
||||
<TR><TD><b>name</b></TD><TD>The input name - preferably reflecting the label
|
||||
on the card input itself</TD>
|
||||
<TR><TD><b>tuners</b></TD><TD>Number of tuners for this input</TD>
|
||||
<TR><TD><b>flags</b></TD><TD>Properties the tuner has</TD>
|
||||
<TR><TD><b>type</b></TD><TD>Input type (if known)</TD>
|
||||
<TR><TD><b>norm</b><TD>The norm for this channel</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The flags defined are
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>VIDEO_VC_TUNER</b><TD>Channel has tuners.</TD>
|
||||
<TR><TD><b>VIDEO_VC_AUDIO</b><TD>Channel has audio.</TD>
|
||||
<TR><TD><b>VIDEO_VC_NORM</b><TD>Channel has norm setting.</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The types defined are
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>VIDEO_TYPE_TV</b><TD>The input is a TV input.</TD>
|
||||
<TR><TD><b>VIDEO_TYPE_CAMERA</b><TD>The input is a camera.</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
<H3>Image Properties</H3>
|
||||
The image properties of the picture can be queried with the <b>VIDIOCGPICT</b>
|
||||
ioctl which fills in a <b>struct video_picture</b>. The <b>VIDIOCSPICT</b>
|
||||
ioctl allows values to be changed. All values except for the palette type
|
||||
are scaled between 0-65535.
|
||||
<P>
|
||||
The <b>struct video_picture</b> consists of the following fields
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>brightness</b><TD>Picture brightness</TD>
|
||||
<TR><TD><b>hue</b><TD>Picture hue (colour only)</TD>
|
||||
<TR><TD><b>colour</b><TD>Picture colour (colour only)</TD>
|
||||
<TR><TD><b>contrast</b><TD>Picture contrast</TD>
|
||||
<TR><TD><b>whiteness</b><TD>The whiteness (greyscale only)</TD>
|
||||
<TR><TD><b>depth</b><TD>The capture depth (may need to match the frame buffer depth)</TD>
|
||||
<TR><TD><b>palette</b><TD>Reports the palette that should be used for this image</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The following palettes are defined
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>VIDEO_PALETTE_GREY</b><TD>Linear intensity grey scale (255 is brightest).</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_HI240</b><TD>The BT848 8bit colour cube.</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_RGB565</b><TD>RGB565 packed into 16 bit words.</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_RGB555</b><TD>RGV555 packed into 16 bit words, top bit undefined.</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_RGB24</b><TD>RGB888 packed into 24bit words.</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_RGB32</b><TD>RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_YUV422</b><TD>Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_YUYV</b><TD>Describe me</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_UYVY</b><TD>Describe me</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_YUV420</b><TD>YUV420 capture</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_YUV411</b><TD>YUV411 capture</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_RAW</b><TD>RAW capture (BT848)</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_YUV422P</b><TD>YUV 4:2:2 Planar</TD>
|
||||
<TR><TD><b>VIDEO_PALETTE_YUV411P</b><TD>YUV 4:1:1 Planar</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
<H3>Tuning</H3>
|
||||
Each video input channel can have one or more tuners associated with it. Many
|
||||
devices will not have tuners. TV cards and radio cards will have one or more
|
||||
tuners attached.
|
||||
<P>
|
||||
Tuners are described by a <b>struct video_tuner</b> which can be obtained by
|
||||
the <b>VIDIOCGTUNER</b> ioctl. Fill in the tuner number in the structure
|
||||
then pass the structure to the ioctl to have the data filled in. The
|
||||
tuner can be switched using <b>VIDIOCSTUNER</b> which takes an integer argument
|
||||
giving the tuner to use. A struct tuner has the following fields
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>tuner</b><TD>Number of the tuner</TD>
|
||||
<TR><TD><b>name</b><TD>Canonical name for this tuner (eg FM/AM/TV)</TD>
|
||||
<TR><TD><b>rangelow</b><TD>Lowest tunable frequency</TD>
|
||||
<TR><TD><b>rangehigh</b><TD>Highest tunable frequency</TD>
|
||||
<TR><TD><b>flags</b><TD>Flags describing the tuner</TD>
|
||||
<TR><TD><b>mode</b><TD>The video signal mode if relevant</TD>
|
||||
<TR><TD><b>signal</b><TD>Signal strength if known - between 0-65535</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The following flags exist
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>VIDEO_TUNER_PAL</b><TD>PAL tuning is supported</TD>
|
||||
<TR><TD><b>VIDEO_TUNER_NTSC</b><TD>NTSC tuning is supported</TD>
|
||||
<TR><TD><b>VIDEO_TUNER_SECAM</b><TD>SECAM tuning is supported</TD>
|
||||
<TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD>
|
||||
<TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD>
|
||||
<TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD>
|
||||
<TR><TD><b>VIDEO_TUNER_RDS_ON</b><TD>The tuner is seeing a RDS datastream</TD>
|
||||
<TR><TD><b>VIDEO_TUNER_MBS_ON</b><TD>The tuner is seeing a MBS datastream</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The following modes are defined
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>VIDEO_MODE_PAL</b><TD>The tuner is in PAL mode</TD>
|
||||
<TR><TD><b>VIDEO_MODE_NTSC</b><TD>The tuner is in NTSC mode</TD>
|
||||
<TR><TD><b>VIDEO_MODE_SECAM</b><TD>The tuner is in SECAM mode</TD>
|
||||
<TR><TD><b>VIDEO_MODE_AUTO</b><TD>The tuner auto switches, or mode does not apply</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the
|
||||
<b>VIDEO_TUNER_LOW</b> flag is set they are in 1/16th KHz. The current
|
||||
frequency is obtained as an unsigned long via the <b>VIDIOCGFREQ</b> ioctl and
|
||||
set by the <b>VIDIOCSFREQ</b> ioctl.
|
||||
<P>
|
||||
<H3>Audio</H3>
|
||||
TV and Radio devices have one or more audio inputs that may be selected.
|
||||
The audio properties are queried by passing a <b>struct video_audio</b> to <b>VIDIOCGAUDIO</b> ioctl. The
|
||||
<b>VIDIOCSAUDIO</b> ioctl sets audio properties.
|
||||
<P>
|
||||
The structure contains the following fields
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>audio</b><TD>The channel number</TD>
|
||||
<TR><TD><b>volume</b><TD>The volume level</TD>
|
||||
<TR><TD><b>bass</b><TD>The bass level</TD>
|
||||
<TR><TD><b>treble</b><TD>The treble level</TD>
|
||||
<TR><TD><b>flags</b><TD>Flags describing the audio channel</TD>
|
||||
<TR><TD><b>name</b><TD>Canonical name for the audio input</TD>
|
||||
<TR><TD><b>mode</b><TD>The mode the audio input is in</TD>
|
||||
<TR><TD><b>balance</b><TD>The left/right balance</TD>
|
||||
<TR><TD><b>step</b><TD>Actual step used by the hardware</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The following flags are defined
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>VIDEO_AUDIO_MUTE</b><TD>The audio is muted</TD>
|
||||
<TR><TD><b>VIDEO_AUDIO_MUTABLE</b><TD>Audio muting is supported</TD>
|
||||
<TR><TD><b>VIDEO_AUDIO_VOLUME</b><TD>The volume is controllable</TD>
|
||||
<TR><TD><b>VIDEO_AUDIO_BASS</b><TD>The bass is controllable</TD>
|
||||
<TR><TD><b>VIDEO_AUDIO_TREBLE</b><TD>The treble is controllable</TD>
|
||||
<TR><TD><b>VIDEO_AUDIO_BALANCE</b><TD>The balance is controllable</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
The following decoding modes are defined
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>VIDEO_SOUND_MONO</b><TD>Mono signal</TD>
|
||||
<TR><TD><b>VIDEO_SOUND_STEREO</b><TD>Stereo signal (NICAM for TV)</TD>
|
||||
<TR><TD><b>VIDEO_SOUND_LANG1</b><TD>European TV alternate language 1</TD>
|
||||
<TR><TD><b>VIDEO_SOUND_LANG2</b><TD>European TV alternate language 2</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
<H3>Reading Images</H3>
|
||||
Each call to the <b>read</b> syscall returns the next available image
|
||||
from the device. It is up to the caller to set format and size (using
|
||||
the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable
|
||||
size buffer and length to the function. Not all devices will support
|
||||
read operations.
|
||||
<P>
|
||||
A second way to handle image capture is via the mmap interface if supported.
|
||||
To use the mmap interface a user first sets the desired image size and depth
|
||||
properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size
|
||||
of buffer to mmap and the offset within the buffer for each frame. The
|
||||
number of frames supported is device dependent and may only be one.
|
||||
<P>
|
||||
The video_mbuf structure contains the following fields
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>size</b><TD>The number of bytes to map</TD>
|
||||
<TR><TD><b>frames</b><TD>The number of frames</TD>
|
||||
<TR><TD><b>offsets</b><TD>The offset of each frame</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the
|
||||
capture to a frame using the format and image size specified in the
|
||||
video_mmap (which should match or be below the initial query size).
|
||||
When the VIDIOCMCAPTURE ioctl returns the frame is <em>not</em>
|
||||
captured yet, the driver just instructed the hardware to start the
|
||||
capture. The application has to use the VIDIOCSYNC ioctl to wait
|
||||
until the capture of a frame is finished. VIDIOCSYNC takes the frame
|
||||
number you want to wait for as argument.
|
||||
<p>
|
||||
It is allowed to call VIDIOCMCAPTURE multiple times (with different
|
||||
frame numbers in video_mmap->frame of course) and thus have multiple
|
||||
outstanding capture requests. A simple way do to double-buffering
|
||||
using this feature looks like this:
|
||||
<pre>
|
||||
/* setup everything */
|
||||
VIDIOCMCAPTURE(0)
|
||||
while (whatever) {
|
||||
VIDIOCMCAPTURE(1)
|
||||
VIDIOCSYNC(0)
|
||||
/* process frame 0 while the hardware captures frame 1 */
|
||||
VIDIOCMCAPTURE(0)
|
||||
VIDIOCSYNC(1)
|
||||
/* process frame 1 while the hardware captures frame 0 */
|
||||
}
|
||||
</pre>
|
||||
Note that you are <em>not</em> limited to only two frames. The API
|
||||
allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of
|
||||
frames the driver granted. Thus it is possible to build deeper queues
|
||||
to avoid loosing frames on load peaks.
|
||||
<p>
|
||||
While capturing to memory the driver will make a "best effort" attempt
|
||||
to capture to screen as well if requested. This normally means all
|
||||
frames that "miss" memory mapped capture will go to the display.
|
||||
<P>
|
||||
A final ioctl exists to allow a device to obtain related devices if a
|
||||
driver has multiple components (for example video0 may not be associated
|
||||
with vbi0 which would cause an intercast display program to make a bad
|
||||
mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated
|
||||
devices if any exist. The video_unit structure has the following fields.
|
||||
<P>
|
||||
<TABLE>
|
||||
<TR><TD><b>video</b><TD>Video capture device</TD>
|
||||
<TR><TD><b>vbi</b><TD>VBI capture device</TD>
|
||||
<TR><TD><b>radio</b><TD>Radio device</TD>
|
||||
<TR><TD><b>audio</b><TD>Audio mixer</TD>
|
||||
<TR><TD><b>teletext</b><TD>Teletext device</TD>
|
||||
</TABLE>
|
||||
<P>
|
||||
<H3>RDS Datastreams</H3>
|
||||
For radio devices that support it, it is possible to receive Radio Data
|
||||
System (RDS) data by means of a read() on the device. The data is packed in
|
||||
groups of three, as follows:
|
||||
<TABLE>
|
||||
<TR><TD>First Octet</TD><TD>Least Significant Byte of RDS Block</TD></TR>
|
||||
<TR><TD>Second Octet</TD><TD>Most Significant Byte of RDS Block
|
||||
<TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit. Indicates that
|
||||
an uncorrectable error occurred during reception of this block.</TD></TR>
|
||||
<TR><TD> </TD><TD>Bit 6:</TD><TD>Corrected bit. Indicates that
|
||||
an error was corrected for this data block.</TD></TR>
|
||||
<TR><TD> </TD><TD>Bits 5-3:</TD><TD>Received Offset. Indicates the
|
||||
offset received by the sync system.</TD></TR>
|
||||
<TR><TD> </TD><TD>Bits 2-0:</TD><TD>Offset Name. Indicates the
|
||||
offset applied to this data.</TD></TR>
|
||||
</TABLE>
|
||||
</BODY>
|
||||
</HTML>
|
||||
<TITLE>V4L API</TITLE>
|
||||
<H1>Video For Linux APIs</H1>
|
||||
<table border=0>
|
||||
<tr>
|
||||
<td>
|
||||
<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html>
|
||||
V4L original API</a>
|
||||
</td><td>
|
||||
Obsoleted by V4L2 API
|
||||
</td></tr><tr><td>
|
||||
<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html>
|
||||
V4L2 API</a>
|
||||
</td><td>
|
||||
Should be used for new projects
|
||||
</td></tr>
|
||||
</table>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
=======
|
||||
|
15
MAINTAINERS
15
MAINTAINERS
@ -512,11 +512,11 @@ W: http://linuxppc64.org
|
||||
S: Supported
|
||||
|
||||
BTTV VIDEO4LINUX DRIVER
|
||||
P: Gerd Knorr
|
||||
M: kraxel@bytesex.org
|
||||
P: Mauro Carvalho Chehab
|
||||
M: mchehab@brturbo.com.br
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://bytesex.org/bttv/
|
||||
S: Orphan
|
||||
W: http://linuxtv.org
|
||||
S: Maintained
|
||||
|
||||
BUSLOGIC SCSI DRIVER
|
||||
P: Leonard N. Zubkoff
|
||||
@ -2625,10 +2625,11 @@ W: http://rio500.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
VIDEO FOR LINUX
|
||||
P: Gerd Knorr
|
||||
M: kraxel@bytesex.org
|
||||
P: Mauro Carvalho Chehab
|
||||
M: mchehab@brturbo.com.br
|
||||
L: video4linux-list@redhat.com
|
||||
S: Orphan
|
||||
W: http://linuxtv.org
|
||||
S: Maintained
|
||||
|
||||
W1 DALLAS'S 1-WIRE BUS
|
||||
P: Evgeniy Polyakov
|
||||
|
4
Makefile
4
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 12
|
||||
EXTRAVERSION =
|
||||
SUBLEVEL = 13
|
||||
EXTRAVERSION =-rc1
|
||||
NAME=Woozy Numbat
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
144
arch/arm/oprofile/backtrace.c
Normal file
144
arch/arm/oprofile/backtrace.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define PCI_ASSIGN_ALL_BUSSES 0x4000
|
||||
|
||||
extern unsigned int pci_probe;
|
||||
extern unsigned long pirq_table_addr;
|
||||
|
||||
/* pci-i386.c */
|
||||
|
||||
|
@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
|
||||
if (BAD_MADT_ENTRY(iosapic, end))
|
||||
return -EINVAL;
|
||||
|
||||
iosapic_init(iosapic->address, iosapic->global_irq_base);
|
||||
|
||||
return 0;
|
||||
return iosapic_init(iosapic->address, iosapic->global_irq_base);
|
||||
}
|
||||
|
||||
|
||||
@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
|
||||
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
acpi_status __init
|
||||
acpi_status __devinit
|
||||
acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
|
||||
{
|
||||
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
@ -825,4 +823,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
|
||||
return AE_OK;
|
||||
}
|
||||
#endif /* CONFIG_NUMA */
|
||||
|
||||
int
|
||||
acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = iosapic_init(phys_addr, gsi_base)))
|
||||
return err;
|
||||
|
||||
#if CONFIG_ACPI_NUMA
|
||||
acpi_map_iosapic(handle, 0, NULL, NULL);
|
||||
#endif /* CONFIG_ACPI_NUMA */
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_register_ioapic);
|
||||
|
||||
int
|
||||
acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base)
|
||||
{
|
||||
return iosapic_remove(gsi_base);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_unregister_ioapic);
|
||||
|
||||
#endif /* CONFIG_ACPI_BOOT */
|
||||
|
@ -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;
|
||||
|
@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
|
||||
&info);
|
||||
|
||||
pbus = pci_scan_bus(bus, &pci_root_ops, controller);
|
||||
pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
|
||||
if (pbus)
|
||||
pcibios_setup_root_windows(pbus, controller);
|
||||
|
||||
@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
|
||||
res->end = region->end + offset;
|
||||
}
|
||||
|
||||
static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
|
||||
{
|
||||
unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
|
||||
struct resource *devr = &dev->resource[idx];
|
||||
|
||||
if (!dev->bus)
|
||||
return 0;
|
||||
for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
|
||||
struct resource *busr = dev->bus->resource[i];
|
||||
|
||||
if (!busr || ((busr->flags ^ devr->flags) & type_mask))
|
||||
continue;
|
||||
if ((devr->start) && (devr->start >= busr->start) &&
|
||||
(devr->end <= busr->end))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_bus_region region;
|
||||
@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
|
||||
region.start = dev->resource[i].start;
|
||||
region.end = dev->resource[i].end;
|
||||
pcibios_bus_to_resource(dev, &dev->resource[i], ®ion);
|
||||
pci_claim_resource(dev, i);
|
||||
if ((is_valid_resource(dev, i)))
|
||||
pci_claim_resource(dev, i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
if (b->self) {
|
||||
pci_read_bridge_bases(b);
|
||||
pcibios_fixup_device_resources(b->self);
|
||||
}
|
||||
list_for_each_entry(dev, &b->devices, bus_list)
|
||||
pcibios_fixup_device_resources(dev);
|
||||
|
||||
@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
|
||||
u16 cmd, old_cmd;
|
||||
int idx;
|
||||
struct resource *r;
|
||||
unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
old_cmd = cmd;
|
||||
for (idx=0; idx<6; idx++) {
|
||||
for (idx=0; idx<PCI_NUM_RESOURCES; idx++) {
|
||||
/* Only set up the desired resources. */
|
||||
if (!(mask & (1 << idx)))
|
||||
continue;
|
||||
|
||||
r = &dev->resource[idx];
|
||||
if (!(r->flags & type_mask))
|
||||
continue;
|
||||
if ((idx == PCI_ROM_RESOURCE) &&
|
||||
(!(r->flags & IORESOURCE_ROM_ENABLE)))
|
||||
continue;
|
||||
if (!r->start && r->end) {
|
||||
printk(KERN_ERR
|
||||
"PCI: Device %s not available because of resource collisions\n",
|
||||
@ -441,8 +471,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
|
||||
if (r->flags & IORESOURCE_MEM)
|
||||
cmd |= PCI_COMMAND_MEMORY;
|
||||
}
|
||||
if (dev->resource[PCI_ROM_RESOURCE].start)
|
||||
cmd |= PCI_COMMAND_MEMORY;
|
||||
if (cmd != old_cmd) {
|
||||
printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
|
||||
pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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 (
|
||||
|
@ -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)
|
||||
|
@ -553,20 +553,29 @@ acpi_bus_driver_init (
|
||||
* upon possible configuration and currently allocated resources.
|
||||
*/
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
|
||||
return_VALUE(0);
|
||||
}
|
||||
|
||||
int
|
||||
acpi_start_single_object (
|
||||
struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
struct acpi_driver *driver;
|
||||
|
||||
ACPI_FUNCTION_TRACE("acpi_start_single_object");
|
||||
|
||||
if (!(driver = device->driver))
|
||||
return_VALUE(0);
|
||||
|
||||
if (driver->ops.start) {
|
||||
result = driver->ops.start(device);
|
||||
if (result && driver->ops.remove)
|
||||
driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
|
||||
return_VALUE(result);
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
|
||||
|
||||
if (driver->ops.scan) {
|
||||
driver->ops.scan(device);
|
||||
}
|
||||
|
||||
return_VALUE(0);
|
||||
return_VALUE(result);
|
||||
}
|
||||
|
||||
static int acpi_driver_attach(struct acpi_driver * drv)
|
||||
@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acpi_driver * drv)
|
||||
|
||||
if (!acpi_bus_match(dev, drv)) {
|
||||
if (!acpi_bus_driver_init(dev, drv)) {
|
||||
acpi_start_single_object(dev);
|
||||
atomic_inc(&drv->references);
|
||||
count++;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
|
||||
@ -1009,8 +1019,8 @@ acpi_bus_remove (
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acpi_bus_add (
|
||||
static int
|
||||
acpi_add_single_object (
|
||||
struct acpi_device **child,
|
||||
struct acpi_device *parent,
|
||||
acpi_handle handle,
|
||||
@ -1019,7 +1029,7 @@ acpi_bus_add (
|
||||
int result = 0;
|
||||
struct acpi_device *device = NULL;
|
||||
|
||||
ACPI_FUNCTION_TRACE("acpi_bus_add");
|
||||
ACPI_FUNCTION_TRACE("acpi_add_single_object");
|
||||
|
||||
if (!child)
|
||||
return_VALUE(-EINVAL);
|
||||
@ -1140,7 +1150,7 @@ acpi_bus_add (
|
||||
*
|
||||
* TBD: Assumes LDM provides driver hot-plug capability.
|
||||
*/
|
||||
acpi_bus_find_driver(device);
|
||||
result = acpi_bus_find_driver(device);
|
||||
|
||||
end:
|
||||
if (!result)
|
||||
@ -1153,10 +1163,10 @@ end:
|
||||
|
||||
return_VALUE(result);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_bus_add);
|
||||
|
||||
|
||||
int acpi_bus_scan (struct acpi_device *start)
|
||||
static int acpi_bus_scan (struct acpi_device *start,
|
||||
struct acpi_bus_ops *ops)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_device *parent = NULL;
|
||||
@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device *start)
|
||||
continue;
|
||||
}
|
||||
|
||||
status = acpi_bus_add(&child, parent, chandle, type);
|
||||
if (ACPI_FAILURE(status))
|
||||
continue;
|
||||
if (ops->acpi_op_add)
|
||||
status = acpi_add_single_object(&child, parent,
|
||||
chandle, type);
|
||||
else
|
||||
status = acpi_bus_get_device(chandle, &child);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
continue;
|
||||
|
||||
if (ops->acpi_op_start) {
|
||||
status = acpi_start_single_object(child);
|
||||
if (ACPI_FAILURE(status))
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device is present, enabled, and functioning then
|
||||
@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device *start)
|
||||
|
||||
return_VALUE(0);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_bus_scan);
|
||||
|
||||
int
|
||||
acpi_bus_add (
|
||||
struct acpi_device **child,
|
||||
struct acpi_device *parent,
|
||||
acpi_handle handle,
|
||||
int type)
|
||||
{
|
||||
int result;
|
||||
struct acpi_bus_ops ops;
|
||||
|
||||
ACPI_FUNCTION_TRACE("acpi_bus_add");
|
||||
|
||||
result = acpi_add_single_object(child, parent, handle, type);
|
||||
if (!result) {
|
||||
memset(&ops, 0, sizeof(ops));
|
||||
ops.acpi_op_add = 1;
|
||||
result = acpi_bus_scan(*child, &ops);
|
||||
}
|
||||
return_VALUE(result);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_bus_add);
|
||||
|
||||
int
|
||||
acpi_bus_start (
|
||||
struct acpi_device *device)
|
||||
{
|
||||
int result;
|
||||
struct acpi_bus_ops ops;
|
||||
|
||||
ACPI_FUNCTION_TRACE("acpi_bus_start");
|
||||
|
||||
if (!device)
|
||||
return_VALUE(-EINVAL);
|
||||
|
||||
result = acpi_start_single_object(device);
|
||||
if (!result) {
|
||||
memset(&ops, 0, sizeof(ops));
|
||||
ops.acpi_op_start = 1;
|
||||
result = acpi_bus_scan(device, &ops);
|
||||
}
|
||||
return_VALUE(result);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_bus_start);
|
||||
|
||||
static int
|
||||
acpi_bus_trim(struct acpi_device *start,
|
||||
@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed (
|
||||
/*
|
||||
* Enumerate all fixed-feature devices.
|
||||
*/
|
||||
if (acpi_fadt.pwr_button == 0)
|
||||
result = acpi_bus_add(&device, acpi_root,
|
||||
if (acpi_fadt.pwr_button == 0) {
|
||||
result = acpi_add_single_object(&device, acpi_root,
|
||||
NULL, ACPI_BUS_TYPE_POWER_BUTTON);
|
||||
if (!result)
|
||||
result = acpi_start_single_object(device);
|
||||
}
|
||||
|
||||
if (acpi_fadt.sleep_button == 0)
|
||||
result = acpi_bus_add(&device, acpi_root,
|
||||
if (acpi_fadt.sleep_button == 0) {
|
||||
result = acpi_add_single_object(&device, acpi_root,
|
||||
NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
|
||||
if (!result)
|
||||
result = acpi_start_single_object(device);
|
||||
}
|
||||
|
||||
return_VALUE(result);
|
||||
}
|
||||
@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed (
|
||||
static int __init acpi_scan_init(void)
|
||||
{
|
||||
int result;
|
||||
struct acpi_bus_ops ops;
|
||||
|
||||
ACPI_FUNCTION_TRACE("acpi_scan_init");
|
||||
|
||||
@ -1357,17 +1427,23 @@ static int __init acpi_scan_init(void)
|
||||
/*
|
||||
* Create the root device in the bus's device tree
|
||||
*/
|
||||
result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT,
|
||||
result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
|
||||
ACPI_BUS_TYPE_SYSTEM);
|
||||
if (result)
|
||||
goto Done;
|
||||
|
||||
result = acpi_start_single_object(acpi_root);
|
||||
|
||||
/*
|
||||
* Enumerate devices in the ACPI namespace.
|
||||
*/
|
||||
result = acpi_bus_scan_fixed(acpi_root);
|
||||
if (!result)
|
||||
result = acpi_bus_scan(acpi_root);
|
||||
if (!result) {
|
||||
memset(&ops, 0, sizeof(ops));
|
||||
ops.acpi_op_add = 1;
|
||||
ops.acpi_op_start = 1;
|
||||
result = acpi_bus_scan(acpi_root, &ops);
|
||||
}
|
||||
|
||||
if (result)
|
||||
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1867,19 +1867,20 @@ static void freed_request(request_queue_t *q, int rw)
|
||||
|
||||
#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
|
||||
/*
|
||||
* Get a free request, queue_lock must not be held
|
||||
* Get a free request, queue_lock must be held.
|
||||
* Returns NULL on failure, with queue_lock held.
|
||||
* Returns !NULL on success, with queue_lock *not held*.
|
||||
*/
|
||||
static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
|
||||
int gfp_mask)
|
||||
{
|
||||
struct request *rq = NULL;
|
||||
struct request_list *rl = &q->rq;
|
||||
struct io_context *ioc = get_io_context(gfp_mask);
|
||||
struct io_context *ioc = current_io_context(GFP_ATOMIC);
|
||||
|
||||
if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
|
||||
goto out;
|
||||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
if (rl->count[rw]+1 >= q->nr_requests) {
|
||||
/*
|
||||
* The queue will fill after this allocation, so set it as
|
||||
@ -1907,11 +1908,18 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
|
||||
* The queue is full and the allocating process is not a
|
||||
* "batcher", and not exempted by the IO scheduler
|
||||
*/
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
get_rq:
|
||||
/*
|
||||
* Only allow batching queuers to allocate up to 50% over the defined
|
||||
* limit of requests, otherwise we could have thousands of requests
|
||||
* allocated with any setting of ->nr_requests
|
||||
*/
|
||||
if (rl->count[rw] >= (3 * q->nr_requests / 2))
|
||||
goto out;
|
||||
|
||||
rl->count[rw]++;
|
||||
rl->starved[rw] = 0;
|
||||
if (rl->count[rw] >= queue_congestion_on_threshold(q))
|
||||
@ -1941,7 +1949,6 @@ rq_starved:
|
||||
if (unlikely(rl->count[rw] == 0))
|
||||
rl->starved[rw] = 1;
|
||||
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1951,21 +1958,23 @@ rq_starved:
|
||||
rq_init(q, rq);
|
||||
rq->rl = rl;
|
||||
out:
|
||||
put_io_context(ioc);
|
||||
return rq;
|
||||
}
|
||||
|
||||
/*
|
||||
* No available requests for this queue, unplug the device and wait for some
|
||||
* requests to become available.
|
||||
*
|
||||
* Called with q->queue_lock held, and returns with it unlocked.
|
||||
*/
|
||||
static struct request *get_request_wait(request_queue_t *q, int rw,
|
||||
struct bio *bio)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
struct request *rq;
|
||||
|
||||
do {
|
||||
rq = get_request(q, rw, bio, GFP_NOIO);
|
||||
while (!rq) {
|
||||
DEFINE_WAIT(wait);
|
||||
struct request_list *rl = &q->rq;
|
||||
|
||||
prepare_to_wait_exclusive(&rl->wait[rw], &wait,
|
||||
@ -1976,7 +1985,8 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
|
||||
if (!rq) {
|
||||
struct io_context *ioc;
|
||||
|
||||
generic_unplug_device(q);
|
||||
__generic_unplug_device(q);
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
io_schedule();
|
||||
|
||||
/*
|
||||
@ -1985,12 +1995,13 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
|
||||
* up to a big batch of them for a small period time.
|
||||
* See ioc_batching, ioc_set_batching
|
||||
*/
|
||||
ioc = get_io_context(GFP_NOIO);
|
||||
ioc = current_io_context(GFP_NOIO);
|
||||
ioc_set_batching(q, ioc);
|
||||
put_io_context(ioc);
|
||||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
}
|
||||
finish_wait(&rl->wait[rw], &wait);
|
||||
} while (!rq);
|
||||
}
|
||||
|
||||
return rq;
|
||||
}
|
||||
@ -2001,14 +2012,18 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
|
||||
|
||||
BUG_ON(rw != READ && rw != WRITE);
|
||||
|
||||
if (gfp_mask & __GFP_WAIT)
|
||||
spin_lock_irq(q->queue_lock);
|
||||
if (gfp_mask & __GFP_WAIT) {
|
||||
rq = get_request_wait(q, rw, NULL);
|
||||
else
|
||||
} else {
|
||||
rq = get_request(q, rw, NULL, gfp_mask);
|
||||
if (!rq)
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
}
|
||||
/* q->queue_lock is unlocked at this point */
|
||||
|
||||
return rq;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(blk_get_request);
|
||||
|
||||
/**
|
||||
@ -2512,7 +2527,7 @@ EXPORT_SYMBOL(blk_attempt_remerge);
|
||||
|
||||
static int __make_request(request_queue_t *q, struct bio *bio)
|
||||
{
|
||||
struct request *req, *freereq = NULL;
|
||||
struct request *req;
|
||||
int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
|
||||
unsigned short prio;
|
||||
sector_t sector;
|
||||
@ -2540,14 +2555,9 @@ static int __make_request(request_queue_t *q, struct bio *bio)
|
||||
goto end_io;
|
||||
}
|
||||
|
||||
again:
|
||||
spin_lock_irq(q->queue_lock);
|
||||
|
||||
if (elv_queue_empty(q)) {
|
||||
blk_plug_device(q);
|
||||
goto get_rq;
|
||||
}
|
||||
if (barrier)
|
||||
if (unlikely(barrier) || elv_queue_empty(q))
|
||||
goto get_rq;
|
||||
|
||||
el_ret = elv_merge(q, &req, bio);
|
||||
@ -2592,40 +2602,24 @@ again:
|
||||
elv_merged_request(q, req);
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* elevator says don't/can't merge. get new request
|
||||
*/
|
||||
case ELEVATOR_NO_MERGE:
|
||||
break;
|
||||
|
||||
/* ELV_NO_MERGE: elevator says don't/can't merge. */
|
||||
default:
|
||||
printk("elevator returned crap (%d)\n", el_ret);
|
||||
BUG();
|
||||
;
|
||||
}
|
||||
|
||||
get_rq:
|
||||
/*
|
||||
* Grab a free request. 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 @@ get_rq:
|
||||
req->rq_disk = bio->bi_bdev->bd_disk;
|
||||
req->start_time = jiffies;
|
||||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
if (elv_queue_empty(q))
|
||||
blk_plug_device(q);
|
||||
add_request(q, req);
|
||||
out:
|
||||
if (freereq)
|
||||
__blk_put_request(q, freereq);
|
||||
if (sync)
|
||||
__generic_unplug_device(q);
|
||||
|
||||
@ -3284,24 +3279,20 @@ void exit_io_context(void)
|
||||
|
||||
/*
|
||||
* If the current task has no IO context then create one and initialise it.
|
||||
* If it does have a context, take a ref on it.
|
||||
* Otherwise, return its existing IO context.
|
||||
*
|
||||
* This is always called in the context of the task which submitted the I/O.
|
||||
* But weird things happen, so we disable local interrupts to ensure exclusive
|
||||
* access to *current.
|
||||
* This returned IO context doesn't have a specifically elevated refcount,
|
||||
* but since the current task itself holds a reference, the context can be
|
||||
* used in general code, so long as it stays within `current` context.
|
||||
*/
|
||||
struct io_context *get_io_context(int gfp_flags)
|
||||
struct io_context *current_io_context(int gfp_flags)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
unsigned long flags;
|
||||
struct io_context *ret;
|
||||
|
||||
local_irq_save(flags);
|
||||
ret = tsk->io_context;
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
local_irq_restore(flags);
|
||||
if (likely(ret))
|
||||
return ret;
|
||||
|
||||
ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
|
||||
if (ret) {
|
||||
@ -3312,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)
|
||||
|
@ -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,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -78,6 +78,7 @@
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/current.h>
|
||||
#include <asm/uaccess.h>
|
||||
@ -894,7 +895,6 @@ static int __init rtc_init(void)
|
||||
struct proc_dir_entry *ent;
|
||||
#if defined(__alpha__) || defined(__mips__)
|
||||
unsigned int year, ctrl;
|
||||
unsigned long uip_watchdog;
|
||||
char *guess = NULL;
|
||||
#endif
|
||||
#ifdef __sparc__
|
||||
@ -1000,12 +1000,8 @@ no_irq:
|
||||
/* Each operating system on an Alpha uses its own epoch.
|
||||
Let's try to guess which one we are using now. */
|
||||
|
||||
uip_watchdog = jiffies;
|
||||
if (rtc_is_updating() != 0)
|
||||
while (jiffies - uip_watchdog < 2*HZ/100) {
|
||||
barrier();
|
||||
cpu_relax();
|
||||
}
|
||||
msleep(20);
|
||||
|
||||
spin_lock_irq(&rtc_lock);
|
||||
year = CMOS_READ(RTC_YEAR);
|
||||
@ -1213,7 +1209,6 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
|
||||
|
||||
void rtc_get_rtc_time(struct rtc_time *rtc_tm)
|
||||
{
|
||||
unsigned long uip_watchdog = jiffies;
|
||||
unsigned char ctrl;
|
||||
#ifdef CONFIG_MACH_DECSTATION
|
||||
unsigned int real_year;
|
||||
@ -1221,7 +1216,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
|
||||
|
||||
/*
|
||||
* read RTC once any update in progress is done. The update
|
||||
* can take just over 2ms. We wait 10 to 20ms. There is no need to
|
||||
* can take just over 2ms. We wait 20ms. There is no need to
|
||||
* to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
|
||||
* If you need to know *exactly* when a second has started, enable
|
||||
* periodic update complete interrupts, (via ioctl) and then
|
||||
@ -1230,10 +1225,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
|
||||
*/
|
||||
|
||||
if (rtc_is_updating() != 0)
|
||||
while (jiffies - uip_watchdog < 2*HZ/100) {
|
||||
barrier();
|
||||
cpu_relax();
|
||||
}
|
||||
msleep(20);
|
||||
|
||||
/*
|
||||
* Only the values that we read from the RTC are set. We leave
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ static didd_adapter_change_notification_t\
|
||||
Array to held adapter information
|
||||
-------------------------------------------------------------------------- */
|
||||
static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS];
|
||||
dword Adapters = 0; /* Number of adapters */
|
||||
static dword Adapters = 0; /* Number of adapters */
|
||||
/* --------------------------------------------------------------------------
|
||||
Shadow IDI_DIMAINT
|
||||
and 'shadow' debug stuff
|
||||
|
@ -312,7 +312,7 @@ wait_busy(hfc4s8s_hw * a)
|
||||
/* function to read critical counter registers that */
|
||||
/* may be udpated by the chip during read */
|
||||
/******************************************************/
|
||||
static volatile u_char
|
||||
static u_char
|
||||
Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
|
||||
{
|
||||
u_char ref8;
|
||||
@ -324,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
|
||||
return in8;
|
||||
}
|
||||
|
||||
static volatile int
|
||||
static int
|
||||
Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
|
||||
{
|
||||
int ref16;
|
||||
@ -1465,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
|
||||
/******************************************/
|
||||
/* disable memory mapped ports / io ports */
|
||||
/******************************************/
|
||||
void
|
||||
static void
|
||||
release_pci_ports(hfc4s8s_hw * hw)
|
||||
{
|
||||
pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
|
||||
@ -1481,7 +1481,7 @@ release_pci_ports(hfc4s8s_hw * hw)
|
||||
/*****************************************/
|
||||
/* enable memory mapped ports / io ports */
|
||||
/*****************************************/
|
||||
void
|
||||
static void
|
||||
enable_pci_ports(hfc4s8s_hw * hw)
|
||||
{
|
||||
#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
|
||||
|
@ -42,6 +42,8 @@ typedef struct _hycapi_appl {
|
||||
|
||||
static hycapi_appl hycapi_applications[CAPI_MAXAPPL];
|
||||
|
||||
static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
|
||||
|
||||
static inline int _hycapi_appCheck(int app_id, int ctrl_no)
|
||||
{
|
||||
if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
|
||||
@ -57,7 +59,7 @@ static inline int _hycapi_appCheck(int app_id, int ctrl_no)
|
||||
Kernel-Capi callback reset_ctr
|
||||
******************************/
|
||||
|
||||
void
|
||||
static void
|
||||
hycapi_reset_ctr(struct capi_ctr *ctrl)
|
||||
{
|
||||
hycapictrl_info *cinfo = ctrl->driverdata;
|
||||
@ -73,7 +75,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl)
|
||||
Kernel-Capi callback remove_ctr
|
||||
******************************/
|
||||
|
||||
void
|
||||
static void
|
||||
hycapi_remove_ctr(struct capi_ctr *ctrl)
|
||||
{
|
||||
int i;
|
||||
@ -215,7 +217,7 @@ Error-checking is done for CAPI-compliance.
|
||||
The application is recorded in the internal list.
|
||||
*************************************************************/
|
||||
|
||||
void
|
||||
static void
|
||||
hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl,
|
||||
capi_register_params *rp)
|
||||
{
|
||||
@ -291,7 +293,7 @@ Release the application from the internal list an remove it's
|
||||
registration at controller-level
|
||||
******************************************************************/
|
||||
|
||||
void
|
||||
static void
|
||||
hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
|
||||
{
|
||||
int chk;
|
||||
@ -364,7 +366,7 @@ firmware-releases that do not check the MsgLen-Indication!
|
||||
|
||||
***************************************************************/
|
||||
|
||||
u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
|
||||
static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
|
||||
{
|
||||
__u16 appl_id;
|
||||
int _len, _len2;
|
||||
@ -437,8 +439,8 @@ Informations provided in the /proc/capi-entries.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
int hycapi_read_proc(char *page, char **start, off_t off,
|
||||
int count, int *eof, struct capi_ctr *ctrl)
|
||||
static int hycapi_read_proc(char *page, char **start, off_t off,
|
||||
int count, int *eof, struct capi_ctr *ctrl)
|
||||
{
|
||||
hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
|
||||
hysdn_card *card = cinfo->card;
|
||||
@ -485,7 +487,7 @@ on capi-interface registration.
|
||||
|
||||
**************************************************************/
|
||||
|
||||
int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
|
||||
static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
|
||||
{
|
||||
#ifdef HYCAPI_PRINTFNAMES
|
||||
printk(KERN_NOTICE "hycapi_load_firmware\n");
|
||||
@ -494,7 +496,7 @@ int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
|
||||
}
|
||||
|
||||
|
||||
char *hycapi_procinfo(struct capi_ctr *ctrl)
|
||||
static char *hycapi_procinfo(struct capi_ctr *ctrl)
|
||||
{
|
||||
hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
|
||||
#ifdef HYCAPI_PRINTFNAMES
|
||||
|
@ -53,7 +53,7 @@ struct boot_data {
|
||||
/* to be called at start of POF file reading, */
|
||||
/* before starting any decryption on any POF record. */
|
||||
/*****************************************************/
|
||||
void
|
||||
static void
|
||||
StartDecryption(struct boot_data *boot)
|
||||
{
|
||||
boot->Cryptor = CRYPT_STARTTERM;
|
||||
@ -66,7 +66,7 @@ StartDecryption(struct boot_data *boot)
|
||||
/* to HI and LO boot loader and (all) seq tags, because */
|
||||
/* global Cryptor is started for whole POF. */
|
||||
/***************************************************************/
|
||||
void
|
||||
static void
|
||||
DecryptBuf(struct boot_data *boot, int cnt)
|
||||
{
|
||||
uchar *bufp = boot->buf.BootBuf;
|
||||
|
@ -227,7 +227,6 @@ typedef struct hycapictrl_info hycapictrl_info;
|
||||
/*****************/
|
||||
/* exported vars */
|
||||
/*****************/
|
||||
extern int cardmax; /* number of found cards */
|
||||
extern hysdn_card *card_root; /* pointer to first card */
|
||||
|
||||
|
||||
@ -244,7 +243,6 @@ extern void hysdn_procconf_release(void); /* deinit proc config filesys */
|
||||
/* hysdn_proclog.c */
|
||||
extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */
|
||||
extern void hysdn_proclog_release(hysdn_card *); /* deinit proc log entry */
|
||||
extern void put_log_buffer(hysdn_card *, char *); /* output log data */
|
||||
extern void hysdn_addlog(hysdn_card *, char *,...); /* output data to log */
|
||||
extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int); /* output card log */
|
||||
|
||||
@ -278,16 +276,6 @@ extern unsigned int hycapi_enable;
|
||||
extern int hycapi_capi_create(hysdn_card *); /* create a new capi device */
|
||||
extern int hycapi_capi_release(hysdn_card *); /* delete the device */
|
||||
extern int hycapi_capi_stop(hysdn_card *card); /* suspend */
|
||||
extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *);
|
||||
extern void hycapi_reset_ctr(struct capi_ctr *);
|
||||
extern void hycapi_remove_ctr(struct capi_ctr *);
|
||||
extern void hycapi_register_appl(struct capi_ctr *, __u16 appl,
|
||||
capi_register_params *);
|
||||
extern void hycapi_release_appl(struct capi_ctr *, __u16 appl);
|
||||
extern u16 hycapi_send_message(struct capi_ctr *, struct sk_buff *skb);
|
||||
extern char *hycapi_procinfo(struct capi_ctr *);
|
||||
extern int hycapi_read_proc(char *page, char **start, off_t off,
|
||||
int count, int *eof, struct capi_ctr *card);
|
||||
extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len);
|
||||
extern void hycapi_tx_capiack(hysdn_card * card);
|
||||
extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
|
||||
|
@ -34,7 +34,7 @@ MODULE_AUTHOR("Werner Cornelius");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
|
||||
int cardmax; /* number of found cards */
|
||||
static int cardmax; /* number of found cards */
|
||||
hysdn_card *card_root = NULL; /* pointer to first card */
|
||||
|
||||
/**********************************************/
|
||||
|
@ -22,6 +22,8 @@
|
||||
/* the proc subdir for the interface is defined in the procconf module */
|
||||
extern struct proc_dir_entry *hysdn_proc_entry;
|
||||
|
||||
static void put_log_buffer(hysdn_card * card, char *cp);
|
||||
|
||||
/*************************************************/
|
||||
/* structure keeping ascii log for device output */
|
||||
/*************************************************/
|
||||
@ -93,7 +95,7 @@ hysdn_addlog(hysdn_card * card, char *fmt,...)
|
||||
/* opened for read got the contents. */
|
||||
/* Flushes buffers not longer in use. */
|
||||
/********************************************/
|
||||
void
|
||||
static void
|
||||
put_log_buffer(hysdn_card * card, char *cp)
|
||||
{
|
||||
struct log_data *ib;
|
||||
|
@ -338,6 +338,7 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error)
|
||||
|
||||
if (atomic_dec_and_test(&rdev->mddev->pending_writes))
|
||||
wake_up(&rdev->mddev->sb_wait);
|
||||
bio_put(bio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
|
||||
zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
|
||||
zr36067-objs := zoran_procfs.o zoran_device.o \
|
||||
zoran_driver.o zoran_card.o
|
||||
tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o
|
||||
|
||||
tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
|
||||
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
$Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $
|
||||
$Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $
|
||||
|
||||
bttv - Bt848 frame grabber driver
|
||||
|
||||
@ -76,6 +76,9 @@ static unsigned int whitecrush_upper = 0xCF;
|
||||
static unsigned int whitecrush_lower = 0x7F;
|
||||
static unsigned int vcr_hack = 0;
|
||||
static unsigned int irq_iswitch = 0;
|
||||
static unsigned int uv_ratio = 50;
|
||||
static unsigned int full_luma_range = 0;
|
||||
static unsigned int coring = 0;
|
||||
|
||||
/* API features (turn on/off stuff for testing) */
|
||||
static unsigned int v4l2 = 1;
|
||||
@ -106,6 +109,9 @@ module_param(adc_crush, int, 0444);
|
||||
module_param(whitecrush_upper, int, 0444);
|
||||
module_param(whitecrush_lower, int, 0444);
|
||||
module_param(vcr_hack, int, 0444);
|
||||
module_param(uv_ratio, int, 0444);
|
||||
module_param(full_luma_range, int, 0444);
|
||||
module_param(coring, int, 0444);
|
||||
|
||||
module_param_array(radio, int, NULL, 0444);
|
||||
|
||||
@ -124,6 +130,9 @@ MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is
|
||||
MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
|
||||
MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
|
||||
MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
|
||||
MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");
|
||||
MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");
|
||||
MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");
|
||||
|
||||
MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
|
||||
MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
|
||||
@ -484,7 +493,10 @@ static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
|
||||
#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5)
|
||||
#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6)
|
||||
#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7)
|
||||
#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 8)
|
||||
#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8)
|
||||
#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9)
|
||||
#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10)
|
||||
#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11)
|
||||
|
||||
static const struct v4l2_queryctrl no_ctl = {
|
||||
.name = "42",
|
||||
@ -618,8 +630,32 @@ static const struct v4l2_queryctrl bttv_ctls[] = {
|
||||
.step = 1,
|
||||
.default_value = 0x7F,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
},{
|
||||
.id = V4L2_CID_PRIVATE_UV_RATIO,
|
||||
.name = "uv ratio",
|
||||
.minimum = 0,
|
||||
.maximum = 100,
|
||||
.step = 1,
|
||||
.default_value = 50,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
},{
|
||||
.id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE,
|
||||
.name = "full luma range",
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
},{
|
||||
.id = V4L2_CID_PRIVATE_CORING,
|
||||
.name = "coring",
|
||||
.minimum = 0,
|
||||
.maximum = 3,
|
||||
.step = 1,
|
||||
.default_value = 0,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
|
||||
|
||||
@ -833,8 +869,8 @@ static void bt848_sat(struct bttv *btv, int color)
|
||||
btv->saturation = color;
|
||||
|
||||
/* 0-511 for the color */
|
||||
val_u = color >> 7;
|
||||
val_v = ((color>>7)*180L)/254;
|
||||
val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
|
||||
val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
|
||||
hibits = (val_u >> 7) & 2;
|
||||
hibits |= (val_v >> 8) & 1;
|
||||
btwrite(val_u & 0xff, BT848_SAT_U_LO);
|
||||
@ -1151,6 +1187,15 @@ static int get_control(struct bttv *btv, struct v4l2_control *c)
|
||||
case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
|
||||
c->value = btv->opt_whitecrush_lower;
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_UV_RATIO:
|
||||
c->value = btv->opt_uv_ratio;
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
|
||||
c->value = btv->opt_full_luma_range;
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_CORING:
|
||||
c->value = btv->opt_coring;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1247,6 +1292,18 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
|
||||
btv->opt_whitecrush_lower = c->value;
|
||||
btwrite(c->value, BT848_WC_DOWN);
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_UV_RATIO:
|
||||
btv->opt_uv_ratio = c->value;
|
||||
bt848_sat(btv, btv->saturation);
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
|
||||
btv->opt_full_luma_range = c->value;
|
||||
btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_CORING:
|
||||
btv->opt_coring = c->value;
|
||||
btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -3117,11 +3174,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
|
||||
return -EINVAL;
|
||||
memset(v,0,sizeof(*v));
|
||||
strcpy(v->name, "Radio");
|
||||
/* japan: 76.0 MHz - 89.9 MHz
|
||||
western europe: 87.5 MHz - 108.0 MHz
|
||||
russia: 65.0 MHz - 108.0 MHz */
|
||||
v->rangelow=(int)(65*16);
|
||||
v->rangehigh=(int)(108*16);
|
||||
bttv_call_i2c_clients(btv,cmd,v);
|
||||
return 0;
|
||||
}
|
||||
@ -3876,6 +3928,9 @@ static int __devinit bttv_probe(struct pci_dev *dev,
|
||||
btv->opt_vcr_hack = vcr_hack;
|
||||
btv->opt_whitecrush_upper = whitecrush_upper;
|
||||
btv->opt_whitecrush_lower = whitecrush_lower;
|
||||
btv->opt_uv_ratio = uv_ratio;
|
||||
btv->opt_full_luma_range = full_luma_range;
|
||||
btv->opt_coring = coring;
|
||||
|
||||
/* fill struct bttv with some useful defaults */
|
||||
btv->init.btv = btv;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
$Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $
|
||||
$Id: bttvp.h,v 1.19 2005/06/16 21:38:45 nsh Exp $
|
||||
|
||||
bttv - Bt848 frame grabber driver
|
||||
|
||||
@ -326,6 +326,9 @@ struct bttv {
|
||||
int opt_vcr_hack;
|
||||
int opt_whitecrush_upper;
|
||||
int opt_whitecrush_lower;
|
||||
int opt_uv_ratio;
|
||||
int opt_full_luma_range;
|
||||
int opt_coring;
|
||||
|
||||
/* radio data/state */
|
||||
int has_radio;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $
|
||||
* $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $
|
||||
*
|
||||
* i2c tv tuner chip device driver
|
||||
* controls microtune tuners, mt2032 + mt2050 at the moment.
|
||||
@ -295,8 +295,8 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
|
||||
int if2 = t->radio_if2;
|
||||
|
||||
// per Manual for FM tuning: first if center freq. 1085 MHz
|
||||
mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
|
||||
1085*1000*1000,if2,if2,if2);
|
||||
mt2032_set_if_freq(c, freq * 1000 / 16,
|
||||
1085*1000*1000,if2,if2,if2);
|
||||
}
|
||||
|
||||
// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $
|
||||
* $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $
|
||||
*
|
||||
* i2c tv tuner chip device driver
|
||||
* controls the philips tda8290+75 tuner chip combo.
|
||||
@ -69,7 +69,7 @@ static __u8 get_freq_entry( struct freq_entry* table, __u16 freq)
|
||||
static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 };
|
||||
static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 };
|
||||
static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
|
||||
0x7C, 0x04, 0xA3, 0x3F,
|
||||
0xfC, 0x04, 0xA3, 0x3F,
|
||||
0x2A, 0x04, 0xFF, 0x00,
|
||||
0x00, 0x40 };
|
||||
static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
|
||||
@ -138,16 +138,24 @@ static int tda8290_tune(struct i2c_client *c)
|
||||
|
||||
static void set_frequency(struct tuner *t, u16 ifc)
|
||||
{
|
||||
u32 N = (((t->freq<<3)+ifc)&0x3fffc);
|
||||
u32 freq;
|
||||
u32 N;
|
||||
|
||||
N = N >> get_freq_entry(div_table, t->freq);
|
||||
if (t->mode == V4L2_TUNER_RADIO)
|
||||
freq = t->freq / 1000;
|
||||
else
|
||||
freq = t->freq;
|
||||
|
||||
N = (((freq<<3)+ifc)&0x3fffc);
|
||||
|
||||
N = N >> get_freq_entry(div_table, freq);
|
||||
t->i2c_set_freq[0] = 0;
|
||||
t->i2c_set_freq[1] = (unsigned char)(N>>8);
|
||||
t->i2c_set_freq[2] = (unsigned char) N;
|
||||
t->i2c_set_freq[3] = 0x40;
|
||||
t->i2c_set_freq[4] = 0x52;
|
||||
t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq);
|
||||
t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq);
|
||||
t->i2c_set_freq[5] = get_freq_entry(band_table, freq);
|
||||
t->i2c_set_freq[6] = get_freq_entry(agc_table, freq);
|
||||
t->i2c_set_freq[7] = 0x8f;
|
||||
}
|
||||
|
||||
|
@ -368,7 +368,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
|
||||
if (t->radio_mode == V4L2_TUNER_MODE_MONO)
|
||||
norm = &radio_mono;
|
||||
else
|
||||
norm = &radio_stereo;
|
||||
norm = &radio_stereo;
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
|
||||
if (tvnorms[i].std & t->std) {
|
||||
@ -566,7 +566,6 @@ static int tda9887_configure(struct tda9887 *t)
|
||||
if (UNSET != t->pinnacle_id) {
|
||||
tda9887_set_pinnacle(t,buf);
|
||||
}
|
||||
|
||||
tda9887_set_config(t,buf);
|
||||
tda9887_set_insmod(t,buf);
|
||||
|
||||
@ -615,8 +614,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
t->pinnacle_id = UNSET;
|
||||
t->radio_mode = V4L2_TUNER_MODE_STEREO;
|
||||
|
||||
i2c_set_clientdata(&t->client, t);
|
||||
i2c_attach_client(&t->client);
|
||||
i2c_set_clientdata(&t->client, t);
|
||||
i2c_attach_client(&t->client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
334
drivers/media/video/tea5767.c
Normal file
334
drivers/media/video/tea5767.c
Normal file
@ -0,0 +1,334 @@
|
||||
/*
|
||||
* For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
|
||||
* I2C address is allways 0xC0.
|
||||
*
|
||||
* $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $
|
||||
*
|
||||
* Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
|
||||
* This code is placed under the terms of the GNU General Public License
|
||||
*
|
||||
* tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
|
||||
* from their contributions on DScaler.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/videodev.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
|
||||
#include <media/tuner.h>
|
||||
|
||||
/* Declared at tuner-core.c */
|
||||
extern unsigned int tuner_debug;
|
||||
|
||||
#define PREFIX "TEA5767 "
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/******************************
|
||||
* Write mode register values *
|
||||
******************************/
|
||||
|
||||
/* First register */
|
||||
#define TEA5767_MUTE 0x80 /* Mutes output */
|
||||
#define TEA5767_SEARCH 0x40 /* Activates station search */
|
||||
/* Bits 0-5 for divider MSB */
|
||||
|
||||
/* Second register */
|
||||
/* Bits 0-7 for divider LSB */
|
||||
|
||||
/* Third register */
|
||||
|
||||
/* Station search from botton to up */
|
||||
#define TEA5767_SEARCH_UP 0x80
|
||||
|
||||
/* Searches with ADC output = 10 */
|
||||
#define TEA5767_SRCH_HIGH_LVL 0x60
|
||||
|
||||
/* Searches with ADC output = 10 */
|
||||
#define TEA5767_SRCH_MID_LVL 0x40
|
||||
|
||||
/* Searches with ADC output = 5 */
|
||||
#define TEA5767_SRCH_LOW_LVL 0x20
|
||||
|
||||
/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
|
||||
#define TEA5767_HIGH_LO_INJECT 0x10
|
||||
|
||||
/* Disable stereo */
|
||||
#define TEA5767_MONO 0x08
|
||||
|
||||
/* Disable right channel and turns to mono */
|
||||
#define TEA5767_MUTE_RIGHT 0x04
|
||||
|
||||
/* Disable left channel and turns to mono */
|
||||
#define TEA5767_MUTE_LEFT 0x02
|
||||
|
||||
#define TEA5767_PORT1_HIGH 0x01
|
||||
|
||||
/* Forth register */
|
||||
#define TEA5767_PORT2_HIGH 0x80
|
||||
/* Chips stops working. Only I2C bus remains on */
|
||||
#define TEA5767_STDBY 0x40
|
||||
|
||||
/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
|
||||
#define TEA5767_JAPAN_BAND 0x20
|
||||
|
||||
/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
|
||||
#define TEA5767_XTAL_32768 0x10
|
||||
|
||||
/* Cuts weak signals */
|
||||
#define TEA5767_SOFT_MUTE 0x08
|
||||
|
||||
/* Activates high cut control */
|
||||
#define TEA5767_HIGH_CUT_CTRL 0x04
|
||||
|
||||
/* Activates stereo noise control */
|
||||
#define TEA5767_ST_NOISE_CTL 0x02
|
||||
|
||||
/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
|
||||
#define TEA5767_SRCH_IND 0x01
|
||||
|
||||
/* Fiveth register */
|
||||
|
||||
/* By activating, it will use Xtal at 13 MHz as reference for divider */
|
||||
#define TEA5767_PLLREF_ENABLE 0x80
|
||||
|
||||
/* By activating, deemphasis=50, or else, deemphasis of 50us */
|
||||
#define TEA5767_DEEMPH_75 0X40
|
||||
|
||||
/*****************************
|
||||
* Read mode register values *
|
||||
*****************************/
|
||||
|
||||
/* First register */
|
||||
#define TEA5767_READY_FLAG_MASK 0x80
|
||||
#define TEA5767_BAND_LIMIT_MASK 0X40
|
||||
/* Bits 0-5 for divider MSB after search or preset */
|
||||
|
||||
/* Second register */
|
||||
/* Bits 0-7 for divider LSB after search or preset */
|
||||
|
||||
/* Third register */
|
||||
#define TEA5767_STEREO_MASK 0x80
|
||||
#define TEA5767_IF_CNTR_MASK 0x7f
|
||||
|
||||
/* Four register */
|
||||
#define TEA5767_ADC_LEVEL_MASK 0xf0
|
||||
|
||||
/* should be 0 */
|
||||
#define TEA5767_CHIP_ID_MASK 0x0f
|
||||
|
||||
/* Fiveth register */
|
||||
/* Reserved for future extensions */
|
||||
#define TEA5767_RESERVED_MASK 0xff
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void set_tv_freq(struct i2c_client *c, unsigned int freq)
|
||||
{
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
|
||||
tuner_warn("This tuner doesn't support TV freq.\n");
|
||||
}
|
||||
|
||||
static void tea5767_status_dump(unsigned char *buffer)
|
||||
{
|
||||
unsigned int div, frq;
|
||||
|
||||
if (TEA5767_READY_FLAG_MASK & buffer[0])
|
||||
printk(PREFIX "Ready Flag ON\n");
|
||||
else
|
||||
printk(PREFIX "Ready Flag OFF\n");
|
||||
|
||||
if (TEA5767_BAND_LIMIT_MASK & buffer[0])
|
||||
printk(PREFIX "Tuner at band limit\n");
|
||||
else
|
||||
printk(PREFIX "Tuner not at band limit\n");
|
||||
|
||||
div=((buffer[0]&0x3f)<<8) | buffer[1];
|
||||
|
||||
switch (TEA5767_HIGH_LO_32768) {
|
||||
case TEA5767_HIGH_LO_13MHz:
|
||||
frq = 1000*(div*50-700-225)/4; /* Freq in KHz */
|
||||
break;
|
||||
case TEA5767_LOW_LO_13MHz:
|
||||
frq = 1000*(div*50+700+225)/4; /* Freq in KHz */
|
||||
break;
|
||||
case TEA5767_LOW_LO_32768:
|
||||
frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */
|
||||
break;
|
||||
case TEA5767_HIGH_LO_32768:
|
||||
default:
|
||||
frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */
|
||||
break;
|
||||
}
|
||||
buffer[0] = (div>>8) & 0x3f;
|
||||
buffer[1] = div & 0xff;
|
||||
|
||||
printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n",
|
||||
frq/1000,frq%1000,div);
|
||||
|
||||
if (TEA5767_STEREO_MASK & buffer[2])
|
||||
printk(PREFIX "Stereo\n");
|
||||
else
|
||||
printk(PREFIX "Mono\n");
|
||||
|
||||
printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK);
|
||||
|
||||
printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4);
|
||||
|
||||
printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK));
|
||||
|
||||
printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK));
|
||||
}
|
||||
|
||||
/* Freq should be specifyed at 62.5 Hz */
|
||||
static void set_radio_freq(struct i2c_client *c, unsigned int frq)
|
||||
{
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
unsigned char buffer[5];
|
||||
unsigned div;
|
||||
int rc;
|
||||
|
||||
if ( tuner_debug )
|
||||
printk(PREFIX "radio freq counter %d\n",frq);
|
||||
|
||||
/* Rounds freq to next decimal value - for 62.5 KHz step */
|
||||
/* frq = 20*(frq/16)+radio_frq[frq%16]; */
|
||||
|
||||
buffer[2] = TEA5767_PORT1_HIGH;
|
||||
buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
|
||||
buffer[4]=0;
|
||||
|
||||
if (t->audmode == V4L2_TUNER_MODE_MONO) {
|
||||
tuner_dbg("TEA5767 set to mono\n");
|
||||
buffer[2] |= TEA5767_MONO;
|
||||
} else
|
||||
tuner_dbg("TEA5767 set to stereo\n");
|
||||
|
||||
switch (t->type) {
|
||||
case TEA5767_HIGH_LO_13MHz:
|
||||
tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
|
||||
buffer[2] |= TEA5767_HIGH_LO_INJECT;
|
||||
buffer[4] |= TEA5767_PLLREF_ENABLE;
|
||||
div = (frq*4/16+700+225+25)/50;
|
||||
break;
|
||||
case TEA5767_LOW_LO_13MHz:
|
||||
tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
|
||||
|
||||
buffer[4] |= TEA5767_PLLREF_ENABLE;
|
||||
div = (frq*4/16-700-225+25)/50;
|
||||
break;
|
||||
case TEA5767_LOW_LO_32768:
|
||||
tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
|
||||
buffer[3] |= TEA5767_XTAL_32768;
|
||||
/* const 700=4000*175 Khz - to adjust freq to right value */
|
||||
div = (1000*(frq*4/16-700-225)+16384)>>15;
|
||||
break;
|
||||
case TEA5767_HIGH_LO_32768:
|
||||
default:
|
||||
tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
|
||||
|
||||
buffer[2] |= TEA5767_HIGH_LO_INJECT;
|
||||
buffer[3] |= TEA5767_XTAL_32768;
|
||||
div = (1000*(frq*4/16+700+225)+16384)>>15;
|
||||
break;
|
||||
}
|
||||
buffer[0] = (div>>8) & 0x3f;
|
||||
buffer[1] = div & 0xff;
|
||||
|
||||
if ( tuner_debug )
|
||||
tea5767_status_dump(buffer);
|
||||
|
||||
if (5 != (rc = i2c_master_send(c,buffer,5)))
|
||||
tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc);
|
||||
}
|
||||
|
||||
static int tea5767_signal(struct i2c_client *c)
|
||||
{
|
||||
unsigned char buffer[5];
|
||||
int rc;
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
if (5 != (rc = i2c_master_recv(c,buffer,5)))
|
||||
tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
|
||||
|
||||
return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4));
|
||||
}
|
||||
|
||||
static int tea5767_stereo(struct i2c_client *c)
|
||||
{
|
||||
unsigned char buffer[5];
|
||||
int rc;
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
if (5 != (rc = i2c_master_recv(c,buffer,5)))
|
||||
tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
|
||||
|
||||
rc = buffer[2] & TEA5767_STEREO_MASK;
|
||||
|
||||
if ( tuner_debug )
|
||||
tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
|
||||
|
||||
return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0);
|
||||
}
|
||||
|
||||
int tea_detection(struct i2c_client *c)
|
||||
{
|
||||
unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
int rc;
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
|
||||
if (5 != (rc = i2c_master_recv(c,buffer,5))) {
|
||||
tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc );
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */
|
||||
if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
|
||||
buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
|
||||
tuner_warn ( "All bytes are equal. It is not a TEA5767\n" );
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Status bytes:
|
||||
* Byte 4: bit 3:1 : CI (Chip Identification) == 0
|
||||
* bit 0 : internally set to 0
|
||||
* Byte 5: bit 7:0 : == 0
|
||||
*/
|
||||
|
||||
if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
|
||||
tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" );
|
||||
return EINVAL;
|
||||
}
|
||||
tuner_warn ( "TEA5767 detected.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tea5767_tuner_init(struct i2c_client *c)
|
||||
{
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
|
||||
if (tea_detection(c)==EINVAL) return EINVAL;
|
||||
|
||||
tuner_info("type set to %d (%s)\n",
|
||||
t->type, TEA5767_TUNER_NAME);
|
||||
strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name));
|
||||
|
||||
t->tv_freq = set_tv_freq;
|
||||
t->radio_freq = set_radio_freq;
|
||||
t->has_signal = tea5767_signal;
|
||||
t->is_stereo = tea5767_stereo;
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $
|
||||
* $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $
|
||||
*
|
||||
* i2c tv tuner chip device driver
|
||||
* core core, i.e. kernel interfaces, registering and so on
|
||||
@ -26,7 +26,6 @@
|
||||
/*
|
||||
* comment line bellow to return to old behavor, where only one I2C device is supported
|
||||
*/
|
||||
#define CONFIG_TUNER_MULTI_I2C /**/
|
||||
|
||||
#define UNSET (-1U)
|
||||
|
||||
@ -58,9 +57,7 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int this_adap;
|
||||
#ifdef CONFIG_TUNER_MULTI_I2C
|
||||
static unsigned short first_tuner, tv_tuner, radio_tuner;
|
||||
#endif
|
||||
|
||||
static struct i2c_driver driver;
|
||||
static struct i2c_client client_template;
|
||||
@ -81,26 +78,9 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
|
||||
return;
|
||||
}
|
||||
if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
|
||||
|
||||
if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
|
||||
/* V4L2_TUNER_CAP_LOW frequency */
|
||||
|
||||
tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n");
|
||||
|
||||
t->tv_freq(c,freq>>10);
|
||||
|
||||
return;
|
||||
} else {
|
||||
/* FIXME: better do that chip-specific, but
|
||||
right now we don't have that in the config
|
||||
struct and this way is still better than no
|
||||
check at all */
|
||||
tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
|
||||
freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
tuner_dbg("62.5 Khz freq step selected for TV.\n");
|
||||
t->tv_freq(c,freq);
|
||||
}
|
||||
|
||||
@ -116,31 +96,18 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
|
||||
tuner_info("no radio tuning for this one, sorry.\n");
|
||||
return;
|
||||
}
|
||||
if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
|
||||
if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
|
||||
/* V4L2_TUNER_CAP_LOW frequency */
|
||||
if (t->type == TUNER_TEA5767) {
|
||||
tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
|
||||
t->radio_freq(c,freq>>10);
|
||||
return;
|
||||
}
|
||||
|
||||
tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n");
|
||||
|
||||
tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
|
||||
|
||||
t->radio_freq(c,freq>>10);
|
||||
return;
|
||||
|
||||
} else {
|
||||
tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
|
||||
freq/16,freq%16*100/16,
|
||||
radio_range[0],radio_range[1]);
|
||||
return;
|
||||
}
|
||||
if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) {
|
||||
if (tuner_debug)
|
||||
tuner_info("radio freq step 62.5Hz (%d.%06d)\n",
|
||||
freq/16000,freq%16000*1000/16);
|
||||
t->radio_freq(c,freq);
|
||||
} else {
|
||||
tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
|
||||
freq/16,freq%16*100/16,
|
||||
radio_range[0],radio_range[1]);
|
||||
}
|
||||
tuner_dbg("62.5 Khz freq step selected for Radio.\n");
|
||||
t->radio_freq(c,freq);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void set_freq(struct i2c_client *c, unsigned long freq)
|
||||
@ -166,8 +133,8 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
|
||||
static void set_type(struct i2c_client *c, unsigned int type)
|
||||
{
|
||||
struct tuner *t = i2c_get_clientdata(c);
|
||||
unsigned char buffer[4];
|
||||
|
||||
tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
|
||||
/* sanity check */
|
||||
if (type == UNSET || type == TUNER_ABSENT)
|
||||
return;
|
||||
@ -179,8 +146,8 @@ static void set_type(struct i2c_client *c, unsigned int type)
|
||||
t->type = type;
|
||||
return;
|
||||
}
|
||||
if (t->initialized)
|
||||
/* run only once */
|
||||
if ((t->initialized) && (t->type == type))
|
||||
/* run only once except type change Hac 04/05*/
|
||||
return;
|
||||
|
||||
t->initialized = 1;
|
||||
@ -193,25 +160,42 @@ static void set_type(struct i2c_client *c, unsigned int type)
|
||||
case TUNER_PHILIPS_TDA8290:
|
||||
tda8290_init(c);
|
||||
break;
|
||||
case TUNER_TEA5767:
|
||||
if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT;
|
||||
break;
|
||||
case TUNER_PHILIPS_FMD1216ME_MK3:
|
||||
buffer[0] = 0x0b;
|
||||
buffer[1] = 0xdc;
|
||||
buffer[2] = 0x9c;
|
||||
buffer[3] = 0x60;
|
||||
i2c_master_send(c,buffer,4);
|
||||
mdelay(1);
|
||||
buffer[2] = 0x86;
|
||||
buffer[3] = 0x54;
|
||||
i2c_master_send(c,buffer,4);
|
||||
default_tuner_init(c);
|
||||
break;
|
||||
default:
|
||||
/* TEA5767 autodetection code */
|
||||
if (tea5767_tuner_init(c)!=EINVAL) {
|
||||
t->type = TUNER_TEA5767;
|
||||
if (first_tuner == 0x60)
|
||||
first_tuner++;
|
||||
break;
|
||||
}
|
||||
|
||||
default_tuner_init(c);
|
||||
break;
|
||||
}
|
||||
tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TUNER_MULTI_I2C
|
||||
#define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \
|
||||
return 0; } else \
|
||||
return 0; } else if (tuner_debug) \
|
||||
tuner_info ("Cmd %s accepted to "tun"\n",cmd);
|
||||
#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \
|
||||
CHECK_ADDR(radio_tuner,cmd,"radio") } else \
|
||||
{ CHECK_ADDR(tv_tuner,cmd,"TV"); }
|
||||
#else
|
||||
#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd);
|
||||
#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TUNER_MULTI_I2C
|
||||
|
||||
static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
|
||||
{
|
||||
@ -242,9 +226,6 @@ static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
|
||||
}
|
||||
set_type(c,tun_addr->type);
|
||||
}
|
||||
#else
|
||||
#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type)
|
||||
#endif
|
||||
|
||||
static char pal[] = "-";
|
||||
module_param_string(pal, pal, sizeof(pal), 0644);
|
||||
@ -284,17 +265,12 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
{
|
||||
struct tuner *t;
|
||||
|
||||
#ifndef CONFIG_TUNER_MULTI_I2C
|
||||
if (this_adap > 0)
|
||||
return -1;
|
||||
#else
|
||||
/* by default, first I2C card is both tv and radio tuner */
|
||||
if (this_adap == 0) {
|
||||
first_tuner = addr;
|
||||
tv_tuner = addr;
|
||||
radio_tuner = addr;
|
||||
}
|
||||
#endif
|
||||
this_adap++;
|
||||
|
||||
client_template.adapter = adap;
|
||||
@ -308,6 +284,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
i2c_set_clientdata(&t->i2c, t);
|
||||
t->type = UNSET;
|
||||
t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */
|
||||
t->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
|
||||
i2c_attach_client(&t->i2c);
|
||||
tuner_info("chip found @ 0x%x (%s)\n",
|
||||
@ -325,11 +302,9 @@ static int tuner_probe(struct i2c_adapter *adap)
|
||||
}
|
||||
this_adap = 0;
|
||||
|
||||
#ifdef CONFIG_TUNER_MULTI_I2C
|
||||
first_tuner = 0;
|
||||
tv_tuner = 0;
|
||||
radio_tuner = 0;
|
||||
#endif
|
||||
|
||||
if (adap->class & I2C_CLASS_TV_ANALOG)
|
||||
return i2c_probe(adap, &addr_data, tuner_attach);
|
||||
@ -392,8 +367,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
t->radio_if2 = 41300 * 1000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
/* --- v4l ioctls --- */
|
||||
/* take care: bttv does userspace copying, we'll get a
|
||||
kernel pointer here... */
|
||||
@ -440,11 +414,18 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
vt->signal = t->has_signal(client);
|
||||
if (t->is_stereo) {
|
||||
if (t->is_stereo(client))
|
||||
vt-> flags |= VIDEO_TUNER_STEREO_ON;
|
||||
vt->flags |= VIDEO_TUNER_STEREO_ON;
|
||||
else
|
||||
vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON;
|
||||
vt->flags &= ~VIDEO_TUNER_STEREO_ON;
|
||||
}
|
||||
vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */
|
||||
|
||||
vt->rangelow = radio_range[0] * 16000;
|
||||
vt->rangehigh = radio_range[1] * 16000;
|
||||
|
||||
} else {
|
||||
vt->rangelow = tv_range[0] * 16;
|
||||
vt->rangehigh = tv_range[1] * 16;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -510,20 +491,46 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
tuner -> signal = t->has_signal(client);
|
||||
if (t->is_stereo) {
|
||||
if (t->is_stereo(client)) {
|
||||
tuner -> capability |= V4L2_TUNER_CAP_STEREO;
|
||||
tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO;
|
||||
tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
|
||||
} else {
|
||||
tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO;
|
||||
tuner -> rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
}
|
||||
}
|
||||
tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
|
||||
tuner->audmode = t->audmode;
|
||||
|
||||
tuner->rangelow = radio_range[0] * 16000;
|
||||
tuner->rangehigh = radio_range[1] * 16000;
|
||||
} else {
|
||||
tuner->rangelow = tv_range[0] * 16;
|
||||
tuner->rangehigh = tv_range[1] * 16;
|
||||
}
|
||||
/* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step to high at 62.5 Hz */
|
||||
tuner->rangelow = tv_range[0] * 16;
|
||||
// tuner->rangehigh = tv_range[1] * 16;
|
||||
// tuner->rangelow = tv_range[0] * 16384;
|
||||
tuner->rangehigh = tv_range[1] * 16384;
|
||||
break;
|
||||
}
|
||||
case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */
|
||||
{
|
||||
struct v4l2_tuner *tuner = arg;
|
||||
|
||||
CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio");
|
||||
SWITCH_V4L2;
|
||||
|
||||
/* To switch the audio mode, applications initialize the
|
||||
index and audmode fields and the reserved array and
|
||||
call the VIDIOC_S_TUNER ioctl. */
|
||||
/* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO,
|
||||
V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2,
|
||||
V4L2_TUNER_MODE_SAP */
|
||||
|
||||
if (tuner->audmode == V4L2_TUNER_MODE_MONO)
|
||||
t->audmode = V4L2_TUNER_MODE_MONO;
|
||||
else
|
||||
t->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
|
||||
set_radio_freq(client, t->freq);
|
||||
break;
|
||||
}
|
||||
case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */
|
||||
break;
|
||||
default:
|
||||
tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
|
||||
/* nothing */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $
|
||||
* $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $
|
||||
*
|
||||
* i2c tv tuner chip device driver
|
||||
* controls all those simple 4-control-bytes style tuners.
|
||||
@ -207,28 +207,27 @@ static struct tunertype tuners[] = {
|
||||
{ "LG PAL (TAPE series)", LGINNOTEK, PAL,
|
||||
16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
|
||||
|
||||
{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
|
||||
16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
|
||||
{ "Philips FQ1236A MK4", Philips, NTSC,
|
||||
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
|
||||
{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
|
||||
16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
|
||||
{ "Philips FQ1236A MK4", Philips, NTSC,
|
||||
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
|
||||
|
||||
/* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
|
||||
{ "Ymec TVision TVF-8531MF", Philips, NTSC,
|
||||
16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
|
||||
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
|
||||
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
|
||||
|
||||
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
|
||||
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
|
||||
{ "Tena TNF9533-D/IF", LGINNOTEK, PAL,
|
||||
16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623},
|
||||
/* Should work for TNF9533-D/IF, TNF9533-B/DF */
|
||||
{ "Tena TNF9533-D/IF", Philips, PAL,
|
||||
16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
|
||||
|
||||
/*
|
||||
* This entry is for TEA5767 FM radio only chip used on several boards
|
||||
* w/TV tuner
|
||||
*/
|
||||
/* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */
|
||||
{ TEA5767_TUNER_NAME, Philips, RADIO,
|
||||
-1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
|
||||
-1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
|
||||
{ "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
|
||||
16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
|
||||
};
|
||||
|
||||
unsigned const int tuner_count = ARRAY_SIZE(tuners);
|
||||
@ -455,24 +454,24 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
|
||||
int rc;
|
||||
|
||||
tun=&tuners[t->type];
|
||||
div = freq + (int)(16*10.7);
|
||||
div = (freq / 1000) + (int)(16*10.7);
|
||||
buffer[2] = tun->config;
|
||||
|
||||
switch (t->type) {
|
||||
case TUNER_TENA_9533_DI:
|
||||
case TUNER_YMEC_TVF_5533MF:
|
||||
|
||||
/*These values are empirically determinated */
|
||||
div = (freq*122)/16 - 20;
|
||||
div = (freq * 122) / 16000 - 20;
|
||||
buffer[2] = 0x88; /* could be also 0x80 */
|
||||
buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
|
||||
break;
|
||||
case TUNER_PHILIPS_FM1216ME_MK3:
|
||||
case TUNER_PHILIPS_FM1236_MK3:
|
||||
case TUNER_PHILIPS_FMD1216ME_MK3:
|
||||
buffer[3] = 0x19;
|
||||
break;
|
||||
case TUNER_PHILIPS_FM1256_IH3:
|
||||
div = (20 * freq)/16 + 333 * 2;
|
||||
div = (20 * freq) / 16000 + 333 * 2;
|
||||
buffer[2] = 0x80;
|
||||
buffer[3] = 0x19;
|
||||
break;
|
||||
@ -505,6 +504,7 @@ int default_tuner_init(struct i2c_client *c)
|
||||
t->radio_freq = default_set_radio_freq;
|
||||
t->has_signal = tuner_signal;
|
||||
t->is_stereo = tuner_stereo;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -364,9 +364,7 @@ static struct pci_driver mptfc_driver = {
|
||||
.id_table = mptfc_pci_table,
|
||||
.probe = mptfc_probe,
|
||||
.remove = __devexit_p(mptscsih_remove),
|
||||
.driver = {
|
||||
.shutdown = mptscsih_shutdown,
|
||||
},
|
||||
.shutdown = mptscsih_shutdown,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mptscsih_suspend,
|
||||
.resume = mptscsih_resume,
|
||||
|
@ -170,7 +170,7 @@ static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
|
||||
#endif
|
||||
|
||||
void mptscsih_remove(struct pci_dev *);
|
||||
void mptscsih_shutdown(struct device *);
|
||||
void mptscsih_shutdown(struct pci_dev *);
|
||||
#ifdef CONFIG_PM
|
||||
int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
|
||||
int mptscsih_resume(struct pci_dev *pdev);
|
||||
@ -988,7 +988,7 @@ mptscsih_remove(struct pci_dev *pdev)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mptscsih_shutdown(&pdev->dev);
|
||||
mptscsih_shutdown(pdev);
|
||||
|
||||
sz1=0;
|
||||
|
||||
@ -1026,9 +1026,9 @@ mptscsih_remove(struct pci_dev *pdev)
|
||||
*
|
||||
*/
|
||||
void
|
||||
mptscsih_shutdown(struct device * dev)
|
||||
mptscsih_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
|
||||
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
||||
struct Scsi_Host *host = ioc->sh;
|
||||
MPT_SCSI_HOST *hd;
|
||||
|
||||
@ -1054,7 +1054,7 @@ mptscsih_shutdown(struct device * dev)
|
||||
int
|
||||
mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
{
|
||||
mptscsih_shutdown(&pdev->dev);
|
||||
mptscsih_shutdown(pdev);
|
||||
return mpt_suspend(pdev,state);
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@
|
||||
#endif
|
||||
|
||||
extern void mptscsih_remove(struct pci_dev *);
|
||||
extern void mptscsih_shutdown(struct device *);
|
||||
extern void mptscsih_shutdown(struct pci_dev *);
|
||||
#ifdef CONFIG_PM
|
||||
extern int mptscsih_suspend(struct pci_dev *pdev, u32 state);
|
||||
extern int mptscsih_resume(struct pci_dev *pdev);
|
||||
|
@ -419,9 +419,7 @@ static struct pci_driver mptspi_driver = {
|
||||
.id_table = mptspi_pci_table,
|
||||
.probe = mptspi_probe,
|
||||
.remove = __devexit_p(mptscsih_remove),
|
||||
.driver = {
|
||||
.shutdown = mptscsih_shutdown,
|
||||
},
|
||||
.shutdown = mptscsih_shutdown,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mptscsih_suspend,
|
||||
.resume = mptscsih_resume,
|
||||
|
@ -822,7 +822,7 @@ static int corkscrew_open(struct net_device *dev)
|
||||
break; /* Bad news! */
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail);
|
||||
vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
|
||||
}
|
||||
vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */
|
||||
outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
|
||||
@ -1406,7 +1406,7 @@ static int boomerang_rx(struct net_device *dev)
|
||||
break; /* Bad news! */
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail);
|
||||
vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
|
||||
vp->rx_skbuff[entry] = skb;
|
||||
}
|
||||
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
|
||||
|
@ -1802,7 +1802,7 @@ vortex_open(struct net_device *dev)
|
||||
break; /* Bad news! */
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
|
||||
vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
|
||||
}
|
||||
if (i != RX_RING_SIZE) {
|
||||
int j;
|
||||
@ -2632,7 +2632,7 @@ boomerang_rx(struct net_device *dev)
|
||||
pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
|
||||
/* 'skb_put()' points to the start of sk_buff data area. */
|
||||
memcpy(skb_put(skb, pkt_len),
|
||||
vp->rx_skbuff[entry]->tail,
|
||||
vp->rx_skbuff[entry]->data,
|
||||
pkt_len);
|
||||
pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
|
||||
vp->rx_copy++;
|
||||
@ -2678,7 +2678,7 @@ boomerang_rx(struct net_device *dev)
|
||||
}
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
|
||||
vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
|
||||
vp->rx_skbuff[entry] = skb;
|
||||
}
|
||||
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
|
||||
|
@ -596,7 +596,7 @@ rx_status_loop:
|
||||
|
||||
mapping =
|
||||
cp->rx_skb[rx_tail].mapping =
|
||||
pci_map_single(cp->pdev, new_skb->tail,
|
||||
pci_map_single(cp->pdev, new_skb->data,
|
||||
buflen, PCI_DMA_FROMDEVICE);
|
||||
cp->rx_skb[rx_tail].skb = new_skb;
|
||||
|
||||
@ -1101,7 +1101,7 @@ static int cp_refill_rx (struct cp_private *cp)
|
||||
skb_reserve(skb, RX_OFFSET);
|
||||
|
||||
cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
|
||||
skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
cp->rx_skb[i].skb = skb;
|
||||
|
||||
cp->rx_ring[i].opts2 = 0;
|
||||
|
@ -546,11 +546,11 @@ static inline void init_rx_bufs(struct net_device *dev)
|
||||
rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1));
|
||||
rbd->b_addr = WSWAPrbd(virt_to_bus(rbd));
|
||||
rbd->skb = skb;
|
||||
rbd->v_data = skb->tail;
|
||||
rbd->b_data = WSWAPchar(virt_to_bus(skb->tail));
|
||||
rbd->v_data = skb->data;
|
||||
rbd->b_data = WSWAPchar(virt_to_bus(skb->data));
|
||||
rbd->size = PKT_BUF_SZ;
|
||||
#ifdef __mc68000__
|
||||
cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ);
|
||||
cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ);
|
||||
#endif
|
||||
}
|
||||
lp->rbd_head = lp->rbds;
|
||||
@ -816,10 +816,10 @@ static inline int i596_rx(struct net_device *dev)
|
||||
rx_in_place = 1;
|
||||
rbd->skb = newskb;
|
||||
newskb->dev = dev;
|
||||
rbd->v_data = newskb->tail;
|
||||
rbd->b_data = WSWAPchar(virt_to_bus(newskb->tail));
|
||||
rbd->v_data = newskb->data;
|
||||
rbd->b_data = WSWAPchar(virt_to_bus(newskb->data));
|
||||
#ifdef __mc68000__
|
||||
cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ);
|
||||
cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -840,7 +840,7 @@ memory_squeeze:
|
||||
skb->protocol=eth_type_trans(skb,dev);
|
||||
skb->len = pkt_len;
|
||||
#ifdef __mc68000__
|
||||
cache_clear(virt_to_phys(rbd->skb->tail),
|
||||
cache_clear(virt_to_phys(rbd->skb->data),
|
||||
pkt_len);
|
||||
#endif
|
||||
netif_rx(skb);
|
||||
|
@ -87,6 +87,7 @@ Revision History:
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
@ -2006,12 +2007,11 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
/* Initialize DMA */
|
||||
if(!pci_dma_supported(pdev, 0xffffffff)){
|
||||
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) {
|
||||
printk(KERN_ERR "amd8111e: DMA not supported,"
|
||||
"exiting.\n");
|
||||
goto err_free_reg;
|
||||
} else
|
||||
pdev->dma_mask = 0xffffffff;
|
||||
goto err_free_reg;
|
||||
}
|
||||
|
||||
reg_addr = pci_resource_start(pdev, 0);
|
||||
reg_len = pci_resource_len(pdev, 0);
|
||||
|
@ -34,10 +34,6 @@
|
||||
only is it difficult to detect, it also moves around in I/O space in
|
||||
response to inb()s from other device probes!
|
||||
*/
|
||||
/*
|
||||
99/03/03 Allied Telesis RE1000 Plus support by T.Hagawa
|
||||
99/12/30 port to 2.3.35 by K.Takai
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -547,7 +547,7 @@ rio_timer (unsigned long data)
|
||||
skb_reserve (skb, 2);
|
||||
np->rx_ring[entry].fraginfo =
|
||||
cpu_to_le64 (pci_map_single
|
||||
(np->pdev, skb->tail, np->rx_buf_sz,
|
||||
(np->pdev, skb->data, np->rx_buf_sz,
|
||||
PCI_DMA_FROMDEVICE));
|
||||
}
|
||||
np->rx_ring[entry].fraginfo |=
|
||||
@ -618,7 +618,7 @@ alloc_list (struct net_device *dev)
|
||||
/* Rubicon now supports 40 bits of addressing space. */
|
||||
np->rx_ring[i].fraginfo =
|
||||
cpu_to_le64 ( pci_map_single (
|
||||
np->pdev, skb->tail, np->rx_buf_sz,
|
||||
np->pdev, skb->data, np->rx_buf_sz,
|
||||
PCI_DMA_FROMDEVICE));
|
||||
np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
|
||||
}
|
||||
@ -906,7 +906,7 @@ receive_packet (struct net_device *dev)
|
||||
/* 16 byte align the IP header */
|
||||
skb_reserve (skb, 2);
|
||||
eth_copy_and_sum (skb,
|
||||
np->rx_skbuff[entry]->tail,
|
||||
np->rx_skbuff[entry]->data,
|
||||
pkt_len, 0);
|
||||
skb_put (skb, pkt_len);
|
||||
pci_dma_sync_single_for_device(np->pdev,
|
||||
@ -950,7 +950,7 @@ receive_packet (struct net_device *dev)
|
||||
skb_reserve (skb, 2);
|
||||
np->rx_ring[entry].fraginfo =
|
||||
cpu_to_le64 (pci_map_single
|
||||
(np->pdev, skb->tail, np->rx_buf_sz,
|
||||
(np->pdev, skb->data, np->rx_buf_sz,
|
||||
PCI_DMA_FROMDEVICE));
|
||||
}
|
||||
np->rx_ring[entry].fraginfo |=
|
||||
|
@ -2447,9 +2447,8 @@ static int e100_resume(struct pci_dev *pdev)
|
||||
#endif
|
||||
|
||||
|
||||
static void e100_shutdown(struct device *dev)
|
||||
static void e100_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
|
||||
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||
struct nic *nic = netdev_priv(netdev);
|
||||
|
||||
@ -2470,11 +2469,7 @@ static struct pci_driver e100_driver = {
|
||||
.suspend = e100_suspend,
|
||||
.resume = e100_resume,
|
||||
#endif
|
||||
|
||||
.driver = {
|
||||
.shutdown = e100_shutdown,
|
||||
}
|
||||
|
||||
.shutdown = e100_shutdown,
|
||||
};
|
||||
|
||||
static int __init e100_init_module(void)
|
||||
|
@ -1269,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *dev)
|
||||
if (skb == NULL)
|
||||
break; /* OK. Just initially short of Rx bufs. */
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
rxf = (struct RxFD *)skb->tail;
|
||||
rxf = (struct RxFD *)skb->data;
|
||||
sp->rx_ringp[i] = rxf;
|
||||
sp->rx_ring_dma[i] =
|
||||
pci_map_single(sp->pdev, rxf,
|
||||
@ -1661,7 +1661,7 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
|
||||
sp->rx_ringp[entry] = NULL;
|
||||
return NULL;
|
||||
}
|
||||
rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail;
|
||||
rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data;
|
||||
sp->rx_ring_dma[entry] =
|
||||
pci_map_single(sp->pdev, rxf,
|
||||
PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
|
||||
@ -1808,10 +1808,10 @@ speedo_rx(struct net_device *dev)
|
||||
|
||||
#if 1 || USE_IP_CSUM
|
||||
/* Packet is in one chunk -- we can copy + cksum. */
|
||||
eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0);
|
||||
eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0);
|
||||
skb_put(skb, pkt_len);
|
||||
#else
|
||||
memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail,
|
||||
memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->data,
|
||||
pkt_len);
|
||||
#endif
|
||||
pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
|
||||
|
@ -1003,7 +1003,7 @@ static void epic_init_ring(struct net_device *dev)
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
||||
ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev,
|
||||
skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn);
|
||||
}
|
||||
ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
|
||||
@ -1274,7 +1274,7 @@ static int epic_rx(struct net_device *dev, int budget)
|
||||
ep->rx_ring[entry].bufaddr,
|
||||
ep->rx_buf_sz,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0);
|
||||
eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0);
|
||||
skb_put(skb, pkt_len);
|
||||
pci_dma_sync_single_for_device(ep->pci_dev,
|
||||
ep->rx_ring[entry].bufaddr,
|
||||
@ -1308,7 +1308,7 @@ static int epic_rx(struct net_device *dev, int budget)
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev,
|
||||
skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
work_done++;
|
||||
}
|
||||
ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn);
|
||||
|
@ -1107,7 +1107,7 @@ static void allocate_rx_buffers(struct net_device *dev)
|
||||
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
np->lack_rxbuf->skbuff = skb;
|
||||
np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->tail,
|
||||
np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data,
|
||||
np->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
np->lack_rxbuf->status = RXOWN;
|
||||
++np->really_rx_count;
|
||||
@ -1300,7 +1300,7 @@ static void init_ring(struct net_device *dev)
|
||||
++np->really_rx_count;
|
||||
np->rx_ring[i].skbuff = skb;
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->tail,
|
||||
np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data,
|
||||
np->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
np->rx_ring[i].status = RXOWN;
|
||||
np->rx_ring[i].control |= RXIC;
|
||||
@ -1737,11 +1737,11 @@ static int netdev_rx(struct net_device *dev)
|
||||
|
||||
#if ! defined(__alpha__)
|
||||
eth_copy_and_sum(skb,
|
||||
np->cur_rx->skbuff->tail, pkt_len, 0);
|
||||
np->cur_rx->skbuff->data, pkt_len, 0);
|
||||
skb_put(skb, pkt_len);
|
||||
#else
|
||||
memcpy(skb_put(skb, pkt_len),
|
||||
np->cur_rx->skbuff->tail, pkt_len);
|
||||
np->cur_rx->skbuff->data, pkt_len);
|
||||
#endif
|
||||
pci_dma_sync_single_for_device(np->pci_dev,
|
||||
np->cur_rx->buffer,
|
||||
|
@ -1149,7 +1149,7 @@ static void hamachi_tx_timeout(struct net_device *dev)
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
||||
hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
|
||||
skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
|
||||
skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
|
||||
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
|
||||
DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2));
|
||||
}
|
||||
@ -1210,7 +1210,7 @@ static void hamachi_init_ring(struct net_device *dev)
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
||||
hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
|
||||
skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
|
||||
skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
|
||||
/* -2 because it doesn't REALLY have that first 2 bytes -KDU */
|
||||
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
|
||||
DescEndPacket | DescIntr | (hmp->rx_buf_sz -2));
|
||||
@ -1509,7 +1509,7 @@ static int hamachi_rx(struct net_device *dev)
|
||||
desc->addr,
|
||||
hmp->rx_buf_sz,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
buf_addr = (u8 *) hmp->rx_skbuff[entry]->tail;
|
||||
buf_addr = (u8 *) hmp->rx_skbuff[entry]->data;
|
||||
frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12])));
|
||||
if (hamachi_debug > 4)
|
||||
printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n",
|
||||
@ -1678,7 +1678,7 @@ static int hamachi_rx(struct net_device *dev)
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
|
||||
skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
|
||||
skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
|
||||
}
|
||||
desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz);
|
||||
if (entry >= RX_RING_SIZE-1)
|
||||
@ -1772,9 +1772,9 @@ static int hamachi_close(struct net_device *dev)
|
||||
readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ',
|
||||
i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr);
|
||||
if (hamachi_debug > 6) {
|
||||
if (*(u8*)hmp->rx_skbuff[i]->tail != 0x69) {
|
||||
if (*(u8*)hmp->rx_skbuff[i]->data != 0x69) {
|
||||
u16 *addr = (u16 *)
|
||||
hmp->rx_skbuff[i]->tail;
|
||||
hmp->rx_skbuff[i]->data;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 0x50; j++)
|
||||
|
@ -862,7 +862,7 @@ lance_init_ring(struct net_device *dev, int gfp)
|
||||
lp->rx_skbuff[i] = skb;
|
||||
if (skb) {
|
||||
skb->dev = dev;
|
||||
rx_buff = skb->tail;
|
||||
rx_buff = skb->data;
|
||||
} else
|
||||
rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
|
||||
if (rx_buff == NULL)
|
||||
|
@ -553,14 +553,14 @@ static inline void init_rx_bufs(struct net_device *dev)
|
||||
if (skb == NULL)
|
||||
panic("%s: alloc_skb() failed", __FILE__);
|
||||
skb_reserve(skb, 2);
|
||||
dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ,
|
||||
dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ,
|
||||
DMA_FROM_DEVICE);
|
||||
skb->dev = dev;
|
||||
rbd->v_next = rbd+1;
|
||||
rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
|
||||
rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd));
|
||||
rbd->skb = skb;
|
||||
rbd->v_data = skb->tail;
|
||||
rbd->v_data = skb->data;
|
||||
rbd->b_data = WSWAPchar(dma_addr);
|
||||
rbd->size = PKT_BUF_SZ;
|
||||
}
|
||||
@ -783,8 +783,8 @@ static inline int i596_rx(struct net_device *dev)
|
||||
rx_in_place = 1;
|
||||
rbd->skb = newskb;
|
||||
newskb->dev = dev;
|
||||
dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE);
|
||||
rbd->v_data = newskb->tail;
|
||||
dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE);
|
||||
rbd->v_data = newskb->data;
|
||||
rbd->b_data = WSWAPchar(dma_addr);
|
||||
CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
|
||||
}
|
||||
|
@ -1926,7 +1926,7 @@ static void refill_rx(struct net_device *dev)
|
||||
break; /* Better luck next round. */
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
np->rx_dma[entry] = pci_map_single(np->pci_dev,
|
||||
skb->tail, buflen, PCI_DMA_FROMDEVICE);
|
||||
skb->data, buflen, PCI_DMA_FROMDEVICE);
|
||||
np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]);
|
||||
}
|
||||
np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz);
|
||||
@ -2280,7 +2280,7 @@ static void netdev_rx(struct net_device *dev)
|
||||
buflen,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
eth_copy_and_sum(skb,
|
||||
np->rx_skbuff[entry]->tail, pkt_len, 0);
|
||||
np->rx_skbuff[entry]->data, pkt_len, 0);
|
||||
skb_put(skb, pkt_len);
|
||||
pci_dma_sync_single_for_device(np->pci_dev,
|
||||
np->rx_dma[entry],
|
||||
|
@ -574,7 +574,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
|
||||
|
||||
dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
|
||||
cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR;
|
||||
buf = pci_map_single(dev->pci_dev, skb->tail,
|
||||
buf = pci_map_single(dev->pci_dev, skb->data,
|
||||
REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
|
||||
build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
|
||||
/* update link of previous rx */
|
||||
@ -604,7 +604,7 @@ static inline int rx_refill(struct net_device *ndev, int gfp)
|
||||
if (unlikely(!skb))
|
||||
break;
|
||||
|
||||
res = (long)skb->tail & 0xf;
|
||||
res = (long)skb->data & 0xf;
|
||||
res = 0x10 - res;
|
||||
res &= 0xf;
|
||||
skb_reserve(skb, res);
|
||||
|
@ -1602,7 +1602,7 @@ pcnet32_init_ring(struct net_device *dev)
|
||||
|
||||
rmb();
|
||||
if (lp->rx_dma_addr[i] == 0)
|
||||
lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail,
|
||||
lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data,
|
||||
PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
|
||||
lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]);
|
||||
lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
|
||||
@ -1983,7 +1983,7 @@ pcnet32_rx(struct net_device *dev)
|
||||
lp->rx_skbuff[entry] = newskb;
|
||||
newskb->dev = dev;
|
||||
lp->rx_dma_addr[entry] =
|
||||
pci_map_single(lp->pci_dev, newskb->tail,
|
||||
pci_map_single(lp->pci_dev, newskb->data,
|
||||
PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
|
||||
lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]);
|
||||
rx_in_place = 1;
|
||||
@ -2020,7 +2020,7 @@ pcnet32_rx(struct net_device *dev)
|
||||
PKT_BUF_SZ-2,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
eth_copy_and_sum(skb,
|
||||
(unsigned char *)(lp->rx_skbuff[entry]->tail),
|
||||
(unsigned char *)(lp->rx_skbuff[entry]->data),
|
||||
pkt_len,0);
|
||||
pci_dma_sync_single_for_device(lp->pci_dev,
|
||||
lp->rx_dma_addr[entry],
|
||||
|
@ -1876,7 +1876,7 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
|
||||
skb_reserve(skb, NET_IP_ALIGN);
|
||||
*sk_buff = skb;
|
||||
|
||||
mapping = pci_map_single(pdev, skb->tail, rx_buf_sz,
|
||||
mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
|
||||
rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
|
||||
@ -2336,7 +2336,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
|
||||
skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
|
||||
if (skb) {
|
||||
skb_reserve(skb, NET_IP_ALIGN);
|
||||
eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0);
|
||||
eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
|
||||
*sk_buff = skb;
|
||||
rtl8169_mark_to_asic(desc, rx_buf_sz);
|
||||
ret = 0;
|
||||
|
@ -1699,11 +1699,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
|
||||
#else
|
||||
ba = &nic->ba[ring_no][block_no][off];
|
||||
skb_reserve(skb, BUF0_LEN);
|
||||
tmp = (unsigned long) skb->data;
|
||||
tmp += ALIGN_SIZE;
|
||||
tmp &= ~ALIGN_SIZE;
|
||||
skb->data = (void *) tmp;
|
||||
skb->tail = (void *) tmp;
|
||||
tmp = ((unsigned long) skb->data & ALIGN_SIZE);
|
||||
if (tmp)
|
||||
skb_reserve(skb, (ALIGN_SIZE + 1) - tmp);
|
||||
|
||||
memset(rxdp, 0, sizeof(RxD_t));
|
||||
rxdp->Buffer2_ptr = pci_map_single
|
||||
|
@ -963,11 +963,11 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
|
||||
/*
|
||||
* Do not interrupt per DMA transfer.
|
||||
*/
|
||||
dsc->dscr_a = virt_to_phys(sb_new->tail) |
|
||||
dsc->dscr_a = virt_to_phys(sb_new->data) |
|
||||
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
|
||||
0;
|
||||
#else
|
||||
dsc->dscr_a = virt_to_phys(sb_new->tail) |
|
||||
dsc->dscr_a = virt_to_phys(sb_new->data) |
|
||||
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
|
||||
M_DMA_DSCRA_INTERRUPT;
|
||||
#endif
|
||||
|
@ -1154,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *net_dev)
|
||||
sis_priv->rx_skbuff[i] = skb;
|
||||
sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
|
||||
sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
|
||||
skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
|
||||
skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
|
||||
}
|
||||
sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
|
||||
|
||||
@ -1776,7 +1776,7 @@ static int sis900_rx(struct net_device *net_dev)
|
||||
sis_priv->rx_skbuff[entry] = skb;
|
||||
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
|
||||
sis_priv->rx_ring[entry].bufptr =
|
||||
pci_map_single(sis_priv->pci_dev, skb->tail,
|
||||
pci_map_single(sis_priv->pci_dev, skb->data,
|
||||
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
|
||||
sis_priv->dirty_rx++;
|
||||
}
|
||||
@ -1809,7 +1809,7 @@ static int sis900_rx(struct net_device *net_dev)
|
||||
sis_priv->rx_skbuff[entry] = skb;
|
||||
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
|
||||
sis_priv->rx_ring[entry].bufptr =
|
||||
pci_map_single(sis_priv->pci_dev, skb->tail,
|
||||
pci_map_single(sis_priv->pci_dev, skb->data,
|
||||
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
|
||||
}
|
||||
}
|
||||
|
1704
drivers/net/skge.c
1704
drivers/net/skge.c
File diff suppressed because it is too large
Load Diff
@ -7,31 +7,6 @@
|
||||
/* PCI config registers */
|
||||
#define PCI_DEV_REG1 0x40
|
||||
#define PCI_DEV_REG2 0x44
|
||||
#ifndef PCI_VPD
|
||||
#define PCI_VPD 0x50
|
||||
#endif
|
||||
|
||||
/* PCI_OUR_REG_2 32 bit Our Register 2 */
|
||||
enum {
|
||||
PCI_VPD_WR_THR = 0xff<<24, /* Bit 31..24: VPD Write Threshold */
|
||||
PCI_DEV_SEL = 0x7f<<17, /* Bit 23..17: EEPROM Device Select */
|
||||
PCI_VPD_ROM_SZ = 7 <<14, /* Bit 16..14: VPD ROM Size */
|
||||
/* Bit 13..12: reserved */
|
||||
PCI_EN_DUMMY_RD = 1<<3, /* Enable Dummy Read */
|
||||
PCI_REV_DESC = 1<<2, /* Reverse Desc. Bytes */
|
||||
PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */
|
||||
};
|
||||
|
||||
/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
|
||||
enum {
|
||||
PCI_VPD_FLAG = 1<<15, /* starts VPD rd/wr cycle */
|
||||
PCI_VPD_ADR_MSK =0x7fffL, /* Bit 14.. 0: VPD Address Mask */
|
||||
VPD_RES_ID = 0x82,
|
||||
VPD_RES_READ = 0x90,
|
||||
VPD_RES_WRITE = 0x81,
|
||||
VPD_RES_END = 0x78,
|
||||
};
|
||||
|
||||
|
||||
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
|
||||
PCI_STATUS_SIG_SYSTEM_ERROR | \
|
||||
@ -39,7 +14,6 @@ enum {
|
||||
PCI_STATUS_REC_TARGET_ABORT | \
|
||||
PCI_STATUS_PARITY)
|
||||
|
||||
|
||||
enum csr_regs {
|
||||
B0_RAP = 0x0000,
|
||||
B0_CTST = 0x0004,
|
||||
@ -229,8 +203,11 @@ enum {
|
||||
IS_XA2_F = 1<<1, /* Q_XA2 End of Frame */
|
||||
IS_XA2_C = 1<<0, /* Q_XA2 Encoding Error */
|
||||
|
||||
IS_PORT_1 = IS_XA1_F| IS_R1_F| IS_MAC1,
|
||||
IS_PORT_2 = IS_XA2_F| IS_R2_F| IS_MAC2,
|
||||
IS_TO_PORT1 = IS_PA_TO_RX1 | IS_PA_TO_TX1,
|
||||
IS_TO_PORT2 = IS_PA_TO_RX2 | IS_PA_TO_TX2,
|
||||
|
||||
IS_PORT_1 = IS_XA1_F| IS_R1_F | IS_TO_PORT1 | IS_MAC1,
|
||||
IS_PORT_2 = IS_XA2_F| IS_R2_F | IS_TO_PORT2 | IS_MAC2,
|
||||
};
|
||||
|
||||
|
||||
@ -288,14 +265,6 @@ enum {
|
||||
CHIP_REV_YU_LITE_A3 = 7, /* Chip Rev. for YUKON-Lite A3 */
|
||||
};
|
||||
|
||||
/* B2_LD_TEST 8 bit EPROM loader test register */
|
||||
enum {
|
||||
LD_T_ON = 1<<3, /* Loader Test mode on */
|
||||
LD_T_OFF = 1<<2, /* Loader Test mode off */
|
||||
LD_T_STEP = 1<<1, /* Decrement FPROM addr. Counter */
|
||||
LD_START = 1<<0, /* Start loading FPROM */
|
||||
};
|
||||
|
||||
/* B2_TI_CTRL 8 bit Timer control */
|
||||
/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
|
||||
enum {
|
||||
@ -313,16 +282,6 @@ enum {
|
||||
TIM_T_STEP = 1<<0, /* Test step */
|
||||
};
|
||||
|
||||
/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
|
||||
/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
|
||||
/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
|
||||
enum {
|
||||
DPT_MSK = 0x00ffffffL, /* Bit 23.. 0: Desc Poll Timer Bits */
|
||||
|
||||
DPT_START = 1<<1, /* Start Descriptor Poll Timer */
|
||||
DPT_STOP = 1<<0, /* Stop Descriptor Poll Timer */
|
||||
};
|
||||
|
||||
/* B2_GP_IO 32 bit General Purpose I/O Register */
|
||||
enum {
|
||||
GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */
|
||||
@ -348,30 +307,6 @@ enum {
|
||||
GP_IO_0 = 1<<0, /* IO_0 pin */
|
||||
};
|
||||
|
||||
/* Rx/Tx Path related Arbiter Test Registers */
|
||||
/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
|
||||
/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
|
||||
/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
|
||||
/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
|
||||
enum {
|
||||
TX2_T_EV = 1<<15,/* TX2 Timeout/Recv Event occured */
|
||||
TX2_T_ON = 1<<14,/* TX2 Timeout/Recv Timer Test On */
|
||||
TX2_T_OFF = 1<<13,/* TX2 Timeout/Recv Timer Tst Off */
|
||||
TX2_T_STEP = 1<<12,/* TX2 Timeout/Recv Timer Step */
|
||||
TX1_T_EV = 1<<11,/* TX1 Timeout/Recv Event occured */
|
||||
TX1_T_ON = 1<<10,/* TX1 Timeout/Recv Timer Test On */
|
||||
TX1_T_OFF = 1<<9, /* TX1 Timeout/Recv Timer Tst Off */
|
||||
TX1_T_STEP = 1<<8, /* TX1 Timeout/Recv Timer Step */
|
||||
RX2_T_EV = 1<<7, /* RX2 Timeout/Recv Event occured */
|
||||
RX2_T_ON = 1<<6, /* RX2 Timeout/Recv Timer Test On */
|
||||
RX2_T_OFF = 1<<5, /* RX2 Timeout/Recv Timer Tst Off */
|
||||
RX2_T_STEP = 1<<4, /* RX2 Timeout/Recv Timer Step */
|
||||
RX1_T_EV = 1<<3, /* RX1 Timeout/Recv Event occured */
|
||||
RX1_T_ON = 1<<2, /* RX1 Timeout/Recv Timer Test On */
|
||||
RX1_T_OFF = 1<<1, /* RX1 Timeout/Recv Timer Tst Off */
|
||||
RX1_T_STEP = 1<<0, /* RX1 Timeout/Recv Timer Step */
|
||||
};
|
||||
|
||||
/* Descriptor Bit Definition */
|
||||
/* TxCtrl Transmit Buffer Control Field */
|
||||
/* RxCtrl Receive Buffer Control Field */
|
||||
@ -428,14 +363,6 @@ enum {
|
||||
RI_RST_SET = 1<<0, /* Set RAM Interface Reset */
|
||||
};
|
||||
|
||||
/* B3_RI_TEST 8 bit RAM Iface Test Register */
|
||||
enum {
|
||||
RI_T_EV = 1<<3, /* Timeout Event occured */
|
||||
RI_T_ON = 1<<2, /* Timeout Timer Test On */
|
||||
RI_T_OFF = 1<<1, /* Timeout Timer Test Off */
|
||||
RI_T_STEP = 1<<0, /* Timeout Timer Step */
|
||||
};
|
||||
|
||||
/* MAC Arbiter Registers */
|
||||
/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
|
||||
enum {
|
||||
@ -452,19 +379,6 @@ enum {
|
||||
#define SK_PKT_TO_MAX 0xffff /* Maximum value */
|
||||
#define SK_RI_TO_53 36 /* RAM interface timeout */
|
||||
|
||||
|
||||
/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
|
||||
enum {
|
||||
MA_ENA_REC_TX2 = 1<<7, /* Enable Recovery Timer TX2 */
|
||||
MA_DIS_REC_TX2 = 1<<6, /* Disable Recovery Timer TX2 */
|
||||
MA_ENA_REC_TX1 = 1<<5, /* Enable Recovery Timer TX1 */
|
||||
MA_DIS_REC_TX1 = 1<<4, /* Disable Recovery Timer TX1 */
|
||||
MA_ENA_REC_RX2 = 1<<3, /* Enable Recovery Timer RX2 */
|
||||
MA_DIS_REC_RX2 = 1<<2, /* Disable Recovery Timer RX2 */
|
||||
MA_ENA_REC_RX1 = 1<<1, /* Enable Recovery Timer RX1 */
|
||||
MA_DIS_REC_RX1 = 1<<0, /* Disable Recovery Timer RX1 */
|
||||
};
|
||||
|
||||
/* Packet Arbiter Registers */
|
||||
/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
|
||||
enum {
|
||||
@ -488,7 +402,7 @@ enum {
|
||||
PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
|
||||
|
||||
|
||||
/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
|
||||
/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
|
||||
/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
|
||||
/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
|
||||
/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
|
||||
@ -511,7 +425,7 @@ enum {
|
||||
/*
|
||||
* Bank 4 - 5
|
||||
*/
|
||||
/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
|
||||
/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
|
||||
enum {
|
||||
TXA_ITI_INI = 0x0200,/* 32 bit Tx Arb Interval Timer Init Val*/
|
||||
TXA_ITI_VAL = 0x0204,/* 32 bit Tx Arb Interval Timer Value */
|
||||
@ -537,7 +451,7 @@ enum {
|
||||
|
||||
/* Queue Register Offsets, use Q_ADDR() to access */
|
||||
enum {
|
||||
B8_Q_REGS = 0x0400, /* base of Queue registers */
|
||||
B8_Q_REGS = 0x0400, /* base of Queue registers */
|
||||
Q_D = 0x00, /* 8*32 bit Current Descriptor */
|
||||
Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */
|
||||
Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */
|
||||
@ -618,8 +532,7 @@ enum {
|
||||
enum {
|
||||
PHY_ADDR_XMAC = 0<<8,
|
||||
PHY_ADDR_BCOM = 1<<8,
|
||||
PHY_ADDR_LONE = 3<<8,
|
||||
PHY_ADDR_NAT = 0<<8,
|
||||
|
||||
/* GPHY address (bits 15..11 of SMI control reg) */
|
||||
PHY_ADDR_MARV = 0,
|
||||
};
|
||||
@ -986,7 +899,7 @@ enum {
|
||||
LINKLED_BLINK_OFF = 0x10,
|
||||
LINKLED_BLINK_ON = 0x20,
|
||||
};
|
||||
|
||||
|
||||
/* GMAC and GPHY Control Registers (YUKON only) */
|
||||
enum {
|
||||
GMAC_CTRL = 0x0f00,/* 32 bit GMAC Control Reg */
|
||||
@ -1151,54 +1064,6 @@ enum {
|
||||
PHY_MARV_FE_SPEC_2 = 0x1c,/* 16 bit r/w Specific Control Reg. 2 */
|
||||
};
|
||||
|
||||
/* Level One-PHY Registers, indirect addressed over XMAC */
|
||||
enum {
|
||||
PHY_LONE_CTRL = 0x00,/* 16 bit r/w PHY Control Register */
|
||||
PHY_LONE_STAT = 0x01,/* 16 bit r/o PHY Status Register */
|
||||
PHY_LONE_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */
|
||||
PHY_LONE_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */
|
||||
PHY_LONE_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */
|
||||
PHY_LONE_AUNE_LP = 0x05,/* 16 bit r/o Link Part Ability Reg */
|
||||
PHY_LONE_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */
|
||||
PHY_LONE_NEPG = 0x07,/* 16 bit r/w Next Page Register */
|
||||
PHY_LONE_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */
|
||||
/* Level One-specific registers */
|
||||
PHY_LONE_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */
|
||||
PHY_LONE_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */
|
||||
PHY_LONE_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Reg */
|
||||
PHY_LONE_PORT_CFG = 0x10,/* 16 bit r/w Port Configuration Reg*/
|
||||
PHY_LONE_Q_STAT = 0x11,/* 16 bit r/o Quick Status Reg */
|
||||
PHY_LONE_INT_ENAB = 0x12,/* 16 bit r/w Interrupt Enable Reg */
|
||||
PHY_LONE_INT_STAT = 0x13,/* 16 bit r/o Interrupt Status Reg */
|
||||
PHY_LONE_LED_CFG = 0x14,/* 16 bit r/w LED Configuration Reg */
|
||||
PHY_LONE_PORT_CTRL = 0x15,/* 16 bit r/w Port Control Reg */
|
||||
PHY_LONE_CIM = 0x16,/* 16 bit r/o CIM Reg */
|
||||
};
|
||||
|
||||
/* National-PHY Registers, indirect addressed over XMAC */
|
||||
enum {
|
||||
PHY_NAT_CTRL = 0x00,/* 16 bit r/w PHY Control Register */
|
||||
PHY_NAT_STAT = 0x01,/* 16 bit r/w PHY Status Register */
|
||||
PHY_NAT_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */
|
||||
PHY_NAT_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */
|
||||
PHY_NAT_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */
|
||||
PHY_NAT_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Ability Reg */
|
||||
PHY_NAT_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */
|
||||
PHY_NAT_NEPG = 0x07,/* 16 bit r/w Next Page Register */
|
||||
PHY_NAT_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner Reg */
|
||||
/* National-specific registers */
|
||||
PHY_NAT_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */
|
||||
PHY_NAT_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */
|
||||
PHY_NAT_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Register */
|
||||
PHY_NAT_EXT_CTRL1 = 0x10,/* 16 bit r/o Extended Control Reg1 */
|
||||
PHY_NAT_Q_STAT1 = 0x11,/* 16 bit r/o Quick Status Reg1 */
|
||||
PHY_NAT_10B_OP = 0x12,/* 16 bit r/o 10Base-T Operations Reg */
|
||||
PHY_NAT_EXT_CTRL2 = 0x13,/* 16 bit r/o Extended Control Reg1 */
|
||||
PHY_NAT_Q_STAT2 = 0x14,/* 16 bit r/o Quick Status Reg2 */
|
||||
|
||||
PHY_NAT_PHY_ADDR = 0x19,/* 16 bit r/o PHY Address Register */
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_CT_RESET = 1<<15, /* Bit 15: (sc) clear all PHY related regs */
|
||||
PHY_CT_LOOP = 1<<14, /* Bit 14: enable Loopback over PHY */
|
||||
@ -1253,8 +1118,29 @@ enum {
|
||||
PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */
|
||||
};
|
||||
|
||||
/* Advertisement register bits */
|
||||
enum {
|
||||
PHY_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */
|
||||
PHY_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */
|
||||
PHY_AN_RF = 1<<13, /* Bit 13: Remote Fault Bits */
|
||||
|
||||
PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11: Try for asymmetric */
|
||||
PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10: Try for pause */
|
||||
PHY_AN_100BASE4 = 1<<9, /* Bit 9: Try for 100mbps 4k packets */
|
||||
PHY_AN_100FULL = 1<<8, /* Bit 8: Try for 100mbps full-duplex */
|
||||
PHY_AN_100HALF = 1<<7, /* Bit 7: Try for 100mbps half-duplex */
|
||||
PHY_AN_10FULL = 1<<6, /* Bit 6: Try for 10mbps full-duplex */
|
||||
PHY_AN_10HALF = 1<<5, /* Bit 5: Try for 10mbps half-duplex */
|
||||
PHY_AN_CSMA = 1<<0, /* Bit 0: Only selector supported */
|
||||
PHY_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/
|
||||
PHY_AN_FULL = PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA,
|
||||
PHY_AN_ALL = PHY_AN_10HALF | PHY_AN_10FULL |
|
||||
PHY_AN_100HALF | PHY_AN_100FULL,
|
||||
};
|
||||
|
||||
/* Xmac Specific */
|
||||
enum {
|
||||
PHY_X_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */
|
||||
PHY_X_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */
|
||||
PHY_X_AN_RFB = 3<<12,/* Bit 13..12: Remote Fault Bits */
|
||||
|
||||
@ -1263,82 +1149,6 @@ enum {
|
||||
PHY_X_AN_FD = 1<<5, /* Bit 5: Full Duplex */
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */
|
||||
|
||||
PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */
|
||||
PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */
|
||||
PHY_B_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_L_AN_RF = 1<<13, /* Bit 13: Remote Fault */
|
||||
/* Bit 12: reserved */
|
||||
PHY_L_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */
|
||||
PHY_L_AN_PC = 1<<10, /* Bit 10: Pause Capable */
|
||||
|
||||
PHY_L_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/
|
||||
};
|
||||
|
||||
/* PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement */
|
||||
/* PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
|
||||
/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
|
||||
enum {
|
||||
PHY_N_AN_RF = 1<<13, /* Bit 13: Remote Fault */
|
||||
|
||||
PHY_N_AN_100F = 1<<11, /* Bit 11: 100Base-T2 FD Support */
|
||||
PHY_N_AN_100H = 1<<10, /* Bit 10: 100Base-T2 HD Support */
|
||||
|
||||
PHY_N_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/
|
||||
};
|
||||
|
||||
/* field type definition for PHY_x_AN_SEL */
|
||||
enum {
|
||||
PHY_SEL_TYPE = 1, /* 00001 = Ethernet */
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_ANE_LP_NP = 1<<3, /* Bit 3: Link Partner can Next Page */
|
||||
PHY_ANE_LOC_NP = 1<<2, /* Bit 2: Local PHY can Next Page */
|
||||
PHY_ANE_RX_PG = 1<<1, /* Bit 1: Page Received */
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_ANE_PAR_DF = 1<<4, /* Bit 4: Parallel Detection Fault */
|
||||
|
||||
PHY_ANE_LP_CAP = 1<<0, /* Bit 0: Link Partner Auto-Neg. Cap. */
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_NP_MORE = 1<<15, /* Bit 15: More, Next Pages to follow */
|
||||
PHY_NP_ACK1 = 1<<14, /* Bit 14: (ro) Ack1, for receiving a message */
|
||||
PHY_NP_MSG_VAL = 1<<13, /* Bit 13: Message Page valid */
|
||||
PHY_NP_ACK2 = 1<<12, /* Bit 12: Ack2, comply with msg content */
|
||||
PHY_NP_TOG = 1<<11, /* Bit 11: Toggle Bit, ensure sync */
|
||||
PHY_NP_MSG = 0x07ff, /* Bit 10..0: Message from/to Link Partner */
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */
|
||||
PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_X_RS_PAUSE = 3<<7,/* Bit 8..7: selected Pause Mode */
|
||||
PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */
|
||||
PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */
|
||||
PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */
|
||||
PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */
|
||||
};
|
||||
|
||||
/** Remote Fault Bits (PHY_X_AN_RFB) encoding */
|
||||
enum {
|
||||
X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */
|
||||
X_RFB_LF = 1<<12, /* Bit 13..12 Link Failure */
|
||||
X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */
|
||||
X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */
|
||||
};
|
||||
|
||||
/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
|
||||
enum {
|
||||
PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */
|
||||
@ -1418,6 +1228,16 @@ enum {
|
||||
PHY_B_PES_MLT3_ER = 1<<0, /* Bit 0: MLT3 code Error */
|
||||
};
|
||||
|
||||
/* PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
|
||||
/* PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
|
||||
enum {
|
||||
PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */
|
||||
|
||||
PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */
|
||||
PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */
|
||||
};
|
||||
|
||||
|
||||
/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
|
||||
enum {
|
||||
PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */
|
||||
@ -1478,7 +1298,9 @@ enum {
|
||||
PHY_B_IS_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */
|
||||
PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */
|
||||
};
|
||||
#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
|
||||
#define PHY_B_DEF_MSK \
|
||||
(~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \
|
||||
PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE))
|
||||
|
||||
/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
|
||||
enum {
|
||||
@ -1495,166 +1317,6 @@ enum {
|
||||
PHY_B_RES_1000HD = 6<<8,/* Bit 10..8: 1000Base-T Half Dup. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Level One-Specific
|
||||
*/
|
||||
/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
|
||||
enum {
|
||||
PHY_L_1000C_TEST = 7<<13,/* Bit 15..13: Test Modes */
|
||||
PHY_L_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */
|
||||
PHY_L_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */
|
||||
PHY_L_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */
|
||||
PHY_L_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */
|
||||
PHY_L_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */
|
||||
};
|
||||
|
||||
/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
|
||||
enum {
|
||||
PHY_L_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */
|
||||
PHY_L_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */
|
||||
PHY_L_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */
|
||||
PHY_L_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status */
|
||||
PHY_L_1000S_LP_FD = 1<<11, /* Bit 11: Link Partner can FD */
|
||||
PHY_L_1000S_LP_HD = 1<<10, /* Bit 10: Link Partner can HD */
|
||||
|
||||
PHY_L_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */
|
||||
|
||||
/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
|
||||
PHY_L_ES_X_FD_CAP = 1<<15, /* Bit 15: 1000Base-X FD capable */
|
||||
PHY_L_ES_X_HD_CAP = 1<<14, /* Bit 14: 1000Base-X HD capable */
|
||||
PHY_L_ES_T_FD_CAP = 1<<13, /* Bit 13: 1000Base-T FD capable */
|
||||
PHY_L_ES_T_HD_CAP = 1<<12, /* Bit 12: 1000Base-T HD capable */
|
||||
};
|
||||
|
||||
/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
|
||||
enum {
|
||||
PHY_L_PC_REP_MODE = 1<<15, /* Bit 15: Repeater Mode */
|
||||
|
||||
PHY_L_PC_TX_DIS = 1<<13, /* Bit 13: Tx output Disabled */
|
||||
PHY_L_PC_BY_SCR = 1<<12, /* Bit 12: Bypass Scrambler */
|
||||
PHY_L_PC_BY_45 = 1<<11, /* Bit 11: Bypass 4B5B-Decoder */
|
||||
PHY_L_PC_JAB_DIS = 1<<10, /* Bit 10: Jabber Disabled */
|
||||
PHY_L_PC_SQE = 1<<9, /* Bit 9: Enable Heartbeat */
|
||||
PHY_L_PC_TP_LOOP = 1<<8, /* Bit 8: TP Loopback */
|
||||
PHY_L_PC_SSS = 1<<7, /* Bit 7: Smart Speed Selection */
|
||||
PHY_L_PC_FIFO_SIZE = 1<<6, /* Bit 6: FIFO Size */
|
||||
PHY_L_PC_PRE_EN = 1<<5, /* Bit 5: Preamble Enable */
|
||||
PHY_L_PC_CIM = 1<<4, /* Bit 4: Carrier Integrity Mon */
|
||||
PHY_L_PC_10_SER = 1<<3, /* Bit 3: Use Serial Output */
|
||||
PHY_L_PC_ANISOL = 1<<2, /* Bit 2: Unisolate Port */
|
||||
PHY_L_PC_TEN_BIT = 1<<1, /* Bit 1: 10bit iface mode on */
|
||||
PHY_L_PC_ALTCLOCK = 1<<0, /* Bit 0: (ro) ALTCLOCK Mode on */
|
||||
};
|
||||
|
||||
/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
|
||||
enum {
|
||||
PHY_L_QS_D_RATE = 3<<14,/* Bit 15..14: Data Rate */
|
||||
PHY_L_QS_TX_STAT = 1<<13, /* Bit 13: Transmitting */
|
||||
PHY_L_QS_RX_STAT = 1<<12, /* Bit 12: Receiving */
|
||||
PHY_L_QS_COL_STAT = 1<<11, /* Bit 11: Collision */
|
||||
PHY_L_QS_L_STAT = 1<<10, /* Bit 10: Link is up */
|
||||
PHY_L_QS_DUP_MOD = 1<<9, /* Bit 9: Full/Half Duplex */
|
||||
PHY_L_QS_AN = 1<<8, /* Bit 8: AutoNeg is On */
|
||||
PHY_L_QS_AN_C = 1<<7, /* Bit 7: AN is Complete */
|
||||
PHY_L_QS_LLE = 7<<4,/* Bit 6..4: Line Length Estim. */
|
||||
PHY_L_QS_PAUSE = 1<<3, /* Bit 3: LP advertised Pause */
|
||||
PHY_L_QS_AS_PAUSE = 1<<2, /* Bit 2: LP adv. asym. Pause */
|
||||
PHY_L_QS_ISOLATE = 1<<1, /* Bit 1: CIM Isolated */
|
||||
PHY_L_QS_EVENT = 1<<0, /* Bit 0: Event has occurred */
|
||||
};
|
||||
|
||||
/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
|
||||
/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
|
||||
enum {
|
||||
PHY_L_IS_AN_F = 1<<13, /* Bit 13: Auto-Negotiation fault */
|
||||
PHY_L_IS_CROSS = 1<<11, /* Bit 11: Crossover used */
|
||||
PHY_L_IS_POL = 1<<10, /* Bit 10: Polarity correct. used */
|
||||
PHY_L_IS_SS = 1<<9, /* Bit 9: Smart Speed Downgrade */
|
||||
PHY_L_IS_CFULL = 1<<8, /* Bit 8: Counter Full */
|
||||
PHY_L_IS_AN_C = 1<<7, /* Bit 7: AutoNeg Complete */
|
||||
PHY_L_IS_SPEED = 1<<6, /* Bit 6: Speed Changed */
|
||||
PHY_L_IS_DUP = 1<<5, /* Bit 5: Duplex Changed */
|
||||
PHY_L_IS_LS = 1<<4, /* Bit 4: Link Status Changed */
|
||||
PHY_L_IS_ISOL = 1<<3, /* Bit 3: Isolate Occured */
|
||||
PHY_L_IS_MDINT = 1<<2, /* Bit 2: (ro) STAT: MII Int Pending */
|
||||
PHY_L_IS_INTEN = 1<<1, /* Bit 1: ENAB: Enable IRQs */
|
||||
PHY_L_IS_FORCE = 1<<0, /* Bit 0: ENAB: Force Interrupt */
|
||||
};
|
||||
|
||||
/* int. mask */
|
||||
#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
|
||||
|
||||
/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
|
||||
enum {
|
||||
PHY_L_LC_LEDC = 3<<14,/* Bit 15..14: Col/Blink/On/Off */
|
||||
PHY_L_LC_LEDR = 3<<12,/* Bit 13..12: Rx/Blink/On/Off */
|
||||
PHY_L_LC_LEDT = 3<<10,/* Bit 11..10: Tx/Blink/On/Off */
|
||||
PHY_L_LC_LEDG = 3<<8,/* Bit 9..8: Giga/Blink/On/Off */
|
||||
PHY_L_LC_LEDS = 3<<6,/* Bit 7..6: 10-100/Blink/On/Off */
|
||||
PHY_L_LC_LEDL = 3<<4,/* Bit 5..4: Link/Blink/On/Off */
|
||||
PHY_L_LC_LEDF = 3<<2,/* Bit 3..2: Duplex/Blink/On/Off */
|
||||
PHY_L_LC_PSTRECH= 1<<1, /* Bit 1: Strech LED Pulses */
|
||||
PHY_L_LC_FREQ = 1<<0, /* Bit 0: 30/100 ms */
|
||||
};
|
||||
|
||||
/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
|
||||
enum {
|
||||
PHY_L_PC_TX_TCLK = 1<<15, /* Bit 15: Enable TX_TCLK */
|
||||
PHY_L_PC_ALT_NP = 1<<13, /* Bit 14: Alternate Next Page */
|
||||
PHY_L_PC_GMII_ALT= 1<<12, /* Bit 13: Alternate GMII driver */
|
||||
PHY_L_PC_TEN_CRS = 1<<10, /* Bit 10: Extend CRS*/
|
||||
};
|
||||
|
||||
/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
|
||||
enum {
|
||||
PHY_L_CIM_ISOL = 0xff<<8,/* Bit 15..8: Isolate Count */
|
||||
PHY_L_CIM_FALSE_CAR = 0xff, /* Bit 7..0: False Carrier Count */
|
||||
};
|
||||
|
||||
/*
|
||||
* Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
|
||||
*/
|
||||
enum {
|
||||
PHY_L_P_NO_PAUSE= 0<<10,/* Bit 11..10: no Pause Mode */
|
||||
PHY_L_P_SYM_MD = 1<<10, /* Bit 11..10: symmetric Pause Mode */
|
||||
PHY_L_P_ASYM_MD = 2<<10,/* Bit 11..10: asymmetric Pause Mode */
|
||||
PHY_L_P_BOTH_MD = 3<<10,/* Bit 11..10: both Pause Mode */
|
||||
};
|
||||
|
||||
/*
|
||||
* National-Specific
|
||||
*/
|
||||
/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
|
||||
enum {
|
||||
PHY_N_1000C_TEST= 7<<13,/* Bit 15..13: Test Modes */
|
||||
PHY_N_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */
|
||||
PHY_N_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */
|
||||
PHY_N_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */
|
||||
PHY_N_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */
|
||||
PHY_N_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */
|
||||
PHY_N_1000C_APC = 1<<7, /* Bit 7: Asymmetric Pause Cap. */};
|
||||
|
||||
|
||||
/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
|
||||
enum {
|
||||
PHY_N_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */
|
||||
PHY_N_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */
|
||||
PHY_N_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */
|
||||
PHY_N_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status*/
|
||||
PHY_N_1000S_LP_FD= 1<<11, /* Bit 11: Link Partner can FD */
|
||||
PHY_N_1000S_LP_HD= 1<<10, /* Bit 10: Link Partner can HD */
|
||||
PHY_N_1000C_LP_APC= 1<<9, /* Bit 9: LP Asym. Pause Cap. */
|
||||
PHY_N_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */
|
||||
};
|
||||
|
||||
/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
|
||||
enum {
|
||||
PHY_N_ES_X_FD_CAP= 1<<15, /* Bit 15: 1000Base-X FD capable */
|
||||
PHY_N_ES_X_HD_CAP= 1<<14, /* Bit 14: 1000Base-X HD capable */
|
||||
PHY_N_ES_T_FD_CAP= 1<<13, /* Bit 13: 1000Base-T FD capable */
|
||||
PHY_N_ES_T_HD_CAP= 1<<12, /* Bit 12: 1000Base-T HD capable */
|
||||
};
|
||||
|
||||
/** Marvell-Specific */
|
||||
enum {
|
||||
PHY_M_AN_NXT_PG = 1<<15, /* Request Next Page */
|
||||
@ -1718,7 +1380,7 @@ enum {
|
||||
PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */
|
||||
};
|
||||
|
||||
#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK)
|
||||
#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK)
|
||||
|
||||
enum {
|
||||
PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */
|
||||
@ -2105,7 +1767,7 @@ enum {
|
||||
GM_GPSR_FC_RX_DIS = 1<<2, /* Bit 2: Rx Flow-Control Mode Disabled */
|
||||
GM_GPSR_PROM_EN = 1<<1, /* Bit 1: Promiscuous Mode Enabled */
|
||||
};
|
||||
|
||||
|
||||
/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
|
||||
enum {
|
||||
GM_GPCR_PROM_ENA = 1<<14, /* Bit 14: Enable Promiscuous Mode */
|
||||
@ -2127,7 +1789,7 @@ enum {
|
||||
|
||||
#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
|
||||
#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
|
||||
|
||||
|
||||
/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
|
||||
enum {
|
||||
GM_TXCR_FORCE_JAM = 1<<15, /* Bit 15: Force Jam / Flow-Control */
|
||||
@ -2138,7 +1800,7 @@ enum {
|
||||
|
||||
#define TX_COL_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK)
|
||||
#define TX_COL_DEF 0x04
|
||||
|
||||
|
||||
/* GM_RX_CTRL 16 bit r/w Receive Control Register */
|
||||
enum {
|
||||
GM_RXCR_UCF_ENA = 1<<15, /* Bit 15: Enable Unicast filtering */
|
||||
@ -2146,7 +1808,7 @@ enum {
|
||||
GM_RXCR_CRC_DIS = 1<<13, /* Bit 13: Remove 4-byte CRC */
|
||||
GM_RXCR_PASS_FC = 1<<12, /* Bit 12: Pass FC packets to FIFO */
|
||||
};
|
||||
|
||||
|
||||
/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
|
||||
enum {
|
||||
GM_TXPA_JAMLEN_MSK = 0x03<<14, /* Bit 15..14: Jam Length */
|
||||
@ -2171,7 +1833,7 @@ enum {
|
||||
GM_SMOD_JUMBO_ENA = 1<<8, /* Bit 8: Enable Jumbo (Max. Frame Len) */
|
||||
GM_SMOD_IPG_MSK = 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */
|
||||
};
|
||||
|
||||
|
||||
#define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK)
|
||||
#define DATA_BLIND_DEF 0x04
|
||||
|
||||
@ -2186,7 +1848,7 @@ enum {
|
||||
GM_SMI_CT_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */
|
||||
GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */
|
||||
};
|
||||
|
||||
|
||||
#define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK)
|
||||
#define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK)
|
||||
|
||||
@ -2195,7 +1857,7 @@ enum {
|
||||
GM_PAR_MIB_CLR = 1<<5, /* Bit 5: Set MIB Clear Counter Mode */
|
||||
GM_PAR_MIB_TST = 1<<4, /* Bit 4: MIB Load Counter (Test Mode) */
|
||||
};
|
||||
|
||||
|
||||
/* Receive Frame Status Encoding */
|
||||
enum {
|
||||
GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */
|
||||
@ -2217,12 +1879,12 @@ enum {
|
||||
/*
|
||||
* GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
|
||||
*/
|
||||
GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR |
|
||||
GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
|
||||
GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR |
|
||||
GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
|
||||
GMR_FS_JABBER,
|
||||
/* Rx GMAC FIFO Flush Mask (default) */
|
||||
RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR |
|
||||
GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE |
|
||||
GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE |
|
||||
GMR_FS_JABBER,
|
||||
};
|
||||
|
||||
@ -2540,10 +2202,6 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
|
||||
#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */
|
||||
|
||||
|
||||
/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
|
||||
enum {
|
||||
XM_GP_ANIP = 1<<6, /* Bit 6: (ro) Auto-Neg. in progress */
|
||||
@ -2662,8 +2320,8 @@ enum {
|
||||
};
|
||||
|
||||
#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
|
||||
#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
|
||||
XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
|
||||
#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
|
||||
XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA)
|
||||
|
||||
/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
|
||||
enum {
|
||||
@ -2793,28 +2451,20 @@ struct skge_hw {
|
||||
u32 intr_mask;
|
||||
struct net_device *dev[2];
|
||||
|
||||
u8 mac_cfg;
|
||||
u8 chip_id;
|
||||
u8 chip_rev;
|
||||
u8 phy_type;
|
||||
u8 pmd_type;
|
||||
u16 phy_addr;
|
||||
u8 ports;
|
||||
|
||||
u32 ram_size;
|
||||
u32 ram_offset;
|
||||
|
||||
|
||||
struct tasklet_struct ext_tasklet;
|
||||
spinlock_t phy_lock;
|
||||
};
|
||||
|
||||
static inline int isdualport(const struct skge_hw *hw)
|
||||
{
|
||||
return !(hw->mac_cfg & CFG_SNG_MAC);
|
||||
}
|
||||
|
||||
static inline u8 chip_rev(const struct skge_hw *hw)
|
||||
{
|
||||
return (hw->mac_cfg & CFG_CHIP_R_MSK) >> 4;
|
||||
}
|
||||
|
||||
static inline int iscopper(const struct skge_hw *hw)
|
||||
{
|
||||
@ -2827,7 +2477,7 @@ enum {
|
||||
FLOW_MODE_REM_SEND = 2, /* Symmetric or just remote */
|
||||
FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */
|
||||
};
|
||||
|
||||
|
||||
struct skge_port {
|
||||
u32 msg_enable;
|
||||
struct skge_hw *hw;
|
||||
@ -2853,8 +2503,8 @@ struct skge_port {
|
||||
void *mem; /* PCI memory for rings */
|
||||
dma_addr_t dma;
|
||||
unsigned long mem_size;
|
||||
unsigned int rx_buf_size;
|
||||
|
||||
struct timer_list link_check;
|
||||
struct timer_list led_blink;
|
||||
};
|
||||
|
||||
@ -2863,7 +2513,6 @@ struct skge_port {
|
||||
static inline u32 skge_read32(const struct skge_hw *hw, int reg)
|
||||
{
|
||||
return readl(hw->regs + reg);
|
||||
|
||||
}
|
||||
|
||||
static inline u16 skge_read16(const struct skge_hw *hw, int reg)
|
||||
@ -2892,114 +2541,87 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val)
|
||||
}
|
||||
|
||||
/* MAC Related Registers inside the device. */
|
||||
#define SKGEMAC_REG(port,reg) (((port)<<7)+(reg))
|
||||
|
||||
/* PCI config space can be accessed via memory mapped space */
|
||||
#define SKGEPCI_REG(reg) ((reg)+ 0x380)
|
||||
|
||||
#define SKGEXM_REG(port, reg) \
|
||||
#define SK_REG(port,reg) (((port)<<7)+(reg))
|
||||
#define SK_XMAC_REG(port, reg) \
|
||||
((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
|
||||
|
||||
static inline u32 skge_xm_read32(const struct skge_hw *hw, int port, int reg)
|
||||
static inline u32 xm_read32(const struct skge_hw *hw, int port, int reg)
|
||||
{
|
||||
return skge_read32(hw, SKGEXM_REG(port,reg));
|
||||
u32 v;
|
||||
v = skge_read16(hw, SK_XMAC_REG(port, reg));
|
||||
v |= (u32)skge_read16(hw, SK_XMAC_REG(port, reg+2)) << 16;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline u16 skge_xm_read16(const struct skge_hw *hw, int port, int reg)
|
||||
static inline u16 xm_read16(const struct skge_hw *hw, int port, int reg)
|
||||
{
|
||||
return skge_read16(hw, SKGEXM_REG(port,reg));
|
||||
return skge_read16(hw, SK_XMAC_REG(port,reg));
|
||||
}
|
||||
|
||||
static inline u8 skge_xm_read8(const struct skge_hw *hw, int port, int reg)
|
||||
static inline void xm_write32(const struct skge_hw *hw, int port, int r, u32 v)
|
||||
{
|
||||
return skge_read8(hw, SKGEXM_REG(port,reg));
|
||||
skge_write16(hw, SK_XMAC_REG(port,r), v & 0xffff);
|
||||
skge_write16(hw, SK_XMAC_REG(port,r+2), v >> 16);
|
||||
}
|
||||
|
||||
static inline void skge_xm_write32(const struct skge_hw *hw, int port, int r, u32 v)
|
||||
static inline void xm_write16(const struct skge_hw *hw, int port, int r, u16 v)
|
||||
{
|
||||
skge_write32(hw, SKGEXM_REG(port,r), v);
|
||||
skge_write16(hw, SK_XMAC_REG(port,r), v);
|
||||
}
|
||||
|
||||
static inline void skge_xm_write16(const struct skge_hw *hw, int port, int r, u16 v)
|
||||
{
|
||||
skge_write16(hw, SKGEXM_REG(port,r), v);
|
||||
}
|
||||
|
||||
static inline void skge_xm_write8(const struct skge_hw *hw, int port, int r, u8 v)
|
||||
{
|
||||
skge_write8(hw, SKGEXM_REG(port,r), v);
|
||||
}
|
||||
|
||||
static inline void skge_xm_outhash(const struct skge_hw *hw, int port, int reg,
|
||||
static inline void xm_outhash(const struct skge_hw *hw, int port, int reg,
|
||||
const u8 *hash)
|
||||
{
|
||||
skge_xm_write16(hw, port, reg,
|
||||
(u16)hash[0] | ((u16)hash[1] << 8));
|
||||
skge_xm_write16(hw, port, reg+2,
|
||||
(u16)hash[2] | ((u16)hash[3] << 8));
|
||||
skge_xm_write16(hw, port, reg+4,
|
||||
(u16)hash[4] | ((u16)hash[5] << 8));
|
||||
skge_xm_write16(hw, port, reg+6,
|
||||
(u16)hash[6] | ((u16)hash[7] << 8));
|
||||
xm_write16(hw, port, reg, (u16)hash[0] | ((u16)hash[1] << 8));
|
||||
xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8));
|
||||
xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8));
|
||||
xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 8));
|
||||
}
|
||||
|
||||
static inline void skge_xm_outaddr(const struct skge_hw *hw, int port, int reg,
|
||||
static inline void xm_outaddr(const struct skge_hw *hw, int port, int reg,
|
||||
const u8 *addr)
|
||||
{
|
||||
skge_xm_write16(hw, port, reg,
|
||||
(u16)addr[0] | ((u16)addr[1] << 8));
|
||||
skge_xm_write16(hw, port, reg,
|
||||
(u16)addr[2] | ((u16)addr[3] << 8));
|
||||
skge_xm_write16(hw, port, reg,
|
||||
(u16)addr[4] | ((u16)addr[5] << 8));
|
||||
xm_write16(hw, port, reg, (u16)addr[0] | ((u16)addr[1] << 8));
|
||||
xm_write16(hw, port, reg+2, (u16)addr[2] | ((u16)addr[3] << 8));
|
||||
xm_write16(hw, port, reg+4, (u16)addr[4] | ((u16)addr[5] << 8));
|
||||
}
|
||||
|
||||
#define SK_GMAC_REG(port,reg) \
|
||||
(BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
|
||||
|
||||
#define SKGEGMA_REG(port,reg) \
|
||||
((reg) + BASE_GMAC_1 + \
|
||||
(port) * (BASE_GMAC_2-BASE_GMAC_1))
|
||||
|
||||
static inline u16 skge_gma_read16(const struct skge_hw *hw, int port, int reg)
|
||||
static inline u16 gma_read16(const struct skge_hw *hw, int port, int reg)
|
||||
{
|
||||
return skge_read16(hw, SKGEGMA_REG(port,reg));
|
||||
return skge_read16(hw, SK_GMAC_REG(port,reg));
|
||||
}
|
||||
|
||||
static inline u32 skge_gma_read32(const struct skge_hw *hw, int port, int reg)
|
||||
static inline u32 gma_read32(const struct skge_hw *hw, int port, int reg)
|
||||
{
|
||||
return (u32) skge_read16(hw, SKGEGMA_REG(port,reg))
|
||||
| ((u32)skge_read16(hw, SKGEGMA_REG(port,reg+4)) << 16);
|
||||
return (u32) skge_read16(hw, SK_GMAC_REG(port,reg))
|
||||
| ((u32)skge_read16(hw, SK_GMAC_REG(port,reg+4)) << 16);
|
||||
}
|
||||
|
||||
static inline u8 skge_gma_read8(const struct skge_hw *hw, int port, int reg)
|
||||
static inline void gma_write16(const struct skge_hw *hw, int port, int r, u16 v)
|
||||
{
|
||||
return skge_read8(hw, SKGEGMA_REG(port,reg));
|
||||
skge_write16(hw, SK_GMAC_REG(port,r), v);
|
||||
}
|
||||
|
||||
static inline void skge_gma_write16(const struct skge_hw *hw, int port, int r, u16 v)
|
||||
static inline void gma_write32(const struct skge_hw *hw, int port, int r, u32 v)
|
||||
{
|
||||
skge_write16(hw, SKGEGMA_REG(port,r), v);
|
||||
skge_write16(hw, SK_GMAC_REG(port, r), (u16) v);
|
||||
skge_write32(hw, SK_GMAC_REG(port, r+4), (u16)(v >> 16));
|
||||
}
|
||||
|
||||
static inline void skge_gma_write32(const struct skge_hw *hw, int port, int r, u32 v)
|
||||
static inline void gma_write8(const struct skge_hw *hw, int port, int r, u8 v)
|
||||
{
|
||||
skge_write16(hw, SKGEGMA_REG(port, r), (u16) v);
|
||||
skge_write32(hw, SKGEGMA_REG(port, r+4), (u16)(v >> 16));
|
||||
skge_write8(hw, SK_GMAC_REG(port,r), v);
|
||||
}
|
||||
|
||||
static inline void skge_gma_write8(const struct skge_hw *hw, int port, int r, u8 v)
|
||||
{
|
||||
skge_write8(hw, SKGEGMA_REG(port,r), v);
|
||||
}
|
||||
|
||||
static inline void skge_gm_set_addr(struct skge_hw *hw, int port, int reg,
|
||||
static inline void gma_set_addr(struct skge_hw *hw, int port, int reg,
|
||||
const u8 *addr)
|
||||
{
|
||||
skge_gma_write16(hw, port, reg,
|
||||
(u16) addr[0] | ((u16) addr[1] << 8));
|
||||
skge_gma_write16(hw, port, reg+4,
|
||||
(u16) addr[2] | ((u16) addr[3] << 8));
|
||||
skge_gma_write16(hw, port, reg+8,
|
||||
(u16) addr[4] | ((u16) addr[5] << 8));
|
||||
gma_write16(hw, port, reg, (u16) addr[0] | ((u16) addr[1] << 8));
|
||||
gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
|
||||
gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -74,6 +74,7 @@
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_slip.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include "slip.h"
|
||||
#ifdef CONFIG_INET
|
||||
|
@ -1998,7 +1998,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
|
||||
if (retval)
|
||||
goto err_out;
|
||||
|
||||
set_irq_type(dev->irq, IRQT_RISING);
|
||||
set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE);
|
||||
|
||||
#ifdef SMC_USE_PXA_DMA
|
||||
{
|
||||
|
@ -182,6 +182,16 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
|
||||
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
|
||||
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
|
||||
#define SMC_IRQ_TRIGGER_TYPE (( \
|
||||
machine_is_omap_h2() \
|
||||
|| machine_is_omap_h3() \
|
||||
|| (machine_is_omap_innovator() && !cpu_is_omap150()) \
|
||||
) ? IRQT_FALLING : IRQT_RISING)
|
||||
|
||||
|
||||
#elif defined(CONFIG_SH_SH4202_MICRODEV)
|
||||
|
||||
#define SMC_CAN_USE_8BIT 0
|
||||
@ -300,6 +310,9 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef SMC_IRQ_TRIGGER_TYPE
|
||||
#define SMC_IRQ_TRIGGER_TYPE IRQT_RISING
|
||||
#endif
|
||||
|
||||
#ifdef SMC_USE_PXA_DMA
|
||||
/*
|
||||
|
@ -1286,7 +1286,7 @@ static void init_ring(struct net_device *dev)
|
||||
np->rx_info[i].skb = skb;
|
||||
if (skb == NULL)
|
||||
break;
|
||||
np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
/* Grrr, we cannot offset to correctly align the IP header. */
|
||||
np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
|
||||
@ -1572,7 +1572,7 @@ static int __netdev_rx(struct net_device *dev, int *quota)
|
||||
pci_dma_sync_single_for_cpu(np->pci_dev,
|
||||
np->rx_info[entry].mapping,
|
||||
pkt_len, PCI_DMA_FROMDEVICE);
|
||||
eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
|
||||
eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0);
|
||||
pci_dma_sync_single_for_device(np->pci_dev,
|
||||
np->rx_info[entry].mapping,
|
||||
pkt_len, PCI_DMA_FROMDEVICE);
|
||||
@ -1696,7 +1696,7 @@ static void refill_rx_ring(struct net_device *dev)
|
||||
if (skb == NULL)
|
||||
break; /* Better luck next round. */
|
||||
np->rx_info[entry].mapping =
|
||||
pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
np->rx_ring[entry].rxaddr =
|
||||
cpu_to_dma(np->rx_info[entry].mapping | RxDescValid);
|
||||
|
@ -1028,7 +1028,7 @@ static void init_ring(struct net_device *dev)
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
||||
np->rx_ring[i].frag[0].addr = cpu_to_le32(
|
||||
pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz,
|
||||
pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz,
|
||||
PCI_DMA_FROMDEVICE));
|
||||
np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
|
||||
}
|
||||
@ -1341,7 +1341,7 @@ static void rx_poll(unsigned long data)
|
||||
np->rx_buf_sz,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
|
||||
eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
|
||||
eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
|
||||
pci_dma_sync_single_for_device(np->pci_dev,
|
||||
desc->frag[0].addr,
|
||||
np->rx_buf_sz,
|
||||
@ -1400,7 +1400,7 @@ static void refill_rx (struct net_device *dev)
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||
np->rx_ring[entry].frag[0].addr = cpu_to_le32(
|
||||
pci_map_single(np->pci_dev, skb->tail,
|
||||
pci_map_single(np->pci_dev, skb->data,
|
||||
np->rx_buf_sz, PCI_DMA_FROMDEVICE));
|
||||
}
|
||||
/* Perhaps we need not reset this field. */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user