Auto merge with /home/aegl/GIT/linus
This commit is contained in:
@@ -84,6 +84,14 @@ void (*port_disable) (struct ata_port *);
|
|||||||
Called from ata_bus_probe() and ata_bus_reset() error paths,
|
Called from ata_bus_probe() and ata_bus_reset() error paths,
|
||||||
as well as when unregistering from the SCSI module (rmmod, hot
|
as well as when unregistering from the SCSI module (rmmod, hot
|
||||||
unplug).
|
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>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
@@ -98,6 +106,13 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
|
|||||||
found. Typically used to apply device-specific fixups prior to
|
found. Typically used to apply device-specific fixups prior to
|
||||||
issue of SET FEATURES - XFER MODE, and prior to operation.
|
issue of SET FEATURES - XFER MODE, and prior to operation.
|
||||||
</para>
|
</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>
|
</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
|
registers / DMA buffers. ->tf_read() is called to read the
|
||||||
hardware registers / DMA buffers, to obtain the current set of
|
hardware registers / DMA buffers, to obtain the current set of
|
||||||
taskfile register values.
|
taskfile register values.
|
||||||
|
Most drivers for taskfile-based hardware (PIO or MMIO) use
|
||||||
|
ata_tf_load() and ata_tf_read() for these hooks.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
@@ -147,6 +164,8 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
|
|||||||
<para>
|
<para>
|
||||||
causes an ATA command, previously loaded with
|
causes an ATA command, previously loaded with
|
||||||
->tf_load(), to be initiated in hardware.
|
->tf_load(), to be initiated in hardware.
|
||||||
|
Most drivers for taskfile-based hardware use ata_exec_command()
|
||||||
|
for this hook.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</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
|
indicating whether or not it is OK to use DMA for the supplied PACKET
|
||||||
command.
|
command.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
This hook may be specified as NULL, in which case libata will
|
||||||
|
assume that atapi dma can be supported.
|
||||||
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
@@ -175,6 +198,14 @@ u8 (*check_err)(struct ata_port *ap);
|
|||||||
Reads the Status/AltStatus/Error ATA shadow register from
|
Reads the Status/AltStatus/Error ATA shadow register from
|
||||||
hardware. On some hardware, reading the Status register has
|
hardware. On some hardware, reading the Status register has
|
||||||
the side effect of clearing the interrupt condition.
|
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>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</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
|
Issues the low-level hardware command(s) that causes one of N
|
||||||
hardware devices to be considered 'selected' (active and
|
hardware devices to be considered 'selected' (active and
|
||||||
available for use) on the ATA bus. This generally has no
|
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>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
@@ -204,6 +241,8 @@ void (*phy_reset) (struct ata_port *ap);
|
|||||||
for device presence (PATA and SATA), typically a soft reset
|
for device presence (PATA and SATA), typically a soft reset
|
||||||
(SRST) will be performed. Drivers typically use the helper
|
(SRST) will be performed. Drivers typically use the helper
|
||||||
functions ata_bus_reset() or sata_phy_reset() for this hook.
|
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>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
@@ -227,6 +266,25 @@ PCI IDE DMA Status register.
|
|||||||
These hooks are typically either no-ops, or simply not implemented, in
|
These hooks are typically either no-ops, or simply not implemented, in
|
||||||
FIS-based drivers.
|
FIS-based drivers.
|
||||||
</para>
|
</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>
|
</sect2>
|
||||||
|
|
||||||
@@ -250,6 +308,10 @@ int (*qc_issue) (struct ata_queued_cmd *qc);
|
|||||||
helper function ata_qc_issue_prot() for taskfile protocol-based
|
helper function ata_qc_issue_prot() for taskfile protocol-based
|
||||||
dispatch. More advanced drivers implement their own ->qc_issue.
|
dispatch. More advanced drivers implement their own ->qc_issue.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and
|
||||||
|
->bmdma_start() as necessary to initiate a transfer.
|
||||||
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
@@ -279,6 +341,21 @@ void (*irq_clear) (struct ata_port *);
|
|||||||
before the interrupt handler is registered, to be sure hardware
|
before the interrupt handler is registered, to be sure hardware
|
||||||
is quiet.
|
is quiet.
|
||||||
</para>
|
</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>
|
</sect2>
|
||||||
|
|
||||||
@@ -292,6 +369,7 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
|
|||||||
<para>
|
<para>
|
||||||
Read and write standard SATA phy registers. Currently only used
|
Read and write standard SATA phy registers. Currently only used
|
||||||
if ->phy_reset hook called the sata_phy_reset() helper function.
|
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>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</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_start() is called just after the data structures for each
|
||||||
port are initialized. Typically this is used to alloc per-port
|
port are initialized. Typically this is used to alloc per-port
|
||||||
DMA buffers / tables / rings, enable DMA engines, and similar
|
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>
|
||||||
<para>
|
<para>
|
||||||
->port_stop() is called after ->host_stop(). It's sole function
|
->port_stop() is called after ->host_stop(). It's sole function
|
||||||
is to release DMA/memory resources, now that they are no longer
|
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>
|
||||||
<para>
|
<para>
|
||||||
->host_stop() is called after all ->port_stop() calls
|
->host_stop() is called after all ->port_stop() calls
|
||||||
have completed. The hook must finalize hardware shutdown, release DMA
|
have completed. The hook must finalize hardware shutdown, release DMA
|
||||||
and other resources, etc.
|
and other resources, etc.
|
||||||
|
This hook may be specified as NULL, in which case it is not called.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
@@ -13,13 +13,14 @@ Allocating Device Numbers
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Major and minor numbers for block and character devices are allocated
|
Major and minor numbers for block and character devices are allocated
|
||||||
by the Linux assigned name and number authority (currently better
|
by the Linux assigned name and number authority (currently this is
|
||||||
known as H Peter Anvin). The site is http://www.lanana.org/. This
|
Torben Mathiasen). The site is http://www.lanana.org/. This
|
||||||
also deals with allocating numbers for devices that are not going to
|
also deals with allocating numbers for devices that are not going to
|
||||||
be submitted to the mainstream kernel.
|
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
|
If you don't use assigned numbers then when your device is submitted it will
|
||||||
get given an assigned number even if that is different from values you may
|
be given an assigned number even if that is different from values you may
|
||||||
have shipped to customers before.
|
have shipped to customers before.
|
||||||
|
|
||||||
Who To Submit Drivers To
|
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
|
If the code area has a general maintainer then please submit it to
|
||||||
the maintainer listed in MAINTAINERS in the kernel file. If the
|
the maintainer listed in MAINTAINERS in the kernel file. If the
|
||||||
maintainer does not respond or you cannot find the appropriate
|
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:
|
Linux 2.4:
|
||||||
The same rules apply as 2.2. The final contact point for 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
|
Licensing: The code must be released to us under the
|
||||||
GNU General Public License. We don't insist on any kind
|
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
|
to be useful to other communities such as BSD you may well
|
||||||
wish to release under multiple licenses.
|
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:
|
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
|
MYFILE= drivers/net/mydriver.c
|
||||||
|
|
||||||
cd $SRCTREE
|
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
|
or unmodified kernel source tree, and generate a diff against your
|
||||||
own source tree. For example:
|
own source tree. For example:
|
||||||
|
|
||||||
MYSRC= /devel/linux-2.4
|
MYSRC= /devel/linux-2.6
|
||||||
|
|
||||||
tar xvfz linux-2.4.0-test11.tar.gz
|
tar xvfz linux-2.6.12.tar.gz
|
||||||
mv linux linux-vanilla
|
mv linux-2.6.12 linux-2.6.12-vanilla
|
||||||
wget http://www.moses.uklinux.net/patches/dontdiff
|
diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \
|
||||||
diff -uprN -X dontdiff linux-vanilla $MYSRC > /tmp/patch
|
linux-2.6.12-vanilla $MYSRC > /tmp/patch
|
||||||
rm -f dontdiff
|
|
||||||
|
|
||||||
"dontdiff" is a list of files which are generated by the kernel during
|
"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
|
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
|
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-
|
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
|
If your changes produce a lot of deltas, you may want to look into
|
||||||
splitting them into individual patches which modify things in
|
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.
|
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:
|
Quilt:
|
||||||
http://savannah.nongnu.org/projects/quilt
|
http://savannah.nongnu.org/projects/quilt
|
||||||
|
|
||||||
Randy Dunlap's patch scripts:
|
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:
|
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.
|
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)
|
since people copy, as long as it's trivial)
|
||||||
Any fix by the author/maintainer of the file. (ie. patch monkey
|
Any fix by the author/maintainer of the file. (ie. patch monkey
|
||||||
in re-transmission mode)
|
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.
|
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
|
SECTION 2 - HINTS, TIPS, AND TRICKS
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
@@ -359,7 +375,5 @@ and 'extern __inline__'.
|
|||||||
4) Don't over-design.
|
4) Don't over-design.
|
||||||
|
|
||||||
Don't try to anticipate nebulous future cases which may or may not
|
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
|
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
|
||||||
See header of drivers/scsi/ips.c.
|
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]
|
isapnp= [ISAPNP]
|
||||||
Format: <RDP>, <reset>, <pci_scan>, <verbosity>
|
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
|
irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
|
||||||
automatically to PCI devices. You can make the kernel
|
automatically to PCI devices. You can make the kernel
|
||||||
exclude IRQs of your ISA cards this way.
|
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
|
lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
|
||||||
if the kernel is unable to find your secondary buses
|
if the kernel is unable to find your secondary buses
|
||||||
and you want to tell it explicitly which ones they are.
|
and you want to tell it explicitly which ones they are.
|
||||||
|
@@ -1,399 +1,16 @@
|
|||||||
<HTML><HEAD>
|
<TITLE>V4L API</TITLE>
|
||||||
<TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE>
|
<H1>Video For Linux APIs</H1>
|
||||||
</HEAD>
|
<table border=0>
|
||||||
<! Revision History: >
|
<tr>
|
||||||
<! 4/30/1999 - Fred Gleason (fredg@wava.com)>
|
<td>
|
||||||
<! Documented extensions for the Radio Data System (RDS) extensions >
|
<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html>
|
||||||
<BODY bgcolor="#ffffff">
|
V4L original API</a>
|
||||||
<H3>Devices</H3>
|
</td><td>
|
||||||
Video4Linux provides the following sets of device files. These live on the
|
Obsoleted by V4L2 API
|
||||||
character device formerly known as "/dev/bttv". /dev/bttv should be a
|
</td></tr><tr><td>
|
||||||
symlink to /dev/video0 for most people.
|
<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html>
|
||||||
<P>
|
V4L2 API</a>
|
||||||
<TABLE>
|
</td><td>
|
||||||
<TR><TH>Device Name</TH><TH>Minor Range</TH><TH>Function</TH>
|
Should be used for new projects
|
||||||
<TR><TD>/dev/video</TD><TD>0-63</TD><TD>Video Capture Interface</TD>
|
</td></tr>
|
||||||
<TR><TD>/dev/radio</TD><TD>64-127</TD><TD>AM/FM Radio Devices</TD>
|
</table>
|
||||||
<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>
|
|
||||||
|
@@ -13,17 +13,17 @@ card=11 - Prolink PlayTV PVR
|
|||||||
card=12 - ASUS PVR-416
|
card=12 - ASUS PVR-416
|
||||||
card=13 - MSI TV-@nywhere
|
card=13 - MSI TV-@nywhere
|
||||||
card=14 - KWorld/VStream XPert DVB-T
|
card=14 - KWorld/VStream XPert DVB-T
|
||||||
card=15 - DVICO FusionHDTV DVB-T1
|
card=15 - DViCO FusionHDTV DVB-T1
|
||||||
card=16 - KWorld LTV883RF
|
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=18 - Hauppauge Nova-T DVB-T
|
||||||
card=19 - Conexant DVB-T reference design
|
card=19 - Conexant DVB-T reference design
|
||||||
card=20 - Provideo PV259
|
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=22 - digitalnow DNTV Live! DVB-T
|
||||||
card=23 - pcHDTV HD3000 HDTV
|
card=23 - pcHDTV HD3000 HDTV
|
||||||
card=24 - Hauppauge WinTV 28xxx (Roslyn) models
|
card=24 - Hauppauge WinTV 28xxx (Roslyn) models
|
||||||
card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
|
card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
|
||||||
card=26 - IODATA GV/BCTV7E
|
card=26 - IODATA GV/BCTV7E
|
||||||
card=27 - PixelView PlayTV Ultra Pro (Stereo)
|
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]
|
55 -> LifeView FlyDVB-T DUO [5168:0306]
|
||||||
56 -> Avermedia AVerTV 307 [1461:a70a]
|
56 -> Avermedia AVerTV 307 [1461:a70a]
|
||||||
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
|
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=58 - Ymec TVision TVF-8531MF
|
||||||
tuner=59 - Ymec TVision TVF-5533MF
|
tuner=59 - Ymec TVision TVF-5533MF
|
||||||
tuner=60 - Thomson DDT 7611 (ATSC/NTSC)
|
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
|
- 24.576MHz -> .audio_clock=0x200000
|
||||||
(xtal * .audio_clock = 51539600)
|
(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
|
Credits
|
||||||
=======
|
=======
|
||||||
|
15
MAINTAINERS
15
MAINTAINERS
@@ -512,11 +512,11 @@ W: http://linuxppc64.org
|
|||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
BTTV VIDEO4LINUX DRIVER
|
BTTV VIDEO4LINUX DRIVER
|
||||||
P: Gerd Knorr
|
P: Mauro Carvalho Chehab
|
||||||
M: kraxel@bytesex.org
|
M: mchehab@brturbo.com.br
|
||||||
L: video4linux-list@redhat.com
|
L: video4linux-list@redhat.com
|
||||||
W: http://bytesex.org/bttv/
|
W: http://linuxtv.org
|
||||||
S: Orphan
|
S: Maintained
|
||||||
|
|
||||||
BUSLOGIC SCSI DRIVER
|
BUSLOGIC SCSI DRIVER
|
||||||
P: Leonard N. Zubkoff
|
P: Leonard N. Zubkoff
|
||||||
@@ -2625,10 +2625,11 @@ W: http://rio500.sourceforge.net
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
VIDEO FOR LINUX
|
VIDEO FOR LINUX
|
||||||
P: Gerd Knorr
|
P: Mauro Carvalho Chehab
|
||||||
M: kraxel@bytesex.org
|
M: mchehab@brturbo.com.br
|
||||||
L: video4linux-list@redhat.com
|
L: video4linux-list@redhat.com
|
||||||
S: Orphan
|
W: http://linuxtv.org
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
W1 DALLAS'S 1-WIRE BUS
|
W1 DALLAS'S 1-WIRE BUS
|
||||||
P: Evgeniy Polyakov
|
P: Evgeniy Polyakov
|
||||||
|
4
Makefile
4
Makefile
@@ -1,7 +1,7 @@
|
|||||||
VERSION = 2
|
VERSION = 2
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 12
|
SUBLEVEL = 13
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =-rc1
|
||||||
NAME=Woozy Numbat
|
NAME=Woozy Numbat
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
@@ -361,6 +361,11 @@ config NO_IDLE_HZ
|
|||||||
Alternatively, if you want dynamic tick automatically enabled
|
Alternatively, if you want dynamic tick automatically enabled
|
||||||
during boot, pass "dyntick=enable" via the kernel command string.
|
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
|
config ARCH_DISCONTIGMEM_ENABLE
|
||||||
bool
|
bool
|
||||||
default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
|
default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
|
||||||
|
@@ -40,8 +40,11 @@
|
|||||||
* 04-Nov-2004 Ben Dooks
|
* 04-Nov-2004 Ben Dooks
|
||||||
* Fix standard IRQ wake for EINT0..4 and RTC
|
* 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
|
* Fixed edge-triggering on ADC IRQ
|
||||||
|
*
|
||||||
|
* 28-Jun-2005 Ben Dooks
|
||||||
|
* Mark IRQ_LCD valid
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
@@ -366,7 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = {
|
|||||||
#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
|
#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
|
||||||
#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
|
#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
|
||||||
#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
|
#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
|
||||||
#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
|
s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
|
||||||
@@ -716,7 +718,6 @@ void __init s3c24xx_init_irq(void)
|
|||||||
case IRQ_UART0:
|
case IRQ_UART0:
|
||||||
case IRQ_UART1:
|
case IRQ_UART1:
|
||||||
case IRQ_UART2:
|
case IRQ_UART2:
|
||||||
case IRQ_LCD:
|
|
||||||
case IRQ_ADCPARENT:
|
case IRQ_ADCPARENT:
|
||||||
set_irq_chip(irqno, &s3c_irq_level_chip);
|
set_irq_chip(irqno, &s3c_irq_level_chip);
|
||||||
set_irq_handler(irqno, do_level_IRQ);
|
set_irq_handler(irqno, do_level_IRQ);
|
||||||
|
@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
|
|||||||
oprofilefs.o oprofile_stats.o \
|
oprofilefs.o oprofile_stats.o \
|
||||||
timer_int.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
|
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);
|
ret = pmu_init(ops, &op_xscale_spec);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ops->backtrace = arm_backtrace;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,8 @@ struct op_arm_model_spec {
|
|||||||
extern struct op_arm_model_spec op_xscale_spec;
|
extern struct op_arm_model_spec op_xscale_spec;
|
||||||
#endif
|
#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 int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
|
||||||
extern void pmu_exit(void);
|
extern void pmu_exit(void);
|
||||||
#endif /* OP_ARM_MODEL_H */
|
#endif /* OP_ARM_MODEL_H */
|
||||||
|
@@ -70,7 +70,8 @@ void usage(void)
|
|||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
unsigned int i, c, sz, setup_sectors;
|
unsigned int i, sz, setup_sectors;
|
||||||
|
int c;
|
||||||
u32 sys_size;
|
u32 sys_size;
|
||||||
byte major_root, minor_root;
|
byte major_root, minor_root;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
@@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_MMCONFIG
|
#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;
|
struct acpi_table_mcfg *mcfg;
|
||||||
|
unsigned long i;
|
||||||
|
int config_size;
|
||||||
|
|
||||||
if (!phys_addr || !size)
|
if (!phys_addr || !size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mcfg->base_reserved) {
|
/* how many config structures do we have */
|
||||||
printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n");
|
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#endif /* CONFIG_PCI_MMCONFIG */
|
||||||
#define acpi_parse_mcfg NULL
|
|
||||||
#endif /* !CONFIG_PCI_MMCONFIG */
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
static int __init
|
static int __init
|
||||||
@@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu)
|
|||||||
EXPORT_SYMBOL(acpi_unmap_lsapic);
|
EXPORT_SYMBOL(acpi_unmap_lsapic);
|
||||||
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
|
#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
|
static unsigned long __init
|
||||||
acpi_scan_rsdp (
|
acpi_scan_rsdp (
|
||||||
unsigned long start,
|
unsigned long start,
|
||||||
@@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void)
|
|||||||
acpi_process_madt();
|
acpi_process_madt();
|
||||||
|
|
||||||
acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
|
acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
|
||||||
acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
|
|||||||
|
|
||||||
int pci_routeirq;
|
int pci_routeirq;
|
||||||
int pcibios_last_bus = -1;
|
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;
|
struct pci_raw_ops *raw_pci_ops;
|
||||||
|
|
||||||
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
|
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);
|
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;
|
extern u8 pci_cache_line_size;
|
||||||
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str)
|
|||||||
} else if (!strcmp(str, "biosirq")) {
|
} else if (!strcmp(str, "biosirq")) {
|
||||||
pci_probe |= PCI_BIOS_IRQ_SCAN;
|
pci_probe |= PCI_BIOS_IRQ_SCAN;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
} else if (!strncmp(str, "pirqaddr=", 9)) {
|
||||||
|
pirq_table_addr = simple_strtoul(str+9, NULL, 0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_PCI_DIRECT
|
#ifdef CONFIG_PCI_DIRECT
|
||||||
|
@@ -57,6 +57,35 @@ struct irq_router_handler {
|
|||||||
|
|
||||||
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
|
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.
|
* 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;
|
u8 *addr;
|
||||||
struct irq_routing_table *rt;
|
struct irq_routing_table *rt;
|
||||||
int i;
|
|
||||||
u8 sum;
|
|
||||||
|
|
||||||
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
|
if (pirq_table_addr) {
|
||||||
rt = (struct irq_routing_table *) addr;
|
rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
|
||||||
if (rt->signature != PIRQ_SIGNATURE ||
|
if (rt)
|
||||||
rt->version != PIRQ_VERSION ||
|
return rt;
|
||||||
rt->size % 16 ||
|
printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
|
||||||
rt->size < sizeof(struct irq_routing_table))
|
}
|
||||||
continue;
|
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
|
||||||
sum = 0;
|
rt = pirq_check_routing_table(addr);
|
||||||
for(i=0; i<rt->size; i++)
|
if (rt)
|
||||||
sum += addr[i];
|
|
||||||
if (!sum) {
|
|
||||||
DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void)
|
|||||||
|
|
||||||
printk("PCI: Probing PCI hardware\n");
|
printk("PCI: Probing PCI hardware\n");
|
||||||
pci_root_bus = pcibios_scan_root(0);
|
pci_root_bus = pcibios_scan_root(0);
|
||||||
|
if (pci_root_bus)
|
||||||
|
pci_bus_add_devices(pci_root_bus);
|
||||||
|
|
||||||
pcibios_fixup_peer_bridges();
|
pcibios_fixup_peer_bridges();
|
||||||
|
|
||||||
|
@@ -11,11 +11,9 @@
|
|||||||
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/acpi.h>
|
||||||
#include "pci.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))
|
#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
|
||||||
|
|
||||||
/* The base address of the last MMCONFIG device accessed */
|
/* 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
|
* Functions for accessing PCI configuration space with MMCONFIG accesses
|
||||||
*/
|
*/
|
||||||
|
static u32 get_base_addr(unsigned int seg, int bus)
|
||||||
static inline void pci_exp_set_dev_base(int bus, int devfn)
|
|
||||||
{
|
{
|
||||||
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) {
|
if (dev_base != mmcfg_last_accessed_device) {
|
||||||
mmcfg_last_accessed_device = dev_base;
|
mmcfg_last_accessed_device = dev_base;
|
||||||
set_fixmap_nocache(FIX_PCIE_MCFG, 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);
|
spin_lock_irqsave(&pci_config_lock, flags);
|
||||||
|
|
||||||
pci_exp_set_dev_base(bus, devfn);
|
pci_exp_set_dev_base(seg, bus, devfn);
|
||||||
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
|
|||||||
|
|
||||||
spin_lock_irqsave(&pci_config_lock, flags);
|
spin_lock_irqsave(&pci_config_lock, flags);
|
||||||
|
|
||||||
pci_exp_set_dev_base(bus, devfn);
|
pci_exp_set_dev_base(seg, bus, devfn);
|
||||||
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void)
|
|||||||
{
|
{
|
||||||
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
|
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
|
||||||
goto out;
|
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;
|
goto out;
|
||||||
|
|
||||||
/* Kludge for now. Don't use mmconfig on AMD systems because
|
/* Kludge for now. Don't use mmconfig on AMD systems because
|
||||||
|
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pci_root_bus = pcibios_scan_root(0);
|
pci_root_bus = pcibios_scan_root(0);
|
||||||
|
if (pci_root_bus)
|
||||||
|
pci_bus_add_devices(pci_root_bus);
|
||||||
if (num_online_nodes() > 1)
|
if (num_online_nodes() > 1)
|
||||||
for_each_online_node(quad) {
|
for_each_online_node(quad) {
|
||||||
if (quad == 0)
|
if (quad == 0)
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#define PCI_ASSIGN_ALL_BUSSES 0x4000
|
#define PCI_ASSIGN_ALL_BUSSES 0x4000
|
||||||
|
|
||||||
extern unsigned int pci_probe;
|
extern unsigned int pci_probe;
|
||||||
|
extern unsigned long pirq_table_addr;
|
||||||
|
|
||||||
/* pci-i386.c */
|
/* 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))
|
if (BAD_MADT_ENTRY(iosapic, end))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
iosapic_init(iosapic->address, iosapic->global_irq_base);
|
return iosapic_init(iosapic->address, iosapic->global_irq_base);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
|
|||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_NUMA
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
acpi_status __init
|
acpi_status __devinit
|
||||||
acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
|
acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
|
||||||
{
|
{
|
||||||
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
|
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;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NUMA */
|
#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 */
|
#endif /* CONFIG_ACPI_BOOT */
|
||||||
|
@@ -129,14 +129,13 @@ static struct iosapic {
|
|||||||
char __iomem *addr; /* base address of IOSAPIC */
|
char __iomem *addr; /* base address of IOSAPIC */
|
||||||
unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */
|
unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */
|
||||||
unsigned short num_rte; /* number of RTE in 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
|
#ifdef CONFIG_NUMA
|
||||||
unsigned short node; /* numa node association via pxm */
|
unsigned short node; /* numa node association via pxm */
|
||||||
#endif
|
#endif
|
||||||
} iosapic_lists[NR_IOSAPICS];
|
} iosapic_lists[NR_IOSAPICS];
|
||||||
|
|
||||||
static int num_iosapic;
|
static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
|
||||||
|
|
||||||
static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */
|
|
||||||
|
|
||||||
static int iosapic_kmalloc_ok;
|
static int iosapic_kmalloc_ok;
|
||||||
static LIST_HEAD(free_rte_list);
|
static LIST_HEAD(free_rte_list);
|
||||||
@@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi)
|
|||||||
{
|
{
|
||||||
int i;
|
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)
|
if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
|
|||||||
rte->refcnt++;
|
rte->refcnt++;
|
||||||
list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
|
list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
|
||||||
iosapic_intr_info[vector].count++;
|
iosapic_intr_info[vector].count++;
|
||||||
|
iosapic_lists[index].rtes_inuse++;
|
||||||
}
|
}
|
||||||
else if (vector_is_shared(vector)) {
|
else if (vector_is_shared(vector)) {
|
||||||
struct iosapic_intr_info *info = &iosapic_intr_info[vector];
|
struct iosapic_intr_info *info = &iosapic_intr_info[vector];
|
||||||
@@ -778,7 +778,7 @@ void
|
|||||||
iosapic_unregister_intr (unsigned int gsi)
|
iosapic_unregister_intr (unsigned int gsi)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int irq, vector;
|
int irq, vector, index;
|
||||||
irq_desc_t *idesc;
|
irq_desc_t *idesc;
|
||||||
u32 low32;
|
u32 low32;
|
||||||
unsigned long trigger, polarity;
|
unsigned long trigger, polarity;
|
||||||
@@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi)
|
|||||||
list_del(&rte->rte_list);
|
list_del(&rte->rte_list);
|
||||||
iosapic_intr_info[vector].count--;
|
iosapic_intr_info[vector].count--;
|
||||||
iosapic_free_rte(rte);
|
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;
|
trigger = iosapic_intr_info[vector].trigger;
|
||||||
polarity = iosapic_intr_info[vector].polarity;
|
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)
|
iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
|
||||||
{
|
{
|
||||||
int num_rte;
|
int num_rte, err, index;
|
||||||
unsigned int isa_irq, ver;
|
unsigned int isa_irq, ver;
|
||||||
char __iomem *addr;
|
char __iomem *addr;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
addr = ioremap(phys_addr, 0);
|
spin_lock_irqsave(&iosapic_lock, flags);
|
||||||
ver = iosapic_version(addr);
|
{
|
||||||
|
addr = ioremap(phys_addr, 0);
|
||||||
|
ver = iosapic_version(addr);
|
||||||
|
|
||||||
/*
|
if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
|
||||||
* The MAX_REDIR register holds the highest input pin
|
iounmap(addr);
|
||||||
* number (starting from 0).
|
spin_unlock_irqrestore(&iosapic_lock, flags);
|
||||||
* We add 1 so that we can use it for number of pins (= RTEs)
|
return err;
|
||||||
*/
|
}
|
||||||
num_rte = ((ver >> 16) & 0xff) + 1;
|
|
||||||
|
|
||||||
iosapic_lists[num_iosapic].addr = addr;
|
/*
|
||||||
iosapic_lists[num_iosapic].gsi_base = gsi_base;
|
* The MAX_REDIR register holds the highest input pin
|
||||||
iosapic_lists[num_iosapic].num_rte = num_rte;
|
* 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
|
#ifdef CONFIG_NUMA
|
||||||
iosapic_lists[num_iosapic].node = MAX_NUMNODES;
|
iosapic_lists[index].node = MAX_NUMNODES;
|
||||||
#endif
|
#endif
|
||||||
num_iosapic++;
|
}
|
||||||
|
spin_unlock_irqrestore(&iosapic_lock, flags);
|
||||||
|
|
||||||
if ((gsi_base == 0) && pcat_compat) {
|
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)
|
for (isa_irq = 0; isa_irq < 16; ++isa_irq)
|
||||||
iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
|
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
|
#ifdef CONFIG_NUMA
|
||||||
void __init
|
void __devinit
|
||||||
map_iosapic_to_node(unsigned int gsi_base, int node)
|
map_iosapic_to_node(unsigned int gsi_base, int node)
|
||||||
{
|
{
|
||||||
int index;
|
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,
|
acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
|
||||||
&info);
|
&info);
|
||||||
|
|
||||||
pbus = pci_scan_bus(bus, &pci_root_ops, controller);
|
pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
|
||||||
if (pbus)
|
if (pbus)
|
||||||
pcibios_setup_root_windows(pbus, controller);
|
pcibios_setup_root_windows(pbus, controller);
|
||||||
|
|
||||||
@@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
|
|||||||
res->end = region->end + offset;
|
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)
|
static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
struct pci_bus_region region;
|
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.start = dev->resource[i].start;
|
||||||
region.end = dev->resource[i].end;
|
region.end = dev->resource[i].end;
|
||||||
pcibios_bus_to_resource(dev, &dev->resource[i], ®ion);
|
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;
|
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)
|
list_for_each_entry(dev, &b->devices, bus_list)
|
||||||
pcibios_fixup_device_resources(dev);
|
pcibios_fixup_device_resources(dev);
|
||||||
|
|
||||||
@@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
|
|||||||
u16 cmd, old_cmd;
|
u16 cmd, old_cmd;
|
||||||
int idx;
|
int idx;
|
||||||
struct resource *r;
|
struct resource *r;
|
||||||
|
unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
|
||||||
|
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||||
old_cmd = cmd;
|
old_cmd = cmd;
|
||||||
for (idx=0; idx<6; idx++) {
|
for (idx=0; idx<PCI_NUM_RESOURCES; idx++) {
|
||||||
/* Only set up the desired resources. */
|
/* Only set up the desired resources. */
|
||||||
if (!(mask & (1 << idx)))
|
if (!(mask & (1 << idx)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = &dev->resource[idx];
|
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) {
|
if (!r->start && r->end) {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"PCI: Device %s not available because of resource collisions\n",
|
"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)
|
if (r->flags & IORESOURCE_MEM)
|
||||||
cmd |= PCI_COMMAND_MEMORY;
|
cmd |= PCI_COMMAND_MEMORY;
|
||||||
}
|
}
|
||||||
if (dev->resource[PCI_ROM_RESOURCE].start)
|
|
||||||
cmd |= PCI_COMMAND_MEMORY;
|
|
||||||
if (cmd != old_cmd) {
|
if (cmd != old_cmd) {
|
||||||
printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
|
printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
|
||||||
pci_write_config_word(dev, PCI_COMMAND, cmd);
|
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;
|
*offset += hose->pci_mem_offset;
|
||||||
res_bit = IORESOURCE_MEM;
|
res_bit = IORESOURCE_MEM;
|
||||||
} else {
|
} else {
|
||||||
io_offset = (unsigned long)hose->io_base_virt;
|
io_offset = hose->io_base_virt - ___IO_BASE;
|
||||||
*offset += io_offset;
|
*offset += io_offset;
|
||||||
res_bit = IORESOURCE_IO;
|
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 */
|
/* found it! construct the final physical address */
|
||||||
if (mmap_state == pci_mmap_io)
|
if (mmap_state == pci_mmap_io)
|
||||||
*offset += hose->io_base_phys - _IO_BASE;
|
*offset += hose->io_base_phys - io_offset;
|
||||||
return rp;
|
return rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
|
|||||||
return result;
|
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
|
void __init
|
||||||
pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
|
pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
|
||||||
int flags, char *name)
|
int flags, char *name)
|
||||||
|
@@ -245,7 +245,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
|
|||||||
|
|
||||||
spin_lock(&desc->lock);
|
spin_lock(&desc->lock);
|
||||||
if (!noirqdebug)
|
if (!noirqdebug)
|
||||||
note_interrupt(irq, desc, action_ret);
|
note_interrupt(irq, desc, action_ret, regs);
|
||||||
if (likely(!(desc->status & IRQ_PENDING)))
|
if (likely(!(desc->status & IRQ_PENDING)))
|
||||||
break;
|
break;
|
||||||
desc->status &= ~IRQ_PENDING;
|
desc->status &= ~IRQ_PENDING;
|
||||||
|
@@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
|
|||||||
*offset += hose->pci_mem_offset;
|
*offset += hose->pci_mem_offset;
|
||||||
res_bit = IORESOURCE_MEM;
|
res_bit = IORESOURCE_MEM;
|
||||||
} else {
|
} else {
|
||||||
io_offset = (unsigned long)hose->io_base_virt;
|
io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
|
||||||
*offset += io_offset;
|
*offset += io_offset;
|
||||||
res_bit = IORESOURCE_IO;
|
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 */
|
/* found it! construct the final physical address */
|
||||||
if (mmap_state == pci_mmap_io)
|
if (mmap_state == pci_mmap_io)
|
||||||
*offset += hose->io_base_phys - io_offset;
|
*offset += hose->io_base_phys - io_offset;
|
||||||
return rp;
|
return rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_read_irq_line);
|
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 */
|
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||||
|
@@ -270,66 +270,10 @@ endmenu
|
|||||||
|
|
||||||
source "drivers/Kconfig"
|
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
|
if !SUN4
|
||||||
source "drivers/sbus/char/Kconfig"
|
source "drivers/sbus/char/Kconfig"
|
||||||
endif
|
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
|
# This one must be before the filesystem configs. -DaveM
|
||||||
|
|
||||||
menu "Unix98 PTY support"
|
menu "Unix98 PTY support"
|
||||||
|
@@ -7,25 +7,50 @@
|
|||||||
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/acpi.h>
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
|
||||||
#define MMCONFIG_APER_SIZE (256*1024*1024)
|
#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 */
|
/* 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,
|
static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
|
||||||
unsigned int devfn, int reg, int len, u32 *value)
|
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)))
|
if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
|
||||||
return -EINVAL;
|
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,
|
static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
|
||||||
unsigned int devfn, int reg, int len, u32 value)
|
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)))
|
if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = {
|
|||||||
|
|
||||||
static int __init pci_mmcfg_init(void)
|
static int __init pci_mmcfg_init(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
|
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
|
||||||
return 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;
|
return 0;
|
||||||
|
|
||||||
/* Kludge for now. Don't use mmconfig on AMD systems because
|
/* Kludge for now. Don't use mmconfig on AMD systems because
|
||||||
@@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* RED-PEN i386 doesn't do _nocache right now */
|
/* RED-PEN i386 doesn't do _nocache right now */
|
||||||
pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE);
|
pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
|
||||||
if (!pci_mmcfg_virt) {
|
if (pci_mmcfg_virt == NULL) {
|
||||||
printk("PCI: Cannot map mmconfig aperture\n");
|
printk("PCI: Can not allocate memory for mmconfig structures\n");
|
||||||
return 0;
|
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;
|
raw_pci_ops = &pci_mmcfg;
|
||||||
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
|
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);
|
return_VALUE(-ENODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = acpi_bus_scan(*device);
|
result = acpi_bus_start(*device);
|
||||||
|
|
||||||
return_VALUE(result);
|
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)
|
* 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.
|
* to resolve PCI information for ACPI-PCI devices defined in the namespace.
|
||||||
* This typically occurs when resolving PCI operation region information.
|
* This typically occurs when resolving PCI operation region information.
|
||||||
*/
|
*/
|
||||||
#ifdef ACPI_FUTURE_USAGE
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_os_get_pci_id (
|
acpi_get_pci_id (
|
||||||
acpi_handle handle,
|
acpi_handle handle,
|
||||||
struct acpi_pci_id *id)
|
struct acpi_pci_id *id)
|
||||||
{
|
{
|
||||||
@@ -78,7 +77,7 @@ acpi_os_get_pci_id (
|
|||||||
struct acpi_device *device = NULL;
|
struct acpi_device *device = NULL;
|
||||||
struct acpi_pci_data *data = NULL;
|
struct acpi_pci_data *data = NULL;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE("acpi_os_get_pci_id");
|
ACPI_FUNCTION_TRACE("acpi_get_pci_id");
|
||||||
|
|
||||||
if (!id)
|
if (!id)
|
||||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
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);
|
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,
|
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
|
||||||
"Invalid ACPI-PCI context for device %s\n",
|
"Invalid ACPI-PCI context for device %s\n",
|
||||||
acpi_device_bid(device)));
|
acpi_device_bid(device)));
|
||||||
@@ -115,7 +114,7 @@ acpi_os_get_pci_id (
|
|||||||
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
#endif /* ACPI_FUTURE_USAGE */
|
EXPORT_SYMBOL(acpi_get_pci_id);
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -129,6 +128,8 @@ acpi_pci_bind (
|
|||||||
char *pathname = NULL;
|
char *pathname = NULL;
|
||||||
struct acpi_buffer buffer = {0, NULL};
|
struct acpi_buffer buffer = {0, NULL};
|
||||||
acpi_handle handle = NULL;
|
acpi_handle handle = NULL;
|
||||||
|
struct pci_dev *dev;
|
||||||
|
struct pci_bus *bus;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE("acpi_pci_bind");
|
ACPI_FUNCTION_TRACE("acpi_pci_bind");
|
||||||
|
|
||||||
@@ -193,8 +194,20 @@ acpi_pci_bind (
|
|||||||
* Locate matching device in PCI namespace. If it doesn't exist
|
* Locate matching device in PCI namespace. If it doesn't exist
|
||||||
* this typically means that the device isn't currently inserted
|
* this typically means that the device isn't currently inserted
|
||||||
* (e.g. docking station, port replicator, etc.).
|
* (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) {
|
if (!data->dev) {
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||||
"Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
|
"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_add (struct acpi_device *device);
|
||||||
static int acpi_pci_root_remove (struct acpi_device *device, int type);
|
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 = {
|
static struct acpi_driver acpi_pci_root_driver = {
|
||||||
.name = ACPI_PCI_ROOT_DRIVER_NAME,
|
.name = ACPI_PCI_ROOT_DRIVER_NAME,
|
||||||
@@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = {
|
|||||||
.ops = {
|
.ops = {
|
||||||
.add = acpi_pci_root_add,
|
.add = acpi_pci_root_add,
|
||||||
.remove = acpi_pci_root_remove,
|
.remove = acpi_pci_root_remove,
|
||||||
|
.start = acpi_pci_root_start,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -169,6 +171,7 @@ acpi_pci_root_add (
|
|||||||
if (!root)
|
if (!root)
|
||||||
return_VALUE(-ENOMEM);
|
return_VALUE(-ENOMEM);
|
||||||
memset(root, 0, sizeof(struct acpi_pci_root));
|
memset(root, 0, sizeof(struct acpi_pci_root));
|
||||||
|
INIT_LIST_HEAD(&root->node);
|
||||||
|
|
||||||
root->handle = device->handle;
|
root->handle = device->handle;
|
||||||
strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
|
strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
|
||||||
@@ -298,12 +301,31 @@ acpi_pci_root_add (
|
|||||||
root->id.bus);
|
root->id.bus);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (result)
|
if (result) {
|
||||||
|
if (!list_empty(&root->node))
|
||||||
|
list_del(&root->node);
|
||||||
kfree(root);
|
kfree(root);
|
||||||
|
}
|
||||||
|
|
||||||
return_VALUE(result);
|
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
|
static int
|
||||||
acpi_pci_root_remove (
|
acpi_pci_root_remove (
|
||||||
|
@@ -723,7 +723,7 @@ int acpi_processor_device_add(
|
|||||||
return_VALUE(-ENODEV);
|
return_VALUE(-ENODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_bus_scan(*device);
|
acpi_bus_start(*device);
|
||||||
|
|
||||||
pr = acpi_driver_data(*device);
|
pr = acpi_driver_data(*device);
|
||||||
if (!pr)
|
if (!pr)
|
||||||
|
@@ -553,20 +553,29 @@ acpi_bus_driver_init (
|
|||||||
* upon possible configuration and currently allocated resources.
|
* 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) {
|
if (driver->ops.start) {
|
||||||
result = driver->ops.start(device);
|
result = driver->ops.start(device);
|
||||||
if (result && driver->ops.remove)
|
if (result && driver->ops.remove)
|
||||||
driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
|
driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
|
||||||
return_VALUE(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
|
return_VALUE(result);
|
||||||
|
|
||||||
if (driver->ops.scan) {
|
|
||||||
driver->ops.scan(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
return_VALUE(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acpi_driver_attach(struct acpi_driver * drv)
|
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_match(dev, drv)) {
|
||||||
if (!acpi_bus_driver_init(dev, drv)) {
|
if (!acpi_bus_driver_init(dev, drv)) {
|
||||||
|
acpi_start_single_object(dev);
|
||||||
atomic_inc(&drv->references);
|
atomic_inc(&drv->references);
|
||||||
count++;
|
count++;
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
|
||||||
@@ -1009,8 +1019,8 @@ acpi_bus_remove (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
static int
|
||||||
acpi_bus_add (
|
acpi_add_single_object (
|
||||||
struct acpi_device **child,
|
struct acpi_device **child,
|
||||||
struct acpi_device *parent,
|
struct acpi_device *parent,
|
||||||
acpi_handle handle,
|
acpi_handle handle,
|
||||||
@@ -1019,7 +1029,7 @@ acpi_bus_add (
|
|||||||
int result = 0;
|
int result = 0;
|
||||||
struct acpi_device *device = NULL;
|
struct acpi_device *device = NULL;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE("acpi_bus_add");
|
ACPI_FUNCTION_TRACE("acpi_add_single_object");
|
||||||
|
|
||||||
if (!child)
|
if (!child)
|
||||||
return_VALUE(-EINVAL);
|
return_VALUE(-EINVAL);
|
||||||
@@ -1140,7 +1150,7 @@ acpi_bus_add (
|
|||||||
*
|
*
|
||||||
* TBD: Assumes LDM provides driver hot-plug capability.
|
* TBD: Assumes LDM provides driver hot-plug capability.
|
||||||
*/
|
*/
|
||||||
acpi_bus_find_driver(device);
|
result = acpi_bus_find_driver(device);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (!result)
|
if (!result)
|
||||||
@@ -1153,10 +1163,10 @@ end:
|
|||||||
|
|
||||||
return_VALUE(result);
|
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;
|
acpi_status status = AE_OK;
|
||||||
struct acpi_device *parent = NULL;
|
struct acpi_device *parent = NULL;
|
||||||
@@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device *start)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = acpi_bus_add(&child, parent, chandle, type);
|
if (ops->acpi_op_add)
|
||||||
if (ACPI_FAILURE(status))
|
status = acpi_add_single_object(&child, parent,
|
||||||
continue;
|
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
|
* If the device is present, enabled, and functioning then
|
||||||
@@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device *start)
|
|||||||
|
|
||||||
return_VALUE(0);
|
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
|
static int
|
||||||
acpi_bus_trim(struct acpi_device *start,
|
acpi_bus_trim(struct acpi_device *start,
|
||||||
@@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed (
|
|||||||
/*
|
/*
|
||||||
* Enumerate all fixed-feature devices.
|
* Enumerate all fixed-feature devices.
|
||||||
*/
|
*/
|
||||||
if (acpi_fadt.pwr_button == 0)
|
if (acpi_fadt.pwr_button == 0) {
|
||||||
result = acpi_bus_add(&device, acpi_root,
|
result = acpi_add_single_object(&device, acpi_root,
|
||||||
NULL, ACPI_BUS_TYPE_POWER_BUTTON);
|
NULL, ACPI_BUS_TYPE_POWER_BUTTON);
|
||||||
|
if (!result)
|
||||||
|
result = acpi_start_single_object(device);
|
||||||
|
}
|
||||||
|
|
||||||
if (acpi_fadt.sleep_button == 0)
|
if (acpi_fadt.sleep_button == 0) {
|
||||||
result = acpi_bus_add(&device, acpi_root,
|
result = acpi_add_single_object(&device, acpi_root,
|
||||||
NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
|
NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
|
||||||
|
if (!result)
|
||||||
|
result = acpi_start_single_object(device);
|
||||||
|
}
|
||||||
|
|
||||||
return_VALUE(result);
|
return_VALUE(result);
|
||||||
}
|
}
|
||||||
@@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed (
|
|||||||
static int __init acpi_scan_init(void)
|
static int __init acpi_scan_init(void)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
struct acpi_bus_ops ops;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE("acpi_scan_init");
|
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
|
* 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);
|
ACPI_BUS_TYPE_SYSTEM);
|
||||||
if (result)
|
if (result)
|
||||||
goto Done;
|
goto Done;
|
||||||
|
|
||||||
|
result = acpi_start_single_object(acpi_root);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enumerate devices in the ACPI namespace.
|
* Enumerate devices in the ACPI namespace.
|
||||||
*/
|
*/
|
||||||
result = acpi_bus_scan_fixed(acpi_root);
|
result = acpi_bus_scan_fixed(acpi_root);
|
||||||
if (!result)
|
if (!result) {
|
||||||
result = acpi_bus_scan(acpi_root);
|
memset(&ops, 0, sizeof(ops));
|
||||||
|
ops.acpi_op_add = 1;
|
||||||
|
ops.acpi_op_start = 1;
|
||||||
|
result = acpi_bus_scan(acpi_root, &ops);
|
||||||
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
|
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)
|
firmware_timeout_store(struct class *class, const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
loading_timeout = simple_strtol(buf, NULL, 10);
|
loading_timeout = simple_strtol(buf, NULL, 10);
|
||||||
|
if (loading_timeout < 0)
|
||||||
|
loading_timeout = 0;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +140,10 @@ firmware_loading_store(struct class_device *class_dev,
|
|||||||
switch (loading) {
|
switch (loading) {
|
||||||
case 1:
|
case 1:
|
||||||
down(&fw_lock);
|
down(&fw_lock);
|
||||||
|
if (!fw_priv->fw) {
|
||||||
|
up(&fw_lock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
vfree(fw_priv->fw->data);
|
vfree(fw_priv->fw->data);
|
||||||
fw_priv->fw->data = NULL;
|
fw_priv->fw->data = NULL;
|
||||||
fw_priv->fw->size = 0;
|
fw_priv->fw->size = 0;
|
||||||
@@ -178,7 +184,7 @@ firmware_data_read(struct kobject *kobj,
|
|||||||
|
|
||||||
down(&fw_lock);
|
down(&fw_lock);
|
||||||
fw = fw_priv->fw;
|
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;
|
ret_count = -ENODEV;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -238,9 +244,10 @@ firmware_data_write(struct kobject *kobj,
|
|||||||
|
|
||||||
if (!capable(CAP_SYS_RAWIO))
|
if (!capable(CAP_SYS_RAWIO))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
down(&fw_lock);
|
down(&fw_lock);
|
||||||
fw = fw_priv->fw;
|
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;
|
retval = -ENODEV;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -418,7 +425,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
|
|||||||
|
|
||||||
fw_priv = class_get_devdata(class_dev);
|
fw_priv = class_get_devdata(class_dev);
|
||||||
|
|
||||||
if (loading_timeout) {
|
if (loading_timeout > 0) {
|
||||||
fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
|
fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
|
||||||
add_timer(&fw_priv->timeout);
|
add_timer(&fw_priv->timeout);
|
||||||
}
|
}
|
||||||
|
@@ -786,7 +786,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
|
|||||||
|
|
||||||
case CCISS_GETLUNINFO: {
|
case CCISS_GETLUNINFO: {
|
||||||
LogvolInfo_struct luninfo;
|
LogvolInfo_struct luninfo;
|
||||||
int i;
|
|
||||||
|
|
||||||
luninfo.LunID = drv->LunID;
|
luninfo.LunID = drv->LunID;
|
||||||
luninfo.num_opens = drv->usage_count;
|
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)
|
#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,
|
static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
|
||||||
int gfp_mask)
|
int gfp_mask)
|
||||||
{
|
{
|
||||||
struct request *rq = NULL;
|
struct request *rq = NULL;
|
||||||
struct request_list *rl = &q->rq;
|
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)))
|
if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
spin_lock_irq(q->queue_lock);
|
|
||||||
if (rl->count[rw]+1 >= q->nr_requests) {
|
if (rl->count[rw]+1 >= q->nr_requests) {
|
||||||
/*
|
/*
|
||||||
* The queue will fill after this allocation, so set it as
|
* 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
|
* The queue is full and the allocating process is not a
|
||||||
* "batcher", and not exempted by the IO scheduler
|
* "batcher", and not exempted by the IO scheduler
|
||||||
*/
|
*/
|
||||||
spin_unlock_irq(q->queue_lock);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_rq:
|
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->count[rw]++;
|
||||||
rl->starved[rw] = 0;
|
rl->starved[rw] = 0;
|
||||||
if (rl->count[rw] >= queue_congestion_on_threshold(q))
|
if (rl->count[rw] >= queue_congestion_on_threshold(q))
|
||||||
@@ -1941,7 +1949,6 @@ rq_starved:
|
|||||||
if (unlikely(rl->count[rw] == 0))
|
if (unlikely(rl->count[rw] == 0))
|
||||||
rl->starved[rw] = 1;
|
rl->starved[rw] = 1;
|
||||||
|
|
||||||
spin_unlock_irq(q->queue_lock);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1951,21 +1958,23 @@ rq_starved:
|
|||||||
rq_init(q, rq);
|
rq_init(q, rq);
|
||||||
rq->rl = rl;
|
rq->rl = rl;
|
||||||
out:
|
out:
|
||||||
put_io_context(ioc);
|
|
||||||
return rq;
|
return rq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No available requests for this queue, unplug the device and wait for some
|
* No available requests for this queue, unplug the device and wait for some
|
||||||
* requests to become available.
|
* 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,
|
static struct request *get_request_wait(request_queue_t *q, int rw,
|
||||||
struct bio *bio)
|
struct bio *bio)
|
||||||
{
|
{
|
||||||
DEFINE_WAIT(wait);
|
|
||||||
struct request *rq;
|
struct request *rq;
|
||||||
|
|
||||||
do {
|
rq = get_request(q, rw, bio, GFP_NOIO);
|
||||||
|
while (!rq) {
|
||||||
|
DEFINE_WAIT(wait);
|
||||||
struct request_list *rl = &q->rq;
|
struct request_list *rl = &q->rq;
|
||||||
|
|
||||||
prepare_to_wait_exclusive(&rl->wait[rw], &wait,
|
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) {
|
if (!rq) {
|
||||||
struct io_context *ioc;
|
struct io_context *ioc;
|
||||||
|
|
||||||
generic_unplug_device(q);
|
__generic_unplug_device(q);
|
||||||
|
spin_unlock_irq(q->queue_lock);
|
||||||
io_schedule();
|
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.
|
* up to a big batch of them for a small period time.
|
||||||
* See ioc_batching, ioc_set_batching
|
* See ioc_batching, ioc_set_batching
|
||||||
*/
|
*/
|
||||||
ioc = get_io_context(GFP_NOIO);
|
ioc = current_io_context(GFP_NOIO);
|
||||||
ioc_set_batching(q, ioc);
|
ioc_set_batching(q, ioc);
|
||||||
put_io_context(ioc);
|
|
||||||
|
spin_lock_irq(q->queue_lock);
|
||||||
}
|
}
|
||||||
finish_wait(&rl->wait[rw], &wait);
|
finish_wait(&rl->wait[rw], &wait);
|
||||||
} while (!rq);
|
}
|
||||||
|
|
||||||
return 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);
|
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);
|
rq = get_request_wait(q, rw, NULL);
|
||||||
else
|
} else {
|
||||||
rq = get_request(q, rw, NULL, gfp_mask);
|
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;
|
return rq;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(blk_get_request);
|
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)
|
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;
|
int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
|
||||||
unsigned short prio;
|
unsigned short prio;
|
||||||
sector_t sector;
|
sector_t sector;
|
||||||
@@ -2540,14 +2555,9 @@ static int __make_request(request_queue_t *q, struct bio *bio)
|
|||||||
goto end_io;
|
goto end_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
again:
|
|
||||||
spin_lock_irq(q->queue_lock);
|
spin_lock_irq(q->queue_lock);
|
||||||
|
|
||||||
if (elv_queue_empty(q)) {
|
if (unlikely(barrier) || elv_queue_empty(q))
|
||||||
blk_plug_device(q);
|
|
||||||
goto get_rq;
|
|
||||||
}
|
|
||||||
if (barrier)
|
|
||||||
goto get_rq;
|
goto get_rq;
|
||||||
|
|
||||||
el_ret = elv_merge(q, &req, bio);
|
el_ret = elv_merge(q, &req, bio);
|
||||||
@@ -2592,40 +2602,24 @@ again:
|
|||||||
elv_merged_request(q, req);
|
elv_merged_request(q, req);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
/* ELV_NO_MERGE: elevator says don't/can't merge. */
|
||||||
* elevator says don't/can't merge. get new request
|
|
||||||
*/
|
|
||||||
case ELEVATOR_NO_MERGE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
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
|
* After dropping the lock and possibly sleeping here, our request
|
||||||
* if we are doing read ahead and abort instead of blocking for
|
* may now be mergeable after it had proven unmergeable (above).
|
||||||
* a free slot.
|
* 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;
|
req->flags |= REQ_CMD;
|
||||||
|
|
||||||
@@ -2654,10 +2648,11 @@ get_rq:
|
|||||||
req->rq_disk = bio->bi_bdev->bd_disk;
|
req->rq_disk = bio->bi_bdev->bd_disk;
|
||||||
req->start_time = jiffies;
|
req->start_time = jiffies;
|
||||||
|
|
||||||
|
spin_lock_irq(q->queue_lock);
|
||||||
|
if (elv_queue_empty(q))
|
||||||
|
blk_plug_device(q);
|
||||||
add_request(q, req);
|
add_request(q, req);
|
||||||
out:
|
out:
|
||||||
if (freereq)
|
|
||||||
__blk_put_request(q, freereq);
|
|
||||||
if (sync)
|
if (sync)
|
||||||
__generic_unplug_device(q);
|
__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 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.
|
* This returned IO context doesn't have a specifically elevated refcount,
|
||||||
* But weird things happen, so we disable local interrupts to ensure exclusive
|
* but since the current task itself holds a reference, the context can be
|
||||||
* access to *current.
|
* 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;
|
struct task_struct *tsk = current;
|
||||||
unsigned long flags;
|
|
||||||
struct io_context *ret;
|
struct io_context *ret;
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
ret = tsk->io_context;
|
ret = tsk->io_context;
|
||||||
if (ret)
|
if (likely(ret))
|
||||||
goto out;
|
return ret;
|
||||||
|
|
||||||
local_irq_restore(flags);
|
|
||||||
|
|
||||||
ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
|
ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
|
||||||
if (ret) {
|
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->nr_batch_requests = 0; /* because this is 0 */
|
||||||
ret->aic = NULL;
|
ret->aic = NULL;
|
||||||
ret->cic = NULL;
|
ret->cic = NULL;
|
||||||
|
tsk->io_context = ret;
|
||||||
local_irq_save(flags);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* very unlikely, someone raced with us in setting up the task
|
|
||||||
* io context. free new context and just grab a reference.
|
|
||||||
*/
|
|
||||||
if (!tsk->io_context)
|
|
||||||
tsk->io_context = ret;
|
|
||||||
else {
|
|
||||||
kmem_cache_free(iocontext_cachep, ret);
|
|
||||||
ret = tsk->io_context;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
atomic_inc(&ret->refcount);
|
|
||||||
local_irq_restore(flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 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);
|
EXPORT_SYMBOL(get_io_context);
|
||||||
|
|
||||||
void copy_io_context(struct io_context **pdst, struct io_context **psrc)
|
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,
|
.subvendor = PCI_ANY_ID,
|
||||||
.subdevice = 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;
|
long seqid;
|
||||||
int broadcast = 0;
|
int broadcast = 0;
|
||||||
|
|
||||||
if (addr->channel > IPMI_NUM_CHANNELS) {
|
if (addr->channel >= IPMI_MAX_CHANNELS) {
|
||||||
spin_lock_irqsave(&intf->counter_lock, flags);
|
spin_lock_irqsave(&intf->counter_lock, flags);
|
||||||
intf->sent_invalid_commands++;
|
intf->sent_invalid_commands++;
|
||||||
spin_unlock_irqrestore(&intf->counter_lock, flags);
|
spin_unlock_irqrestore(&intf->counter_lock, flags);
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
|
@@ -451,7 +451,7 @@ static int __init moxa_init(void)
|
|||||||
int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
|
int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < n) {
|
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))
|
if (pci_enable_device(p))
|
||||||
continue;
|
continue;
|
||||||
|
@@ -1095,7 +1095,7 @@ static int __init rio_init(void)
|
|||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
/* First look for the JET devices: */
|
/* 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,
|
PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
|
||||||
pdev))) {
|
pdev))) {
|
||||||
if (pci_enable_device(pdev)) continue;
|
if (pci_enable_device(pdev)) continue;
|
||||||
@@ -1169,7 +1169,7 @@ static int __init rio_init(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Then look for the older RIO/PCI devices: */
|
/* 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,
|
PCI_DEVICE_ID_SPECIALIX_RIO,
|
||||||
pdev))) {
|
pdev))) {
|
||||||
if (pci_enable_device(pdev)) continue;
|
if (pci_enable_device(pdev)) continue;
|
||||||
|
@@ -78,6 +78,7 @@
|
|||||||
#include <linux/sysctl.h>
|
#include <linux/sysctl.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/bcd.h>
|
#include <linux/bcd.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
#include <asm/current.h>
|
#include <asm/current.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
@@ -894,7 +895,6 @@ static int __init rtc_init(void)
|
|||||||
struct proc_dir_entry *ent;
|
struct proc_dir_entry *ent;
|
||||||
#if defined(__alpha__) || defined(__mips__)
|
#if defined(__alpha__) || defined(__mips__)
|
||||||
unsigned int year, ctrl;
|
unsigned int year, ctrl;
|
||||||
unsigned long uip_watchdog;
|
|
||||||
char *guess = NULL;
|
char *guess = NULL;
|
||||||
#endif
|
#endif
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
@@ -1000,12 +1000,8 @@ no_irq:
|
|||||||
/* Each operating system on an Alpha uses its own epoch.
|
/* Each operating system on an Alpha uses its own epoch.
|
||||||
Let's try to guess which one we are using now. */
|
Let's try to guess which one we are using now. */
|
||||||
|
|
||||||
uip_watchdog = jiffies;
|
|
||||||
if (rtc_is_updating() != 0)
|
if (rtc_is_updating() != 0)
|
||||||
while (jiffies - uip_watchdog < 2*HZ/100) {
|
msleep(20);
|
||||||
barrier();
|
|
||||||
cpu_relax();
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irq(&rtc_lock);
|
spin_lock_irq(&rtc_lock);
|
||||||
year = CMOS_READ(RTC_YEAR);
|
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)
|
void rtc_get_rtc_time(struct rtc_time *rtc_tm)
|
||||||
{
|
{
|
||||||
unsigned long uip_watchdog = jiffies;
|
|
||||||
unsigned char ctrl;
|
unsigned char ctrl;
|
||||||
#ifdef CONFIG_MACH_DECSTATION
|
#ifdef CONFIG_MACH_DECSTATION
|
||||||
unsigned int real_year;
|
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
|
* 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.
|
* 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
|
* If you need to know *exactly* when a second has started, enable
|
||||||
* periodic update complete interrupts, (via ioctl) and then
|
* 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)
|
if (rtc_is_updating() != 0)
|
||||||
while (jiffies - uip_watchdog < 2*HZ/100) {
|
msleep(20);
|
||||||
barrier();
|
|
||||||
cpu_relax();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only the values that we read from the RTC are set. We leave
|
* 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
|
static int __init
|
||||||
tipar_setup(char *str)
|
tipar_setup(char *str)
|
||||||
{
|
{
|
||||||
int ints[2];
|
int ints[3];
|
||||||
|
|
||||||
str = get_options(str, ARRAY_SIZE(ints), ints);
|
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);
|
ld = tty_ldisc_ref(tty);
|
||||||
switch (arg) {
|
switch (arg) {
|
||||||
case TCIFLUSH:
|
case TCIFLUSH:
|
||||||
if (ld->flush_buffer)
|
if (ld && ld->flush_buffer)
|
||||||
ld->flush_buffer(tty);
|
ld->flush_buffer(tty);
|
||||||
break;
|
break;
|
||||||
case TCIOFLUSH:
|
case TCIOFLUSH:
|
||||||
if (ld->flush_buffer)
|
if (ld && ld->flush_buffer)
|
||||||
ld->flush_buffer(tty);
|
ld->flush_buffer(tty);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case TCOFLUSH:
|
case TCOFLUSH:
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
#include <linux/signal.h>
|
#include <linux/signal.h>
|
||||||
|
#include <linux/timex.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
@@ -386,7 +387,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
|
|||||||
if (!perm)
|
if (!perm)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (arg)
|
if (arg)
|
||||||
arg = 1193182 / arg;
|
arg = CLOCK_TICK_RATE / arg;
|
||||||
kd_mksound(arg, 0);
|
kd_mksound(arg, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -403,7 +404,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
|
|||||||
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
|
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
|
||||||
count = ticks ? (arg & 0xffff) : 0;
|
count = ticks ? (arg & 0xffff) : 0;
|
||||||
if (count)
|
if (count)
|
||||||
count = 1193182 / count;
|
count = CLOCK_TICK_RATE / count;
|
||||||
kd_mksound(count, ticks);
|
kd_mksound(count, ticks);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -162,7 +162,7 @@ ixp2000_wdt_release(struct inode *inode, struct file *file)
|
|||||||
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
|
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
|
||||||
wdt_disable();
|
wdt_disable();
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
|
printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
|
||||||
"timer will not stop\n");
|
"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)) {
|
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
|
||||||
wdt_disable();
|
wdt_disable();
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
|
printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
|
||||||
"timer will not stop\n");
|
"timer will not stop\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ static didd_adapter_change_notification_t\
|
|||||||
Array to held adapter information
|
Array to held adapter information
|
||||||
-------------------------------------------------------------------------- */
|
-------------------------------------------------------------------------- */
|
||||||
static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS];
|
static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS];
|
||||||
dword Adapters = 0; /* Number of adapters */
|
static dword Adapters = 0; /* Number of adapters */
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
Shadow IDI_DIMAINT
|
Shadow IDI_DIMAINT
|
||||||
and 'shadow' debug stuff
|
and 'shadow' debug stuff
|
||||||
|
@@ -312,7 +312,7 @@ wait_busy(hfc4s8s_hw * a)
|
|||||||
/* function to read critical counter registers that */
|
/* function to read critical counter registers that */
|
||||||
/* may be udpated by the chip during read */
|
/* may be udpated by the chip during read */
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
static volatile u_char
|
static u_char
|
||||||
Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
|
Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
|
||||||
{
|
{
|
||||||
u_char ref8;
|
u_char ref8;
|
||||||
@@ -324,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
|
|||||||
return in8;
|
return in8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile int
|
static int
|
||||||
Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
|
Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
|
||||||
{
|
{
|
||||||
int ref16;
|
int ref16;
|
||||||
@@ -1465,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
|
|||||||
/******************************************/
|
/******************************************/
|
||||||
/* disable memory mapped ports / io ports */
|
/* disable memory mapped ports / io ports */
|
||||||
/******************************************/
|
/******************************************/
|
||||||
void
|
static void
|
||||||
release_pci_ports(hfc4s8s_hw * hw)
|
release_pci_ports(hfc4s8s_hw * hw)
|
||||||
{
|
{
|
||||||
pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
|
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 */
|
/* enable memory mapped ports / io ports */
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
void
|
static void
|
||||||
enable_pci_ports(hfc4s8s_hw * hw)
|
enable_pci_ports(hfc4s8s_hw * hw)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
|
#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
|
||||||
|
@@ -42,6 +42,8 @@ typedef struct _hycapi_appl {
|
|||||||
|
|
||||||
static hycapi_appl hycapi_applications[CAPI_MAXAPPL];
|
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)
|
static inline int _hycapi_appCheck(int app_id, int ctrl_no)
|
||||||
{
|
{
|
||||||
if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
|
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
|
Kernel-Capi callback reset_ctr
|
||||||
******************************/
|
******************************/
|
||||||
|
|
||||||
void
|
static void
|
||||||
hycapi_reset_ctr(struct capi_ctr *ctrl)
|
hycapi_reset_ctr(struct capi_ctr *ctrl)
|
||||||
{
|
{
|
||||||
hycapictrl_info *cinfo = ctrl->driverdata;
|
hycapictrl_info *cinfo = ctrl->driverdata;
|
||||||
@@ -73,7 +75,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl)
|
|||||||
Kernel-Capi callback remove_ctr
|
Kernel-Capi callback remove_ctr
|
||||||
******************************/
|
******************************/
|
||||||
|
|
||||||
void
|
static void
|
||||||
hycapi_remove_ctr(struct capi_ctr *ctrl)
|
hycapi_remove_ctr(struct capi_ctr *ctrl)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -215,7 +217,7 @@ Error-checking is done for CAPI-compliance.
|
|||||||
The application is recorded in the internal list.
|
The application is recorded in the internal list.
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
void
|
static void
|
||||||
hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl,
|
hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl,
|
||||||
capi_register_params *rp)
|
capi_register_params *rp)
|
||||||
{
|
{
|
||||||
@@ -291,7 +293,7 @@ Release the application from the internal list an remove it's
|
|||||||
registration at controller-level
|
registration at controller-level
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
void
|
static void
|
||||||
hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
|
hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
|
||||||
{
|
{
|
||||||
int chk;
|
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;
|
__u16 appl_id;
|
||||||
int _len, _len2;
|
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,
|
static int hycapi_read_proc(char *page, char **start, off_t off,
|
||||||
int count, int *eof, struct capi_ctr *ctrl)
|
int count, int *eof, struct capi_ctr *ctrl)
|
||||||
{
|
{
|
||||||
hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
|
hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
|
||||||
hysdn_card *card = cinfo->card;
|
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
|
#ifdef HYCAPI_PRINTFNAMES
|
||||||
printk(KERN_NOTICE "hycapi_load_firmware\n");
|
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);
|
hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
|
||||||
#ifdef HYCAPI_PRINTFNAMES
|
#ifdef HYCAPI_PRINTFNAMES
|
||||||
|
@@ -53,7 +53,7 @@ struct boot_data {
|
|||||||
/* to be called at start of POF file reading, */
|
/* to be called at start of POF file reading, */
|
||||||
/* before starting any decryption on any POF record. */
|
/* before starting any decryption on any POF record. */
|
||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
void
|
static void
|
||||||
StartDecryption(struct boot_data *boot)
|
StartDecryption(struct boot_data *boot)
|
||||||
{
|
{
|
||||||
boot->Cryptor = CRYPT_STARTTERM;
|
boot->Cryptor = CRYPT_STARTTERM;
|
||||||
@@ -66,7 +66,7 @@ StartDecryption(struct boot_data *boot)
|
|||||||
/* to HI and LO boot loader and (all) seq tags, because */
|
/* to HI and LO boot loader and (all) seq tags, because */
|
||||||
/* global Cryptor is started for whole POF. */
|
/* global Cryptor is started for whole POF. */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
void
|
static void
|
||||||
DecryptBuf(struct boot_data *boot, int cnt)
|
DecryptBuf(struct boot_data *boot, int cnt)
|
||||||
{
|
{
|
||||||
uchar *bufp = boot->buf.BootBuf;
|
uchar *bufp = boot->buf.BootBuf;
|
||||||
|
@@ -227,7 +227,6 @@ typedef struct hycapictrl_info hycapictrl_info;
|
|||||||
/*****************/
|
/*****************/
|
||||||
/* exported vars */
|
/* exported vars */
|
||||||
/*****************/
|
/*****************/
|
||||||
extern int cardmax; /* number of found cards */
|
|
||||||
extern hysdn_card *card_root; /* pointer to first card */
|
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 */
|
/* hysdn_proclog.c */
|
||||||
extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */
|
extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */
|
||||||
extern void hysdn_proclog_release(hysdn_card *); /* deinit 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_addlog(hysdn_card *, char *,...); /* output data to log */
|
||||||
extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int); /* output card 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_create(hysdn_card *); /* create a new capi device */
|
||||||
extern int hycapi_capi_release(hysdn_card *); /* delete the device */
|
extern int hycapi_capi_release(hysdn_card *); /* delete the device */
|
||||||
extern int hycapi_capi_stop(hysdn_card *card); /* suspend */
|
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_rx_capipkt(hysdn_card * card, uchar * buf, word len);
|
||||||
extern void hycapi_tx_capiack(hysdn_card * card);
|
extern void hycapi_tx_capiack(hysdn_card * card);
|
||||||
extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
|
extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
|
||||||
|
@@ -34,7 +34,7 @@ MODULE_AUTHOR("Werner Cornelius");
|
|||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
|
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 */
|
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 */
|
/* the proc subdir for the interface is defined in the procconf module */
|
||||||
extern struct proc_dir_entry *hysdn_proc_entry;
|
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 */
|
/* structure keeping ascii log for device output */
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
@@ -93,7 +95,7 @@ hysdn_addlog(hysdn_card * card, char *fmt,...)
|
|||||||
/* opened for read got the contents. */
|
/* opened for read got the contents. */
|
||||||
/* Flushes buffers not longer in use. */
|
/* Flushes buffers not longer in use. */
|
||||||
/********************************************/
|
/********************************************/
|
||||||
void
|
static void
|
||||||
put_log_buffer(hysdn_card * card, char *cp)
|
put_log_buffer(hysdn_card * card, char *cp)
|
||||||
{
|
{
|
||||||
struct log_data *ib;
|
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))
|
if (atomic_dec_and_test(&rdev->mddev->pending_writes))
|
||||||
wake_up(&rdev->mddev->sb_wait);
|
wake_up(&rdev->mddev->sb_wait);
|
||||||
|
bio_put(bio);
|
||||||
return 0;
|
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
|
zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
|
||||||
zr36067-objs := zoran_procfs.o zoran_device.o \
|
zr36067-objs := zoran_procfs.o zoran_device.o \
|
||||||
zoran_driver.o zoran_card.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_DEV) += videodev.o v4l2-common.o v4l1-compat.o
|
||||||
|
|
||||||
obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.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
|
bttv - Bt848 frame grabber driver
|
||||||
|
|
||||||
@@ -76,6 +76,9 @@ static unsigned int whitecrush_upper = 0xCF;
|
|||||||
static unsigned int whitecrush_lower = 0x7F;
|
static unsigned int whitecrush_lower = 0x7F;
|
||||||
static unsigned int vcr_hack = 0;
|
static unsigned int vcr_hack = 0;
|
||||||
static unsigned int irq_iswitch = 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) */
|
/* API features (turn on/off stuff for testing) */
|
||||||
static unsigned int v4l2 = 1;
|
static unsigned int v4l2 = 1;
|
||||||
@@ -106,6 +109,9 @@ module_param(adc_crush, int, 0444);
|
|||||||
module_param(whitecrush_upper, int, 0444);
|
module_param(whitecrush_upper, int, 0444);
|
||||||
module_param(whitecrush_lower, int, 0444);
|
module_param(whitecrush_lower, int, 0444);
|
||||||
module_param(vcr_hack, 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);
|
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(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(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(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_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
|
||||||
MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
|
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_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5)
|
||||||
#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6)
|
#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_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 = {
|
static const struct v4l2_queryctrl no_ctl = {
|
||||||
.name = "42",
|
.name = "42",
|
||||||
@@ -618,8 +630,32 @@ static const struct v4l2_queryctrl bttv_ctls[] = {
|
|||||||
.step = 1,
|
.step = 1,
|
||||||
.default_value = 0x7F,
|
.default_value = 0x7F,
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
.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);
|
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;
|
btv->saturation = color;
|
||||||
|
|
||||||
/* 0-511 for the color */
|
/* 0-511 for the color */
|
||||||
val_u = color >> 7;
|
val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
|
||||||
val_v = ((color>>7)*180L)/254;
|
val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
|
||||||
hibits = (val_u >> 7) & 2;
|
hibits = (val_u >> 7) & 2;
|
||||||
hibits |= (val_v >> 8) & 1;
|
hibits |= (val_v >> 8) & 1;
|
||||||
btwrite(val_u & 0xff, BT848_SAT_U_LO);
|
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:
|
case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
|
||||||
c->value = btv->opt_whitecrush_lower;
|
c->value = btv->opt_whitecrush_lower;
|
||||||
break;
|
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:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1247,6 +1292,18 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
|
|||||||
btv->opt_whitecrush_lower = c->value;
|
btv->opt_whitecrush_lower = c->value;
|
||||||
btwrite(c->value, BT848_WC_DOWN);
|
btwrite(c->value, BT848_WC_DOWN);
|
||||||
break;
|
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:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -3117,11 +3174,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
memset(v,0,sizeof(*v));
|
memset(v,0,sizeof(*v));
|
||||||
strcpy(v->name, "Radio");
|
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);
|
bttv_call_i2c_clients(btv,cmd,v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3876,6 +3928,9 @@ static int __devinit bttv_probe(struct pci_dev *dev,
|
|||||||
btv->opt_vcr_hack = vcr_hack;
|
btv->opt_vcr_hack = vcr_hack;
|
||||||
btv->opt_whitecrush_upper = whitecrush_upper;
|
btv->opt_whitecrush_upper = whitecrush_upper;
|
||||||
btv->opt_whitecrush_lower = whitecrush_lower;
|
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 */
|
/* fill struct bttv with some useful defaults */
|
||||||
btv->init.btv = btv;
|
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
|
bttv - Bt848 frame grabber driver
|
||||||
|
|
||||||
@@ -326,6 +326,9 @@ struct bttv {
|
|||||||
int opt_vcr_hack;
|
int opt_vcr_hack;
|
||||||
int opt_whitecrush_upper;
|
int opt_whitecrush_upper;
|
||||||
int opt_whitecrush_lower;
|
int opt_whitecrush_lower;
|
||||||
|
int opt_uv_ratio;
|
||||||
|
int opt_full_luma_range;
|
||||||
|
int opt_coring;
|
||||||
|
|
||||||
/* radio data/state */
|
/* radio data/state */
|
||||||
int has_radio;
|
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
|
* i2c tv tuner chip device driver
|
||||||
* controls microtune tuners, mt2032 + mt2050 at the moment.
|
* 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;
|
int if2 = t->radio_if2;
|
||||||
|
|
||||||
// per Manual for FM tuning: first if center freq. 1085 MHz
|
// per Manual for FM tuning: first if center freq. 1085 MHz
|
||||||
mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
|
mt2032_set_if_freq(c, freq * 1000 / 16,
|
||||||
1085*1000*1000,if2,if2,if2);
|
1085*1000*1000,if2,if2,if2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
|
// 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
|
* i2c tv tuner chip device driver
|
||||||
* controls the philips tda8290+75 tuner chip combo.
|
* 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_enable_bridge[2] = { 0x21, 0xC0 };
|
||||||
static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 };
|
static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 };
|
||||||
static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
|
static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
|
||||||
0x7C, 0x04, 0xA3, 0x3F,
|
0xfC, 0x04, 0xA3, 0x3F,
|
||||||
0x2A, 0x04, 0xFF, 0x00,
|
0x2A, 0x04, 0xFF, 0x00,
|
||||||
0x00, 0x40 };
|
0x00, 0x40 };
|
||||||
static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
|
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)
|
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[0] = 0;
|
||||||
t->i2c_set_freq[1] = (unsigned char)(N>>8);
|
t->i2c_set_freq[1] = (unsigned char)(N>>8);
|
||||||
t->i2c_set_freq[2] = (unsigned char) N;
|
t->i2c_set_freq[2] = (unsigned char) N;
|
||||||
t->i2c_set_freq[3] = 0x40;
|
t->i2c_set_freq[3] = 0x40;
|
||||||
t->i2c_set_freq[4] = 0x52;
|
t->i2c_set_freq[4] = 0x52;
|
||||||
t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq);
|
t->i2c_set_freq[5] = get_freq_entry(band_table, freq);
|
||||||
t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq);
|
t->i2c_set_freq[6] = get_freq_entry(agc_table, freq);
|
||||||
t->i2c_set_freq[7] = 0x8f;
|
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)
|
if (t->radio_mode == V4L2_TUNER_MODE_MONO)
|
||||||
norm = &radio_mono;
|
norm = &radio_mono;
|
||||||
else
|
else
|
||||||
norm = &radio_stereo;
|
norm = &radio_stereo;
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
|
for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
|
||||||
if (tvnorms[i].std & t->std) {
|
if (tvnorms[i].std & t->std) {
|
||||||
@@ -566,7 +566,6 @@ static int tda9887_configure(struct tda9887 *t)
|
|||||||
if (UNSET != t->pinnacle_id) {
|
if (UNSET != t->pinnacle_id) {
|
||||||
tda9887_set_pinnacle(t,buf);
|
tda9887_set_pinnacle(t,buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
tda9887_set_config(t,buf);
|
tda9887_set_config(t,buf);
|
||||||
tda9887_set_insmod(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->pinnacle_id = UNSET;
|
||||||
t->radio_mode = V4L2_TUNER_MODE_STEREO;
|
t->radio_mode = V4L2_TUNER_MODE_STEREO;
|
||||||
|
|
||||||
i2c_set_clientdata(&t->client, t);
|
i2c_set_clientdata(&t->client, t);
|
||||||
i2c_attach_client(&t->client);
|
i2c_attach_client(&t->client);
|
||||||
|
|
||||||
return 0;
|
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
|
* i2c tv tuner chip device driver
|
||||||
* core core, i.e. kernel interfaces, registering and so on
|
* 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
|
* comment line bellow to return to old behavor, where only one I2C device is supported
|
||||||
*/
|
*/
|
||||||
#define CONFIG_TUNER_MULTI_I2C /**/
|
|
||||||
|
|
||||||
#define UNSET (-1U)
|
#define UNSET (-1U)
|
||||||
|
|
||||||
@@ -58,9 +57,7 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
|
|||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
static int this_adap;
|
static int this_adap;
|
||||||
#ifdef CONFIG_TUNER_MULTI_I2C
|
|
||||||
static unsigned short first_tuner, tv_tuner, radio_tuner;
|
static unsigned short first_tuner, tv_tuner, radio_tuner;
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct i2c_driver driver;
|
static struct i2c_driver driver;
|
||||||
static struct i2c_client client_template;
|
static struct i2c_client client_template;
|
||||||
@@ -81,26 +78,9 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
|
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",
|
tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
|
||||||
freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
|
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);
|
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");
|
tuner_info("no radio tuning for this one, sorry.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
|
if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) {
|
||||||
if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
|
if (tuner_debug)
|
||||||
/* V4L2_TUNER_CAP_LOW frequency */
|
tuner_info("radio freq step 62.5Hz (%d.%06d)\n",
|
||||||
if (t->type == TUNER_TEA5767) {
|
freq/16000,freq%16000*1000/16);
|
||||||
tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
|
t->radio_freq(c,freq);
|
||||||
t->radio_freq(c,freq>>10);
|
} else {
|
||||||
return;
|
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("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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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)
|
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)
|
static void set_type(struct i2c_client *c, unsigned int type)
|
||||||
{
|
{
|
||||||
struct tuner *t = i2c_get_clientdata(c);
|
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 */
|
/* sanity check */
|
||||||
if (type == UNSET || type == TUNER_ABSENT)
|
if (type == UNSET || type == TUNER_ABSENT)
|
||||||
return;
|
return;
|
||||||
@@ -179,8 +146,8 @@ static void set_type(struct i2c_client *c, unsigned int type)
|
|||||||
t->type = type;
|
t->type = type;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (t->initialized)
|
if ((t->initialized) && (t->type == type))
|
||||||
/* run only once */
|
/* run only once except type change Hac 04/05*/
|
||||||
return;
|
return;
|
||||||
|
|
||||||
t->initialized = 1;
|
t->initialized = 1;
|
||||||
@@ -193,25 +160,42 @@ static void set_type(struct i2c_client *c, unsigned int type)
|
|||||||
case TUNER_PHILIPS_TDA8290:
|
case TUNER_PHILIPS_TDA8290:
|
||||||
tda8290_init(c);
|
tda8290_init(c);
|
||||||
break;
|
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:
|
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);
|
default_tuner_init(c);
|
||||||
break;
|
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) { \
|
#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);
|
tuner_info ("Cmd %s accepted to "tun"\n",cmd);
|
||||||
#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \
|
#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \
|
||||||
CHECK_ADDR(radio_tuner,cmd,"radio") } else \
|
CHECK_ADDR(radio_tuner,cmd,"radio") } else \
|
||||||
{ CHECK_ADDR(tv_tuner,cmd,"TV"); }
|
{ 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)
|
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);
|
set_type(c,tun_addr->type);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char pal[] = "-";
|
static char pal[] = "-";
|
||||||
module_param_string(pal, pal, sizeof(pal), 0644);
|
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;
|
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 */
|
/* by default, first I2C card is both tv and radio tuner */
|
||||||
if (this_adap == 0) {
|
if (this_adap == 0) {
|
||||||
first_tuner = addr;
|
first_tuner = addr;
|
||||||
tv_tuner = addr;
|
tv_tuner = addr;
|
||||||
radio_tuner = addr;
|
radio_tuner = addr;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
this_adap++;
|
this_adap++;
|
||||||
|
|
||||||
client_template.adapter = 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);
|
i2c_set_clientdata(&t->i2c, t);
|
||||||
t->type = UNSET;
|
t->type = UNSET;
|
||||||
t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */
|
t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */
|
||||||
|
t->audmode = V4L2_TUNER_MODE_STEREO;
|
||||||
|
|
||||||
i2c_attach_client(&t->i2c);
|
i2c_attach_client(&t->i2c);
|
||||||
tuner_info("chip found @ 0x%x (%s)\n",
|
tuner_info("chip found @ 0x%x (%s)\n",
|
||||||
@@ -325,11 +302,9 @@ static int tuner_probe(struct i2c_adapter *adap)
|
|||||||
}
|
}
|
||||||
this_adap = 0;
|
this_adap = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_TUNER_MULTI_I2C
|
|
||||||
first_tuner = 0;
|
first_tuner = 0;
|
||||||
tv_tuner = 0;
|
tv_tuner = 0;
|
||||||
radio_tuner = 0;
|
radio_tuner = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (adap->class & I2C_CLASS_TV_ANALOG)
|
if (adap->class & I2C_CLASS_TV_ANALOG)
|
||||||
return i2c_probe(adap, &addr_data, tuner_attach);
|
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;
|
t->radio_if2 = 41300 * 1000;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* --- v4l ioctls --- */
|
/* --- v4l ioctls --- */
|
||||||
/* take care: bttv does userspace copying, we'll get a
|
/* take care: bttv does userspace copying, we'll get a
|
||||||
kernel pointer here... */
|
kernel pointer here... */
|
||||||
@@ -440,11 +414,18 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||||||
vt->signal = t->has_signal(client);
|
vt->signal = t->has_signal(client);
|
||||||
if (t->is_stereo) {
|
if (t->is_stereo) {
|
||||||
if (t->is_stereo(client))
|
if (t->is_stereo(client))
|
||||||
vt-> flags |= VIDEO_TUNER_STEREO_ON;
|
vt->flags |= VIDEO_TUNER_STEREO_ON;
|
||||||
else
|
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->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;
|
return 0;
|
||||||
@@ -510,20 +491,46 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||||||
tuner -> signal = t->has_signal(client);
|
tuner -> signal = t->has_signal(client);
|
||||||
if (t->is_stereo) {
|
if (t->is_stereo) {
|
||||||
if (t->is_stereo(client)) {
|
if (t->is_stereo(client)) {
|
||||||
tuner -> capability |= V4L2_TUNER_CAP_STEREO;
|
tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
|
||||||
tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO;
|
|
||||||
} else {
|
} 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;
|
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:
|
default:
|
||||||
tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
|
tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
|
||||||
/* nothing */
|
/* 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
|
* i2c tv tuner chip device driver
|
||||||
* controls all those simple 4-control-bytes style tuners.
|
* controls all those simple 4-control-bytes style tuners.
|
||||||
@@ -207,28 +207,27 @@ static struct tunertype tuners[] = {
|
|||||||
{ "LG PAL (TAPE series)", LGINNOTEK, PAL,
|
{ "LG PAL (TAPE series)", LGINNOTEK, PAL,
|
||||||
16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
|
16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
|
||||||
|
|
||||||
{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
|
{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
|
||||||
16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
|
16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
|
||||||
{ "Philips FQ1236A MK4", Philips, NTSC,
|
{ "Philips FQ1236A MK4", Philips, NTSC,
|
||||||
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
|
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
|
||||||
|
|
||||||
/* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
|
/* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
|
||||||
{ "Ymec TVision TVF-8531MF", Philips, NTSC,
|
{ "Ymec TVision TVF-8531MF", Philips, NTSC,
|
||||||
16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
|
16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
|
||||||
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
|
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
|
||||||
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
|
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
|
||||||
|
|
||||||
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
|
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
|
||||||
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
|
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
|
||||||
{ "Tena TNF9533-D/IF", LGINNOTEK, PAL,
|
/* Should work for TNF9533-D/IF, TNF9533-B/DF */
|
||||||
16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623},
|
{ "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,
|
{ 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);
|
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;
|
int rc;
|
||||||
|
|
||||||
tun=&tuners[t->type];
|
tun=&tuners[t->type];
|
||||||
div = freq + (int)(16*10.7);
|
div = (freq / 1000) + (int)(16*10.7);
|
||||||
buffer[2] = tun->config;
|
buffer[2] = tun->config;
|
||||||
|
|
||||||
switch (t->type) {
|
switch (t->type) {
|
||||||
case TUNER_TENA_9533_DI:
|
case TUNER_TENA_9533_DI:
|
||||||
case TUNER_YMEC_TVF_5533MF:
|
case TUNER_YMEC_TVF_5533MF:
|
||||||
|
|
||||||
/*These values are empirically determinated */
|
/*These values are empirically determinated */
|
||||||
div = (freq*122)/16 - 20;
|
div = (freq * 122) / 16000 - 20;
|
||||||
buffer[2] = 0x88; /* could be also 0x80 */
|
buffer[2] = 0x88; /* could be also 0x80 */
|
||||||
buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
|
buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
|
||||||
break;
|
break;
|
||||||
case TUNER_PHILIPS_FM1216ME_MK3:
|
case TUNER_PHILIPS_FM1216ME_MK3:
|
||||||
case TUNER_PHILIPS_FM1236_MK3:
|
case TUNER_PHILIPS_FM1236_MK3:
|
||||||
|
case TUNER_PHILIPS_FMD1216ME_MK3:
|
||||||
buffer[3] = 0x19;
|
buffer[3] = 0x19;
|
||||||
break;
|
break;
|
||||||
case TUNER_PHILIPS_FM1256_IH3:
|
case TUNER_PHILIPS_FM1256_IH3:
|
||||||
div = (20 * freq)/16 + 333 * 2;
|
div = (20 * freq) / 16000 + 333 * 2;
|
||||||
buffer[2] = 0x80;
|
buffer[2] = 0x80;
|
||||||
buffer[3] = 0x19;
|
buffer[3] = 0x19;
|
||||||
break;
|
break;
|
||||||
@@ -505,6 +504,7 @@ int default_tuner_init(struct i2c_client *c)
|
|||||||
t->radio_freq = default_set_radio_freq;
|
t->radio_freq = default_set_radio_freq;
|
||||||
t->has_signal = tuner_signal;
|
t->has_signal = tuner_signal;
|
||||||
t->is_stereo = tuner_stereo;
|
t->is_stereo = tuner_stereo;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -364,9 +364,7 @@ static struct pci_driver mptfc_driver = {
|
|||||||
.id_table = mptfc_pci_table,
|
.id_table = mptfc_pci_table,
|
||||||
.probe = mptfc_probe,
|
.probe = mptfc_probe,
|
||||||
.remove = __devexit_p(mptscsih_remove),
|
.remove = __devexit_p(mptscsih_remove),
|
||||||
.driver = {
|
.shutdown = mptscsih_shutdown,
|
||||||
.shutdown = mptscsih_shutdown,
|
|
||||||
},
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.suspend = mptscsih_suspend,
|
.suspend = mptscsih_suspend,
|
||||||
.resume = mptscsih_resume,
|
.resume = mptscsih_resume,
|
||||||
|
@@ -170,7 +170,7 @@ static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void mptscsih_remove(struct pci_dev *);
|
void mptscsih_remove(struct pci_dev *);
|
||||||
void mptscsih_shutdown(struct device *);
|
void mptscsih_shutdown(struct pci_dev *);
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
|
int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
|
||||||
int mptscsih_resume(struct pci_dev *pdev);
|
int mptscsih_resume(struct pci_dev *pdev);
|
||||||
@@ -988,7 +988,7 @@ mptscsih_remove(struct pci_dev *pdev)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mptscsih_shutdown(&pdev->dev);
|
mptscsih_shutdown(pdev);
|
||||||
|
|
||||||
sz1=0;
|
sz1=0;
|
||||||
|
|
||||||
@@ -1026,9 +1026,9 @@ mptscsih_remove(struct pci_dev *pdev)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void
|
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;
|
struct Scsi_Host *host = ioc->sh;
|
||||||
MPT_SCSI_HOST *hd;
|
MPT_SCSI_HOST *hd;
|
||||||
|
|
||||||
@@ -1054,7 +1054,7 @@ mptscsih_shutdown(struct device * dev)
|
|||||||
int
|
int
|
||||||
mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
|
mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||||
{
|
{
|
||||||
mptscsih_shutdown(&pdev->dev);
|
mptscsih_shutdown(pdev);
|
||||||
return mpt_suspend(pdev,state);
|
return mpt_suspend(pdev,state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -82,7 +82,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void mptscsih_remove(struct pci_dev *);
|
extern void mptscsih_remove(struct pci_dev *);
|
||||||
extern void mptscsih_shutdown(struct device *);
|
extern void mptscsih_shutdown(struct pci_dev *);
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
extern int mptscsih_suspend(struct pci_dev *pdev, u32 state);
|
extern int mptscsih_suspend(struct pci_dev *pdev, u32 state);
|
||||||
extern int mptscsih_resume(struct pci_dev *pdev);
|
extern int mptscsih_resume(struct pci_dev *pdev);
|
||||||
|
@@ -419,9 +419,7 @@ static struct pci_driver mptspi_driver = {
|
|||||||
.id_table = mptspi_pci_table,
|
.id_table = mptspi_pci_table,
|
||||||
.probe = mptspi_probe,
|
.probe = mptspi_probe,
|
||||||
.remove = __devexit_p(mptscsih_remove),
|
.remove = __devexit_p(mptscsih_remove),
|
||||||
.driver = {
|
.shutdown = mptscsih_shutdown,
|
||||||
.shutdown = mptscsih_shutdown,
|
|
||||||
},
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.suspend = mptscsih_suspend,
|
.suspend = mptscsih_suspend,
|
||||||
.resume = mptscsih_resume,
|
.resume = mptscsih_resume,
|
||||||
|
@@ -822,7 +822,7 @@ static int corkscrew_open(struct net_device *dev)
|
|||||||
break; /* Bad news! */
|
break; /* Bad news! */
|
||||||
skb->dev = dev; /* Mark as being used by this device. */
|
skb->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
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. */
|
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);
|
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! */
|
break; /* Bad news! */
|
||||||
skb->dev = dev; /* Mark as being used by this device. */
|
skb->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
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_skbuff[entry] = skb;
|
||||||
}
|
}
|
||||||
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
|
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
|
||||||
|
@@ -1802,7 +1802,7 @@ vortex_open(struct net_device *dev)
|
|||||||
break; /* Bad news! */
|
break; /* Bad news! */
|
||||||
skb->dev = dev; /* Mark as being used by this device. */
|
skb->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
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) {
|
if (i != RX_RING_SIZE) {
|
||||||
int j;
|
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);
|
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. */
|
/* 'skb_put()' points to the start of sk_buff data area. */
|
||||||
memcpy(skb_put(skb, pkt_len),
|
memcpy(skb_put(skb, pkt_len),
|
||||||
vp->rx_skbuff[entry]->tail,
|
vp->rx_skbuff[entry]->data,
|
||||||
pkt_len);
|
pkt_len);
|
||||||
pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
|
pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
|
||||||
vp->rx_copy++;
|
vp->rx_copy++;
|
||||||
@@ -2678,7 +2678,7 @@ boomerang_rx(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
skb->dev = dev; /* Mark as being used by this device. */
|
skb->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
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_skbuff[entry] = skb;
|
||||||
}
|
}
|
||||||
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
|
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
|
||||||
|
@@ -596,7 +596,7 @@ rx_status_loop:
|
|||||||
|
|
||||||
mapping =
|
mapping =
|
||||||
cp->rx_skb[rx_tail].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);
|
buflen, PCI_DMA_FROMDEVICE);
|
||||||
cp->rx_skb[rx_tail].skb = new_skb;
|
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);
|
skb_reserve(skb, RX_OFFSET);
|
||||||
|
|
||||||
cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
|
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_skb[i].skb = skb;
|
||||||
|
|
||||||
cp->rx_ring[i].opts2 = 0;
|
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_next = WSWAPrbd(virt_to_bus(rbd+1));
|
||||||
rbd->b_addr = WSWAPrbd(virt_to_bus(rbd));
|
rbd->b_addr = WSWAPrbd(virt_to_bus(rbd));
|
||||||
rbd->skb = skb;
|
rbd->skb = skb;
|
||||||
rbd->v_data = skb->tail;
|
rbd->v_data = skb->data;
|
||||||
rbd->b_data = WSWAPchar(virt_to_bus(skb->tail));
|
rbd->b_data = WSWAPchar(virt_to_bus(skb->data));
|
||||||
rbd->size = PKT_BUF_SZ;
|
rbd->size = PKT_BUF_SZ;
|
||||||
#ifdef __mc68000__
|
#ifdef __mc68000__
|
||||||
cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ);
|
cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
lp->rbd_head = lp->rbds;
|
lp->rbd_head = lp->rbds;
|
||||||
@@ -816,10 +816,10 @@ static inline int i596_rx(struct net_device *dev)
|
|||||||
rx_in_place = 1;
|
rx_in_place = 1;
|
||||||
rbd->skb = newskb;
|
rbd->skb = newskb;
|
||||||
newskb->dev = dev;
|
newskb->dev = dev;
|
||||||
rbd->v_data = newskb->tail;
|
rbd->v_data = newskb->data;
|
||||||
rbd->b_data = WSWAPchar(virt_to_bus(newskb->tail));
|
rbd->b_data = WSWAPchar(virt_to_bus(newskb->data));
|
||||||
#ifdef __mc68000__
|
#ifdef __mc68000__
|
||||||
cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ);
|
cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -840,7 +840,7 @@ memory_squeeze:
|
|||||||
skb->protocol=eth_type_trans(skb,dev);
|
skb->protocol=eth_type_trans(skb,dev);
|
||||||
skb->len = pkt_len;
|
skb->len = pkt_len;
|
||||||
#ifdef __mc68000__
|
#ifdef __mc68000__
|
||||||
cache_clear(virt_to_phys(rbd->skb->tail),
|
cache_clear(virt_to_phys(rbd->skb->data),
|
||||||
pkt_len);
|
pkt_len);
|
||||||
#endif
|
#endif
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
|
@@ -87,6 +87,7 @@ Revision History:
|
|||||||
#include <linux/if_vlan.h>
|
#include <linux/if_vlan.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/crc32.h>
|
#include <linux/crc32.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@@ -2006,12 +2007,11 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize DMA */
|
/* 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,"
|
printk(KERN_ERR "amd8111e: DMA not supported,"
|
||||||
"exiting.\n");
|
"exiting.\n");
|
||||||
goto err_free_reg;
|
goto err_free_reg;
|
||||||
} else
|
}
|
||||||
pdev->dma_mask = 0xffffffff;
|
|
||||||
|
|
||||||
reg_addr = pci_resource_start(pdev, 0);
|
reg_addr = pci_resource_start(pdev, 0);
|
||||||
reg_len = pci_resource_len(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
|
only is it difficult to detect, it also moves around in I/O space in
|
||||||
response to inb()s from other device probes!
|
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/config.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
@@ -547,7 +547,7 @@ rio_timer (unsigned long data)
|
|||||||
skb_reserve (skb, 2);
|
skb_reserve (skb, 2);
|
||||||
np->rx_ring[entry].fraginfo =
|
np->rx_ring[entry].fraginfo =
|
||||||
cpu_to_le64 (pci_map_single
|
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));
|
PCI_DMA_FROMDEVICE));
|
||||||
}
|
}
|
||||||
np->rx_ring[entry].fraginfo |=
|
np->rx_ring[entry].fraginfo |=
|
||||||
@@ -618,7 +618,7 @@ alloc_list (struct net_device *dev)
|
|||||||
/* Rubicon now supports 40 bits of addressing space. */
|
/* Rubicon now supports 40 bits of addressing space. */
|
||||||
np->rx_ring[i].fraginfo =
|
np->rx_ring[i].fraginfo =
|
||||||
cpu_to_le64 ( pci_map_single (
|
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));
|
PCI_DMA_FROMDEVICE));
|
||||||
np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
|
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 */
|
/* 16 byte align the IP header */
|
||||||
skb_reserve (skb, 2);
|
skb_reserve (skb, 2);
|
||||||
eth_copy_and_sum (skb,
|
eth_copy_and_sum (skb,
|
||||||
np->rx_skbuff[entry]->tail,
|
np->rx_skbuff[entry]->data,
|
||||||
pkt_len, 0);
|
pkt_len, 0);
|
||||||
skb_put (skb, pkt_len);
|
skb_put (skb, pkt_len);
|
||||||
pci_dma_sync_single_for_device(np->pdev,
|
pci_dma_sync_single_for_device(np->pdev,
|
||||||
@@ -950,7 +950,7 @@ receive_packet (struct net_device *dev)
|
|||||||
skb_reserve (skb, 2);
|
skb_reserve (skb, 2);
|
||||||
np->rx_ring[entry].fraginfo =
|
np->rx_ring[entry].fraginfo =
|
||||||
cpu_to_le64 (pci_map_single
|
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));
|
PCI_DMA_FROMDEVICE));
|
||||||
}
|
}
|
||||||
np->rx_ring[entry].fraginfo |=
|
np->rx_ring[entry].fraginfo |=
|
||||||
|
@@ -2447,9 +2447,8 @@ static int e100_resume(struct pci_dev *pdev)
|
|||||||
#endif
|
#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 net_device *netdev = pci_get_drvdata(pdev);
|
||||||
struct nic *nic = netdev_priv(netdev);
|
struct nic *nic = netdev_priv(netdev);
|
||||||
|
|
||||||
@@ -2470,11 +2469,7 @@ static struct pci_driver e100_driver = {
|
|||||||
.suspend = e100_suspend,
|
.suspend = e100_suspend,
|
||||||
.resume = e100_resume,
|
.resume = e100_resume,
|
||||||
#endif
|
#endif
|
||||||
|
.shutdown = e100_shutdown,
|
||||||
.driver = {
|
|
||||||
.shutdown = e100_shutdown,
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init e100_init_module(void)
|
static int __init e100_init_module(void)
|
||||||
|
@@ -1269,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *dev)
|
|||||||
if (skb == NULL)
|
if (skb == NULL)
|
||||||
break; /* OK. Just initially short of Rx bufs. */
|
break; /* OK. Just initially short of Rx bufs. */
|
||||||
skb->dev = dev; /* Mark as being used by this device. */
|
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_ringp[i] = rxf;
|
||||||
sp->rx_ring_dma[i] =
|
sp->rx_ring_dma[i] =
|
||||||
pci_map_single(sp->pdev, rxf,
|
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;
|
sp->rx_ringp[entry] = NULL;
|
||||||
return 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] =
|
sp->rx_ring_dma[entry] =
|
||||||
pci_map_single(sp->pdev, rxf,
|
pci_map_single(sp->pdev, rxf,
|
||||||
PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
|
PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
|
||||||
@@ -1808,10 +1808,10 @@ speedo_rx(struct net_device *dev)
|
|||||||
|
|
||||||
#if 1 || USE_IP_CSUM
|
#if 1 || USE_IP_CSUM
|
||||||
/* Packet is in one chunk -- we can copy + cksum. */
|
/* 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);
|
skb_put(skb, pkt_len);
|
||||||
#else
|
#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);
|
pkt_len);
|
||||||
#endif
|
#endif
|
||||||
pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
|
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->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
||||||
ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev,
|
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->rx_ring[i].rxstatus = cpu_to_le32(DescOwn);
|
||||||
}
|
}
|
||||||
ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
|
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_ring[entry].bufaddr,
|
||||||
ep->rx_buf_sz,
|
ep->rx_buf_sz,
|
||||||
PCI_DMA_FROMDEVICE);
|
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);
|
skb_put(skb, pkt_len);
|
||||||
pci_dma_sync_single_for_device(ep->pci_dev,
|
pci_dma_sync_single_for_device(ep->pci_dev,
|
||||||
ep->rx_ring[entry].bufaddr,
|
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->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||||
ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev,
|
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++;
|
work_done++;
|
||||||
}
|
}
|
||||||
ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn);
|
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. */
|
skb->dev = dev; /* Mark as being used by this device. */
|
||||||
np->lack_rxbuf->skbuff = skb;
|
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->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||||
np->lack_rxbuf->status = RXOWN;
|
np->lack_rxbuf->status = RXOWN;
|
||||||
++np->really_rx_count;
|
++np->really_rx_count;
|
||||||
@@ -1300,7 +1300,7 @@ static void init_ring(struct net_device *dev)
|
|||||||
++np->really_rx_count;
|
++np->really_rx_count;
|
||||||
np->rx_ring[i].skbuff = skb;
|
np->rx_ring[i].skbuff = skb;
|
||||||
skb->dev = dev; /* Mark as being used by this device. */
|
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_buf_sz, PCI_DMA_FROMDEVICE);
|
||||||
np->rx_ring[i].status = RXOWN;
|
np->rx_ring[i].status = RXOWN;
|
||||||
np->rx_ring[i].control |= RXIC;
|
np->rx_ring[i].control |= RXIC;
|
||||||
@@ -1737,11 +1737,11 @@ static int netdev_rx(struct net_device *dev)
|
|||||||
|
|
||||||
#if ! defined(__alpha__)
|
#if ! defined(__alpha__)
|
||||||
eth_copy_and_sum(skb,
|
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);
|
skb_put(skb, pkt_len);
|
||||||
#else
|
#else
|
||||||
memcpy(skb_put(skb, pkt_len),
|
memcpy(skb_put(skb, pkt_len),
|
||||||
np->cur_rx->skbuff->tail, pkt_len);
|
np->cur_rx->skbuff->data, pkt_len);
|
||||||
#endif
|
#endif
|
||||||
pci_dma_sync_single_for_device(np->pci_dev,
|
pci_dma_sync_single_for_device(np->pci_dev,
|
||||||
np->cur_rx->buffer,
|
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->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
||||||
hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
|
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 |
|
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
|
||||||
DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2));
|
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->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
||||||
hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
|
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 */
|
/* -2 because it doesn't REALLY have that first 2 bytes -KDU */
|
||||||
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
|
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
|
||||||
DescEndPacket | DescIntr | (hmp->rx_buf_sz -2));
|
DescEndPacket | DescIntr | (hmp->rx_buf_sz -2));
|
||||||
@@ -1509,7 +1509,7 @@ static int hamachi_rx(struct net_device *dev)
|
|||||||
desc->addr,
|
desc->addr,
|
||||||
hmp->rx_buf_sz,
|
hmp->rx_buf_sz,
|
||||||
PCI_DMA_FROMDEVICE);
|
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])));
|
frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12])));
|
||||||
if (hamachi_debug > 4)
|
if (hamachi_debug > 4)
|
||||||
printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n",
|
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->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||||
desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
|
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);
|
desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz);
|
||||||
if (entry >= RX_RING_SIZE-1)
|
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] ? '>' : ' ',
|
readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ',
|
||||||
i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr);
|
i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr);
|
||||||
if (hamachi_debug > 6) {
|
if (hamachi_debug > 6) {
|
||||||
if (*(u8*)hmp->rx_skbuff[i]->tail != 0x69) {
|
if (*(u8*)hmp->rx_skbuff[i]->data != 0x69) {
|
||||||
u16 *addr = (u16 *)
|
u16 *addr = (u16 *)
|
||||||
hmp->rx_skbuff[i]->tail;
|
hmp->rx_skbuff[i]->data;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < 0x50; 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;
|
lp->rx_skbuff[i] = skb;
|
||||||
if (skb) {
|
if (skb) {
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
rx_buff = skb->tail;
|
rx_buff = skb->data;
|
||||||
} else
|
} else
|
||||||
rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
|
rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
|
||||||
if (rx_buff == NULL)
|
if (rx_buff == NULL)
|
||||||
|
@@ -553,14 +553,14 @@ static inline void init_rx_bufs(struct net_device *dev)
|
|||||||
if (skb == NULL)
|
if (skb == NULL)
|
||||||
panic("%s: alloc_skb() failed", __FILE__);
|
panic("%s: alloc_skb() failed", __FILE__);
|
||||||
skb_reserve(skb, 2);
|
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);
|
DMA_FROM_DEVICE);
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
rbd->v_next = rbd+1;
|
rbd->v_next = rbd+1;
|
||||||
rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
|
rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
|
||||||
rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd));
|
rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd));
|
||||||
rbd->skb = skb;
|
rbd->skb = skb;
|
||||||
rbd->v_data = skb->tail;
|
rbd->v_data = skb->data;
|
||||||
rbd->b_data = WSWAPchar(dma_addr);
|
rbd->b_data = WSWAPchar(dma_addr);
|
||||||
rbd->size = PKT_BUF_SZ;
|
rbd->size = PKT_BUF_SZ;
|
||||||
}
|
}
|
||||||
@@ -783,8 +783,8 @@ static inline int i596_rx(struct net_device *dev)
|
|||||||
rx_in_place = 1;
|
rx_in_place = 1;
|
||||||
rbd->skb = newskb;
|
rbd->skb = newskb;
|
||||||
newskb->dev = dev;
|
newskb->dev = dev;
|
||||||
dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE);
|
dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE);
|
||||||
rbd->v_data = newskb->tail;
|
rbd->v_data = newskb->data;
|
||||||
rbd->b_data = WSWAPchar(dma_addr);
|
rbd->b_data = WSWAPchar(dma_addr);
|
||||||
CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
|
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. */
|
break; /* Better luck next round. */
|
||||||
skb->dev = dev; /* Mark as being used by this device. */
|
skb->dev = dev; /* Mark as being used by this device. */
|
||||||
np->rx_dma[entry] = pci_map_single(np->pci_dev,
|
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].addr = cpu_to_le32(np->rx_dma[entry]);
|
||||||
}
|
}
|
||||||
np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz);
|
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,
|
buflen,
|
||||||
PCI_DMA_FROMDEVICE);
|
PCI_DMA_FROMDEVICE);
|
||||||
eth_copy_and_sum(skb,
|
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);
|
skb_put(skb, pkt_len);
|
||||||
pci_dma_sync_single_for_device(np->pci_dev,
|
pci_dma_sync_single_for_device(np->pci_dev,
|
||||||
np->rx_dma[entry],
|
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;
|
dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
|
||||||
cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR;
|
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);
|
REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
|
||||||
build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
|
build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
|
||||||
/* update link of previous rx */
|
/* update link of previous rx */
|
||||||
@@ -604,7 +604,7 @@ static inline int rx_refill(struct net_device *ndev, int gfp)
|
|||||||
if (unlikely(!skb))
|
if (unlikely(!skb))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
res = (long)skb->tail & 0xf;
|
res = (long)skb->data & 0xf;
|
||||||
res = 0x10 - res;
|
res = 0x10 - res;
|
||||||
res &= 0xf;
|
res &= 0xf;
|
||||||
skb_reserve(skb, res);
|
skb_reserve(skb, res);
|
||||||
|
@@ -1602,7 +1602,7 @@ pcnet32_init_ring(struct net_device *dev)
|
|||||||
|
|
||||||
rmb();
|
rmb();
|
||||||
if (lp->rx_dma_addr[i] == 0)
|
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);
|
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].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]);
|
||||||
lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
|
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;
|
lp->rx_skbuff[entry] = newskb;
|
||||||
newskb->dev = dev;
|
newskb->dev = dev;
|
||||||
lp->rx_dma_addr[entry] =
|
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);
|
PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
|
||||||
lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]);
|
lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]);
|
||||||
rx_in_place = 1;
|
rx_in_place = 1;
|
||||||
@@ -2020,7 +2020,7 @@ pcnet32_rx(struct net_device *dev)
|
|||||||
PKT_BUF_SZ-2,
|
PKT_BUF_SZ-2,
|
||||||
PCI_DMA_FROMDEVICE);
|
PCI_DMA_FROMDEVICE);
|
||||||
eth_copy_and_sum(skb,
|
eth_copy_and_sum(skb,
|
||||||
(unsigned char *)(lp->rx_skbuff[entry]->tail),
|
(unsigned char *)(lp->rx_skbuff[entry]->data),
|
||||||
pkt_len,0);
|
pkt_len,0);
|
||||||
pci_dma_sync_single_for_device(lp->pci_dev,
|
pci_dma_sync_single_for_device(lp->pci_dev,
|
||||||
lp->rx_dma_addr[entry],
|
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);
|
skb_reserve(skb, NET_IP_ALIGN);
|
||||||
*sk_buff = skb;
|
*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);
|
PCI_DMA_FROMDEVICE);
|
||||||
|
|
||||||
rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
|
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);
|
skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
|
||||||
if (skb) {
|
if (skb) {
|
||||||
skb_reserve(skb, NET_IP_ALIGN);
|
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;
|
*sk_buff = skb;
|
||||||
rtl8169_mark_to_asic(desc, rx_buf_sz);
|
rtl8169_mark_to_asic(desc, rx_buf_sz);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@@ -1699,11 +1699,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
|
|||||||
#else
|
#else
|
||||||
ba = &nic->ba[ring_no][block_no][off];
|
ba = &nic->ba[ring_no][block_no][off];
|
||||||
skb_reserve(skb, BUF0_LEN);
|
skb_reserve(skb, BUF0_LEN);
|
||||||
tmp = (unsigned long) skb->data;
|
tmp = ((unsigned long) skb->data & ALIGN_SIZE);
|
||||||
tmp += ALIGN_SIZE;
|
if (tmp)
|
||||||
tmp &= ~ALIGN_SIZE;
|
skb_reserve(skb, (ALIGN_SIZE + 1) - tmp);
|
||||||
skb->data = (void *) tmp;
|
|
||||||
skb->tail = (void *) tmp;
|
|
||||||
|
|
||||||
memset(rxdp, 0, sizeof(RxD_t));
|
memset(rxdp, 0, sizeof(RxD_t));
|
||||||
rxdp->Buffer2_ptr = pci_map_single
|
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.
|
* 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)) |
|
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
|
||||||
0;
|
0;
|
||||||
#else
|
#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)) |
|
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
|
||||||
M_DMA_DSCRA_INTERRUPT;
|
M_DMA_DSCRA_INTERRUPT;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1154,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *net_dev)
|
|||||||
sis_priv->rx_skbuff[i] = skb;
|
sis_priv->rx_skbuff[i] = skb;
|
||||||
sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
|
sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
|
||||||
sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
|
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);
|
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_skbuff[entry] = skb;
|
||||||
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
|
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
|
||||||
sis_priv->rx_ring[entry].bufptr =
|
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);
|
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
|
||||||
sis_priv->dirty_rx++;
|
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_skbuff[entry] = skb;
|
||||||
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
|
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
|
||||||
sis_priv->rx_ring[entry].bufptr =
|
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);
|
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 */
|
/* PCI config registers */
|
||||||
#define PCI_DEV_REG1 0x40
|
#define PCI_DEV_REG1 0x40
|
||||||
#define PCI_DEV_REG2 0x44
|
#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 | \
|
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
|
||||||
PCI_STATUS_SIG_SYSTEM_ERROR | \
|
PCI_STATUS_SIG_SYSTEM_ERROR | \
|
||||||
@@ -39,7 +14,6 @@ enum {
|
|||||||
PCI_STATUS_REC_TARGET_ABORT | \
|
PCI_STATUS_REC_TARGET_ABORT | \
|
||||||
PCI_STATUS_PARITY)
|
PCI_STATUS_PARITY)
|
||||||
|
|
||||||
|
|
||||||
enum csr_regs {
|
enum csr_regs {
|
||||||
B0_RAP = 0x0000,
|
B0_RAP = 0x0000,
|
||||||
B0_CTST = 0x0004,
|
B0_CTST = 0x0004,
|
||||||
@@ -229,8 +203,11 @@ enum {
|
|||||||
IS_XA2_F = 1<<1, /* Q_XA2 End of Frame */
|
IS_XA2_F = 1<<1, /* Q_XA2 End of Frame */
|
||||||
IS_XA2_C = 1<<0, /* Q_XA2 Encoding Error */
|
IS_XA2_C = 1<<0, /* Q_XA2 Encoding Error */
|
||||||
|
|
||||||
IS_PORT_1 = IS_XA1_F| IS_R1_F| IS_MAC1,
|
IS_TO_PORT1 = IS_PA_TO_RX1 | IS_PA_TO_TX1,
|
||||||
IS_PORT_2 = IS_XA2_F| IS_R2_F| IS_MAC2,
|
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 */
|
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_TI_CTRL 8 bit Timer control */
|
||||||
/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
|
/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
|
||||||
enum {
|
enum {
|
||||||
@@ -313,16 +282,6 @@ enum {
|
|||||||
TIM_T_STEP = 1<<0, /* Test step */
|
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 */
|
/* B2_GP_IO 32 bit General Purpose I/O Register */
|
||||||
enum {
|
enum {
|
||||||
GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */
|
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 */
|
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 */
|
/* Descriptor Bit Definition */
|
||||||
/* TxCtrl Transmit Buffer Control Field */
|
/* TxCtrl Transmit Buffer Control Field */
|
||||||
/* RxCtrl Receive Buffer Control Field */
|
/* RxCtrl Receive Buffer Control Field */
|
||||||
@@ -428,14 +363,6 @@ enum {
|
|||||||
RI_RST_SET = 1<<0, /* Set RAM Interface Reset */
|
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 */
|
/* MAC Arbiter Registers */
|
||||||
/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
|
/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
|
||||||
enum {
|
enum {
|
||||||
@@ -452,19 +379,6 @@ enum {
|
|||||||
#define SK_PKT_TO_MAX 0xffff /* Maximum value */
|
#define SK_PKT_TO_MAX 0xffff /* Maximum value */
|
||||||
#define SK_RI_TO_53 36 /* RAM interface timeout */
|
#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 */
|
/* Packet Arbiter Registers */
|
||||||
/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
|
/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
|
||||||
enum {
|
enum {
|
||||||
@@ -488,7 +402,7 @@ enum {
|
|||||||
PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
|
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_INI 32 bit Tx Arb Interval Timer Init Val */
|
||||||
/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
|
/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
|
||||||
/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
|
/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
|
||||||
@@ -511,7 +425,7 @@ enum {
|
|||||||
/*
|
/*
|
||||||
* Bank 4 - 5
|
* 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 {
|
enum {
|
||||||
TXA_ITI_INI = 0x0200,/* 32 bit Tx Arb Interval Timer Init Val*/
|
TXA_ITI_INI = 0x0200,/* 32 bit Tx Arb Interval Timer Init Val*/
|
||||||
TXA_ITI_VAL = 0x0204,/* 32 bit Tx Arb Interval Timer Value */
|
TXA_ITI_VAL = 0x0204,/* 32 bit Tx Arb Interval Timer Value */
|
||||||
@@ -537,7 +451,7 @@ enum {
|
|||||||
|
|
||||||
/* Queue Register Offsets, use Q_ADDR() to access */
|
/* Queue Register Offsets, use Q_ADDR() to access */
|
||||||
enum {
|
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_D = 0x00, /* 8*32 bit Current Descriptor */
|
||||||
Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */
|
Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */
|
||||||
Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */
|
Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */
|
||||||
@@ -618,8 +532,7 @@ enum {
|
|||||||
enum {
|
enum {
|
||||||
PHY_ADDR_XMAC = 0<<8,
|
PHY_ADDR_XMAC = 0<<8,
|
||||||
PHY_ADDR_BCOM = 1<<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) */
|
/* GPHY address (bits 15..11 of SMI control reg) */
|
||||||
PHY_ADDR_MARV = 0,
|
PHY_ADDR_MARV = 0,
|
||||||
};
|
};
|
||||||
@@ -986,7 +899,7 @@ enum {
|
|||||||
LINKLED_BLINK_OFF = 0x10,
|
LINKLED_BLINK_OFF = 0x10,
|
||||||
LINKLED_BLINK_ON = 0x20,
|
LINKLED_BLINK_ON = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* GMAC and GPHY Control Registers (YUKON only) */
|
/* GMAC and GPHY Control Registers (YUKON only) */
|
||||||
enum {
|
enum {
|
||||||
GMAC_CTRL = 0x0f00,/* 32 bit GMAC Control Reg */
|
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 */
|
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 {
|
enum {
|
||||||
PHY_CT_RESET = 1<<15, /* Bit 15: (sc) clear all PHY related regs */
|
PHY_CT_RESET = 1<<15, /* Bit 15: (sc) clear all PHY related regs */
|
||||||
PHY_CT_LOOP = 1<<14, /* Bit 14: enable Loopback over PHY */
|
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) */
|
PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Advertisement register bits */
|
||||||
enum {
|
enum {
|
||||||
PHY_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */
|
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_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */
|
||||||
PHY_X_AN_RFB = 3<<12,/* Bit 13..12: Remote Fault Bits */
|
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 */
|
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 */
|
/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
|
||||||
enum {
|
enum {
|
||||||
PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */
|
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_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 *****/
|
/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
|
||||||
enum {
|
enum {
|
||||||
PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */
|
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_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */
|
||||||
PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */
|
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 */
|
/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
|
||||||
enum {
|
enum {
|
||||||
@@ -1495,166 +1317,6 @@ enum {
|
|||||||
PHY_B_RES_1000HD = 6<<8,/* Bit 10..8: 1000Base-T Half Dup. */
|
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 */
|
/** Marvell-Specific */
|
||||||
enum {
|
enum {
|
||||||
PHY_M_AN_NXT_PG = 1<<15, /* Request Next Page */
|
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) */
|
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 {
|
enum {
|
||||||
PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */
|
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_FC_RX_DIS = 1<<2, /* Bit 2: Rx Flow-Control Mode Disabled */
|
||||||
GM_GPSR_PROM_EN = 1<<1, /* Bit 1: Promiscuous Mode Enabled */
|
GM_GPSR_PROM_EN = 1<<1, /* Bit 1: Promiscuous Mode Enabled */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
|
/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
|
||||||
enum {
|
enum {
|
||||||
GM_GPCR_PROM_ENA = 1<<14, /* Bit 14: Enable Promiscuous Mode */
|
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_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)
|
#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 */
|
/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
|
||||||
enum {
|
enum {
|
||||||
GM_TXCR_FORCE_JAM = 1<<15, /* Bit 15: Force Jam / Flow-Control */
|
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_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK)
|
||||||
#define TX_COL_DEF 0x04
|
#define TX_COL_DEF 0x04
|
||||||
|
|
||||||
/* GM_RX_CTRL 16 bit r/w Receive Control Register */
|
/* GM_RX_CTRL 16 bit r/w Receive Control Register */
|
||||||
enum {
|
enum {
|
||||||
GM_RXCR_UCF_ENA = 1<<15, /* Bit 15: Enable Unicast filtering */
|
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_CRC_DIS = 1<<13, /* Bit 13: Remove 4-byte CRC */
|
||||||
GM_RXCR_PASS_FC = 1<<12, /* Bit 12: Pass FC packets to FIFO */
|
GM_RXCR_PASS_FC = 1<<12, /* Bit 12: Pass FC packets to FIFO */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
|
/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
|
||||||
enum {
|
enum {
|
||||||
GM_TXPA_JAMLEN_MSK = 0x03<<14, /* Bit 15..14: Jam Length */
|
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_JUMBO_ENA = 1<<8, /* Bit 8: Enable Jumbo (Max. Frame Len) */
|
||||||
GM_SMOD_IPG_MSK = 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */
|
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_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK)
|
||||||
#define DATA_BLIND_DEF 0x04
|
#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_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */
|
||||||
GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */
|
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_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)
|
#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_CLR = 1<<5, /* Bit 5: Set MIB Clear Counter Mode */
|
||||||
GM_PAR_MIB_TST = 1<<4, /* Bit 4: MIB Load Counter (Test Mode) */
|
GM_PAR_MIB_TST = 1<<4, /* Bit 4: MIB Load Counter (Test Mode) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Receive Frame Status Encoding */
|
/* Receive Frame Status Encoding */
|
||||||
enum {
|
enum {
|
||||||
GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */
|
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 (analogous to XMR_FS_ANY_ERR)
|
||||||
*/
|
*/
|
||||||
GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_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_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
|
||||||
GMR_FS_JABBER,
|
GMR_FS_JABBER,
|
||||||
/* Rx GMAC FIFO Flush Mask (default) */
|
/* Rx GMAC FIFO Flush Mask (default) */
|
||||||
RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR |
|
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,
|
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 */
|
/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
|
||||||
enum {
|
enum {
|
||||||
XM_GP_ANIP = 1<<6, /* Bit 6: (ro) Auto-Neg. in progress */
|
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_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 |\
|
#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)
|
XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA)
|
||||||
|
|
||||||
/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
|
/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
|
||||||
enum {
|
enum {
|
||||||
@@ -2793,28 +2451,20 @@ struct skge_hw {
|
|||||||
u32 intr_mask;
|
u32 intr_mask;
|
||||||
struct net_device *dev[2];
|
struct net_device *dev[2];
|
||||||
|
|
||||||
u8 mac_cfg;
|
|
||||||
u8 chip_id;
|
u8 chip_id;
|
||||||
|
u8 chip_rev;
|
||||||
u8 phy_type;
|
u8 phy_type;
|
||||||
u8 pmd_type;
|
u8 pmd_type;
|
||||||
u16 phy_addr;
|
u16 phy_addr;
|
||||||
|
u8 ports;
|
||||||
|
|
||||||
u32 ram_size;
|
u32 ram_size;
|
||||||
u32 ram_offset;
|
u32 ram_offset;
|
||||||
|
|
||||||
struct tasklet_struct ext_tasklet;
|
struct tasklet_struct ext_tasklet;
|
||||||
spinlock_t phy_lock;
|
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)
|
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_REM_SEND = 2, /* Symmetric or just remote */
|
||||||
FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */
|
FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct skge_port {
|
struct skge_port {
|
||||||
u32 msg_enable;
|
u32 msg_enable;
|
||||||
struct skge_hw *hw;
|
struct skge_hw *hw;
|
||||||
@@ -2853,8 +2503,8 @@ struct skge_port {
|
|||||||
void *mem; /* PCI memory for rings */
|
void *mem; /* PCI memory for rings */
|
||||||
dma_addr_t dma;
|
dma_addr_t dma;
|
||||||
unsigned long mem_size;
|
unsigned long mem_size;
|
||||||
|
unsigned int rx_buf_size;
|
||||||
|
|
||||||
struct timer_list link_check;
|
|
||||||
struct timer_list led_blink;
|
struct timer_list led_blink;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2863,7 +2513,6 @@ struct skge_port {
|
|||||||
static inline u32 skge_read32(const struct skge_hw *hw, int reg)
|
static inline u32 skge_read32(const struct skge_hw *hw, int reg)
|
||||||
{
|
{
|
||||||
return readl(hw->regs + reg);
|
return readl(hw->regs + reg);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u16 skge_read16(const struct skge_hw *hw, int 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. */
|
/* MAC Related Registers inside the device. */
|
||||||
#define SKGEMAC_REG(port,reg) (((port)<<7)+(reg))
|
#define SK_REG(port,reg) (((port)<<7)+(reg))
|
||||||
|
#define SK_XMAC_REG(port, reg) \
|
||||||
/* PCI config space can be accessed via memory mapped space */
|
|
||||||
#define SKGEPCI_REG(reg) ((reg)+ 0x380)
|
|
||||||
|
|
||||||
#define SKGEXM_REG(port, reg) \
|
|
||||||
((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
|
((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)
|
static inline void xm_outhash(const struct skge_hw *hw, int port, int reg,
|
||||||
{
|
|
||||||
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,
|
|
||||||
const u8 *hash)
|
const u8 *hash)
|
||||||
{
|
{
|
||||||
skge_xm_write16(hw, port, reg,
|
xm_write16(hw, port, reg, (u16)hash[0] | ((u16)hash[1] << 8));
|
||||||
(u16)hash[0] | ((u16)hash[1] << 8));
|
xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8));
|
||||||
skge_xm_write16(hw, port, reg+2,
|
xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8));
|
||||||
(u16)hash[2] | ((u16)hash[3] << 8));
|
xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
const u8 *addr)
|
||||||
{
|
{
|
||||||
skge_xm_write16(hw, port, reg,
|
xm_write16(hw, port, reg, (u16)addr[0] | ((u16)addr[1] << 8));
|
||||||
(u16)addr[0] | ((u16)addr[1] << 8));
|
xm_write16(hw, port, reg+2, (u16)addr[2] | ((u16)addr[3] << 8));
|
||||||
skge_xm_write16(hw, port, reg,
|
xm_write16(hw, port, reg+4, (u16)addr[4] | ((u16)addr[5] << 8));
|
||||||
(u16)addr[2] | ((u16)addr[3] << 8));
|
|
||||||
skge_xm_write16(hw, port, reg,
|
|
||||||
(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) \
|
static inline u16 gma_read16(const struct skge_hw *hw, int port, int 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)
|
|
||||||
{
|
{
|
||||||
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))
|
return (u32) skge_read16(hw, SK_GMAC_REG(port,reg))
|
||||||
| ((u32)skge_read16(hw, SKGEGMA_REG(port,reg+4)) << 16);
|
| ((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_write8(hw, SK_GMAC_REG(port,r), v);
|
||||||
skge_write32(hw, SKGEGMA_REG(port, r+4), (u16)(v >> 16));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void skge_gma_write8(const struct skge_hw *hw, int port, int r, u8 v)
|
static inline void gma_set_addr(struct skge_hw *hw, int port, int reg,
|
||||||
{
|
|
||||||
skge_write8(hw, SKGEGMA_REG(port,r), v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void skge_gm_set_addr(struct skge_hw *hw, int port, int reg,
|
|
||||||
const u8 *addr)
|
const u8 *addr)
|
||||||
{
|
{
|
||||||
skge_gma_write16(hw, port, reg,
|
gma_write16(hw, port, reg, (u16) addr[0] | ((u16) addr[1] << 8));
|
||||||
(u16) addr[0] | ((u16) addr[1] << 8));
|
gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
|
||||||
skge_gma_write16(hw, port, reg+4,
|
gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
|
||||||
(u16) addr[2] | ((u16) addr[3] << 8));
|
|
||||||
skge_gma_write16(hw, port, reg+8,
|
|
||||||
(u16) addr[4] | ((u16) addr[5] << 8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -74,6 +74,7 @@
|
|||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <linux/if_arp.h>
|
#include <linux/if_arp.h>
|
||||||
#include <linux/if_slip.h>
|
#include <linux/if_slip.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include "slip.h"
|
#include "slip.h"
|
||||||
#ifdef CONFIG_INET
|
#ifdef CONFIG_INET
|
||||||
|
@@ -1998,7 +1998,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
|
|||||||
if (retval)
|
if (retval)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
set_irq_type(dev->irq, IRQT_RISING);
|
set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE);
|
||||||
|
|
||||||
#ifdef SMC_USE_PXA_DMA
|
#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_insl(a, r, p, l) readsl((a) + (r), p, l)
|
||||||
#define SMC_outsl(a, r, p, l) writesl((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)
|
#elif defined(CONFIG_SH_SH4202_MICRODEV)
|
||||||
|
|
||||||
#define SMC_CAN_USE_8BIT 0
|
#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
|
#endif
|
||||||
|
|
||||||
|
#ifndef SMC_IRQ_TRIGGER_TYPE
|
||||||
|
#define SMC_IRQ_TRIGGER_TYPE IRQT_RISING
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SMC_USE_PXA_DMA
|
#ifdef SMC_USE_PXA_DMA
|
||||||
/*
|
/*
|
||||||
|
@@ -1286,7 +1286,7 @@ static void init_ring(struct net_device *dev)
|
|||||||
np->rx_info[i].skb = skb;
|
np->rx_info[i].skb = skb;
|
||||||
if (skb == NULL)
|
if (skb == NULL)
|
||||||
break;
|
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. */
|
skb->dev = dev; /* Mark as being used by this device. */
|
||||||
/* Grrr, we cannot offset to correctly align the IP header. */
|
/* Grrr, we cannot offset to correctly align the IP header. */
|
||||||
np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
|
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,
|
pci_dma_sync_single_for_cpu(np->pci_dev,
|
||||||
np->rx_info[entry].mapping,
|
np->rx_info[entry].mapping,
|
||||||
pkt_len, PCI_DMA_FROMDEVICE);
|
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,
|
pci_dma_sync_single_for_device(np->pci_dev,
|
||||||
np->rx_info[entry].mapping,
|
np->rx_info[entry].mapping,
|
||||||
pkt_len, PCI_DMA_FROMDEVICE);
|
pkt_len, PCI_DMA_FROMDEVICE);
|
||||||
@@ -1696,7 +1696,7 @@ static void refill_rx_ring(struct net_device *dev)
|
|||||||
if (skb == NULL)
|
if (skb == NULL)
|
||||||
break; /* Better luck next round. */
|
break; /* Better luck next round. */
|
||||||
np->rx_info[entry].mapping =
|
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. */
|
skb->dev = dev; /* Mark as being used by this device. */
|
||||||
np->rx_ring[entry].rxaddr =
|
np->rx_ring[entry].rxaddr =
|
||||||
cpu_to_dma(np->rx_info[entry].mapping | RxDescValid);
|
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->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
skb_reserve(skb, 2); /* 16 byte align the IP header. */
|
||||||
np->rx_ring[i].frag[0].addr = cpu_to_le32(
|
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));
|
PCI_DMA_FROMDEVICE));
|
||||||
np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
|
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,
|
np->rx_buf_sz,
|
||||||
PCI_DMA_FROMDEVICE);
|
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,
|
pci_dma_sync_single_for_device(np->pci_dev,
|
||||||
desc->frag[0].addr,
|
desc->frag[0].addr,
|
||||||
np->rx_buf_sz,
|
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->dev = dev; /* Mark as being used by this device. */
|
||||||
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
|
||||||
np->rx_ring[entry].frag[0].addr = cpu_to_le32(
|
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));
|
np->rx_buf_sz, PCI_DMA_FROMDEVICE));
|
||||||
}
|
}
|
||||||
/* Perhaps we need not reset this field. */
|
/* Perhaps we need not reset this field. */
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user