aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/obsolete/dv13949
-rw-r--r--Documentation/ABI/removed/dv139414
-rw-r--r--Documentation/ABI/removed/raw139415
-rw-r--r--Documentation/ABI/removed/raw1394_legacy_isochronous16
-rw-r--r--Documentation/ABI/removed/video139416
-rw-r--r--Documentation/feature-removal-schedule.txt10
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/firewire/Kconfig5
-rw-r--r--drivers/firewire/Makefile1
-rw-r--r--drivers/firewire/init_ohci1394_dma.c (renamed from drivers/ieee1394/init_ohci1394_dma.c)76
-rw-r--r--drivers/ieee1394/Kconfig182
-rw-r--r--drivers/ieee1394/Makefile18
-rw-r--r--drivers/ieee1394/config_roms.c194
-rw-r--r--drivers/ieee1394/config_roms.h19
-rw-r--r--drivers/ieee1394/csr.c843
-rw-r--r--drivers/ieee1394/csr.h99
-rw-r--r--drivers/ieee1394/csr1212.c1467
-rw-r--r--drivers/ieee1394/csr1212.h383
-rw-r--r--drivers/ieee1394/dma.c289
-rw-r--r--drivers/ieee1394/dma.h89
-rw-r--r--drivers/ieee1394/dv1394-private.h587
-rw-r--r--drivers/ieee1394/dv1394.c2584
-rw-r--r--drivers/ieee1394/dv1394.h305
-rw-r--r--drivers/ieee1394/eth1394.c1720
-rw-r--r--drivers/ieee1394/eth1394.h234
-rw-r--r--drivers/ieee1394/highlevel.c691
-rw-r--r--drivers/ieee1394/highlevel.h141
-rw-r--r--drivers/ieee1394/hosts.c249
-rw-r--r--drivers/ieee1394/hosts.h201
-rw-r--r--drivers/ieee1394/ieee1394-ioctl.h106
-rw-r--r--drivers/ieee1394/ieee1394.h220
-rw-r--r--drivers/ieee1394/ieee1394_core.c1380
-rw-r--r--drivers/ieee1394/ieee1394_core.h172
-rw-r--r--drivers/ieee1394/ieee1394_hotplug.h19
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c595
-rw-r--r--drivers/ieee1394/ieee1394_transactions.h40
-rw-r--r--drivers/ieee1394/ieee1394_types.h69
-rw-r--r--drivers/ieee1394/iso.c568
-rw-r--r--drivers/ieee1394/iso.h195
-rw-r--r--drivers/ieee1394/nodemgr.c1901
-rw-r--r--drivers/ieee1394/nodemgr.h186
-rw-r--r--drivers/ieee1394/ohci1394.c3590
-rw-r--r--drivers/ieee1394/ohci1394.h453
-rw-r--r--drivers/ieee1394/pcilynx.c1554
-rw-r--r--drivers/ieee1394/pcilynx.h468
-rw-r--r--drivers/ieee1394/raw1394-private.h81
-rw-r--r--drivers/ieee1394/raw1394.c3096
-rw-r--r--drivers/ieee1394/raw1394.h191
-rw-r--r--drivers/ieee1394/sbp2.c2138
-rw-r--r--drivers/ieee1394/sbp2.h346
-rw-r--r--drivers/ieee1394/video1394.c1528
-rw-r--r--drivers/ieee1394/video1394.h67
52 files changed, 96 insertions, 29325 deletions
diff --git a/Documentation/ABI/obsolete/dv1394 b/Documentation/ABI/obsolete/dv1394
deleted file mode 100644
index 2ee36864ca1..00000000000
--- a/Documentation/ABI/obsolete/dv1394
+++ /dev/null
@@ -1,9 +0,0 @@
-What: dv1394 (a.k.a. "OHCI-DV I/O support" for FireWire)
-Contact: linux1394-devel@lists.sourceforge.net
-Description:
- New application development should use raw1394 + userspace libraries
- instead, notably libiec61883 which is functionally equivalent.
-
-Users:
- ffmpeg/libavformat (used by a variety of media players)
- dvgrab v1.x (replaced by dvgrab2 on top of raw1394 and resp. libraries)
diff --git a/Documentation/ABI/removed/dv1394 b/Documentation/ABI/removed/dv1394
new file mode 100644
index 00000000000..c2310b6676f
--- /dev/null
+++ b/Documentation/ABI/removed/dv1394
@@ -0,0 +1,14 @@
+What: dv1394 (a.k.a. "OHCI-DV I/O support" for FireWire)
+Date: May 2010 (scheduled), finally removed in kernel v2.6.37
+Contact: linux1394-devel@lists.sourceforge.net
+Description:
+ /dev/dv1394/* were character device files, one for each FireWire
+ controller and for NTSC and PAL respectively, from which DV data
+ could be received by read() or transmitted by write(). A few
+ ioctl()s allowed limited control.
+ This special-purpose interface has been superseded by libraw1394 +
+ libiec61883 which are functionally equivalent, support HDV, and
+ transparently work on top of the newer firewire kernel drivers.
+
+Users:
+ ffmpeg/libavformat (if configured for DV1394)
diff --git a/Documentation/ABI/removed/raw1394 b/Documentation/ABI/removed/raw1394
new file mode 100644
index 00000000000..490aa1efc4a
--- /dev/null
+++ b/Documentation/ABI/removed/raw1394
@@ -0,0 +1,15 @@
+What: raw1394 (a.k.a. "Raw IEEE1394 I/O support" for FireWire)
+Date: May 2010 (scheduled), finally removed in kernel v2.6.37
+Contact: linux1394-devel@lists.sourceforge.net
+Description:
+ /dev/raw1394 was a character device file that allowed low-level
+ access to FireWire buses. Its major drawbacks were its inability
+ to implement sensible device security policies, and its low level
+ of abstraction that required userspace clients do duplicate much
+ of the kernel's ieee1394 core functionality.
+ Replaced by /dev/fw*, i.e. the <linux/firewire-cdev.h> ABI of
+ firewire-core.
+
+Users:
+ libraw1394 (works with firewire-cdev too, transparent to library ABI
+ users)
diff --git a/Documentation/ABI/removed/raw1394_legacy_isochronous b/Documentation/ABI/removed/raw1394_legacy_isochronous
deleted file mode 100644
index 1b629622d88..00000000000
--- a/Documentation/ABI/removed/raw1394_legacy_isochronous
+++ /dev/null
@@ -1,16 +0,0 @@
-What: legacy isochronous ABI of raw1394 (1st generation iso ABI)
-Date: June 2007 (scheduled), removed in kernel v2.6.23
-Contact: linux1394-devel@lists.sourceforge.net
-Description:
- The two request types RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN have
- been deprecated for quite some time. They are very inefficient as they
- come with high interrupt load and several layers of callbacks for each
- packet. Because of these deficiencies, the video1394 and dv1394 drivers
- and the 3rd-generation isochronous ABI in raw1394 (rawiso) were created.
-
-Users:
- libraw1394 users via the long deprecated API raw1394_iso_write,
- raw1394_start_iso_write, raw1394_start_iso_rcv, raw1394_stop_iso_rcv
-
- libdc1394, which optionally uses these old libraw1394 calls
- alternatively to the more efficient video1394 ABI
diff --git a/Documentation/ABI/removed/video1394 b/Documentation/ABI/removed/video1394
new file mode 100644
index 00000000000..c39c25aee77
--- /dev/null
+++ b/Documentation/ABI/removed/video1394
@@ -0,0 +1,16 @@
+What: video1394 (a.k.a. "OHCI-1394 Video support" for FireWire)
+Date: May 2010 (scheduled), finally removed in kernel v2.6.37
+Contact: linux1394-devel@lists.sourceforge.net
+Description:
+ /dev/video1394/* were character device files, one for each FireWire
+ controller, which were used for isochronous I/O. It was added as an
+ alternative to raw1394's isochronous I/O functionality which had
+ performance issues in its first generation. Any video1394 user had
+ to use raw1394 + libraw1394 too because video1394 did not provide
+ asynchronous I/O for device discovery and configuration.
+ Replaced by /dev/fw*, i.e. the <linux/firewire-cdev.h> ABI of
+ firewire-core.
+
+Users:
+ libdc1394 (works with firewire-cdev too, transparent to library ABI
+ users)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 9961f1564d2..e833c8c81e6 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -502,16 +502,6 @@ Who: Thomas Gleixner <tglx@linutronix.de>
----------------------------
-What: old ieee1394 subsystem (CONFIG_IEEE1394)
-When: 2.6.37
-Files: drivers/ieee1394/ except init_ohci1394_dma.c
-Why: superseded by drivers/firewire/ (CONFIG_FIREWIRE) which offers more
- features, better performance, and better security, all with smaller
- and more modern code base
-Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
-
-----------------------------
-
What: The acpi_sleep=s4_nonvs command line option
When: 2.6.37
Files: arch/x86/kernel/acpi/sleep.c
diff --git a/drivers/Makefile b/drivers/Makefile
index 167af319cfd..14cf9077bb2 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -51,7 +51,6 @@ obj-y += net/
obj-$(CONFIG_ATM) += atm/
obj-$(CONFIG_FUSION) += message/
obj-y += firewire/
-obj-y += ieee1394/
obj-$(CONFIG_UIO) += uio/
obj-y += cdrom/
obj-y += auxdisplay/
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index fcf3ea28340..40a222e19b2 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -3,9 +3,6 @@ menu "IEEE 1394 (FireWire) support"
# firewire-core does not depend on PCI but is
# not useful without PCI controller driver
-comment "You can enable one or both FireWire driver stacks."
-comment "The newer stack is recommended."
-
config FIREWIRE
tristate "FireWire driver stack"
select CRC_ITU_T
@@ -64,8 +61,6 @@ config FIREWIRE_NET
To compile this driver as a module, say M here: The module will be
called firewire-net.
-source "drivers/ieee1394/Kconfig"
-
config FIREWIRE_NOSY
tristate "Nosy - a FireWire traffic sniffer for PCILynx cards"
depends on PCI
diff --git a/drivers/firewire/Makefile b/drivers/firewire/Makefile
index 3c6a7fb20aa..e3870d5c43d 100644
--- a/drivers/firewire/Makefile
+++ b/drivers/firewire/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o
obj-$(CONFIG_FIREWIRE_SBP2) += firewire-sbp2.o
obj-$(CONFIG_FIREWIRE_NET) += firewire-net.o
obj-$(CONFIG_FIREWIRE_NOSY) += nosy.o
+obj-$(CONFIG_PROVIDE_OHCI1394_DMA_INIT) += init_ohci1394_dma.o
diff --git a/drivers/ieee1394/init_ohci1394_dma.c b/drivers/firewire/init_ohci1394_dma.c
index ddaab6eb8ac..a9a347adb35 100644
--- a/drivers/ieee1394/init_ohci1394_dma.c
+++ b/drivers/firewire/init_ohci1394_dma.c
@@ -32,23 +32,41 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <linux/interrupt.h> /* for ohci1394.h */
#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
#include <linux/pci.h> /* for PCI defines */
-#include <linux/init_ohci1394_dma.h>
+#include <linux/string.h>
+
#include <asm/pci-direct.h> /* for direct PCI config space access */
#include <asm/fixmap.h>
-#include "ieee1394_types.h"
-#include "ohci1394.h"
+#include <linux/init_ohci1394_dma.h>
+#include "ohci.h"
int __initdata init_ohci1394_dma_early;
+struct ohci {
+ void __iomem *registers;
+};
+
+static inline void reg_write(const struct ohci *ohci, int offset, u32 data)
+{
+ writel(data, ohci->registers + offset);
+}
+
+static inline u32 reg_read(const struct ohci *ohci, int offset)
+{
+ return readl(ohci->registers + offset);
+}
+
+#define OHCI_LOOP_COUNT 100 /* Number of loops for reg read waits */
+
/* Reads a PHY register of an OHCI-1394 controller */
-static inline u8 __init get_phy_reg(struct ti_ohci *ohci, u8 addr)
+static inline u8 __init get_phy_reg(struct ohci *ohci, u8 addr)
{
int i;
- quadlet_t r;
+ u32 r;
reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000);
@@ -63,22 +81,22 @@ static inline u8 __init get_phy_reg(struct ti_ohci *ohci, u8 addr)
}
/* Writes to a PHY register of an OHCI-1394 controller */
-static inline void __init set_phy_reg(struct ti_ohci *ohci, u8 addr, u8 data)
+static inline void __init set_phy_reg(struct ohci *ohci, u8 addr, u8 data)
{
int i;
reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000);
for (i = 0; i < OHCI_LOOP_COUNT; i++) {
- u32 r = reg_read(ohci, OHCI1394_PhyControl);
- if (!(r & 0x00004000))
+ if (!(reg_read(ohci, OHCI1394_PhyControl) & 0x00004000))
break;
mdelay(1);
}
}
/* Resets an OHCI-1394 controller (for sane state before initialization) */
-static inline void __init init_ohci1394_soft_reset(struct ti_ohci *ohci) {
+static inline void __init init_ohci1394_soft_reset(struct ohci *ohci)
+{
int i;
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
@@ -91,10 +109,14 @@ static inline void __init init_ohci1394_soft_reset(struct ti_ohci *ohci) {
}
}
+#define OHCI1394_MAX_AT_REQ_RETRIES 0xf
+#define OHCI1394_MAX_AT_RESP_RETRIES 0x2
+#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8
+
/* Basic OHCI-1394 register and port inititalization */
-static inline void __init init_ohci1394_initialize(struct ti_ohci *ohci)
+static inline void __init init_ohci1394_initialize(struct ohci *ohci)
{
- quadlet_t bus_options;
+ u32 bus_options;
int num_ports, i;
/* Put some defaults to these undefined bus options */
@@ -116,7 +138,7 @@ static inline void __init init_ohci1394_initialize(struct ti_ohci *ohci)
/* enable phys */
reg_write(ohci, OHCI1394_LinkControlSet,
- OHCI1394_LinkControl_RcvPhyPkt);
+ OHCI1394_LinkControl_rcvPhyPkt);
/* Don't accept phy packets into AR request context */
reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400);
@@ -128,7 +150,7 @@ static inline void __init init_ohci1394_initialize(struct ti_ohci *ohci)
reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);
/* Accept asyncronous transfer requests from all nodes for now */
- reg_write(ohci,OHCI1394_AsReqFilterHiSet, 0x80000000);
+ reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);
/* Specify asyncronous transfer retries */
reg_write(ohci, OHCI1394_ATRetries,
@@ -137,7 +159,8 @@ static inline void __init init_ohci1394_initialize(struct ti_ohci *ohci)
(OHCI1394_MAX_PHYS_RESP_RETRIES<<8));
/* We don't want hardware swapping */
- reg_write(ohci, OHCI1394_HCControlClear, OHCI1394_HCControl_noByteSwap);
+ reg_write(ohci, OHCI1394_HCControlClear,
+ OHCI1394_HCControl_noByteSwapData);
/* Enable link */
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
@@ -164,11 +187,11 @@ static inline void __init init_ohci1394_initialize(struct ti_ohci *ohci)
* has to be enabled after each bus reset when needed. We resort
* to polling here because on early boot, we have no interrupts.
*/
-static inline void __init init_ohci1394_wait_for_busresets(struct ti_ohci *ohci)
+static inline void __init init_ohci1394_wait_for_busresets(struct ohci *ohci)
{
int i, events;
- for (i=0; i < 9; i++) {
+ for (i = 0; i < 9; i++) {
mdelay(200);
events = reg_read(ohci, OHCI1394_IntEventSet);
if (events & OHCI1394_busReset)
@@ -182,18 +205,18 @@ static inline void __init init_ohci1394_wait_for_busresets(struct ti_ohci *ohci)
* This enables remote DMA access over IEEE1394 from every host for the low
* 4GB of address space. DMA accesses above 4GB are not available currently.
*/
-static inline void __init init_ohci1394_enable_physical_dma(struct ti_ohci *hci)
+static inline void __init init_ohci1394_enable_physical_dma(struct ohci *ohci)
{
- reg_write(hci, OHCI1394_PhyReqFilterHiSet, 0xffffffff);
- reg_write(hci, OHCI1394_PhyReqFilterLoSet, 0xffffffff);
- reg_write(hci, OHCI1394_PhyUpperBound, 0xffff0000);
+ reg_write(ohci, OHCI1394_PhyReqFilterHiSet, 0xffffffff);
+ reg_write(ohci, OHCI1394_PhyReqFilterLoSet, 0xffffffff);
+ reg_write(ohci, OHCI1394_PhyUpperBound, 0xffff0000);
}
/**
* init_ohci1394_reset_and_init_dma - init controller and enable DMA
* This initializes the given controller and enables physical DMA engine in it.
*/
-static inline void __init init_ohci1394_reset_and_init_dma(struct ti_ohci *ohci)
+static inline void __init init_ohci1394_reset_and_init_dma(struct ohci *ohci)
{
/* Start off with a soft reset, clears everything to a sane state. */
init_ohci1394_soft_reset(ohci);
@@ -225,7 +248,7 @@ static inline void __init init_ohci1394_reset_and_init_dma(struct ti_ohci *ohci)
static inline void __init init_ohci1394_controller(int num, int slot, int func)
{
unsigned long ohci_base;
- struct ti_ohci ohci;
+ struct ohci ohci;
printk(KERN_INFO "init_ohci1394_dma: initializing OHCI-1394"
" at %02x:%02x.%x\n", num, slot, func);
@@ -235,7 +258,7 @@ static inline void __init init_ohci1394_controller(int num, int slot, int func)
set_fixmap_nocache(FIX_OHCI1394_BASE, ohci_base);
- ohci.registers = (void *)fix_to_virt(FIX_OHCI1394_BASE);
+ ohci.registers = (void __iomem *)fix_to_virt(FIX_OHCI1394_BASE);
init_ohci1394_reset_and_init_dma(&ohci);
}
@@ -247,6 +270,7 @@ static inline void __init init_ohci1394_controller(int num, int slot, int func)
void __init init_ohci1394_dma_on_all_controllers(void)
{
int num, slot, func;
+ u32 class;
if (!early_pci_allowed())
return;
@@ -255,9 +279,9 @@ void __init init_ohci1394_dma_on_all_controllers(void)
for (num = 0; num < 32; num++) {
for (slot = 0; slot < 32; slot++) {
for (func = 0; func < 8; func++) {
- u32 class = read_pci_config(num,slot,func,
+ class = read_pci_config(num, slot, func,
PCI_CLASS_REVISION);
- if ((class == 0xffffffff))
+ if (class == 0xffffffff)
continue; /* No device at this func */
if (class>>8 != PCI_CLASS_SERIAL_FIREWIRE_OHCI)
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
deleted file mode 100644
index e02096cf7d9..00000000000
--- a/drivers/ieee1394/Kconfig
+++ /dev/null
@@ -1,182 +0,0 @@
-config IEEE1394
- tristate "Legacy alternative FireWire driver stack"
- depends on PCI || BROKEN
- help
- IEEE 1394 describes a high performance serial bus, which is also
- known as FireWire(tm) or i.Link(tm) and is used for connecting all
- sorts of devices (most notably digital video cameras) to your
- computer.
-
- If you have FireWire hardware and want to use it, say Y here. This
- is the core support only, you will also need to select a driver for
- your IEEE 1394 adapter.
-
- To compile this driver as a module, say M here: the module will be
- called ieee1394.
-
- NOTE:
- ieee1394 is superseded by the newer firewire-core driver. See
- http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
- further information on how to switch to the new FireWire drivers.
-
-config IEEE1394_OHCI1394
- tristate "OHCI-1394 controllers"
- depends on PCI && IEEE1394
- help
- Enable this driver if you have an IEEE 1394 controller based on the
- OHCI-1394 specification. The current driver is only tested with OHCI
- chipsets made by Texas Instruments and NEC. Most third-party vendors
- use one of these chipsets. It should work with any OHCI-1394
- compliant card, however.
-
- To compile this driver as a module, say M here: the module will be
- called ohci1394.
-
- NOTE:
- ohci1394 is superseded by the newer firewire-ohci driver. See
- http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
- further information on how to switch to the new FireWire drivers.
-
- If you want to install firewire-ohci and ohci1394 together, you
- should configure them only as modules and blacklist the driver(s)
- which you don't want to have auto-loaded. Add either
-
- blacklist ohci1394
- blacklist video1394
- blacklist dv1394
- or
- blacklist firewire-ohci
-
- to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf
- depending on your distribution.
-
-comment "PCILynx controller requires I2C"
- depends on IEEE1394 && I2C=n
-
-config IEEE1394_PCILYNX
- tristate "PCILynx controller"
- depends on PCI && IEEE1394 && I2C
- select I2C_ALGOBIT
- help
- Say Y here if you have an IEEE-1394 controller with the Texas
- Instruments PCILynx chip. Note: this driver is written for revision
- 2 of this chip and may not work with revision 0.
-
- To compile this driver as a module, say M here: the module will be
- called pcilynx.
-
- Only some old and now very rare PCI and CardBus cards and
- PowerMacs G3 B&W contain the PCILynx controller. Therefore
- almost everybody can say N here.
-
-comment "SBP-2 support (for storage devices) requires SCSI"
- depends on IEEE1394 && SCSI=n
-
-config IEEE1394_SBP2
- tristate "Storage devices (SBP-2 protocol)"
- depends on IEEE1394 && SCSI
- help
- This option enables you to use SBP-2 devices connected to an IEEE
- 1394 bus. SBP-2 devices include storage devices like harddisks and
- DVD drives, also some other FireWire devices like scanners.
-
- You should also enable support for disks, CD-ROMs, etc. in the SCSI
- configuration section.
-
- To compile this driver as a module, say M here: the module will be
- called sbp2.
-
- NOTE:
- sbp2 is superseded by the newer firewire-sbp2 driver. See
- http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
- further information on how to switch to the new FireWire drivers.
-
-config IEEE1394_SBP2_PHYS_DMA
- bool "Enable replacement for physical DMA in SBP2"
- depends on IEEE1394_SBP2 && VIRT_TO_BUS && EXPERIMENTAL
- help
- This builds sbp2 for use with non-OHCI host adapters which do not
- support physical DMA or for when ohci1394 is run with phys_dma=0.
- Physical DMA is data movement without assistance of the drivers'
- interrupt handlers. This option includes the interrupt handlers
- that are required in absence of this hardware feature.
-
- This option is buggy and currently broken on some architectures.
- If unsure, say N.
-
-config IEEE1394_ETH1394_ROM_ENTRY
- depends on IEEE1394
- bool
- default n
-
-config IEEE1394_ETH1394
- tristate "IP networking over 1394 (experimental)"
- depends on IEEE1394 && EXPERIMENTAL && INET
- select IEEE1394_ETH1394_ROM_ENTRY
- help
- This driver implements a functional majority of RFC 2734: IPv4 over
- 1394. It will provide IP connectivity with implementations of RFC
- 2734 found on other operating systems. It will not communicate with
- older versions of this driver found in stock kernels prior to 2.6.3.
- This driver is still considered experimental. It does not yet support
- MCAP, therefore multicast support is significantly limited.
-
- The module is called eth1394 although it does not emulate Ethernet.
-
- NOTE:
- eth1394 is superseded by the newer firewire-net driver. See
- http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
- further information on how to switch to the new FireWire drivers.
-
-config IEEE1394_RAWIO
- tristate "raw1394 userspace interface"
- depends on IEEE1394
- help
- This option adds support for the raw1394 device file which enables
- direct communication of user programs with IEEE 1394 devices
- (isochronous and asynchronous). Almost all application programs
- which access FireWire require this option.
-
- To compile this driver as a module, say M here: the module will be
- called raw1394.
-
- NOTE:
- raw1394 is superseded by the newer firewire-core driver. See
- http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
- further information on how to switch to the new FireWire drivers.
-
-config IEEE1394_VIDEO1394
- tristate "video1394 userspace interface"
- depends on IEEE1394 && IEEE1394_OHCI1394
- help
- This option adds support for the video1394 device files which enable
- isochronous communication of user programs with IEEE 1394 devices,
- especially video capture or export. This interface is used by all
- libdc1394 based programs and by several other programs, in addition to
- the raw1394 interface. It is generally not required for DV capture.
-
- To compile this driver as a module, say M here: the module will be
- called video1394.
-
- NOTE:
- video1394 is superseded by the newer firewire-core driver. See
- http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
- further information on how to switch to the new FireWire drivers.
-
-config IEEE1394_DV1394
- tristate "dv1394 userspace interface (deprecated)"
- depends on IEEE1394 && IEEE1394_OHCI1394
- help
- The dv1394 driver is unsupported and may be removed from Linux in a
- future release. Its functionality is now provided by either
- raw1394 or firewire-core together with libraries such as libiec61883.
-
-config IEEE1394_VERBOSEDEBUG
- bool "Excessive debugging output"
- depends on IEEE1394
- help
- If you say Y here, you will get very verbose debugging logs from the
- ieee1394 drivers, including sent and received packet headers. This
- will quickly result in large amounts of data sent to the system log.
-
- Say Y if you really need the debugging output. Everyone else says N.
diff --git a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile
deleted file mode 100644
index 1f8153b5750..00000000000
--- a/drivers/ieee1394/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Makefile for the Linux IEEE 1394 implementation
-#
-
-ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
- highlevel.o csr.o nodemgr.o dma.o iso.o \
- csr1212.o config_roms.o
-
-obj-$(CONFIG_IEEE1394) += ieee1394.o
-obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o
-obj-$(CONFIG_IEEE1394_OHCI1394) += ohci1394.o
-obj-$(CONFIG_IEEE1394_VIDEO1394) += video1394.o
-obj-$(CONFIG_IEEE1394_RAWIO) += raw1394.o
-obj-$(CONFIG_IEEE1394_SBP2) += sbp2.o
-obj-$(CONFIG_IEEE1394_DV1394) += dv1394.o
-obj-$(CONFIG_IEEE1394_ETH1394) += eth1394.o
-
-obj-$(CONFIG_PROVIDE_OHCI1394_DMA_INIT) += init_ohci1394_dma.o
diff --git a/drivers/ieee1394/config_roms.c b/drivers/ieee1394/config_roms.c
deleted file mode 100644
index 1b981207fa7..00000000000
--- a/drivers/ieee1394/config_roms.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * ConfigROM entries
- *
- * Copyright (C) 2004 Ben Collins
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#include <linux/types.h>
-
-#include "csr1212.h"
-#include "ieee1394.h"
-#include "ieee1394_types.h"
-#include "hosts.h"
-#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "csr.h"
-#include "config_roms.h"
-
-struct hpsb_config_rom_entry {
- const char *name;
-
- /* Base initialization, called at module load */
- int (*init)(void);
-
- /* Cleanup called at module exit */
- void (*cleanup)(void);
-
- /* The flag added to host->config_roms */
- unsigned int flag;
-};
-
-/* The default host entry. This must succeed. */
-int hpsb_default_host_entry(struct hpsb_host *host)
-{
- struct csr1212_keyval *root;
- struct csr1212_keyval *vend_id = NULL;
- struct csr1212_keyval *text = NULL;
- char csr_name[128];
- int ret;
-
- sprintf(csr_name, "Linux - %s", host->driver->name);
- root = host->csr.rom->root_kv;
-
- vend_id = csr1212_new_immediate(CSR1212_KV_ID_VENDOR, host->csr.guid_hi >> 8);
- text = csr1212_new_string_descriptor_leaf(csr_name);
-
- if (!vend_id || !text) {
- if (vend_id)
- csr1212_release_keyval(vend_id);
- if (text)
- csr1212_release_keyval(text);
- csr1212_destroy_csr(host->csr.rom);
- return -ENOMEM;
- }
-
- csr1212_associate_keyval(vend_id, text);
- csr1212_release_keyval(text);
- ret = csr1212_attach_keyval_to_directory(root, vend_id);
- csr1212_release_keyval(vend_id);
- if (ret != CSR1212_SUCCESS) {
- csr1212_destroy_csr(host->csr.rom);
- return -ENOMEM;
- }
-
- host->update_config_rom = 1;
-
- return 0;
-}
-
-
-#ifdef CONFIG_IEEE1394_ETH1394_ROM_ENTRY
-#include "eth1394.h"
-
-static struct csr1212_keyval *ip1394_ud;
-
-static int config_rom_ip1394_init(void)
-{
- struct csr1212_keyval *spec_id = NULL;
- struct csr1212_keyval *spec_desc = NULL;
- struct csr1212_keyval *ver = NULL;
- struct csr1212_keyval *ver_desc = NULL;
- int ret = -ENOMEM;
-
- ip1394_ud = csr1212_new_directory(CSR1212_KV_ID_UNIT);
-
- spec_id = csr1212_new_immediate(CSR1212_KV_ID_SPECIFIER_ID,
- ETHER1394_GASP_SPECIFIER_ID);
- spec_desc = csr1212_new_string_descriptor_leaf("IANA");
- ver = csr1212_new_immediate(CSR1212_KV_ID_VERSION,
- ETHER1394_GASP_VERSION);
- ver_desc = csr1212_new_string_descriptor_leaf("IPv4");
-
- if (!ip1394_ud || !spec_id || !spec_desc || !ver || !ver_desc)
- goto ip1394_fail;
-
- csr1212_associate_keyval(spec_id, spec_desc);
- csr1212_associate_keyval(ver, ver_desc);
- if (csr1212_attach_keyval_to_directory(ip1394_ud, spec_id)
- == CSR1212_SUCCESS &&
- csr1212_attach_keyval_to_directory(ip1394_ud, ver)
- == CSR1212_SUCCESS)
- ret = 0;
-
-ip1394_fail:
- if (ret && ip1394_ud) {
- csr1212_release_keyval(ip1394_ud);
- ip1394_ud = NULL;
- }
-
- if (spec_id)
- csr1212_release_keyval(spec_id);
- if (spec_desc)
- csr1212_release_keyval(spec_desc);
- if (ver)
- csr1212_release_keyval(ver);
- if (ver_desc)
- csr1212_release_keyval(ver_desc);
-
- return ret;
-}
-
-static void config_rom_ip1394_cleanup(void)
-{
- if (ip1394_ud) {
- csr1212_release_keyval(ip1394_ud);
- ip1394_ud = NULL;
- }
-}
-
-int hpsb_config_rom_ip1394_add(struct hpsb_host *host)
-{
- if (!ip1394_ud)
- return -ENODEV;
-
- if (csr1212_attach_keyval_to_directory(host->csr.rom->root_kv,
- ip1394_ud) != CSR1212_SUCCESS)
- return -ENOMEM;
-
- host->config_roms |= HPSB_CONFIG_ROM_ENTRY_IP1394;
- host->update_config_rom = 1;
- return 0;
-}
-EXPORT_SYMBOL_GPL(hpsb_config_rom_ip1394_add);
-
-void hpsb_config_rom_ip1394_remove(struct hpsb_host *host)
-{
- csr1212_detach_keyval_from_directory(host->csr.rom->root_kv, ip1394_ud);
- host->config_roms &= ~HPSB_CONFIG_ROM_ENTRY_IP1394;
- host->update_config_rom = 1;
-}
-EXPORT_SYMBOL_GPL(hpsb_config_rom_ip1394_remove);
-
-static struct hpsb_config_rom_entry ip1394_entry = {
- .name = "ip1394",
- .init = config_rom_ip1394_init,
- .cleanup = config_rom_ip1394_cleanup,
- .flag = HPSB_CONFIG_ROM_ENTRY_IP1394,
-};
-
-#endif /* CONFIG_IEEE1394_ETH1394_ROM_ENTRY */
-
-static struct hpsb_config_rom_entry *const config_rom_entries[] = {
-#ifdef CONFIG_IEEE1394_ETH1394_ROM_ENTRY
- &ip1394_entry,
-#endif
-};
-
-/* Initialize all config roms */
-int hpsb_init_config_roms(void)
-{
- int i, error = 0;
-
- for (i = 0; i < ARRAY_SIZE(config_rom_entries); i++)
- if (config_rom_entries[i]->init()) {
- HPSB_ERR("Failed to initialize config rom entry `%s'",
- config_rom_entries[i]->name);
- error = -1;
- }
-
- return error;
-}
-
-/* Cleanup all config roms */
-void hpsb_cleanup_config_roms(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(config_rom_entries); i++)
- config_rom_entries[i]->cleanup();
-}
diff --git a/drivers/ieee1394/config_roms.h b/drivers/ieee1394/config_roms.h
deleted file mode 100644
index 1f5cd1f16c4..00000000000
--- a/drivers/ieee1394/config_roms.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _IEEE1394_CONFIG_ROMS_H
-#define _IEEE1394_CONFIG_ROMS_H
-
-struct hpsb_host;
-
-int hpsb_default_host_entry(struct hpsb_host *host);
-int hpsb_init_config_roms(void);
-void hpsb_cleanup_config_roms(void);
-
-/* List of flags to check if a host contains a certain extra config rom
- * entry. Available in the host->config_roms member. */
-#define HPSB_CONFIG_ROM_ENTRY_IP1394 0x00000001
-
-#ifdef CONFIG_IEEE1394_ETH1394_ROM_ENTRY
-int hpsb_config_rom_ip1394_add(struct hpsb_host *host);
-void hpsb_config_rom_ip1394_remove(struct hpsb_host *host);
-#endif
-
-#endif /* _IEEE1394_CONFIG_ROMS_H */
diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
deleted file mode 100644
index d696f69ebce..00000000000
--- a/drivers/ieee1394/csr.c
+++ /dev/null
@@ -1,843 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * CSR implementation, iso/bus manager implementation.
- *
- * Copyright (C) 1999 Andreas E. Bombe
- * 2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- *
- *
- * Contributions:
- *
- * Manfred Weihs <weihs@ict.tuwien.ac.at>
- * configuration ROM manipulation
- *
- */
-
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/param.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-
-#include "csr1212.h"
-#include "ieee1394_types.h"
-#include "hosts.h"
-#include "ieee1394.h"
-#include "highlevel.h"
-#include "ieee1394_core.h"
-
-/* Module Parameters */
-/* this module parameter can be used to disable mapping of the FCP registers */
-
-static int fcp = 1;
-module_param(fcp, int, 0444);
-MODULE_PARM_DESC(fcp, "Map FCP registers (default = 1, disable = 0).");
-
-static struct csr1212_keyval *node_cap = NULL;
-
-static void add_host(struct hpsb_host *host);
-static void remove_host(struct hpsb_host *host);
-static void host_reset(struct hpsb_host *host);
-static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
- u64 addr, size_t length, u16 fl);
-static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
- quadlet_t *data, u64 addr, size_t length, u16 flags);
-static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
- u64 addr, size_t length, u16 flags);
-static int write_regs(struct hpsb_host *host, int nodeid, int destid,
- quadlet_t *data, u64 addr, size_t length, u16 flags);
-static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl);
-static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
- u64 addr, octlet_t data, octlet_t arg, int extcode, u16 fl);
-static int read_config_rom(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
- u64 addr, size_t length, u16 fl);
-static u64 allocate_addr_range(u64 size, u32 alignment, void *__host);
-static void release_addr_range(u64 addr, void *__host);
-
-static struct hpsb_highlevel csr_highlevel = {
- .name = "standard registers",
- .add_host = add_host,
- .remove_host = remove_host,
- .host_reset = host_reset,
-};
-
-static const struct hpsb_address_ops map_ops = {
- .read = read_maps,
-};
-
-static const struct hpsb_address_ops fcp_ops = {
- .write = write_fcp,
-};
-
-static const struct hpsb_address_ops reg_ops = {
- .read = read_regs,
- .write = write_regs,
- .lock = lock_regs,
- .lock64 = lock64_regs,
-};
-
-static const struct hpsb_address_ops config_rom_ops = {
- .read = read_config_rom,
-};
-
-struct csr1212_bus_ops csr_bus_ops = {
- .allocate_addr_range = allocate_addr_range,
- .release_addr = release_addr_range,
-};
-
-
-static u16 csr_crc16(unsigned *data, int length)
-{
- int check=0, i;
- int shift, sum, next=0;
-
- for (i = length; i; i--) {
- for (next = check, shift = 28; shift >= 0; shift -= 4 ) {
- sum = ((next >> 12) ^ (be32_to_cpu(*data) >> shift)) & 0xf;
- next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
- }
- check = next & 0xffff;
- data++;
- }
-
- return check;
-}
-
-static void host_reset(struct hpsb_host *host)
-{
- host->csr.state &= 0x300;
-
- host->csr.bus_manager_id = 0x3f;
- host->csr.bandwidth_available = 4915;
- host->csr.channels_available_hi = 0xfffffffe; /* pre-alloc ch 31 per 1394a-2000 */
- host->csr.channels_available_lo = ~0;
- host->csr.broadcast_channel = 0x80000000 | 31;
-
- if (host->is_irm) {
- if (host->driver->hw_csr_reg) {
- host->driver->hw_csr_reg(host, 2, 0xfffffffe, ~0);
- }
- }
-
- host->csr.node_ids = host->node_id << 16;
-
- if (!host->is_root) {
- /* clear cmstr bit */
- host->csr.state &= ~0x100;
- }
-
- be32_add_cpu(&host->csr.topology_map[1], 1);
- host->csr.topology_map[2] = cpu_to_be32(host->node_count << 16
- | host->selfid_count);
- host->csr.topology_map[0] =
- cpu_to_be32((host->selfid_count + 2) << 16
- | csr_crc16(host->csr.topology_map + 1,
- host->selfid_count + 2));
-
- be32_add_cpu(&host->csr.speed_map[1], 1);
- host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16
- | csr_crc16(host->csr.speed_map+1,
- 0x3f1));
-}
-
-/*
- * HI == seconds (bits 0:2)
- * LO == fractions of a second in units of 125usec (bits 19:31)
- *
- * Convert SPLIT_TIMEOUT to jiffies.
- * The default and minimum as per 1394a-2000 clause 8.3.2.2.6 is 100ms.
- */
-static inline void calculate_expire(struct csr_control *csr)
-{
- unsigned int usecs = (csr->split_timeout_hi & 7) * 1000000 +
- (csr->split_timeout_lo >> 19) * 125;
-
- csr->expire = usecs_to_jiffies(usecs > 100000 ? usecs : 100000);
- HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
-}
-
-
-static void add_host(struct hpsb_host *host)
-{
- struct csr1212_keyval *root;
- quadlet_t bus_info[CSR_BUS_INFO_SIZE];
-
- hpsb_register_addrspace(&csr_highlevel, host, &reg_ops,
- CSR_REGISTER_BASE,
- CSR_REGISTER_BASE + CSR_CONFIG_ROM);
- hpsb_register_addrspace(&csr_highlevel, host, &config_rom_ops,
- CSR_REGISTER_BASE + CSR_CONFIG_ROM,
- CSR_REGISTER_BASE + CSR_CONFIG_ROM_END);
- if (fcp) {
- hpsb_register_addrspace(&csr_highlevel, host, &fcp_ops,
- CSR_REGISTER_BASE + CSR_FCP_COMMAND,
- CSR_REGISTER_BASE + CSR_FCP_END);
- }
- hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
- CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP,
- CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP_END);
- hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
- CSR_REGISTER_BASE + CSR_SPEED_MAP,
- CSR_REGISTER_BASE + CSR_SPEED_MAP_END);
-
- spin_lock_init(&host->csr.lock);
-
- host->csr.state = 0;
- host->csr.node_ids = 0;
- host->csr.split_timeout_hi = 0;
- host->csr.split_timeout_lo = 800 << 19;
- calculate_expire(&host->csr);
- host->csr.cycle_time = 0;
- host->csr.bus_time = 0;
- host->csr.bus_manager_id = 0x3f;
- host->csr.bandwidth_available = 4915;
- host->csr.channels_available_hi = 0xfffffffe; /* pre-alloc ch 31 per 1394a-2000 */
- host->csr.channels_available_lo = ~0;
- host->csr.broadcast_channel = 0x80000000 | 31;
-
- if (host->is_irm) {
- if (host->driver->hw_csr_reg) {
- host->driver->hw_csr_reg(host, 2, 0xfffffffe, ~0);
- }
- }
-
- if (host->csr.max_rec >= 9)
- host->csr.max_rom = 2;
- else if (host->csr.max_rec >= 5)
- host->csr.max_rom = 1;
- else
- host->csr.max_rom = 0;
-
- host->csr.generation = 2;
-
- bus_info[1] = IEEE1394_BUSID_MAGIC;
- bus_info[2] = cpu_to_be32((hpsb_disable_irm ? 0 : 1 << CSR_IRMC_SHIFT) |
- (1 << CSR_CMC_SHIFT) |
- (1 << CSR_ISC_SHIFT) |
- (0 << CSR_BMC_SHIFT) |
- (0 << CSR_PMC_SHIFT) |
- (host->csr.cyc_clk_acc << CSR_CYC_CLK_ACC_SHIFT) |
- (host->csr.max_rec << CSR_MAX_REC_SHIFT) |
- (host->csr.max_rom << CSR_MAX_ROM_SHIFT) |
- (host->csr.generation << CSR_GENERATION_SHIFT) |
- host->csr.lnk_spd);
-
- bus_info[3] = cpu_to_be32(host->csr.guid_hi);
- bus_info[4] = cpu_to_be32(host->csr.guid_lo);
-
- /* The hardware copy of the bus info block will be set later when a
- * bus reset is issued. */
-
- csr1212_init_local_csr(host->csr.rom, bus_info, host->csr.max_rom);
-
- root = host->csr.rom->root_kv;
-
- if(csr1212_attach_keyval_to_directory(root, node_cap) != CSR1212_SUCCESS) {
- HPSB_ERR("Failed to attach Node Capabilities to root directory");
- }
-
- host->update_config_rom = 1;
-}
-
-static void remove_host(struct hpsb_host *host)
-{
- quadlet_t bus_info[CSR_BUS_INFO_SIZE];
-
- bus_info[1] = IEEE1394_BUSID_MAGIC;
- bus_info[2] = cpu_to_be32((0 << CSR_IRMC_SHIFT) |
- (0 << CSR_CMC_SHIFT) |
- (0 << CSR_ISC_SHIFT) |
- (0 << CSR_BMC_SHIFT) |
- (0 << CSR_PMC_SHIFT) |
- (host->csr.cyc_clk_acc << CSR_CYC_CLK_ACC_SHIFT) |
- (host->csr.max_rec << CSR_MAX_REC_SHIFT) |
- (0 << CSR_MAX_ROM_SHIFT) |
- (0 << CSR_GENERATION_SHIFT) |
- host->csr.lnk_spd);
-
- bus_info[3] = cpu_to_be32(host->csr.guid_hi);
- bus_info[4] = cpu_to_be32(host->csr.guid_lo);
-
- csr1212_detach_keyval_from_directory(host->csr.rom->root_kv, node_cap);
-
- csr1212_init_local_csr(host->csr.rom, bus_info, 0);
- host->update_config_rom = 1;
-}
-
-
-int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom,
- size_t buffersize, unsigned char rom_version)
-{
- unsigned long flags;
- int ret;
-
- HPSB_NOTICE("hpsb_update_config_rom() is deprecated");
-
- spin_lock_irqsave(&host->csr.lock, flags);
- if (rom_version != host->csr.generation)
- ret = -1;
- else if (buffersize > host->csr.rom->cache_head->size)
- ret = -2;
- else {
- /* Just overwrite the generated ConfigROM image with new data,
- * it can be regenerated later. */
- memcpy(host->csr.rom->cache_head->data, new_rom, buffersize);
- host->csr.rom->cache_head->len = buffersize;
-
- if (host->driver->set_hw_config_rom)
- host->driver->set_hw_config_rom(host, host->csr.rom->bus_info_data);
- /* Increment the generation number to keep some sort of sync
- * with the newer ConfigROM manipulation method. */
- host->csr.generation++;
- if (host->csr.generation > 0xf || host->csr.generation < 2)
- host->csr.generation = 2;
- ret=0;
- }
- spin_unlock_irqrestore(&host->csr.lock, flags);
- return ret;
-}
-
-
-/* Read topology / speed maps and configuration ROM */
-static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
- u64 addr, size_t length, u16 fl)
-{
- unsigned long flags;
- int csraddr = addr - CSR_REGISTER_BASE;
- const char *src;
-
- spin_lock_irqsave(&host->csr.lock, flags);
-
- if (csraddr < CSR_SPEED_MAP) {
- src = ((char *)host->csr.topology_map) + csraddr
- - CSR_TOPOLOGY_MAP;
- } else {
- src = ((char *)host->csr.speed_map) + csraddr - CSR_SPEED_MAP;
- }
-
- memcpy(buffer, src, length);
- spin_unlock_irqrestore(&host->csr.lock, flags);
- return RCODE_COMPLETE;
-}
-
-
-#define out if (--length == 0) break
-
-static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
- u64 addr, size_t length, u16 flags)
-{
- int csraddr = addr - CSR_REGISTER_BASE;
- int oldcycle;
- quadlet_t ret;
-
- if ((csraddr | length) & 0x3)
- return RCODE_TYPE_ERROR;
-
- length /= 4;
-
- switch (csraddr) {
- case CSR_STATE_CLEAR:
- *(buf++) = cpu_to_be32(host->csr.state);
- out;
- case CSR_STATE_SET:
- *(buf++) = cpu_to_be32(host->csr.state);
- out;
- case CSR_NODE_IDS:
- *(buf++) = cpu_to_be32(host->csr.node_ids);
- out;
-
- case CSR_RESET_START:
- return RCODE_TYPE_ERROR;
-
- /* address gap - handled by default below */
-
- case CSR_SPLIT_TIMEOUT_HI:
- *(buf++) = cpu_to_be32(host->csr.split_timeout_hi);
- out;
- case CSR_SPLIT_TIMEOUT_LO:
- *(buf++) = cpu_to_be32(host->csr.split_timeout_lo);
- out;
-
- /* address gap */
- return RCODE_ADDRESS_ERROR;
-
- case CSR_CYCLE_TIME:
- oldcycle = host->csr.cycle_time;
- host->csr.cycle_time =
- host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
-
- if (oldcycle > host->csr.cycle_time) {
- /* cycle time wrapped around */
- host->csr.bus_time += 1 << 7;
- }
- *(buf++) = cpu_to_be32(host->csr.cycle_time);
- out;
- case CSR_BUS_TIME:
- oldcycle = host->csr.cycle_time;
- host->csr.cycle_time =
- host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
-
- if (oldcycle > host->csr.cycle_time) {
- /* cycle time wrapped around */
- host->csr.bus_time += (1 << 7);
- }
- *(buf++) = cpu_to_be32(host->csr.bus_time
- | (host->csr.cycle_time >> 25));
- out;
-
- /* address gap */
- return RCODE_ADDRESS_ERROR;
-
- case CSR_BUSY_TIMEOUT:
- /* not yet implemented */
- return RCODE_ADDRESS_ERROR;
-
- case CSR_BUS_MANAGER_ID:
- if (host->driver->hw_csr_reg)
- ret = host->driver->hw_csr_reg(host, 0, 0, 0);
- else
- ret = host->csr.bus_manager_id;
-
- *(buf++) = cpu_to_be32(ret);
- out;
- case CSR_BANDWIDTH_AVAILABLE:
- if (host->driver->hw_csr_reg)
- ret = host->driver->hw_csr_reg(host, 1, 0, 0);
- else
- ret = host->csr.bandwidth_available;
-
- *(buf++) = cpu_to_be32(ret);
- out;
- case CSR_CHANNELS_AVAILABLE_HI:
- if (host->driver->hw_csr_reg)
- ret = host->driver->hw_csr_reg(host, 2, 0, 0);
- else
- ret = host->csr.channels_available_hi;
-
- *(buf++) = cpu_to_be32(ret);
- out;
- case CSR_CHANNELS_AVAILABLE_LO:
- if (host->driver->hw_csr_reg)
- ret = host->driver->hw_csr_reg(host, 3, 0, 0);
- else
- ret = host->csr.channels_available_lo;
-
- *(buf++) = cpu_to_be32(ret);
- out;
-
- case CSR_BROADCAST_CHANNEL:
- *(buf++) = cpu_to_be32(host->csr.broadcast_channel);
- out;
-
- /* address gap to end - fall through to default */
- default:
- return RCODE_ADDRESS_ERROR;
- }
-
- return RCODE_COMPLETE;
-}
-
-static int write_regs(struct hpsb_host *host, int nodeid, int destid,
- quadlet_t *data, u64 addr, size_t length, u16 flags)
-{
- int csraddr = addr - CSR_REGISTER_BASE;
-
- if ((csraddr | length) & 0x3)
- return RCODE_TYPE_ERROR;
-
- length /= 4;
-
- switch (csraddr) {
- case CSR_STATE_CLEAR:
- /* FIXME FIXME FIXME */
- printk("doh, someone wants to mess with state clear\n");
- out;
- case CSR_STATE_SET:
- printk("doh, someone wants to mess with state set\n");
- out;
-
- case CSR_NODE_IDS:
- host->csr.node_ids &= NODE_MASK << 16;
- host->csr.node_ids |= be32_to_cpu(*(data++)) & (BUS_MASK << 16);
- host->node_id = host->csr.node_ids >> 16;
- host->driver->devctl(host, SET_BUS_ID, host->node_id >> 6);
- out;
-
- case CSR_RESET_START:
- /* FIXME - perform command reset */
- out;
-
- /* address gap */
- return RCODE_ADDRESS_ERROR;
-
- case CSR_SPLIT_TIMEOUT_HI:
- host->csr.split_timeout_hi =
- be32_to_cpu(*(data++)) & 0x00000007;
- calculate_expire(&host->csr);
- out;
- case CSR_SPLIT_TIMEOUT_LO:
- host->csr.split_timeout_lo =
- be32_to_cpu(*(data++)) & 0xfff80000;
- calculate_expire(&host->csr);
- out;
-
- /* address gap */
- return RCODE_ADDRESS_ERROR;
-
- case CSR_CYCLE_TIME:
- /* should only be set by cycle start packet, automatically */
- host->csr.cycle_time = be32_to_cpu(*data);
- host->driver->devctl(host, SET_CYCLE_COUNTER,
- be32_to_cpu(*(data++)));
- out;
- case CSR_BUS_TIME:
- host->csr.bus_time = be32_to_cpu(*(data++)) & 0xffffff80;
- out;
-
- /* address gap */
- return RCODE_ADDRESS_ERROR;
-
- case CSR_BUSY_TIMEOUT:
- /* not yet implemented */
- return RCODE_ADDRESS_ERROR;
-
- case CSR_BUS_MANAGER_ID:
- case CSR_BANDWIDTH_AVAILABLE:
- case CSR_CHANNELS_AVAILABLE_HI:
- case CSR_CHANNELS_AVAILABLE_LO:
- /* these are not writable, only lockable */
- return RCODE_TYPE_ERROR;
-
- case CSR_BROADCAST_CHANNEL:
- /* only the valid bit can be written */
- host->csr.broadcast_channel = (host->csr.broadcast_channel & ~0x40000000)
- | (be32_to_cpu(*data) & 0x40000000);
- out;
-
- /* address gap to end - fall through */
- default:
- return RCODE_ADDRESS_ERROR;
- }
-
- return RCODE_COMPLETE;
-}
-
-#undef out
-
-
-static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl)
-{
- int csraddr = addr - CSR_REGISTER_BASE;
- unsigned long flags;
- quadlet_t *regptr = NULL;
-
- if (csraddr & 0x3)
- return RCODE_TYPE_ERROR;
-
- if (csraddr < CSR_BUS_MANAGER_ID || csraddr > CSR_CHANNELS_AVAILABLE_LO
- || extcode != EXTCODE_COMPARE_SWAP)
- goto unsupported_lockreq;
-
- data = be32_to_cpu(data);
- arg = be32_to_cpu(arg);
-
- /* Is somebody releasing the broadcast_channel on us? */
- if (csraddr == CSR_CHANNELS_AVAILABLE_HI && (data & 0x1)) {
- /* Note: this is may not be the right way to handle
- * the problem, so we should look into the proper way
- * eventually. */
- HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
- "broadcast channel 31. Ignoring.",
- NODE_BUS_ARGS(host, nodeid));
-
- data &= ~0x1; /* keep broadcast channel allocated */
- }
-
- if (host->driver->hw_csr_reg) {
- quadlet_t old;
-
- old = host->driver->
- hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
- data, arg);
-
- *store = cpu_to_be32(old);
- return RCODE_COMPLETE;
- }
-
- spin_lock_irqsave(&host->csr.lock, flags);
-
- switch (csraddr) {
- case CSR_BUS_MANAGER_ID:
- regptr = &host->csr.bus_manager_id;
- *store = cpu_to_be32(*regptr);
- if (*regptr == arg)
- *regptr = data;
- break;
-
- case CSR_BANDWIDTH_AVAILABLE:
- {
- quadlet_t bandwidth;
- quadlet_t old;
- quadlet_t new;
-
- regptr = &host->csr.bandwidth_available;
- old = *regptr;
-
- /* bandwidth available algorithm adapted from IEEE 1394a-2000 spec */
- if (arg > 0x1fff) {
- *store = cpu_to_be32(old); /* change nothing */
- break;
- }
- data &= 0x1fff;
- if (arg >= data) {
- /* allocate bandwidth */
- bandwidth = arg - data;
- if (old >= bandwidth) {
- new = old - bandwidth;
- *store = cpu_to_be32(arg);
- *regptr = new;
- } else {
- *store = cpu_to_be32(old);
- }
- } else {
- /* deallocate bandwidth */
- bandwidth = data - arg;
- if (old + bandwidth < 0x2000) {
- new = old + bandwidth;
- *store = cpu_to_be32(arg);
- *regptr = new;
- } else {
- *store = cpu_to_be32(old);
- }
- }
- break;
- }
-
- case CSR_CHANNELS_AVAILABLE_HI:
- {
- /* Lock algorithm for CHANNELS_AVAILABLE as recommended by 1394a-2000 */
- quadlet_t affected_channels = arg ^ data;
-
- regptr = &host->csr.channels_available_hi;
-
- if ((arg & affected_channels) == (*regptr & affected_channels)) {
- *regptr ^= affected_channels;
- *store = cpu_to_be32(arg);
- } else {
- *store = cpu_to_be32(*regptr);
- }
-
- break;
- }
-
- case CSR_CHANNELS_AVAILABLE_LO:
- {
- /* Lock algorithm for CHANNELS_AVAILABLE as recommended by 1394a-2000 */
- quadlet_t affected_channels = arg ^ data;
-
- regptr = &host->csr.channels_available_lo;
-
- if ((arg & affected_channels) == (*regptr & affected_channels)) {
- *regptr ^= affected_channels;
- *store = cpu_to_be32(arg);
- } else {
- *store = cpu_to_be32(*regptr);
- }
- break;
- }
- }
-
- spin_unlock_irqrestore(&host->csr.lock, flags);
-
- return RCODE_COMPLETE;
-
- unsupported_lockreq:
- switch (csraddr) {
- case CSR_STATE_CLEAR:
- case CSR_STATE_SET:
- case CSR_RESET_START:
- case CSR_NODE_IDS:
- case CSR_SPLIT_TIMEOUT_HI:
- case CSR_SPLIT_TIMEOUT_LO:
- case CSR_CYCLE_TIME:
- case CSR_BUS_TIME:
- case CSR_BROADCAST_CHANNEL:
- return RCODE_TYPE_ERROR;
-
- case CSR_BUSY_TIMEOUT:
- /* not yet implemented - fall through */
- default:
- return RCODE_ADDRESS_ERROR;
- }
-}
-
-static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
- u64 addr, octlet_t data, octlet_t arg, int extcode, u16 fl)
-{
- int csraddr = addr - CSR_REGISTER_BASE;
- unsigned long flags;
-
- data = be64_to_cpu(data);
- arg = be64_to_cpu(arg);
-
- if (csraddr & 0x3)
- return RCODE_TYPE_ERROR;
-
- if (csraddr != CSR_CHANNELS_AVAILABLE
- || extcode != EXTCODE_COMPARE_SWAP)
- goto unsupported_lock64req;
-
- /* Is somebody releasing the broadcast_channel on us? */
- if (csraddr == CSR_CHANNELS_AVAILABLE_HI && (data & 0x100000000ULL)) {
- /* Note: this is may not be the right way to handle
- * the problem, so we should look into the proper way
- * eventually. */
- HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
- "broadcast channel 31. Ignoring.",
- NODE_BUS_ARGS(host, nodeid));
-
- data &= ~0x100000000ULL; /* keep broadcast channel allocated */
- }
-
- if (host->driver->hw_csr_reg) {
- quadlet_t data_hi, data_lo;
- quadlet_t arg_hi, arg_lo;
- quadlet_t old_hi, old_lo;
-
- data_hi = data >> 32;
- data_lo = data & 0xFFFFFFFF;
- arg_hi = arg >> 32;
- arg_lo = arg & 0xFFFFFFFF;
-
- old_hi = host->driver->hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
- data_hi, arg_hi);
-
- old_lo = host->driver->hw_csr_reg(host, ((csraddr + 4) - CSR_BUS_MANAGER_ID) >> 2,
- data_lo, arg_lo);
-
- *store = cpu_to_be64(((octlet_t)old_hi << 32) | old_lo);
- } else {
- octlet_t old;
- octlet_t affected_channels = arg ^ data;
-
- spin_lock_irqsave(&host->csr.lock, flags);
-
- old = ((octlet_t)host->csr.channels_available_hi << 32) | host->csr.channels_available_lo;
-
- if ((arg & affected_channels) == (old & affected_channels)) {
- host->csr.channels_available_hi ^= (affected_channels >> 32);
- host->csr.channels_available_lo ^= (affected_channels & 0xffffffff);
- *store = cpu_to_be64(arg);
- } else {
- *store = cpu_to_be64(old);
- }
-
- spin_unlock_irqrestore(&host->csr.lock, flags);
- }
-
- /* Is somebody erroneously releasing the broadcast_channel on us? */
- if (host->csr.channels_available_hi & 0x1)
- host->csr.channels_available_hi &= ~0x1;
-
- return RCODE_COMPLETE;
-
- unsupported_lock64req:
- switch (csraddr) {
- case CSR_STATE_CLEAR:
- case CSR_STATE_SET:
- case CSR_RESET_START:
- case CSR_NODE_IDS:
- case CSR_SPLIT_TIMEOUT_HI:
- case CSR_SPLIT_TIMEOUT_LO:
- case CSR_CYCLE_TIME:
- case CSR_BUS_TIME:
- case CSR_BUS_MANAGER_ID:
- case CSR_BROADCAST_CHANNEL:
- case CSR_BUSY_TIMEOUT:
- case CSR_BANDWIDTH_AVAILABLE:
- return RCODE_TYPE_ERROR;
-
- default:
- return RCODE_ADDRESS_ERROR;
- }
-}
-
-static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
- quadlet_t *data, u64 addr, size_t length, u16 flags)
-{
- int csraddr = addr - CSR_REGISTER_BASE;
-
- if (length > 512)
- return RCODE_TYPE_ERROR;
-
- switch (csraddr) {
- case CSR_FCP_COMMAND:
- highlevel_fcp_request(host, nodeid, 0, (u8 *)data, length);
- break;
- case CSR_FCP_RESPONSE:
- highlevel_fcp_request(host, nodeid, 1, (u8 *)data, length);
- break;
- default:
- return RCODE_TYPE_ERROR;
- }
-
- return RCODE_COMPLETE;
-}
-
-static int read_config_rom(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
- u64 addr, size_t length, u16 fl)
-{
- u32 offset = addr - CSR1212_REGISTER_SPACE_BASE;
-
- if (csr1212_read(host->csr.rom, offset, buffer, length) == CSR1212_SUCCESS)
- return RCODE_COMPLETE;
- else
- return RCODE_ADDRESS_ERROR;
-}
-
-static u64 allocate_addr_range(u64 size, u32 alignment, void *__host)
-{
- struct hpsb_host *host = (struct hpsb_host*)__host;
-
- return hpsb_allocate_and_register_addrspace(&csr_highlevel,
- host,
- &config_rom_ops,
- size, alignment,
- CSR1212_UNITS_SPACE_BASE,
- CSR1212_UNITS_SPACE_END);
-}
-
-static void release_addr_range(u64 addr, void *__host)
-{
- struct hpsb_host *host = (struct hpsb_host*)__host;
- hpsb_unregister_addrspace(&csr_highlevel, host, addr);
-}
-
-
-int init_csr(void)
-{
- node_cap = csr1212_new_immediate(CSR1212_KV_ID_NODE_CAPABILITIES, 0x0083c0);
- if (!node_cap) {
- HPSB_ERR("Failed to allocate memory for Node Capabilties ConfigROM entry!");
- return -ENOMEM;
- }
-
- hpsb_register_highlevel(&csr_highlevel);
-
- return 0;
-}
-
-void cleanup_csr(void)
-{
- if (node_cap)
- csr1212_release_keyval(node_cap);
- hpsb_unregister_highlevel(&csr_highlevel);
-}
diff --git a/drivers/ieee1394/csr.h b/drivers/ieee1394/csr.h
deleted file mode 100644
index 90fb3f2192c..00000000000
--- a/drivers/ieee1394/csr.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef _IEEE1394_CSR_H
-#define _IEEE1394_CSR_H
-
-#include <linux/spinlock_types.h>
-
-#include "csr1212.h"
-#include "ieee1394_types.h"
-
-#define CSR_REGISTER_BASE 0xfffff0000000ULL
-
-/* register offsets relative to CSR_REGISTER_BASE */
-#define CSR_STATE_CLEAR 0x0
-#define CSR_STATE_SET 0x4
-#define CSR_NODE_IDS 0x8
-#define CSR_RESET_START 0xc
-#define CSR_SPLIT_TIMEOUT_HI 0x18
-#define CSR_SPLIT_TIMEOUT_LO 0x1c
-#define CSR_CYCLE_TIME 0x200
-#define CSR_BUS_TIME 0x204
-#define CSR_BUSY_TIMEOUT 0x210
-#define CSR_BUS_MANAGER_ID 0x21c
-#define CSR_BANDWIDTH_AVAILABLE 0x220
-#define CSR_CHANNELS_AVAILABLE 0x224
-#define CSR_CHANNELS_AVAILABLE_HI 0x224
-#define CSR_CHANNELS_AVAILABLE_LO 0x228
-#define CSR_BROADCAST_CHANNEL 0x234
-#define CSR_CONFIG_ROM 0x400
-#define CSR_CONFIG_ROM_END 0x800
-#define CSR_FCP_COMMAND 0xB00
-#define CSR_FCP_RESPONSE 0xD00
-#define CSR_FCP_END 0xF00
-#define CSR_TOPOLOGY_MAP 0x1000
-#define CSR_TOPOLOGY_MAP_END 0x1400
-#define CSR_SPEED_MAP 0x2000
-#define CSR_SPEED_MAP_END 0x3000
-
-/* IEEE 1394 bus specific Configuration ROM Key IDs */
-#define IEEE1394_KV_ID_POWER_REQUIREMENTS (0x30)
-
-/* IEEE 1394 Bus Information Block specifics */
-#define CSR_BUS_INFO_SIZE (5 * sizeof(quadlet_t))
-
-#define CSR_IRMC_SHIFT 31
-#define CSR_CMC_SHIFT 30
-#define CSR_ISC_SHIFT 29
-#define CSR_BMC_SHIFT 28
-#define CSR_PMC_SHIFT 27
-#define CSR_CYC_CLK_ACC_SHIFT 16
-#define CSR_MAX_REC_SHIFT 12
-#define CSR_MAX_ROM_SHIFT 8
-#define CSR_GENERATION_SHIFT 4
-
-static inline void csr_set_bus_info_generation(struct csr1212_csr *csr, u8 gen)
-{
- csr->bus_info_data[2] &= ~cpu_to_be32(0xf << CSR_GENERATION_SHIFT);
- csr->bus_info_data[2] |= cpu_to_be32((u32)gen << CSR_GENERATION_SHIFT);
-}
-
-struct csr_control {
- spinlock_t lock;
-
- quadlet_t state;
- quadlet_t node_ids;
- quadlet_t split_timeout_hi, split_timeout_lo;
- unsigned long expire; /* Calculated from split_timeout */
- quadlet_t cycle_time;
- quadlet_t bus_time;
- quadlet_t bus_manager_id;
- quadlet_t bandwidth_available;
- quadlet_t channels_available_hi, channels_available_lo;
- quadlet_t broadcast_channel;
-
- /* Bus Info */
- quadlet_t guid_hi, guid_lo;
- u8 cyc_clk_acc;
- u8 max_rec;
- u8 max_rom;
- u8 generation; /* Only use values between 0x2 and 0xf */
- u8 lnk_spd;
-
- unsigned long gen_timestamp[16];
-
- struct csr1212_csr *rom;
-
- quadlet_t topology_map[256];
- quadlet_t speed_map[1024];
-};
-
-extern struct csr1212_bus_ops csr_bus_ops;
-
-int init_csr(void);
-void cleanup_csr(void);
-
-/* hpsb_update_config_rom() is deprecated */
-struct hpsb_host;
-int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom,
- size_t size, unsigned char rom_version);
-
-#endif /* _IEEE1394_CSR_H */
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
deleted file mode 100644
index e76cac64c53..00000000000
--- a/drivers/ieee1394/csr1212.c
+++ /dev/null
@@ -1,1467 +0,0 @@
-/*
- * csr1212.c -- IEEE 1212 Control and Status Register support for Linux
- *
- * Copyright (C) 2003 Francois Retief <fgretief@sun.ac.za>
- * Steve Kinneberg <kinnebergsteve@acmsystems.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/* TODO List:
- * - Verify interface consistency: i.e., public functions that take a size
- * parameter expect size to be in bytes.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/kmemcheck.h>
-#include <linux/string.h>
-#include <asm/bug.h>
-#include <asm/byteorder.h>
-
-#include "csr1212.h"
-
-
-/* Permitted key type for each key id */
-#define __I (1 << CSR1212_KV_TYPE_IMMEDIATE)
-#define __C (1 << CSR1212_KV_TYPE_CSR_OFFSET)
-#define __D (1 << CSR1212_KV_TYPE_DIRECTORY)
-#define __L (1 << CSR1212_KV_TYPE_LEAF)
-static const u8 csr1212_key_id_type_map[0x30] = {
- __C, /* used by Apple iSight */
- __D | __L, /* Descriptor */
- __I | __D | __L, /* Bus_Dependent_Info */
- __I | __D | __L, /* Vendor */
- __I, /* Hardware_Version */
- 0, 0, /* Reserved */
- __D | __L | __I, /* Module */
- __I, 0, 0, 0, /* used by Apple iSight, Reserved */
- __I, /* Node_Capabilities */
- __L, /* EUI_64 */
- 0, 0, 0, /* Reserved */
- __D, /* Unit */
- __I, /* Specifier_ID */
- __I, /* Version */
- __I | __C | __D | __L, /* Dependent_Info */
- __L, /* Unit_Location */
- 0, /* Reserved */
- __I, /* Model */
- __D, /* Instance */
- __L, /* Keyword */
- __D, /* Feature */
- __L, /* Extended_ROM */
- __I, /* Extended_Key_Specifier_ID */
- __I, /* Extended_Key */
- __I | __C | __D | __L, /* Extended_Data */
- __L, /* Modifiable_Descriptor */
- __I, /* Directory_ID */
- __I, /* Revision */
-};
-#undef __I
-#undef __C
-#undef __D
-#undef __L
-
-
-#define quads_to_bytes(_q) ((_q) * sizeof(u32))
-#define bytes_to_quads(_b) DIV_ROUND_UP(_b, sizeof(u32))
-
-static void free_keyval(struct csr1212_keyval *kv)
-{
- if ((kv->key.type == CSR1212_KV_TYPE_LEAF) &&
- (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM))
- CSR1212_FREE(kv->value.leaf.data);
-
- CSR1212_FREE(kv);
-}
-
-static u16 csr1212_crc16(const u32 *buffer, size_t length)
-{
- int shift;
- u32 data;
- u16 sum, crc = 0;
-
- for (; length; length--) {
- data = be32_to_cpu(*buffer);
- buffer++;
- for (shift = 28; shift >= 0; shift -= 4 ) {
- sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
- crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
- }
- crc &= 0xffff;
- }
-
- return cpu_to_be16(crc);
-}
-
-/* Microsoft computes the CRC with the bytes in reverse order. */
-static u16 csr1212_msft_crc16(const u32 *buffer, size_t length)
-{
- int shift;
- u32 data;
- u16 sum, crc = 0;
-
- for (; length; length--) {
- data = le32_to_cpu(*buffer);
- buffer++;
- for (shift = 28; shift >= 0; shift -= 4 ) {
- sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
- crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
- }
- crc &= 0xffff;
- }
-
- return cpu_to_be16(crc);
-}
-
-static struct csr1212_dentry *
-csr1212_find_keyval(struct csr1212_keyval *dir, struct csr1212_keyval *kv)
-{
- struct csr1212_dentry *pos;
-
- for (pos = dir->value.directory.dentries_head;
- pos != NULL; pos = pos->next)
- if (pos->kv == kv)
- return pos;
- return NULL;
-}
-
-static struct csr1212_keyval *
-csr1212_find_keyval_offset(struct csr1212_keyval *kv_list, u32 offset)
-{
- struct csr1212_keyval *kv;
-
- for (kv = kv_list->next; kv && (kv != kv_list); kv = kv->next)
- if (kv->offset == offset)
- return kv;
- return NULL;
-}
-
-
-/* Creation Routines */
-
-struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
- size_t bus_info_size, void *private)
-{
- struct csr1212_csr *csr;
-
- csr = CSR1212_MALLOC(sizeof(*csr));
- if (!csr)
- return NULL;
-
- csr->cache_head =
- csr1212_rom_cache_malloc(CSR1212_CONFIG_ROM_SPACE_OFFSET,
- CSR1212_CONFIG_ROM_SPACE_SIZE);
- if (!csr->cache_head) {
- CSR1212_FREE(csr);
- return NULL;
- }
-
- /* The keyval key id is not used for the root node, but a valid key id
- * that can be used for a directory needs to be passed to
- * csr1212_new_directory(). */
- csr->root_kv = csr1212_new_directory(CSR1212_KV_ID_VENDOR);
- if (!csr->root_kv) {
- CSR1212_FREE(csr->cache_head);
- CSR1212_FREE(csr);
- return NULL;
- }
-
- csr->bus_info_data = csr->cache_head->data;
- csr->bus_info_len = bus_info_size;
- csr->crc_len = bus_info_size;
- csr->ops = ops;
- csr->private = private;
- csr->cache_tail = csr->cache_head;
-
- return csr;
-}
-
-void csr1212_init_local_csr(struct csr1212_csr *csr,
- const u32 *bus_info_data, int max_rom)
-{
- static const int mr_map[] = { 4, 64, 1024, 0 };
-
- BUG_ON(max_rom & ~0x3);
- csr->max_rom = mr_map[max_rom];
- memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
-}
-
-static struct csr1212_keyval *csr1212_new_keyval(u8 type, u8 key)
-{
- struct csr1212_keyval *kv;
-
- if (key < 0x30 && ((csr1212_key_id_type_map[key] & (1 << type)) == 0))
- return NULL;
-
- kv = CSR1212_MALLOC(sizeof(*kv));
- if (!kv)
- return NULL;
-
- atomic_set(&kv->refcnt, 1);
- kv->key.type = type;
- kv->key.id = key;
- kv->associate = NULL;
- kv->next = NULL;
- kv->prev = NULL;
- kv->offset = 0;
- kv->valid = 0;
- return kv;
-}
-
-struct csr1212_keyval *csr1212_new_immediate(u8 key, u32 value)
-{
- struct csr1212_keyval *kv;
-
- kv = csr1212_new_keyval(CSR1212_KV_TYPE_IMMEDIATE, key);
- if (!kv)
- return NULL;
-
- kv->value.immediate = value;
- kv->valid = 1;
- return kv;
-}
-
-static struct csr1212_keyval *
-csr1212_new_leaf(u8 key, const void *data, size_t data_len)
-{
- struct csr1212_keyval *kv;
-
- kv = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, key);
- if (!kv)
- return NULL;
-
- if (data_len > 0) {
- kv->value.leaf.data = CSR1212_MALLOC(data_len);
- if (!kv->value.leaf.data) {
- CSR1212_FREE(kv);
- return NULL;
- }
-
- if (data)
- memcpy(kv->value.leaf.data, data, data_len);
- } else {
- kv->value.leaf.data = NULL;
- }
-
- kv->value.leaf.len = bytes_to_quads(data_len);
- kv->offset = 0;
- kv->valid = 1;
-
- return kv;
-}
-
-static struct csr1212_keyval *
-csr1212_new_csr_offset(u8 key, u32 csr_offset)
-{
- struct csr1212_keyval *kv;
-
- kv = csr1212_new_keyval(CSR1212_KV_TYPE_CSR_OFFSET, key);
- if (!kv)
- return NULL;
-
- kv->value.csr_offset = csr_offset;
-
- kv->offset = 0;
- kv->valid = 1;
- return kv;
-}
-
-struct csr1212_keyval *csr1212_new_directory(u8 key)
-{
- struct csr1212_keyval *kv;
-
- kv = csr1212_new_keyval(CSR1212_KV_TYPE_DIRECTORY, key);
- if (!kv)
- return NULL;
-
- kv->value.directory.len = 0;
- kv->offset = 0;
- kv->value.directory.dentries_head = NULL;
- kv->value.directory.dentries_tail = NULL;
- kv->valid = 1;
- return kv;
-}
-
-void csr1212_associate_keyval(struct csr1212_keyval *kv,
- struct csr1212_keyval *associate)
-{
- BUG_ON(!kv || !associate || kv->key.id == CSR1212_KV_ID_DESCRIPTOR ||
- (associate->key.id != CSR1212_KV_ID_DESCRIPTOR &&
- associate->key.id != CSR1212_KV_ID_DEPENDENT_INFO &&
- associate->key.id != CSR1212_KV_ID_EXTENDED_KEY &&
- associate->key.id != CSR1212_KV_ID_EXTENDED_DATA &&
- associate->key.id < 0x30) ||
- (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID &&
- associate->key.id != CSR1212_KV_ID_EXTENDED_KEY) ||
- (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
- associate->key.id != CSR1212_KV_ID_EXTENDED_DATA) ||
- (associate->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
- kv->key.id != CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) ||
- (associate->key.id == CSR1212_KV_ID_EXTENDED_DATA &&
- kv->key.id != CSR1212_KV_ID_EXTENDED_KEY));
-
- if (kv->associate)
- csr1212_release_keyval(kv->associate);
-
- csr1212_keep_keyval(associate);
- kv->associate = associate;
-}
-
-static int __csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
- struct csr1212_keyval *kv,
- bool keep_keyval)
-{
- struct csr1212_dentry *dentry;
-
- BUG_ON(!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY);
-
- dentry = CSR1212_MALLOC(sizeof(*dentry));
- if (!dentry)
- return -ENOMEM;
-
- if (keep_keyval)
- csr1212_keep_keyval(kv);
- dentry->kv = kv;
-
- dentry->next = NULL;
- dentry->prev = dir->value.directory.dentries_tail;
-
- if (!dir->value.directory.dentries_head)
- dir->value.directory.dentries_head = dentry;
-
- if (dir->value.directory.dentries_tail)
- dir->value.directory.dentries_tail->next = dentry;
- dir->value.directory.dentries_tail = dentry;
-
- return CSR1212_SUCCESS;
-}
-
-int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
- struct csr1212_keyval *kv)
-{
- return __csr1212_attach_keyval_to_directory(dir, kv, true);
-}
-
-#define CSR1212_DESCRIPTOR_LEAF_DATA(kv) \
- (&((kv)->value.leaf.data[1]))
-
-#define CSR1212_DESCRIPTOR_LEAF_SET_TYPE(kv, type) \
- ((kv)->value.leaf.data[0] = \
- cpu_to_be32(CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID(kv) | \
- ((type) << CSR1212_DESCRIPTOR_LEAF_TYPE_SHIFT)))
-#define CSR1212_DESCRIPTOR_LEAF_SET_SPECIFIER_ID(kv, spec_id) \
- ((kv)->value.leaf.data[0] = \
- cpu_to_be32((CSR1212_DESCRIPTOR_LEAF_TYPE(kv) << \
- CSR1212_DESCRIPTOR_LEAF_TYPE_SHIFT) | \
- ((spec_id) & CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID_MASK)))
-
-static struct csr1212_keyval *
-csr1212_new_descriptor_leaf(u8 dtype, u32 specifier_id,
- const void *data, size_t data_len)
-{
- struct csr1212_keyval *kv;
-
- kv = csr1212_new_leaf(CSR1212_KV_ID_DESCRIPTOR, NULL,
- data_len + CSR1212_DESCRIPTOR_LEAF_OVERHEAD);
- if (!kv)
- return NULL;
-
- kmemcheck_annotate_variable(kv->value.leaf.data[0]);
- CSR1212_DESCRIPTOR_LEAF_SET_TYPE(kv, dtype);
- CSR1212_DESCRIPTOR_LEAF_SET_SPECIFIER_ID(kv, specifier_id);
-
- if (data)
- memcpy(CSR1212_DESCRIPTOR_LEAF_DATA(kv), data, data_len);
-
- return kv;
-}
-
-/* Check if string conforms to minimal ASCII as per IEEE 1212 clause 7.4 */
-static int csr1212_check_minimal_ascii(const char *s)
-{
- static const char minimal_ascii_table[] = {
- /* 1 2 4 8 16 32 64 128 */
- 128, /* --, --, --, --, --, --, --, 07, */
- 4 + 16 + 32, /* --, --, 0a, --, 0C, 0D, --, --, */
- 0, /* --, --, --, --, --, --, --, --, */
- 0, /* --, --, --, --, --, --, --, --, */
- 255 - 8 - 16, /* 20, 21, 22, --, --, 25, 26, 27, */
- 255, /* 28, 29, 2a, 2b, 2c, 2d, 2e, 2f, */
- 255, /* 30, 31, 32, 33, 34, 35, 36, 37, */
- 255, /* 38, 39, 3a, 3b, 3c, 3d, 3e, 3f, */
- 255, /* 40, 41, 42, 43, 44, 45, 46, 47, */
- 255, /* 48, 49, 4a, 4b, 4c, 4d, 4e, 4f, */
- 255, /* 50, 51, 52, 53, 54, 55, 56, 57, */
- 1 + 2 + 4 + 128, /* 58, 59, 5a, --, --, --, --, 5f, */
- 255 - 1, /* --, 61, 62, 63, 64, 65, 66, 67, */
- 255, /* 68, 69, 6a, 6b, 6c, 6d, 6e, 6f, */
- 255, /* 70, 71, 72, 73, 74, 75, 76, 77, */
- 1 + 2 + 4, /* 78, 79, 7a, --, --, --, --, --, */
- };
- int i, j;
-
- for (; *s; s++) {
- i = *s >> 3; /* i = *s / 8; */
- j = 1 << (*s & 3); /* j = 1 << (*s % 8); */
-
- if (i >= ARRAY_SIZE(minimal_ascii_table) ||
- !(minimal_ascii_table[i] & j))
- return -EINVAL;
- }
- return 0;
-}
-
-/* IEEE 1212 clause 7.5.4.1 textual descriptors (English, minimal ASCII) */
-struct csr1212_keyval *csr1212_new_string_descriptor_leaf(const char *s)
-{
- struct csr1212_keyval *kv;
- u32 *text;
- size_t str_len, quads;
-
- if (!s || !*s || csr1212_check_minimal_ascii(s))
- return NULL;
-
- str_len = strlen(s);
- quads = bytes_to_quads(str_len);
- kv = csr1212_new_descriptor_leaf(0, 0, NULL, quads_to_bytes(quads) +
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_OVERHEAD);
- if (!kv)
- return NULL;
-
- kv->value.leaf.data[1] = 0; /* width, character_set, language */
- text = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(kv);
- text[quads - 1] = 0; /* padding */
- memcpy(text, s, str_len);
-
- return kv;
-}
-
-
-/* Destruction Routines */
-
-void csr1212_detach_keyval_from_directory(struct csr1212_keyval *dir,
- struct csr1212_keyval *kv)
-{
- struct csr1212_dentry *dentry;
-
- if (!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY)
- return;
-
- dentry = csr1212_find_keyval(dir, kv);
-
- if (!dentry)
- return;
-
- if (dentry->prev)
- dentry->prev->next = dentry->next;
- if (dentry->next)
- dentry->next->prev = dentry->prev;
- if (dir->value.directory.dentries_head == dentry)
- dir->value.directory.dentries_head = dentry->next;
- if (dir->value.directory.dentries_tail == dentry)
- dir->value.directory.dentries_tail = dentry->prev;
-
- CSR1212_FREE(dentry);
-
- csr1212_release_keyval(kv);
-}
-
-/* This function is used to free the memory taken by a keyval. If the given
- * keyval is a directory type, then any keyvals contained in that directory
- * will be destroyed as well if noone holds a reference on them. By means of
- * list manipulation, this routine will descend a directory structure in a
- * non-recursive manner. */
-void csr1212_release_keyval(struct csr1212_keyval *kv)
-{
- struct csr1212_keyval *k, *a;
- struct csr1212_dentry dentry;
- struct csr1212_dentry *head, *tail;
-
- if (!atomic_dec_and_test(&kv->refcnt))
- return;
-
- dentry.kv = kv;
- dentry.next = NULL;
- dentry.prev = NULL;
-
- head = &dentry;
- tail = head;
-
- while (head) {
- k = head->kv;
-
- while (k) {
- /* must not dec_and_test kv->refcnt again */
- if (k != kv && !atomic_dec_and_test(&k->refcnt))
- break;
-
- a = k->associate;
-
- if (k->key.type == CSR1212_KV_TYPE_DIRECTORY) {
- /* If the current entry is a directory, move all
- * the entries to the destruction list. */
- if (k->value.directory.dentries_head) {
- tail->next =
- k->value.directory.dentries_head;
- k->value.directory.dentries_head->prev =
- tail;
- tail = k->value.directory.dentries_tail;
- }
- }
- free_keyval(k);
- k = a;
- }
-
- head = head->next;
- if (head) {
- if (head->prev && head->prev != &dentry)
- CSR1212_FREE(head->prev);
- head->prev = NULL;
- } else if (tail != &dentry) {
- CSR1212_FREE(tail);
- }
- }
-}
-
-void csr1212_destroy_csr(struct csr1212_csr *csr)
-{
- struct csr1212_csr_rom_cache *c, *oc;
- struct csr1212_cache_region *cr, *ocr;
-
- csr1212_release_keyval(csr->root_kv);
-
- c = csr->cache_head;
- while (c) {
- oc = c;
- cr = c->filled_head;
- while (cr) {
- ocr = cr;
- cr = cr->next;
- CSR1212_FREE(ocr);
- }
- c = c->next;
- CSR1212_FREE(oc);
- }
-
- CSR1212_FREE(csr);
-}
-
-
-/* CSR Image Creation */
-
-static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize)
-{
- struct csr1212_csr_rom_cache *cache;
- u64 csr_addr;
-
- BUG_ON(!csr || !csr->ops || !csr->ops->allocate_addr_range ||
- !csr->ops->release_addr || csr->max_rom < 1);
-
- /* ROM size must be a multiple of csr->max_rom */
- romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1);
-
- csr_addr = csr->ops->allocate_addr_range(romsize, csr->max_rom,
- csr->private);
- if (csr_addr == CSR1212_INVALID_ADDR_SPACE)
- return -ENOMEM;
-
- if (csr_addr < CSR1212_REGISTER_SPACE_BASE) {
- /* Invalid address returned from allocate_addr_range(). */
- csr->ops->release_addr(csr_addr, csr->private);
- return -ENOMEM;
- }
-
- cache = csr1212_rom_cache_malloc(csr_addr - CSR1212_REGISTER_SPACE_BASE,
- romsize);
- if (!cache) {
- csr->ops->release_addr(csr_addr, csr->private);
- return -ENOMEM;
- }
-
- cache->ext_rom = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF,
- CSR1212_KV_ID_EXTENDED_ROM);
- if (!cache->ext_rom) {
- csr->ops->release_addr(csr_addr, csr->private);
- CSR1212_FREE(cache);
- return -ENOMEM;
- }
-
- if (csr1212_attach_keyval_to_directory(csr->root_kv, cache->ext_rom) !=
- CSR1212_SUCCESS) {
- csr1212_release_keyval(cache->ext_rom);
- csr->ops->release_addr(csr_addr, csr->private);
- CSR1212_FREE(cache);
- return -ENOMEM;
- }
- cache->ext_rom->offset = csr_addr - CSR1212_REGISTER_SPACE_BASE;
- cache->ext_rom->value.leaf.len = -1;
- cache->ext_rom->value.leaf.data = cache->data;
-
- /* Add cache to tail of cache list */
- cache->prev = csr->cache_tail;
- csr->cache_tail->next = cache;
- csr->cache_tail = cache;
- return CSR1212_SUCCESS;
-}
-
-static void csr1212_remove_cache(struct csr1212_csr *csr,
- struct csr1212_csr_rom_cache *cache)
-{
- if (csr->cache_head == cache)
- csr->cache_head = cache->next;
- if (csr->cache_tail == cache)
- csr->cache_tail = cache->prev;
-
- if (cache->prev)
- cache->prev->next = cache->next;
- if (cache->next)
- cache->next->prev = cache->prev;
-
- if (cache->ext_rom) {
- csr1212_detach_keyval_from_directory(csr->root_kv,
- cache->ext_rom);
- csr1212_release_keyval(cache->ext_rom);
- }
-
- CSR1212_FREE(cache);
-}
-
-static int csr1212_generate_layout_subdir(struct csr1212_keyval *dir,
- struct csr1212_keyval **layout_tail)
-{
- struct csr1212_dentry *dentry;
- struct csr1212_keyval *dkv;
- struct csr1212_keyval *last_extkey_spec = NULL;
- struct csr1212_keyval *last_extkey = NULL;
- int num_entries = 0;
-
- for (dentry = dir->value.directory.dentries_head; dentry;
- dentry = dentry->next) {
- for (dkv = dentry->kv; dkv; dkv = dkv->associate) {
- /* Special Case: Extended Key Specifier_ID */
- if (dkv->key.id ==
- CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) {
- if (last_extkey_spec == NULL)
- last_extkey_spec = dkv;
- else if (dkv->value.immediate !=
- last_extkey_spec->value.immediate)
- last_extkey_spec = dkv;
- else
- continue;
- /* Special Case: Extended Key */
- } else if (dkv->key.id == CSR1212_KV_ID_EXTENDED_KEY) {
- if (last_extkey == NULL)
- last_extkey = dkv;
- else if (dkv->value.immediate !=
- last_extkey->value.immediate)
- last_extkey = dkv;
- else
- continue;
- }
-
- num_entries += 1;
-
- switch (dkv->key.type) {
- default:
- case CSR1212_KV_TYPE_IMMEDIATE:
- case CSR1212_KV_TYPE_CSR_OFFSET:
- break;
- case CSR1212_KV_TYPE_LEAF:
- case CSR1212_KV_TYPE_DIRECTORY:
- /* Remove from list */
- if (dkv->prev && (dkv->prev->next == dkv))
- dkv->prev->next = dkv->next;
- if (dkv->next && (dkv->next->prev == dkv))
- dkv->next->prev = dkv->prev;
- //if (dkv == *layout_tail)
- // *layout_tail = dkv->prev;
-
- /* Special case: Extended ROM leafs */
- if (dkv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
- dkv->value.leaf.len = -1;
- /* Don't add Extended ROM leafs in the
- * layout list, they are handled
- * differently. */
- break;
- }
-
- /* Add to tail of list */
- dkv->next = NULL;
- dkv->prev = *layout_tail;
- (*layout_tail)->next = dkv;
- *layout_tail = dkv;
- break;
- }
- }
- }
- return num_entries;
-}
-
-static size_t csr1212_generate_layout_order(struct csr1212_keyval *kv)
-{
- struct csr1212_keyval *ltail = kv;
- size_t agg_size = 0;
-
- while (kv) {
- switch (kv->key.type) {
- case CSR1212_KV_TYPE_LEAF:
- /* Add 1 quadlet for crc/len field */
- agg_size += kv->value.leaf.len + 1;
- break;
-
- case CSR1212_KV_TYPE_DIRECTORY:
- kv->value.directory.len =
- csr1212_generate_layout_subdir(kv, &ltail);
- /* Add 1 quadlet for crc/len field */
- agg_size += kv->value.directory.len + 1;
- break;
- }
- kv = kv->next;
- }
- return quads_to_bytes(agg_size);
-}
-
-static struct csr1212_keyval *
-csr1212_generate_positions(struct csr1212_csr_rom_cache *cache,
- struct csr1212_keyval *start_kv, int start_pos)
-{
- struct csr1212_keyval *kv = start_kv;
- struct csr1212_keyval *okv = start_kv;
- int pos = start_pos;
- int kv_len = 0, okv_len = 0;
-
- cache->layout_head = kv;
-
- while (kv && pos < cache->size) {
- /* Special case: Extended ROM leafs */
- if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
- kv->offset = cache->offset + pos;
-
- switch (kv->key.type) {
- case CSR1212_KV_TYPE_LEAF:
- kv_len = kv->value.leaf.len;
- break;
-
- case CSR1212_KV_TYPE_DIRECTORY:
- kv_len = kv->value.directory.len;
- break;
-
- default:
- /* Should never get here */
- WARN_ON(1);
- break;
- }
-
- pos += quads_to_bytes(kv_len + 1);
-
- if (pos <= cache->size) {
- okv = kv;
- okv_len = kv_len;
- kv = kv->next;
- }
- }
-
- cache->layout_tail = okv;
- cache->len = okv->offset - cache->offset + quads_to_bytes(okv_len + 1);
-
- return kv;
-}
-
-#define CSR1212_KV_KEY_SHIFT 24
-#define CSR1212_KV_KEY_TYPE_SHIFT 6
-#define CSR1212_KV_KEY_ID_MASK 0x3f
-#define CSR1212_KV_KEY_TYPE_MASK 0x3 /* after shift */
-
-static void
-csr1212_generate_tree_subdir(struct csr1212_keyval *dir, u32 *data_buffer)
-{
- struct csr1212_dentry *dentry;
- struct csr1212_keyval *last_extkey_spec = NULL;
- struct csr1212_keyval *last_extkey = NULL;
- int index = 0;
-
- for (dentry = dir->value.directory.dentries_head;
- dentry;
- dentry = dentry->next) {
- struct csr1212_keyval *a;
-
- for (a = dentry->kv; a; a = a->associate) {
- u32 value = 0;
-
- /* Special Case: Extended Key Specifier_ID */
- if (a->key.id ==
- CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) {
- if (last_extkey_spec == NULL)
- last_extkey_spec = a;
- else if (a->value.immediate !=
- last_extkey_spec->value.immediate)
- last_extkey_spec = a;
- else
- continue;
-
- /* Special Case: Extended Key */
- } else if (a->key.id == CSR1212_KV_ID_EXTENDED_KEY) {
- if (last_extkey == NULL)
- last_extkey = a;
- else if (a->value.immediate !=
- last_extkey->value.immediate)
- last_extkey = a;
- else
- continue;
- }
-
- switch (a->key.type) {
- case CSR1212_KV_TYPE_IMMEDIATE:
- value = a->value.immediate;
- break;
- case CSR1212_KV_TYPE_CSR_OFFSET:
- value = a->value.csr_offset;
- break;
- case CSR1212_KV_TYPE_LEAF:
- value = a->offset;
- value -= dir->offset + quads_to_bytes(1+index);
- value = bytes_to_quads(value);
- break;
- case CSR1212_KV_TYPE_DIRECTORY:
- value = a->offset;
- value -= dir->offset + quads_to_bytes(1+index);
- value = bytes_to_quads(value);
- break;
- default:
- /* Should never get here */
- WARN_ON(1);
- break;
- }
-
- value |= (a->key.id & CSR1212_KV_KEY_ID_MASK) <<
- CSR1212_KV_KEY_SHIFT;
- value |= (a->key.type & CSR1212_KV_KEY_TYPE_MASK) <<
- (CSR1212_KV_KEY_SHIFT +
- CSR1212_KV_KEY_TYPE_SHIFT);
- data_buffer[index] = cpu_to_be32(value);
- index++;
- }
- }
-}
-
-struct csr1212_keyval_img {
- u16 length;
- u16 crc;
-
- /* Must be last */
- u32 data[0]; /* older gcc can't handle [] which is standard */
-};
-
-static void csr1212_fill_cache(struct csr1212_csr_rom_cache *cache)
-{
- struct csr1212_keyval *kv, *nkv;
- struct csr1212_keyval_img *kvi;
-
- for (kv = cache->layout_head;
- kv != cache->layout_tail->next;
- kv = nkv) {
- kvi = (struct csr1212_keyval_img *)(cache->data +
- bytes_to_quads(kv->offset - cache->offset));
- switch (kv->key.type) {
- default:
- case CSR1212_KV_TYPE_IMMEDIATE:
- case CSR1212_KV_TYPE_CSR_OFFSET:
- /* Should never get here */
- WARN_ON(1);
- break;
-
- case CSR1212_KV_TYPE_LEAF:
- /* Don't copy over Extended ROM areas, they are
- * already filled out! */
- if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
- memcpy(kvi->data, kv->value.leaf.data,
- quads_to_bytes(kv->value.leaf.len));
-
- kvi->length = cpu_to_be16(kv->value.leaf.len);
- kvi->crc = csr1212_crc16(kvi->data, kv->value.leaf.len);
- break;
-
- case CSR1212_KV_TYPE_DIRECTORY:
- csr1212_generate_tree_subdir(kv, kvi->data);
-
- kvi->length = cpu_to_be16(kv->value.directory.len);
- kvi->crc = csr1212_crc16(kvi->data,
- kv->value.directory.len);
- break;
- }
-
- nkv = kv->next;
- if (kv->prev)
- kv->prev->next = NULL;
- if (kv->next)
- kv->next->prev = NULL;
- kv->prev = NULL;
- kv->next = NULL;
- }
-}
-
-/* This size is arbitrarily chosen.
- * The struct overhead is subtracted for more economic allocations. */
-#define CSR1212_EXTENDED_ROM_SIZE (2048 - sizeof(struct csr1212_csr_rom_cache))
-
-int csr1212_generate_csr_image(struct csr1212_csr *csr)
-{
- struct csr1212_bus_info_block_img *bi;
- struct csr1212_csr_rom_cache *cache;
- struct csr1212_keyval *kv;
- size_t agg_size;
- int ret;
- int init_offset;
-
- BUG_ON(!csr);
-
- cache = csr->cache_head;
-
- bi = (struct csr1212_bus_info_block_img*)cache->data;
-
- bi->length = bytes_to_quads(csr->bus_info_len) - 1;
- bi->crc_length = bi->length;
- bi->crc = csr1212_crc16(bi->data, bi->crc_length);
-
- csr->root_kv->next = NULL;
- csr->root_kv->prev = NULL;
-
- agg_size = csr1212_generate_layout_order(csr->root_kv);
-
- init_offset = csr->bus_info_len;
-
- for (kv = csr->root_kv, cache = csr->cache_head;
- kv;
- cache = cache->next) {
- if (!cache) {
- /* Estimate approximate number of additional cache
- * regions needed (it assumes that the cache holding
- * the first 1K Config ROM space always exists). */
- int est_c = agg_size / (CSR1212_EXTENDED_ROM_SIZE -
- (2 * sizeof(u32))) + 1;
-
- /* Add additional cache regions, extras will be
- * removed later */
- for (; est_c; est_c--) {
- ret = csr1212_append_new_cache(csr,
- CSR1212_EXTENDED_ROM_SIZE);
- if (ret != CSR1212_SUCCESS)
- return ret;
- }
- /* Need to re-layout for additional cache regions */
- agg_size = csr1212_generate_layout_order(csr->root_kv);
- kv = csr->root_kv;
- cache = csr->cache_head;
- init_offset = csr->bus_info_len;
- }
- kv = csr1212_generate_positions(cache, kv, init_offset);
- agg_size -= cache->len;
- init_offset = sizeof(u32);
- }
-
- /* Remove unused, excess cache regions */
- while (cache) {
- struct csr1212_csr_rom_cache *oc = cache;
-
- cache = cache->next;
- csr1212_remove_cache(csr, oc);
- }
-
- /* Go through the list backward so that when done, the correct CRC
- * will be calculated for the Extended ROM areas. */
- for (cache = csr->cache_tail; cache; cache = cache->prev) {
- /* Only Extended ROM caches should have this set. */
- if (cache->ext_rom) {
- int leaf_size;
-
- /* Make sure the Extended ROM leaf is a multiple of
- * max_rom in size. */
- BUG_ON(csr->max_rom < 1);
- leaf_size = (cache->len + (csr->max_rom - 1)) &
- ~(csr->max_rom - 1);
-
- /* Zero out the unused ROM region */
- memset(cache->data + bytes_to_quads(cache->len), 0x00,
- leaf_size - cache->len);
-
- /* Subtract leaf header */
- leaf_size -= sizeof(u32);
-
- /* Update the Extended ROM leaf length */
- cache->ext_rom->value.leaf.len =
- bytes_to_quads(leaf_size);
- } else {
- /* Zero out the unused ROM region */
- memset(cache->data + bytes_to_quads(cache->len), 0x00,
- cache->size - cache->len);
- }
-
- /* Copy the data into the cache buffer */
- csr1212_fill_cache(cache);
-
- if (cache != csr->cache_head) {
- /* Set the length and CRC of the extended ROM. */
- struct csr1212_keyval_img *kvi =
- (struct csr1212_keyval_img*)cache->data;
- u16 len = bytes_to_quads(cache->len) - 1;
-
- kvi->length = cpu_to_be16(len);
- kvi->crc = csr1212_crc16(kvi->data, len);
- }
- }
-
- return CSR1212_SUCCESS;
-}
-
-int csr1212_read(struct csr1212_csr *csr, u32 offset, void *buffer, u32 len)
-{
- struct csr1212_csr_rom_cache *cache;
-
- for (cache = csr->cache_head; cache; cache = cache->next)
- if (offset >= cache->offset &&
- (offset + len) <= (cache->offset + cache->size)) {
- memcpy(buffer, &cache->data[
- bytes_to_quads(offset - cache->offset)],
- len);
- return CSR1212_SUCCESS;
- }
-
- return -ENOENT;
-}
-
-/*
- * Apparently there are many different wrong implementations of the CRC
- * algorithm. We don't fail, we just warn... approximately once per GUID.
- */
-static void
-csr1212_check_crc(const u32 *buffer, size_t length, u16 crc, __be32 *guid)
-{
- static u64 last_bad_eui64;
- u64 eui64 = ((u64)be32_to_cpu(guid[0]) << 32) | be32_to_cpu(guid[1]);
-
- if (csr1212_crc16(buffer, length) == crc ||
- csr1212_msft_crc16(buffer, length) == crc ||
- eui64 == last_bad_eui64)
- return;
-
- printk(KERN_DEBUG "ieee1394: config ROM CRC error\n");
- last_bad_eui64 = eui64;
-}
-
-/* Parse a chunk of data as a Config ROM */
-
-static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
-{
- struct csr1212_bus_info_block_img *bi;
- struct csr1212_cache_region *cr;
- int i;
- int ret;
-
- for (i = 0; i < csr->bus_info_len; i += sizeof(u32)) {
- ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
- &csr->cache_head->data[bytes_to_quads(i)],
- csr->private);
- if (ret != CSR1212_SUCCESS)
- return ret;
-
- /* check ROM header's info_length */
- if (i == 0 &&
- be32_to_cpu(csr->cache_head->data[0]) >> 24 !=
- bytes_to_quads(csr->bus_info_len) - 1)
- return -EINVAL;
- }
-
- bi = (struct csr1212_bus_info_block_img*)csr->cache_head->data;
- csr->crc_len = quads_to_bytes(bi->crc_length);
-
- /* IEEE 1212 recommends that crc_len be equal to bus_info_len, but that
- * is not always the case, so read the rest of the crc area 1 quadlet at
- * a time. */
- for (i = csr->bus_info_len; i <= csr->crc_len; i += sizeof(u32)) {
- ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
- &csr->cache_head->data[bytes_to_quads(i)],
- csr->private);
- if (ret != CSR1212_SUCCESS)
- return ret;
- }
-
- csr1212_check_crc(bi->data, bi->crc_length, bi->crc,
- &csr->bus_info_data[3]);
-
- cr = CSR1212_MALLOC(sizeof(*cr));
- if (!cr)
- return -ENOMEM;
-
- cr->next = NULL;
- cr->prev = NULL;
- cr->offset_start = 0;
- cr->offset_end = csr->crc_len + 4;
-
- csr->cache_head->filled_head = cr;
- csr->cache_head->filled_tail = cr;
-
- return CSR1212_SUCCESS;
-}
-
-#define CSR1212_KV_KEY(q) (be32_to_cpu(q) >> CSR1212_KV_KEY_SHIFT)
-#define CSR1212_KV_KEY_TYPE(q) (CSR1212_KV_KEY(q) >> CSR1212_KV_KEY_TYPE_SHIFT)
-#define CSR1212_KV_KEY_ID(q) (CSR1212_KV_KEY(q) & CSR1212_KV_KEY_ID_MASK)
-#define CSR1212_KV_VAL_MASK 0xffffff
-#define CSR1212_KV_VAL(q) (be32_to_cpu(q) & CSR1212_KV_VAL_MASK)
-
-static int
-csr1212_parse_dir_entry(struct csr1212_keyval *dir, u32 ki, u32 kv_pos)
-{
- int ret = CSR1212_SUCCESS;
- struct csr1212_keyval *k = NULL;
- u32 offset;
- bool keep_keyval = true;
-
- switch (CSR1212_KV_KEY_TYPE(ki)) {
- case CSR1212_KV_TYPE_IMMEDIATE:
- k = csr1212_new_immediate(CSR1212_KV_KEY_ID(ki),
- CSR1212_KV_VAL(ki));
- if (!k) {
- ret = -ENOMEM;
- goto out;
- }
- /* Don't keep local reference when parsing. */
- keep_keyval = false;
- break;
-
- case CSR1212_KV_TYPE_CSR_OFFSET:
- k = csr1212_new_csr_offset(CSR1212_KV_KEY_ID(ki),
- CSR1212_KV_VAL(ki));
- if (!k) {
- ret = -ENOMEM;
- goto out;
- }
- /* Don't keep local reference when parsing. */
- keep_keyval = false;
- break;
-
- default:
- /* Compute the offset from 0xffff f000 0000. */
- offset = quads_to_bytes(CSR1212_KV_VAL(ki)) + kv_pos;
- if (offset == kv_pos) {
- /* Uh-oh. Can't have a relative offset of 0 for Leaves
- * or Directories. The Config ROM image is most likely
- * messed up, so we'll just abort here. */
- ret = -EIO;
- goto out;
- }
-
- k = csr1212_find_keyval_offset(dir, offset);
-
- if (k)
- break; /* Found it. */
-
- if (CSR1212_KV_KEY_TYPE(ki) == CSR1212_KV_TYPE_DIRECTORY)
- k = csr1212_new_directory(CSR1212_KV_KEY_ID(ki));
- else
- k = csr1212_new_leaf(CSR1212_KV_KEY_ID(ki), NULL, 0);
-
- if (!k) {
- ret = -ENOMEM;
- goto out;
- }
- /* Don't keep local reference when parsing. */
- keep_keyval = false;
- /* Contents not read yet so it's not valid. */
- k->valid = 0;
- k->offset = offset;
-
- k->prev = dir;
- k->next = dir->next;
- dir->next->prev = k;
- dir->next = k;
- }
- ret = __csr1212_attach_keyval_to_directory(dir, k, keep_keyval);
-out:
- if (ret != CSR1212_SUCCESS && k != NULL)
- free_keyval(k);
- return ret;
-}
-
-int csr1212_parse_keyval(struct csr1212_keyval *kv,
- struct csr1212_csr_rom_cache *cache)
-{
- struct csr1212_keyval_img *kvi;
- int i;
- int ret = CSR1212_SUCCESS;
- int kvi_len;
-
- kvi = (struct csr1212_keyval_img*)
- &cache->data[bytes_to_quads(kv->offset - cache->offset)];
- kvi_len = be16_to_cpu(kvi->length);
-
- /* GUID is wrong in here in case of extended ROM. We don't care. */
- csr1212_check_crc(kvi->data, kvi_len, kvi->crc, &cache->data[3]);
-
- switch (kv->key.type) {
- case CSR1212_KV_TYPE_DIRECTORY:
- for (i = 0; i < kvi_len; i++) {
- u32 ki = kvi->data[i];
-
- /* Some devices put null entries in their unit
- * directories. If we come across such an entry,
- * then skip it. */
- if (ki == 0x0)
- continue;
- ret = csr1212_parse_dir_entry(kv, ki,
- kv->offset + quads_to_bytes(i + 1));
- }
- kv->value.directory.len = kvi_len;
- break;
-
- case CSR1212_KV_TYPE_LEAF:
- if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
- size_t size = quads_to_bytes(kvi_len);
-
- kv->value.leaf.data = CSR1212_MALLOC(size);
- if (!kv->value.leaf.data) {
- ret = -ENOMEM;
- goto out;
- }
-
- kv->value.leaf.len = kvi_len;
- memcpy(kv->value.leaf.data, kvi->data, size);
- }
- break;
- }
-
- kv->valid = 1;
-out:
- return ret;
-}
-
-static int
-csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
-{
- struct csr1212_cache_region *cr, *ncr, *newcr = NULL;
- struct csr1212_keyval_img *kvi = NULL;
- struct csr1212_csr_rom_cache *cache;
- int cache_index;
- u64 addr;
- u32 *cache_ptr;
- u16 kv_len = 0;
-
- BUG_ON(!csr || !kv || csr->max_rom < 1);
-
- /* First find which cache the data should be in (or go in if not read
- * yet). */
- for (cache = csr->cache_head; cache; cache = cache->next)
- if (kv->offset >= cache->offset &&
- kv->offset < (cache->offset + cache->size))
- break;
-
- if (!cache) {
- u32 q, cache_size;
-
- /* Only create a new cache for Extended ROM leaves. */
- if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
- return -EINVAL;
-
- if (csr->ops->bus_read(csr,
- CSR1212_REGISTER_SPACE_BASE + kv->offset,
- &q, csr->private))
- return -EIO;
-
- kv->value.leaf.len = be32_to_cpu(q) >> 16;
-
- cache_size = (quads_to_bytes(kv->value.leaf.len + 1) +
- (csr->max_rom - 1)) & ~(csr->max_rom - 1);
-
- cache = csr1212_rom_cache_malloc(kv->offset, cache_size);
- if (!cache)
- return -ENOMEM;
-
- kv->value.leaf.data = &cache->data[1];
- csr->cache_tail->next = cache;
- cache->prev = csr->cache_tail;
- cache->next = NULL;
- csr->cache_tail = cache;
- cache->filled_head =
- CSR1212_MALLOC(sizeof(*cache->filled_head));
- if (!cache->filled_head)
- return -ENOMEM;
-
- cache->filled_head->offset_start = 0;
- cache->filled_head->offset_end = sizeof(u32);
- cache->filled_tail = cache->filled_head;
- cache->filled_head->next = NULL;
- cache->filled_head->prev = NULL;
- cache->data[0] = q;
-
- /* Don't read the entire extended ROM now. Pieces of it will
- * be read when entries inside it are read. */
- return csr1212_parse_keyval(kv, cache);
- }
-
- cache_index = kv->offset - cache->offset;
-
- /* Now seach read portions of the cache to see if it is there. */
- for (cr = cache->filled_head; cr; cr = cr->next) {
- if (cache_index < cr->offset_start) {
- newcr = CSR1212_MALLOC(sizeof(*newcr));
- if (!newcr)
- return -ENOMEM;
-
- newcr->offset_start = cache_index & ~(csr->max_rom - 1);
- newcr->offset_end = newcr->offset_start;
- newcr->next = cr;
- newcr->prev = cr->prev;
- cr->prev = newcr;
- cr = newcr;
- break;
- } else if ((cache_index >= cr->offset_start) &&
- (cache_index < cr->offset_end)) {
- kvi = (struct csr1212_keyval_img*)
- (&cache->data[bytes_to_quads(cache_index)]);
- kv_len = quads_to_bytes(be16_to_cpu(kvi->length) + 1);
- break;
- } else if (cache_index == cr->offset_end) {
- break;
- }
- }
-
- if (!cr) {
- cr = cache->filled_tail;
- newcr = CSR1212_MALLOC(sizeof(*newcr));
- if (!newcr)
- return -ENOMEM;
-
- newcr->offset_start = cache_index & ~(csr->max_rom - 1);
- newcr->offset_end = newcr->offset_start;
- newcr->prev = cr;
- newcr->next = cr->next;
- cr->next = newcr;
- cr = newcr;
- cache->filled_tail = newcr;
- }
-
- while(!kvi || cr->offset_end < cache_index + kv_len) {
- cache_ptr = &cache->data[bytes_to_quads(cr->offset_end &
- ~(csr->max_rom - 1))];
-
- addr = (CSR1212_CSR_ARCH_REG_SPACE_BASE + cache->offset +
- cr->offset_end) & ~(csr->max_rom - 1);
-
- if (csr->ops->bus_read(csr, addr, cache_ptr, csr->private))
- return -EIO;
-
- cr->offset_end += csr->max_rom - (cr->offset_end &
- (csr->max_rom - 1));
-
- if (!kvi && (cr->offset_end > cache_index)) {
- kvi = (struct csr1212_keyval_img*)
- (&cache->data[bytes_to_quads(cache_index)]);
- kv_len = quads_to_bytes(be16_to_cpu(kvi->length) + 1);
- }
-
- if ((kv_len + (kv->offset - cache->offset)) > cache->size) {
- /* The Leaf or Directory claims its length extends
- * beyond the ConfigROM image region and thus beyond the
- * end of our cache region. Therefore, we abort now
- * rather than seg faulting later. */
- return -EIO;
- }
-
- ncr = cr->next;
-
- if (ncr && (cr->offset_end >= ncr->offset_start)) {
- /* consolidate region entries */
- ncr->offset_start = cr->offset_start;
-
- if (cr->prev)
- cr->prev->next = cr->next;
- ncr->prev = cr->prev;
- if (cache->filled_head == cr)
- cache->filled_head = ncr;
- CSR1212_FREE(cr);
- cr = ncr;
- }
- }
-
- return csr1212_parse_keyval(kv, cache);
-}
-
-struct csr1212_keyval *
-csr1212_get_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
-{
- if (!kv)
- return NULL;
- if (!kv->valid)
- if (csr1212_read_keyval(csr, kv) != CSR1212_SUCCESS)
- return NULL;
- return kv;
-}
-
-int csr1212_parse_csr(struct csr1212_csr *csr)
-{
- struct csr1212_dentry *dentry;
- int ret;
-
- BUG_ON(!csr || !csr->ops || !csr->ops->bus_read);
-
- ret = csr1212_parse_bus_info_block(csr);
- if (ret != CSR1212_SUCCESS)
- return ret;
-
- /*
- * There has been a buggy firmware with bus_info_block.max_rom > 0
- * spotted which actually only supported quadlet read requests to the
- * config ROM. Therefore read everything quadlet by quadlet regardless
- * of what the bus info block says.
- */
- csr->max_rom = 4;
-
- csr->cache_head->layout_head = csr->root_kv;
- csr->cache_head->layout_tail = csr->root_kv;
-
- csr->root_kv->offset = (CSR1212_CONFIG_ROM_SPACE_BASE & 0xffff) +
- csr->bus_info_len;
-
- csr->root_kv->valid = 0;
- csr->root_kv->next = csr->root_kv;
- csr->root_kv->prev = csr->root_kv;
- ret = csr1212_read_keyval(csr, csr->root_kv);
- if (ret != CSR1212_SUCCESS)
- return ret;
-
- /* Scan through the Root directory finding all extended ROM regions
- * and make cache regions for them */
- for (dentry = csr->root_kv->value.directory.dentries_head;
- dentry; dentry = dentry->next) {
- if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM &&
- !dentry->kv->valid) {
- ret = csr1212_read_keyval(csr, dentry->kv);
- if (ret != CSR1212_SUCCESS)
- return ret;
- }
- }
-
- return CSR1212_SUCCESS;
-}
diff --git a/drivers/ieee1394/csr1212.h b/drivers/ieee1394/csr1212.h
deleted file mode 100644
index a892d922dbc..00000000000
--- a/drivers/ieee1394/csr1212.h
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * csr1212.h -- IEEE 1212 Control and Status Register support for Linux
- *
- * Copyright (C) 2003 Francois Retief <fgretief@sun.ac.za>
- * Steve Kinneberg <kinnebergsteve@acmsystems.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __CSR1212_H__
-#define __CSR1212_H__
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/atomic.h>
-
-#define CSR1212_MALLOC(size) kmalloc((size), GFP_KERNEL)
-#define CSR1212_FREE(ptr) kfree(ptr)
-
-#define CSR1212_SUCCESS (0)
-
-
-/* CSR 1212 key types */
-#define CSR1212_KV_TYPE_IMMEDIATE 0
-#define CSR1212_KV_TYPE_CSR_OFFSET 1
-#define CSR1212_KV_TYPE_LEAF 2
-#define CSR1212_KV_TYPE_DIRECTORY 3
-
-
-/* CSR 1212 key ids */
-#define CSR1212_KV_ID_DESCRIPTOR 0x01
-#define CSR1212_KV_ID_BUS_DEPENDENT_INFO 0x02
-#define CSR1212_KV_ID_VENDOR 0x03
-#define CSR1212_KV_ID_HARDWARE_VERSION 0x04
-#define CSR1212_KV_ID_MODULE 0x07
-#define CSR1212_KV_ID_NODE_CAPABILITIES 0x0C
-#define CSR1212_KV_ID_EUI_64 0x0D
-#define CSR1212_KV_ID_UNIT 0x11
-#define CSR1212_KV_ID_SPECIFIER_ID 0x12
-#define CSR1212_KV_ID_VERSION 0x13
-#define CSR1212_KV_ID_DEPENDENT_INFO 0x14
-#define CSR1212_KV_ID_UNIT_LOCATION 0x15
-#define CSR1212_KV_ID_MODEL 0x17
-#define CSR1212_KV_ID_INSTANCE 0x18
-#define CSR1212_KV_ID_KEYWORD 0x19
-#define CSR1212_KV_ID_FEATURE 0x1A
-#define CSR1212_KV_ID_EXTENDED_ROM 0x1B
-#define CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID 0x1C
-#define CSR1212_KV_ID_EXTENDED_KEY 0x1D
-#define CSR1212_KV_ID_EXTENDED_DATA 0x1E
-#define CSR1212_KV_ID_MODIFIABLE_DESCRIPTOR 0x1F
-#define CSR1212_KV_ID_DIRECTORY_ID 0x20
-#define CSR1212_KV_ID_REVISION 0x21
-
-
-/* IEEE 1212 Address space map */
-#define CSR1212_ALL_SPACE_BASE (0x000000000000ULL)
-#define CSR1212_ALL_SPACE_SIZE (1ULL << 48)
-#define CSR1212_ALL_SPACE_END (CSR1212_ALL_SPACE_BASE + CSR1212_ALL_SPACE_SIZE)
-
-#define CSR1212_MEMORY_SPACE_BASE (0x000000000000ULL)
-#define CSR1212_MEMORY_SPACE_SIZE ((256ULL * (1ULL << 40)) - (512ULL * (1ULL << 20)))
-#define CSR1212_MEMORY_SPACE_END (CSR1212_MEMORY_SPACE_BASE + CSR1212_MEMORY_SPACE_SIZE)
-
-#define CSR1212_PRIVATE_SPACE_BASE (0xffffe0000000ULL)
-#define CSR1212_PRIVATE_SPACE_SIZE (256ULL * (1ULL << 20))
-#define CSR1212_PRIVATE_SPACE_END (CSR1212_PRIVATE_SPACE_BASE + CSR1212_PRIVATE_SPACE_SIZE)
-
-#define CSR1212_REGISTER_SPACE_BASE (0xfffff0000000ULL)
-#define CSR1212_REGISTER_SPACE_SIZE (256ULL * (1ULL << 20))
-#define CSR1212_REGISTER_SPACE_END (CSR1212_REGISTER_SPACE_BASE + CSR1212_REGISTER_SPACE_SIZE)
-
-#define CSR1212_CSR_ARCH_REG_SPACE_BASE (0xfffff0000000ULL)
-#define CSR1212_CSR_ARCH_REG_SPACE_SIZE (512)
-#define CSR1212_CSR_ARCH_REG_SPACE_END (CSR1212_CSR_ARCH_REG_SPACE_BASE + CSR1212_CSR_ARCH_REG_SPACE_SIZE)
-#define CSR1212_CSR_ARCH_REG_SPACE_OFFSET (CSR1212_CSR_ARCH_REG_SPACE_BASE - CSR1212_REGISTER_SPACE_BASE)
-
-#define CSR1212_CSR_BUS_DEP_REG_SPACE_BASE (0xfffff0000200ULL)
-#define CSR1212_CSR_BUS_DEP_REG_SPACE_SIZE (512)
-#define CSR1212_CSR_BUS_DEP_REG_SPACE_END (CSR1212_CSR_BUS_DEP_REG_SPACE_BASE + CSR1212_CSR_BUS_DEP_REG_SPACE_SIZE)
-#define CSR1212_CSR_BUS_DEP_REG_SPACE_OFFSET (CSR1212_CSR_BUS_DEP_REG_SPACE_BASE - CSR1212_REGISTER_SPACE_BASE)
-
-#define CSR1212_CONFIG_ROM_SPACE_BASE (0xfffff0000400ULL)
-#define CSR1212_CONFIG_ROM_SPACE_SIZE (1024)
-#define CSR1212_CONFIG_ROM_SPACE_END (CSR1212_CONFIG_ROM_SPACE_BASE + CSR1212_CONFIG_ROM_SPACE_SIZE)
-#define CSR1212_CONFIG_ROM_SPACE_OFFSET (CSR1212_CONFIG_ROM_SPACE_BASE - CSR1212_REGISTER_SPACE_BASE)
-
-#define CSR1212_UNITS_SPACE_BASE (0xfffff0000800ULL)
-#define CSR1212_UNITS_SPACE_SIZE ((256ULL * (1ULL << 20)) - 2048)
-#define CSR1212_UNITS_SPACE_END (CSR1212_UNITS_SPACE_BASE + CSR1212_UNITS_SPACE_SIZE)
-#define CSR1212_UNITS_SPACE_OFFSET (CSR1212_UNITS_SPACE_BASE - CSR1212_REGISTER_SPACE_BASE)
-
-#define CSR1212_INVALID_ADDR_SPACE -1
-
-
-/* Config ROM image structures */
-struct csr1212_bus_info_block_img {
- u8 length;
- u8 crc_length;
- u16 crc;
-
- /* Must be last */
- u32 data[0]; /* older gcc can't handle [] which is standard */
-};
-
-struct csr1212_leaf {
- int len;
- u32 *data;
-};
-
-struct csr1212_dentry {
- struct csr1212_dentry *next, *prev;
- struct csr1212_keyval *kv;
-};
-
-struct csr1212_directory {
- int len;
- struct csr1212_dentry *dentries_head, *dentries_tail;
-};
-
-struct csr1212_keyval {
- struct {
- u8 type;
- u8 id;
- } key;
- union {
- u32 immediate;
- u32 csr_offset;
- struct csr1212_leaf leaf;
- struct csr1212_directory directory;
- } value;
- struct csr1212_keyval *associate;
- atomic_t refcnt;
-
- /* used in generating and/or parsing CSR image */
- struct csr1212_keyval *next, *prev; /* flat list of CSR elements */
- u32 offset; /* position in CSR from 0xffff f000 0000 */
- u8 valid; /* flag indicating keyval has valid data*/
-};
-
-
-struct csr1212_cache_region {
- struct csr1212_cache_region *next, *prev;
- u32 offset_start; /* inclusive */
- u32 offset_end; /* exclusive */
-};
-
-struct csr1212_csr_rom_cache {
- struct csr1212_csr_rom_cache *next, *prev;
- struct csr1212_cache_region *filled_head, *filled_tail;
- struct csr1212_keyval *layout_head, *layout_tail;
- size_t size;
- u32 offset;
- struct csr1212_keyval *ext_rom;
- size_t len;
-
- /* Must be last */
- u32 data[0]; /* older gcc can't handle [] which is standard */
-};
-
-struct csr1212_csr {
- size_t bus_info_len; /* bus info block length in bytes */
- size_t crc_len; /* crc length in bytes */
- __be32 *bus_info_data; /* bus info data incl bus name and EUI */
-
- void *private; /* private, bus specific data */
- struct csr1212_bus_ops *ops;
-
- struct csr1212_keyval *root_kv;
-
- int max_rom; /* max bytes readable in Config ROM region */
-
- /* Items below used for image parsing and generation */
- struct csr1212_csr_rom_cache *cache_head, *cache_tail;
-};
-
-struct csr1212_bus_ops {
- /* This function is used by csr1212 to read additional information
- * from remote nodes when parsing a Config ROM (i.e., read Config ROM
- * entries located in the Units Space. Must return 0 on success
- * anything else indicates an error. */
- int (*bus_read) (struct csr1212_csr *csr, u64 addr,
- void *buffer, void *private);
-
- /* This function is used by csr1212 to allocate a region in units space
- * in the event that Config ROM entries don't all fit in the predefined
- * 1K region. The void *private parameter is private member of struct
- * csr1212_csr. */
- u64 (*allocate_addr_range) (u64 size, u32 alignment, void *private);
-
- /* This function is used by csr1212 to release a region in units space
- * that is no longer needed. */
- void (*release_addr) (u64 addr, void *private);
-};
-
-
-/* Descriptor Leaf manipulation macros */
-#define CSR1212_DESCRIPTOR_LEAF_TYPE_SHIFT 24
-#define CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID_MASK 0xffffff
-#define CSR1212_DESCRIPTOR_LEAF_OVERHEAD (1 * sizeof(u32))
-
-#define CSR1212_DESCRIPTOR_LEAF_TYPE(kv) \
- (be32_to_cpu((kv)->value.leaf.data[0]) >> \
- CSR1212_DESCRIPTOR_LEAF_TYPE_SHIFT)
-#define CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID(kv) \
- (be32_to_cpu((kv)->value.leaf.data[0]) & \
- CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID_MASK)
-
-
-/* Text Descriptor Leaf manipulation macros */
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_WIDTH_SHIFT 28
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_WIDTH_MASK 0xf /* after shift */
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_CHAR_SET_SHIFT 16
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_CHAR_SET_MASK 0xfff /* after shift */
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_LANGUAGE_MASK 0xffff
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_OVERHEAD (1 * sizeof(u32))
-
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_WIDTH(kv) \
- (be32_to_cpu((kv)->value.leaf.data[1]) >> \
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_WIDTH_SHIFT)
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_CHAR_SET(kv) \
- ((be32_to_cpu((kv)->value.leaf.data[1]) >> \
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_CHAR_SET_SHIFT) & \
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_CHAR_SET_MASK)
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_LANGUAGE(kv) \
- (be32_to_cpu((kv)->value.leaf.data[1]) & \
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_LANGUAGE_MASK)
-#define CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(kv) \
- (&((kv)->value.leaf.data[2]))
-
-
-/* The following 2 function are for creating new Configuration ROM trees. The
- * first function is used for both creating local trees and parsing remote
- * trees. The second function adds pertinent information to local Configuration
- * ROM trees - namely data for the bus information block. */
-extern struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
- size_t bus_info_size,
- void *private);
-extern void csr1212_init_local_csr(struct csr1212_csr *csr,
- const u32 *bus_info_data, int max_rom);
-
-
-/* Destroy a Configuration ROM tree and release all memory taken by the tree. */
-extern void csr1212_destroy_csr(struct csr1212_csr *csr);
-
-
-/* The following set of functions are fore creating new keyvals for placement in
- * a Configuration ROM tree. Code that creates new keyvals with these functions
- * must release those keyvals with csr1212_release_keyval() when they are no
- * longer needed. */
-extern struct csr1212_keyval *csr1212_new_immediate(u8 key, u32 value);
-extern struct csr1212_keyval *csr1212_new_directory(u8 key);
-extern struct csr1212_keyval *csr1212_new_string_descriptor_leaf(const char *s);
-
-
-/* The following function manages association between keyvals. Typically,
- * Descriptor Leaves and Directories will be associated with another keyval and
- * it is desirable for the Descriptor keyval to be place immediately after the
- * keyval that it is associated with.
- * Take care with subsequent ROM modifications: There is no function to remove
- * previously specified associations.
- */
-extern void csr1212_associate_keyval(struct csr1212_keyval *kv,
- struct csr1212_keyval *associate);
-
-
-/* The following functions manage the association of a keyval and directories.
- * A keyval may be attached to more than one directory. */
-extern int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
- struct csr1212_keyval *kv);
-extern void csr1212_detach_keyval_from_directory(struct csr1212_keyval *dir,
- struct csr1212_keyval *kv);
-
-
-/* Creates a complete Configuration ROM image in the list of caches available
- * via csr->cache_head. */
-extern int csr1212_generate_csr_image(struct csr1212_csr *csr);
-
-
-/* This is a convience function for reading a block of data out of one of the
- * caches in the csr->cache_head list. */
-extern int csr1212_read(struct csr1212_csr *csr, u32 offset, void *buffer,
- u32 len);
-
-
-/* The following functions are in place for parsing Configuration ROM images.
- * csr1212_parse_keyval() is used should there be a need to directly parse a
- * Configuration ROM directly. */
-extern int csr1212_parse_keyval(struct csr1212_keyval *kv,
- struct csr1212_csr_rom_cache *cache);
-extern int csr1212_parse_csr(struct csr1212_csr *csr);
-
-
-/* This function allocates a new cache which may be used for either parsing or
- * generating sub-sets of Configuration ROM images. */
-static inline struct csr1212_csr_rom_cache *
-csr1212_rom_cache_malloc(u32 offset, size_t size)
-{
- struct csr1212_csr_rom_cache *cache;
-
- cache = CSR1212_MALLOC(sizeof(*cache) + size);
- if (!cache)
- return NULL;
-
- cache->next = NULL;
- cache->prev = NULL;
- cache->filled_head = NULL;
- cache->filled_tail = NULL;
- cache->layout_head = NULL;
- cache->layout_tail = NULL;
- cache->offset = offset;
- cache->size = size;
- cache->ext_rom = NULL;
-
- return cache;
-}
-
-
-/* This function ensures that a keyval contains data when referencing a keyval
- * created by parsing a Configuration ROM. */
-extern struct csr1212_keyval *
-csr1212_get_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv);
-
-
-/* This function increments the reference count for a keyval should there be a
- * need for code to retain a keyval that has been parsed. */
-static inline void csr1212_keep_keyval(struct csr1212_keyval *kv)
-{
- atomic_inc(&kv->refcnt);
- smp_mb__after_atomic_inc();
-}
-
-
-/* This function decrements a keyval's reference count and will destroy the
- * keyval when there are no more users of the keyval. This should be called by
- * any code that calls csr1212_keep_keyval() or any of the keyval creation
- * routines csr1212_new_*(). */
-extern void csr1212_release_keyval(struct csr1212_keyval *kv);
-
-
-/*
- * This macro allows for looping over the keyval entries in a directory and it
- * ensures that keyvals from remote ConfigROMs are parsed properly.
- *
- * struct csr1212_csr *_csr points to the CSR associated with dir.
- * struct csr1212_keyval *_kv points to the current keyval (loop index).
- * struct csr1212_keyval *_dir points to the directory to be looped.
- * struct csr1212_dentry *_pos is used internally for indexing.
- *
- * kv will be NULL upon exit of the loop.
- */
-#define csr1212_for_each_dir_entry(_csr, _kv, _dir, _pos) \
- for (csr1212_get_keyval((_csr), (_dir)), \
- _pos = (_dir)->value.directory.dentries_head, \
- _kv = (_pos) ? csr1212_get_keyval((_csr), _pos->kv) : NULL;\
- (_kv) && (_pos); \
- (_kv->associate == NULL) ? \
- ((_pos = _pos->next), (_kv = (_pos) ? \
- csr1212_get_keyval((_csr), _pos->kv) : \
- NULL)) : \
- (_kv = csr1212_get_keyval((_csr), _kv->associate)))
-
-#endif /* __CSR1212_H__ */
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
deleted file mode 100644
index d178699b194..00000000000
--- a/drivers/ieee1394/dma.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * DMA region bookkeeping routines
- *
- * Copyright (C) 2002 Maas Digital LLC
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/scatterlist.h>
-
-#include "dma.h"
-
-/* dma_prog_region */
-
-void dma_prog_region_init(struct dma_prog_region *prog)
-{
- prog->kvirt = NULL;
- prog->dev = NULL;
- prog->n_pages = 0;
- prog->bus_addr = 0;
-}
-
-int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes,
- struct pci_dev *dev)
-{
- /* round up to page size */
- n_bytes = PAGE_ALIGN(n_bytes);
-
- prog->n_pages = n_bytes >> PAGE_SHIFT;
-
- prog->kvirt = pci_alloc_consistent(dev, n_bytes, &prog->bus_addr);
- if (!prog->kvirt) {
- printk(KERN_ERR
- "dma_prog_region_alloc: pci_alloc_consistent() failed\n");
- dma_prog_region_free(prog);
- return -ENOMEM;
- }
-
- prog->dev = dev;
-
- return 0;
-}
-
-void dma_prog_region_free(struct dma_prog_region *prog)
-{
- if (prog->kvirt) {
- pci_free_consistent(prog->dev, prog->n_pages << PAGE_SHIFT,
- prog->kvirt, prog->bus_addr);
- }
-
- prog->kvirt = NULL;
- prog->dev = NULL;
- prog->n_pages = 0;
- prog->bus_addr = 0;
-}
-
-/* dma_region */
-
-/**
- * dma_region_init - clear out all fields but do not allocate anything
- */
-void dma_region_init(struct dma_region *dma)
-{
- dma->kvirt = NULL;
- dma->dev = NULL;
- dma->n_pages = 0;
- dma->n_dma_pages = 0;
- dma->sglist = NULL;
-}
-
-/**
- * dma_region_alloc - allocate the buffer and map it to the IOMMU
- */
-int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
- struct pci_dev *dev, int direction)
-{
- unsigned int i;
-
- /* round up to page size */
- n_bytes = PAGE_ALIGN(n_bytes);
-
- dma->n_pages = n_bytes >> PAGE_SHIFT;
-
- dma->kvirt = vmalloc_32(n_bytes);
- if (!dma->kvirt) {
- printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n");
- goto err;
- }
-
- /* Clear the ram out, no junk to the user */
- memset(dma->kvirt, 0, n_bytes);
-
- /* allocate scatter/gather list */
- dma->sglist = vmalloc(dma->n_pages * sizeof(*dma->sglist));
- if (!dma->sglist) {
- printk(KERN_ERR "dma_region_alloc: vmalloc(sglist) failed\n");
- goto err;
- }
-
- sg_init_table(dma->sglist, dma->n_pages);
-
- /* fill scatter/gather list with pages */
- for (i = 0; i < dma->n_pages; i++) {
- unsigned long va =
- (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
-
- sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va),
- PAGE_SIZE, 0);
- }
-
- /* map sglist to the IOMMU */
- dma->n_dma_pages =
- pci_map_sg(dev, dma->sglist, dma->n_pages, direction);
-
- if (dma->n_dma_pages == 0) {
- printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n");
- goto err;
- }
-
- dma->dev = dev;
- dma->direction = direction;
-
- return 0;
-
- err:
- dma_region_free(dma);
- return -ENOMEM;
-}
-
-/**
- * dma_region_free - unmap and free the buffer
- */
-void dma_region_free(struct dma_region *dma)
-{
- if (dma->n_dma_pages) {
- pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages,
- dma->direction);
- dma->n_dma_pages = 0;
- dma->dev = NULL;
- }
-
- vfree(dma->sglist);
- dma->sglist = NULL;
-
- vfree(dma->kvirt);
- dma->kvirt = NULL;
- dma->n_pages = 0;
-}
-
-/* find the scatterlist index and remaining offset corresponding to a
- given offset from the beginning of the buffer */
-static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
- unsigned int start, unsigned long *rem)
-{
- int i;
- unsigned long off = offset;
-
- for (i = start; i < dma->n_dma_pages; i++) {
- if (off < sg_dma_len(&dma->sglist[i])) {
- *rem = off;
- break;
- }
-
- off -= sg_dma_len(&dma->sglist[i]);
- }
-
- BUG_ON(i >= dma->n_dma_pages);
-
- return i;
-}
-
-/**
- * dma_region_offset_to_bus - get bus address of an offset within a DMA region
- *
- * Returns the DMA bus address of the byte with the given @offset relative to
- * the beginning of the @dma.
- */
-dma_addr_t dma_region_offset_to_bus(struct dma_region * dma,
- unsigned long offset)
-{
- unsigned long rem = 0;
-
- struct scatterlist *sg =
- &dma->sglist[dma_region_find(dma, offset, 0, &rem)];
- return sg_dma_address(sg) + rem;
-}
-
-/**
- * dma_region_sync_for_cpu - sync the CPU's view of the buffer
- */
-void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
- unsigned long len)
-{
- int first, last;
- unsigned long rem = 0;
-
- if (!len)
- len = 1;
-
- first = dma_region_find(dma, offset, 0, &rem);
- last = dma_region_find(dma, rem + len - 1, first, &rem);
-
- pci_dma_sync_sg_for_cpu(dma->dev, &dma->sglist[first], last - first + 1,
- dma->direction);
-}
-
-/**
- * dma_region_sync_for_device - sync the IO bus' view of the buffer
- */
-void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
- unsigned long len)
-{
- int first, last;
- unsigned long rem = 0;
-
- if (!len)
- len = 1;
-
- first = dma_region_find(dma, offset, 0, &rem);
- last = dma_region_find(dma, rem + len - 1, first, &rem);
-
- pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first],
- last - first + 1, dma->direction);
-}
-
-#ifdef CONFIG_MMU
-
-static int dma_region_pagefault(struct vm_area_struct *vma,
- struct vm_fault *vmf)
-{
- struct dma_region *dma = (struct dma_region *)vma->vm_private_data;
-
- if (!dma->kvirt)
- return VM_FAULT_SIGBUS;
-
- if (vmf->pgoff >= dma->n_pages)
- return VM_FAULT_SIGBUS;
-
- vmf->page = vmalloc_to_page(dma->kvirt + (vmf->pgoff << PAGE_SHIFT));
- get_page(vmf->page);
- return 0;
-}
-
-static const struct vm_operations_struct dma_region_vm_ops = {
- .fault = dma_region_pagefault,
-};
-
-/**
- * dma_region_mmap - map the buffer into a user space process
- */
-int dma_region_mmap(struct dma_region *dma, struct file *file,
- struct vm_area_struct *vma)
-{
- unsigned long size;
-
- if (!dma->kvirt)
- return -EINVAL;
-
- /* must be page-aligned (XXX: comment is wrong, we could allow pgoff) */
- if (vma->vm_pgoff != 0)
- return -EINVAL;
-
- /* check the length */
- size = vma->vm_end - vma->vm_start;
- if (size > (dma->n_pages << PAGE_SHIFT))
- return -EINVAL;
-
- vma->vm_ops = &dma_region_vm_ops;
- vma->vm_private_data = dma;
- vma->vm_file = file;
- vma->vm_flags |= VM_RESERVED | VM_ALWAYSDUMP;
-
- return 0;
-}
-
-#else /* CONFIG_MMU */
-
-int dma_region_mmap(struct dma_region *dma, struct file *file,
- struct vm_area_struct *vma)
-{
- return -EINVAL;
-}
-
-#endif /* CONFIG_MMU */
diff --git a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h
deleted file mode 100644
index 467373cab8e..00000000000
--- a/drivers/ieee1394/dma.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * DMA region bookkeeping routines
- *
- * Copyright (C) 2002 Maas Digital LLC
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#ifndef IEEE1394_DMA_H
-#define IEEE1394_DMA_H
-
-#include <asm/types.h>
-
-struct file;
-struct pci_dev;
-struct scatterlist;
-struct vm_area_struct;
-
-/**
- * struct dma_prog_region - small contiguous DMA buffer
- * @kvirt: kernel virtual address
- * @dev: PCI device
- * @n_pages: number of kernel pages
- * @bus_addr: base bus address
- *
- * a small, physically contiguous DMA buffer with random-access, synchronous
- * usage characteristics
- */
-struct dma_prog_region {
- unsigned char *kvirt;
- struct pci_dev *dev;
- unsigned int n_pages;
- dma_addr_t bus_addr;
-};
-
-/* clear out all fields but do not allocate any memory */
-void dma_prog_region_init(struct dma_prog_region *prog);
-int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes,
- struct pci_dev *dev);
-void dma_prog_region_free(struct dma_prog_region *prog);
-
-static inline dma_addr_t dma_prog_region_offset_to_bus(
- struct dma_prog_region *prog, unsigned long offset)
-{
- return prog->bus_addr + offset;
-}
-
-/**
- * struct dma_region - large non-contiguous DMA buffer
- * @virt: kernel virtual address
- * @dev: PCI device
- * @n_pages: number of kernel pages
- * @n_dma_pages: number of IOMMU pages
- * @sglist: IOMMU mapping
- * @direction: PCI_DMA_TODEVICE, etc.
- *
- * a large, non-physically-contiguous DMA buffer with streaming, asynchronous
- * usage characteristics
- */
-struct dma_region {
- unsigned char *kvirt;
- struct pci_dev *dev;
- unsigned int n_pages;
- unsigned int n_dma_pages;
- struct scatterlist *sglist;
- int direction;
-};
-
-void dma_region_init(struct dma_region *dma);
-int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
- struct pci_dev *dev, int direction);
-void dma_region_free(struct dma_region *dma);
-void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
- unsigned long len);
-void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
- unsigned long len);
-int dma_region_mmap(struct dma_region *dma, struct file *file,
- struct vm_area_struct *vma);
-dma_addr_t dma_region_offset_to_bus(struct dma_region *dma,
- unsigned long offset);
-
-/**
- * dma_region_i - macro to index into a DMA region (or dma_prog_region)
- */
-#define dma_region_i(_dma, _type, _index) \
- ( ((_type*) ((_dma)->kvirt)) + (_index) )
-
-#endif /* IEEE1394_DMA_H */
diff --git a/drivers/ieee1394/dv1394-private.h b/drivers/ieee1394/dv1394-private.h
deleted file mode 100644
index 18b92cbf4a9..00000000000
--- a/drivers/ieee1394/dv1394-private.h
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * dv1394-private.h - DV input/output over IEEE 1394 on OHCI chips
- * Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
- * receive by Dan Dennedy <dan@dennedy.org>
- *
- * based on:
- * video1394.h - driver for OHCI 1394 boards
- * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
- * Peter Schlaile <udbz@rz.uni-karlsruhe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef _DV_1394_PRIVATE_H
-#define _DV_1394_PRIVATE_H
-
-#include "ieee1394.h"
-#include "ohci1394.h"
-#include "dma.h"
-
-/* data structures private to the dv1394 driver */
-/* none of this is exposed to user-space */
-
-
-/*
- the 8-byte CIP (Common Isochronous Packet) header that precedes
- each packet of DV data.
-
- See the IEC 61883 standard.
-*/
-
-struct CIP_header { unsigned char b[8]; };
-
-static inline void fill_cip_header(struct CIP_header *cip,
- unsigned char source_node_id,
- unsigned long counter,
- enum pal_or_ntsc format,
- unsigned long timestamp)
-{
- cip->b[0] = source_node_id;
- cip->b[1] = 0x78; /* packet size in quadlets (480/4) - even for empty packets! */
- cip->b[2] = 0x00;
- cip->b[3] = counter;
-
- cip->b[4] = 0x80; /* const */
-
- switch(format) {
- case DV1394_PAL:
- cip->b[5] = 0x80;
- break;
- case DV1394_NTSC:
- cip->b[5] = 0x00;
- break;
- }
-
- cip->b[6] = timestamp >> 8;
- cip->b[7] = timestamp & 0xFF;
-}
-
-
-
-/*
- DMA commands used to program the OHCI's DMA engine
-
- See the Texas Instruments OHCI 1394 chipset documentation.
-*/
-
-struct output_more_immediate { __le32 q[8]; };
-struct output_more { __le32 q[4]; };
-struct output_last { __le32 q[4]; };
-struct input_more { __le32 q[4]; };
-struct input_last { __le32 q[4]; };
-
-/* outputs */
-
-static inline void fill_output_more_immediate(struct output_more_immediate *omi,
- unsigned char tag,
- unsigned char channel,
- unsigned char sync_tag,
- unsigned int payload_size)
-{
- omi->q[0] = cpu_to_le32(0x02000000 | 8); /* OUTPUT_MORE_IMMEDIATE; 8 is the size of the IT header */
- omi->q[1] = cpu_to_le32(0);
- omi->q[2] = cpu_to_le32(0);
- omi->q[3] = cpu_to_le32(0);
-
- /* IT packet header */
- omi->q[4] = cpu_to_le32( (0x0 << 16) /* IEEE1394_SPEED_100 */
- | (tag << 14)
- | (channel << 8)
- | (TCODE_ISO_DATA << 4)
- | (sync_tag) );
-
- /* reserved field; mimic behavior of my Sony DSR-40 */
- omi->q[5] = cpu_to_le32((payload_size << 16) | (0x7F << 8) | 0xA0);
-
- omi->q[6] = cpu_to_le32(0);
- omi->q[7] = cpu_to_le32(0);
-}
-
-static inline void fill_output_more(struct output_more *om,
- unsigned int data_size,
- unsigned long data_phys_addr)
-{
- om->q[0] = cpu_to_le32(data_size);
- om->q[1] = cpu_to_le32(data_phys_addr);
- om->q[2] = cpu_to_le32(0);
- om->q[3] = cpu_to_le32(0);
-}
-
-static inline void fill_output_last(struct output_last *ol,
- int want_timestamp,
- int want_interrupt,
- unsigned int data_size,
- unsigned long data_phys_addr)
-{
- u32 temp = 0;
- temp |= 1 << 28; /* OUTPUT_LAST */
-
- if (want_timestamp) /* controller will update timestamp at DMA time */
- temp |= 1 << 27;
-
- if (want_interrupt)
- temp |= 3 << 20;
-
- temp |= 3 << 18; /* must take branch */
- temp |= data_size;
-
- ol->q[0] = cpu_to_le32(temp);
- ol->q[1] = cpu_to_le32(data_phys_addr);
- ol->q[2] = cpu_to_le32(0);
- ol->q[3] = cpu_to_le32(0);
-}
-
-/* inputs */
-
-static inline void fill_input_more(struct input_more *im,
- int want_interrupt,
- unsigned int data_size,
- unsigned long data_phys_addr)
-{
- u32 temp = 2 << 28; /* INPUT_MORE */
- temp |= 8 << 24; /* s = 1, update xferStatus and resCount */
- if (want_interrupt)
- temp |= 0 << 20; /* interrupts, i=0 in packet-per-buffer mode */
- temp |= 0x0 << 16; /* disable branch to address for packet-per-buffer mode */
- /* disable wait on sync field, not used in DV :-( */
- temp |= data_size;
-
- im->q[0] = cpu_to_le32(temp);
- im->q[1] = cpu_to_le32(data_phys_addr);
- im->q[2] = cpu_to_le32(0); /* branchAddress and Z not use in packet-per-buffer mode */
- im->q[3] = cpu_to_le32(0); /* xferStatus & resCount, resCount must be initialize to data_size */
-}
-
-static inline void fill_input_last(struct input_last *il,
- int want_interrupt,
- unsigned int data_size,
- unsigned long data_phys_addr)
-{
- u32 temp = 3 << 28; /* INPUT_LAST */
- temp |= 8 << 24; /* s = 1, update xferStatus and resCount */
- if (want_interrupt)
- temp |= 3 << 20; /* enable interrupts */
- temp |= 0xC << 16; /* enable branch to address */
- /* disable wait on sync field, not used in DV :-( */
- temp |= data_size;
-
- il->q[0] = cpu_to_le32(temp);
- il->q[1] = cpu_to_le32(data_phys_addr);
- il->q[2] = cpu_to_le32(1); /* branchAddress (filled in later) and Z = 1 descriptor in next block */
- il->q[3] = cpu_to_le32(data_size); /* xferStatus & resCount, resCount must be initialize to data_size */
-}
-
-
-
-/*
- A "DMA descriptor block" consists of several contiguous DMA commands.
- struct DMA_descriptor_block encapsulates all of the commands necessary
- to send one packet of DV data.
-
- There are three different types of these blocks:
-
- 1) command to send an empty packet (CIP header only, no DV data):
-
- OUTPUT_MORE-Immediate <-- contains the iso header in-line
- OUTPUT_LAST <-- points to the CIP header
-
- 2) command to send a full packet when the DV data payload does NOT
- cross a page boundary:
-
- OUTPUT_MORE-Immediate <-- contains the iso header in-line
- OUTPUT_MORE <-- points to the CIP header
- OUTPUT_LAST <-- points to entire DV data payload
-
- 3) command to send a full packet when the DV payload DOES cross
- a page boundary:
-
- OUTPUT_MORE-Immediate <-- contains the iso header in-line
- OUTPUT_MORE <-- points to the CIP header
- OUTPUT_MORE <-- points to first part of DV data payload
- OUTPUT_LAST <-- points to second part of DV data payload
-
- This struct describes all three block types using unions.
-
- !!! It is vital that an even number of these descriptor blocks fit on one
- page of memory, since a block cannot cross a page boundary !!!
-
- */
-
-struct DMA_descriptor_block {
-
- union {
- struct {
- /* iso header, common to all output block types */
- struct output_more_immediate omi;
-
- union {
- /* empty packet */
- struct {
- struct output_last ol; /* CIP header */
- } empty;
-
- /* full packet */
- struct {
- struct output_more om; /* CIP header */
-
- union {
- /* payload does not cross page boundary */
- struct {
- struct output_last ol; /* data payload */
- } nocross;
-
- /* payload crosses page boundary */
- struct {
- struct output_more om; /* data payload */
- struct output_last ol; /* data payload */
- } cross;
- } u;
-
- } full;
- } u;
- } out;
-
- struct {
- struct input_last il;
- } in;
-
- } u;
-
- /* ensure that PAGE_SIZE % sizeof(struct DMA_descriptor_block) == 0
- by padding out to 128 bytes */
- u32 __pad__[12];
-};
-
-
-/* struct frame contains all data associated with one frame in the
- ringbuffer these are allocated when the DMA context is initialized
- do_dv1394_init(). They are re-used after the card finishes
- transmitting the frame. */
-
-struct video_card; /* forward declaration */
-
-struct frame {
-
- /* points to the struct video_card that owns this frame */
- struct video_card *video;
-
- /* index of this frame in video_card->frames[] */
- unsigned int frame_num;
-
- /* FRAME_CLEAR - DMA program not set up, waiting for data
- FRAME_READY - DMA program written, ready to transmit
-
- Changes to these should be locked against the interrupt
- */
- enum {
- FRAME_CLEAR = 0,
- FRAME_READY
- } state;
-
- /* whether this frame has been DMA'ed already; used only from
- the IRQ handler to determine whether the frame can be reset */
- int done;
-
-
- /* kernel virtual pointer to the start of this frame's data in
- the user ringbuffer. Use only for CPU access; to get the DMA
- bus address you must go through the video->user_dma mapping */
- unsigned long data;
-
- /* Max # of packets per frame */
-#define MAX_PACKETS 500
-
-
- /* a PAGE_SIZE memory pool for allocating CIP headers
- !header_pool must be aligned to PAGE_SIZE! */
- struct CIP_header *header_pool;
- dma_addr_t header_pool_dma;
-
-
- /* a physically contiguous memory pool for allocating DMA
- descriptor blocks; usually around 64KB in size
- !descriptor_pool must be aligned to PAGE_SIZE! */
- struct DMA_descriptor_block *descriptor_pool;
- dma_addr_t descriptor_pool_dma;
- unsigned long descriptor_pool_size;
-
-
- /* # of packets allocated for this frame */
- unsigned int n_packets;
-
-
- /* below are several pointers (kernel virtual addresses, not
- DMA bus addresses) to parts of the DMA program. These are
- set each time the DMA program is written in
- frame_prepare(). They are used later on, e.g. from the
- interrupt handler, to check the status of the frame */
-
- /* points to status/timestamp field of first DMA packet */
- /* (we'll check it later to monitor timestamp accuracy) */
- __le32 *frame_begin_timestamp;
-
- /* the timestamp we assigned to the first packet in the frame */
- u32 assigned_timestamp;
-
- /* pointer to the first packet's CIP header (where the timestamp goes) */
- struct CIP_header *cip_syt1;
-
- /* pointer to the second packet's CIP header
- (only set if the first packet was empty) */
- struct CIP_header *cip_syt2;
-
- /* in order to figure out what caused an interrupt,
- store pointers to the status fields of the two packets
- that can cause interrupts. We'll check these from the
- interrupt handler.
- */
- __le32 *mid_frame_timestamp;
- __le32 *frame_end_timestamp;
-
- /* branch address field of final packet. This is effectively
- the "tail" in the chain of DMA descriptor blocks.
- We will fill it with the address of the first DMA descriptor
- block in the subsequent frame, once it is ready.
- */
- __le32 *frame_end_branch;
-
- /* the number of descriptors in the first descriptor block
- of the frame. Needed to start DMA */
- int first_n_descriptors;
-};
-
-
-struct packet {
- __le16 timestamp;
- u16 invalid;
- u16 iso_header;
- __le16 data_length;
- u32 cip_h1;
- u32 cip_h2;
- unsigned char data[480];
- unsigned char padding[16]; /* force struct size =512 for page alignment */
-};
-
-
-/* allocate/free a frame */
-static struct frame* frame_new(unsigned int frame_num, struct video_card *video);
-static void frame_delete(struct frame *f);
-
-/* reset f so that it can be used again */
-static void frame_reset(struct frame *f);
-
-/* struct video_card contains all data associated with one instance
- of the dv1394 driver
-*/
-enum modes {
- MODE_RECEIVE,
- MODE_TRANSMIT
-};
-
-struct video_card {
-
- /* ohci card to which this instance corresponds */
- struct ti_ohci *ohci;
-
- /* OHCI card id; the link between the VFS inode and a specific video_card
- (essentially the device minor number) */
- int id;
-
- /* entry in dv1394_cards */
- struct list_head list;
-
- /* OHCI card IT DMA context number, -1 if not in use */
- int ohci_it_ctx;
- struct ohci1394_iso_tasklet it_tasklet;
-
- /* register offsets for current IT DMA context, 0 if not in use */
- u32 ohci_IsoXmitContextControlSet;
- u32 ohci_IsoXmitContextControlClear;
- u32 ohci_IsoXmitCommandPtr;
-
- /* OHCI card IR DMA context number, -1 if not in use */
- struct ohci1394_iso_tasklet ir_tasklet;
- int ohci_ir_ctx;
-
- /* register offsets for current IR DMA context, 0 if not in use */
- u32 ohci_IsoRcvContextControlSet;
- u32 ohci_IsoRcvContextControlClear;
- u32 ohci_IsoRcvCommandPtr;
- u32 ohci_IsoRcvContextMatch;
-
-
- /* CONCURRENCY CONTROL */
-
- /* there are THREE levels of locking associated with video_card. */
-
- /*
- 1) the 'open' flag - this prevents more than one process from
- opening the device. (the driver currently assumes only one opener).
- This is a regular int, but use test_and_set_bit() (on bit zero)
- for atomicity.
- */
- unsigned long open;
-
- /*
- 2) the spinlock - this provides mutual exclusion between the interrupt
- handler and process-context operations. Generally you must take the
- spinlock under the following conditions:
- 1) DMA (and hence the interrupt handler) may be running
- AND
- 2) you need to operate on the video_card, especially active_frame
-
- It is OK to play with video_card without taking the spinlock if
- you are certain that DMA is not running. Even if DMA is running,
- it is OK to *read* active_frame with the lock, then drop it
- immediately. This is safe because the interrupt handler will never
- advance active_frame onto a frame that is not READY (and the spinlock
- must be held while marking a frame READY).
-
- spinlock is also used to protect ohci_it_ctx and ohci_ir_ctx,
- which can be accessed from both process and interrupt context
- */
- spinlock_t spinlock;
-
- /* flag to prevent spurious interrupts (which OHCI seems to
- generate a lot :) from accessing the struct */
- int dma_running;
-
- /*
- 3) the sleeping mutex 'mtx' - this is used from process context only,
- to serialize various operations on the video_card. Even though only one
- open() is allowed, we still need to prevent multiple threads of execution
- from entering calls like read, write, ioctl, etc.
-
- I honestly can't think of a good reason to use dv1394 from several threads
- at once, but we need to serialize anyway to prevent oopses =).
-
- NOTE: if you need both spinlock and mtx, take mtx first to avoid deadlock!
- */
- struct mutex mtx;
-
- /* people waiting for buffer space, please form a line here... */
- wait_queue_head_t waitq;
-
- /* support asynchronous I/O signals (SIGIO) */
- struct fasync_struct *fasync;
-
- /* the large, non-contiguous (rvmalloc()) ringbuffer for DV
- data, exposed to user-space via mmap() */
- unsigned long dv_buf_size;
- struct dma_region dv_buf;
-
- /* next byte in the ringbuffer that a write() call will fill */
- size_t write_off;
-
- struct frame *frames[DV1394_MAX_FRAMES];
-
- /* n_frames also serves as an indicator that this struct video_card is
- initialized and ready to run DMA buffers */
-
- int n_frames;
-
- /* this is the frame that is currently "owned" by the OHCI DMA controller
- (set to -1 iff DMA is not running)
-
- ! must lock against the interrupt handler when accessing it !
-
- RULES:
-
- Only the interrupt handler may change active_frame if DMA
- is running; if not, process may change it
-
- If the next frame is READY, the interrupt handler will advance
- active_frame when the current frame is finished.
-
- If the next frame is CLEAR, the interrupt handler will re-transmit
- the current frame, and the dropped_frames counter will be incremented.
-
- The interrupt handler will NEVER advance active_frame to a
- frame that is not READY.
- */
- int active_frame;
- int first_run;
-
- /* the same locking rules apply to these three fields also: */
-
- /* altered ONLY from process context. Must check first_clear_frame->state;
- if it's READY, that means the ringbuffer is full with READY frames;
- if it's CLEAR, that means one or more ringbuffer frames are CLEAR */
- unsigned int first_clear_frame;
-
- /* altered both by process and interrupt */
- unsigned int n_clear_frames;
-
- /* only altered by the interrupt */
- unsigned int dropped_frames;
-
-
-
- /* the CIP accumulator and continuity counter are properties
- of the DMA stream as a whole (not a single frame), so they
- are stored here in the video_card */
-
- unsigned long cip_accum;
- unsigned long cip_n, cip_d;
- unsigned int syt_offset;
- unsigned int continuity_counter;
-
- enum pal_or_ntsc pal_or_ntsc;
-
- /* redundant, but simplifies the code somewhat */
- unsigned int frame_size; /* in bytes */
-
- /* the isochronous channel to use, -1 if video card is inactive */
- int channel;
-
-
- /* physically contiguous packet ringbuffer for receive */
- struct dma_region packet_buf;
- unsigned long packet_buf_size;
-
- unsigned int current_packet;
- int first_frame; /* received first start frame marker? */
- enum modes mode;
-};
-
-/*
- if the video_card is not initialized, then the ONLY fields that are valid are:
- ohci
- open
- n_frames
-*/
-
-static inline int video_card_initialized(struct video_card *v)
-{
- return v->n_frames > 0;
-}
-
-static int do_dv1394_init(struct video_card *video, struct dv1394_init *init);
-static int do_dv1394_init_default(struct video_card *video);
-static void do_dv1394_shutdown(struct video_card *video, int free_user_buf);
-
-
-/* NTSC empty packet rate accurate to within 0.01%,
- calibrated against a Sony DSR-40 DVCAM deck */
-
-#define CIP_N_NTSC 68000000
-#define CIP_D_NTSC 1068000000
-
-#define CIP_N_PAL 1
-#define CIP_D_PAL 16
-
-#endif /* _DV_1394_PRIVATE_H */
-
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
deleted file mode 100644
index c5a031b79d0..00000000000
--- a/drivers/ieee1394/dv1394.c
+++ /dev/null
@@ -1,2584 +0,0 @@
-/*
- * dv1394.c - DV input/output over IEEE 1394 on OHCI chips
- * Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
- * receive by Dan Dennedy <dan@dennedy.org>
- *
- * based on:
- * video1394.c - video driver for OHCI 1394 boards
- * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- OVERVIEW
-
- I designed dv1394 as a "pipe" that you can use to shoot DV onto a
- FireWire bus. In transmission mode, dv1394 does the following:
-
- 1. accepts contiguous frames of DV data from user-space, via write()
- or mmap() (see dv1394.h for the complete API)
- 2. wraps IEC 61883 packets around the DV data, inserting
- empty synchronization packets as necessary
- 3. assigns accurate SYT timestamps to the outgoing packets
- 4. shoots them out using the OHCI card's IT DMA engine
-
- Thanks to Dan Dennedy, we now have a receive mode that does the following:
-
- 1. accepts raw IEC 61883 packets from the OHCI card
- 2. re-assembles the DV data payloads into contiguous frames,
- discarding empty packets
- 3. sends the DV data to user-space via read() or mmap()
-*/
-
-/*
- TODO:
-
- - tunable frame-drop behavior: either loop last frame, or halt transmission
-
- - use a scatter/gather buffer for DMA programs (f->descriptor_pool)
- so that we don't rely on allocating 64KB of contiguous kernel memory
- via pci_alloc_consistent()
-
- DONE:
- - during reception, better handling of dropped frames and continuity errors
- - during reception, prevent DMA from bypassing the irq tasklets
- - reduce irq rate during reception (1/250 packets).
- - add many more internal buffers during reception with scatter/gather dma.
- - add dbc (continuity) checking on receive, increment status.dropped_frames
- if not continuous.
- - restart IT DMA after a bus reset
- - safely obtain and release ISO Tx channels in cooperation with OHCI driver
- - map received DIF blocks to their proper location in DV frame (ensure
- recovery if dropped packet)
- - handle bus resets gracefully (OHCI card seems to take care of this itself(!))
- - do not allow resizing the user_buf once allocated; eliminate nuke_buffer_mappings
- - eliminated #ifdef DV1394_DEBUG_LEVEL by inventing macros debug_printk and irq_printk
- - added wmb() and mb() to places where PCI read/write ordering needs to be enforced
- - set video->id correctly
- - store video_cards in an array indexed by OHCI card ID, rather than a list
- - implement DMA context allocation to cooperate with other users of the OHCI
- - fix all XXX showstoppers
- - disable IR/IT DMA interrupts on shutdown
- - flush pci writes to the card by issuing a read
- - character device dispatching
- - switch over to the new kernel DMA API (pci_map_*()) (* needs testing on platforms with IOMMU!)
- - keep all video_cards in a list (for open() via chardev), set file->private_data = video
- - dv1394_poll should indicate POLLIN when receiving buffers are available
- - add proc fs interface to set cip_n, cip_d, syt_offset, and video signal
- - expose xmit and recv as separate devices (not exclusive)
- - expose NTSC and PAL as separate devices (can be overridden)
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
-#include <linux/mutex.h>
-#include <linux/bitops.h>
-#include <asm/byteorder.h>
-#include <asm/atomic.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/vmalloc.h>
-#include <linux/string.h>
-#include <linux/compat.h>
-#include <linux/cdev.h>
-
-#include "dv1394.h"
-#include "dv1394-private.h"
-#include "highlevel.h"
-#include "hosts.h"
-#include "ieee1394.h"
-#include "ieee1394_core.h"
-#include "ieee1394_hotplug.h"
-#include "ieee1394_types.h"
-#include "nodemgr.h"
-#include "ohci1394.h"
-
-/* DEBUG LEVELS:
- 0 - no debugging messages
- 1 - some debugging messages, but none during DMA frame transmission
- 2 - lots of messages, including during DMA frame transmission
- (will cause underflows if your machine is too slow!)
-*/
-
-#define DV1394_DEBUG_LEVEL 0
-
-/* for debugging use ONLY: allow more than one open() of the device */
-/* #define DV1394_ALLOW_MORE_THAN_ONE_OPEN 1 */
-
-#if DV1394_DEBUG_LEVEL >= 2
-#define irq_printk( args... ) printk( args )
-#else
-#define irq_printk( args... ) do {} while (0)
-#endif
-
-#if DV1394_DEBUG_LEVEL >= 1
-#define debug_printk( args... ) printk( args)
-#else
-#define debug_printk( args... ) do {} while (0)
-#endif
-
-/* issue a dummy PCI read to force the preceding write
- to be posted to the PCI bus immediately */
-
-static inline void flush_pci_write(struct ti_ohci *ohci)
-{
- mb();
- reg_read(ohci, OHCI1394_IsochronousCycleTimer);
-}
-
-static void it_tasklet_func(unsigned long data);
-static void ir_tasklet_func(unsigned long data);
-
-#ifdef CONFIG_COMPAT
-static long dv1394_compat_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
-#endif
-
-/* GLOBAL DATA */
-
-/* list of all video_cards */
-static LIST_HEAD(dv1394_cards);
-static DEFINE_SPINLOCK(dv1394_cards_lock);
-
-/* translate from a struct file* to the corresponding struct video_card* */
-
-static inline struct video_card* file_to_video_card(struct file *file)
-{
- return file->private_data;
-}
-
-/*** FRAME METHODS *********************************************************/
-
-static void frame_reset(struct frame *f)
-{
- f->state = FRAME_CLEAR;
- f->done = 0;
- f->n_packets = 0;
- f->frame_begin_timestamp = NULL;
- f->assigned_timestamp = 0;
- f->cip_syt1 = NULL;
- f->cip_syt2 = NULL;
- f->mid_frame_timestamp = NULL;
- f->frame_end_timestamp = NULL;
- f->frame_end_branch = NULL;
-}
-
-static struct frame* frame_new(unsigned int frame_num, struct video_card *video)
-{
- struct frame *f = kmalloc(sizeof(*f), GFP_KERNEL);
- if (!f)
- return NULL;
-
- f->video = video;
- f->frame_num = frame_num;
-
- f->header_pool = pci_alloc_consistent(f->video->ohci->dev, PAGE_SIZE, &f->header_pool_dma);
- if (!f->header_pool) {
- printk(KERN_ERR "dv1394: failed to allocate CIP header pool\n");
- kfree(f);
- return NULL;
- }
-
- debug_printk("dv1394: frame_new: allocated CIP header pool at virt 0x%08lx (contig) dma 0x%08lx size %ld\n",
- (unsigned long) f->header_pool, (unsigned long) f->header_pool_dma, PAGE_SIZE);
-
- f->descriptor_pool_size = MAX_PACKETS * sizeof(struct DMA_descriptor_block);
- /* make it an even # of pages */
- f->descriptor_pool_size += PAGE_SIZE - (f->descriptor_pool_size%PAGE_SIZE);
-
- f->descriptor_pool = pci_alloc_consistent(f->video->ohci->dev,
- f->descriptor_pool_size,
- &f->descriptor_pool_dma);
- if (!f->descriptor_pool) {
- pci_free_consistent(f->video->ohci->dev, PAGE_SIZE, f->header_pool, f->header_pool_dma);
- kfree(f);
- return NULL;
- }
-
- debug_printk("dv1394: frame_new: allocated DMA program memory at virt 0x%08lx (contig) dma 0x%08lx size %ld\n",
- (unsigned long) f->descriptor_pool, (unsigned long) f->descriptor_pool_dma, f->descriptor_pool_size);
-
- f->data = 0;
- frame_reset(f);
-
- return f;
-}
-
-static void frame_delete(struct frame *f)
-{
- pci_free_consistent(f->video->ohci->dev, PAGE_SIZE, f->header_pool, f->header_pool_dma);
- pci_free_consistent(f->video->ohci->dev, f->descriptor_pool_size, f->descriptor_pool, f->descriptor_pool_dma);
- kfree(f);
-}
-
-
-
-
-/*
- frame_prepare() - build the DMA program for transmitting
-
- Frame_prepare() must be called OUTSIDE the video->spinlock.
- However, frame_prepare() must still be serialized, so
- it should be called WITH the video->mtx taken.
- */
-
-static void frame_prepare(struct video_card *video, unsigned int this_frame)
-{
- struct frame *f = video->frames[this_frame];
- int last_frame;
-
- struct DMA_descriptor_block *block;
- dma_addr_t block_dma;
- struct CIP_header *cip;
- dma_addr_t cip_dma;
-
- unsigned int n_descriptors, full_packets, packets_per_frame, payload_size;
-
- /* these flags denote packets that need special attention */
- int empty_packet, first_packet, last_packet, mid_packet;
-
- __le32 *branch_address, *last_branch_address = NULL;
- unsigned long data_p;
- int first_packet_empty = 0;
- u32 cycleTimer, ct_sec, ct_cyc, ct_off;
- unsigned long irq_flags;
-
- irq_printk("frame_prepare( %d ) ---------------------\n", this_frame);
-
- full_packets = 0;
-
-
-
- if (video->pal_or_ntsc == DV1394_PAL)
- packets_per_frame = DV1394_PAL_PACKETS_PER_FRAME;
- else
- packets_per_frame = DV1394_NTSC_PACKETS_PER_FRAME;
-
- while ( full_packets < packets_per_frame ) {
- empty_packet = first_packet = last_packet = mid_packet = 0;
-
- data_p = f->data + full_packets * 480;
-
- /************************************************/
- /* allocate a descriptor block and a CIP header */
- /************************************************/
-
- /* note: these should NOT cross a page boundary (DMA restriction) */
-
- if (f->n_packets >= MAX_PACKETS) {
- printk(KERN_ERR "dv1394: FATAL ERROR: max packet count exceeded\n");
- return;
- }
-
- /* the block surely won't cross a page boundary,
- since an even number of descriptor_blocks fit on a page */
- block = &(f->descriptor_pool[f->n_packets]);
-
- /* DMA address of the block = offset of block relative
- to the kernel base address of the descriptor pool
- + DMA base address of the descriptor pool */
- block_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma;
-
-
- /* the whole CIP pool fits on one page, so no worries about boundaries */
- if ( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool)
- > PAGE_SIZE) {
- printk(KERN_ERR "dv1394: FATAL ERROR: no room to allocate CIP header\n");
- return;
- }
-
- cip = &(f->header_pool[f->n_packets]);
-
- /* DMA address of the CIP header = offset of cip
- relative to kernel base address of the header pool
- + DMA base address of the header pool */
- cip_dma = (unsigned long) cip % PAGE_SIZE + f->header_pool_dma;
-
- /* is this an empty packet? */
-
- if (video->cip_accum > (video->cip_d - video->cip_n)) {
- empty_packet = 1;
- payload_size = 8;
- video->cip_accum -= (video->cip_d - video->cip_n);
- } else {
- payload_size = 488;
- video->cip_accum += video->cip_n;
- }
-
- /* there are three important packets each frame:
-
- the first packet in the frame - we ask the card to record the timestamp when
- this packet is actually sent, so we can monitor
- how accurate our timestamps are. Also, the first
- packet serves as a semaphore to let us know that
- it's OK to free the *previous* frame's DMA buffer
-
- the last packet in the frame - this packet is used to detect buffer underflows.
- if this is the last ready frame, the last DMA block
- will have a branch back to the beginning of the frame
- (so that the card will re-send the frame on underflow).
- if this branch gets taken, we know that at least one
- frame has been dropped. When the next frame is ready,
- the branch is pointed to its first packet, and the
- semaphore is disabled.
-
- a "mid" packet slightly before the end of the frame - this packet should trigger
- an interrupt so we can go and assign a timestamp to the first packet
- in the next frame. We don't use the very last packet in the frame
- for this purpose, because that would leave very little time to set
- the timestamp before DMA starts on the next frame.
- */
-
- if (f->n_packets == 0) {
- first_packet = 1;
- } else if ( full_packets == (packets_per_frame-1) ) {
- last_packet = 1;
- } else if (f->n_packets == packets_per_frame) {
- mid_packet = 1;
- }
-
-
- /********************/
- /* setup CIP header */
- /********************/
-
- /* the timestamp will be written later from the
- mid-frame interrupt handler. For now we just
- store the address of the CIP header(s) that
- need a timestamp. */
-
- /* first packet in the frame needs a timestamp */
- if (first_packet) {
- f->cip_syt1 = cip;
- if (empty_packet)
- first_packet_empty = 1;
-
- } else if (first_packet_empty && (f->n_packets == 1) ) {
- /* if the first packet was empty, the second
- packet's CIP header also needs a timestamp */
- f->cip_syt2 = cip;
- }
-
- fill_cip_header(cip,
- /* the node ID number of the OHCI card */
- reg_read(video->ohci, OHCI1394_NodeID) & 0x3F,
- video->continuity_counter,
- video->pal_or_ntsc,
- 0xFFFF /* the timestamp is filled in later */);
-
- /* advance counter, only for full packets */
- if ( ! empty_packet )
- video->continuity_counter++;
-
- /******************************/
- /* setup DMA descriptor block */
- /******************************/
-
- /* first descriptor - OUTPUT_MORE_IMMEDIATE, for the controller's IT header */
- fill_output_more_immediate( &(block->u.out.omi), 1, video->channel, 0, payload_size);
-
- if (empty_packet) {
- /* second descriptor - OUTPUT_LAST for CIP header */
- fill_output_last( &(block->u.out.u.empty.ol),
-
- /* want completion status on all interesting packets */
- (first_packet || mid_packet || last_packet) ? 1 : 0,
-
- /* want interrupts on all interesting packets */
- (first_packet || mid_packet || last_packet) ? 1 : 0,
-
- sizeof(struct CIP_header), /* data size */
- cip_dma);
-
- if (first_packet)
- f->frame_begin_timestamp = &(block->u.out.u.empty.ol.q[3]);
- else if (mid_packet)
- f->mid_frame_timestamp = &(block->u.out.u.empty.ol.q[3]);
- else if (last_packet) {
- f->frame_end_timestamp = &(block->u.out.u.empty.ol.q[3]);
- f->frame_end_branch = &(block->u.out.u.empty.ol.q[2]);
- }
-
- branch_address = &(block->u.out.u.empty.ol.q[2]);
- n_descriptors = 3;
- if (first_packet)
- f->first_n_descriptors = n_descriptors;
-
- } else { /* full packet */
-
- /* second descriptor - OUTPUT_MORE for CIP header */
- fill_output_more( &(block->u.out.u.full.om),
- sizeof(struct CIP_header), /* data size */
- cip_dma);
-
-
- /* third (and possibly fourth) descriptor - for DV data */
- /* the 480-byte payload can cross a page boundary; if so,
- we need to split it into two DMA descriptors */
-
- /* does the 480-byte data payload cross a page boundary? */
- if ( (PAGE_SIZE- ((unsigned long)data_p % PAGE_SIZE) ) < 480 ) {
-
- /* page boundary crossed */
-
- fill_output_more( &(block->u.out.u.full.u.cross.om),
- /* data size - how much of data_p fits on the first page */
- PAGE_SIZE - (data_p % PAGE_SIZE),
-
- /* DMA address of data_p */
- dma_region_offset_to_bus(&video->dv_buf,
- data_p - (unsigned long) video->dv_buf.kvirt));
-
- fill_output_last( &(block->u.out.u.full.u.cross.ol),
-
- /* want completion status on all interesting packets */
- (first_packet || mid_packet || last_packet) ? 1 : 0,
-
- /* want interrupt on all interesting packets */
- (first_packet || mid_packet || last_packet) ? 1 : 0,
-
- /* data size - remaining portion of data_p */
- 480 - (PAGE_SIZE - (data_p % PAGE_SIZE)),
-
- /* DMA address of data_p + PAGE_SIZE - (data_p % PAGE_SIZE) */
- dma_region_offset_to_bus(&video->dv_buf,
- data_p + PAGE_SIZE - (data_p % PAGE_SIZE) - (unsigned long) video->dv_buf.kvirt));
-
- if (first_packet)
- f->frame_begin_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
- else if (mid_packet)
- f->mid_frame_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
- else if (last_packet) {
- f->frame_end_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]);
- f->frame_end_branch = &(block->u.out.u.full.u.cross.ol.q[2]);
- }
-
- branch_address = &(block->u.out.u.full.u.cross.ol.q[2]);
-
- n_descriptors = 5;
- if (first_packet)
- f->first_n_descriptors = n_descriptors;
-
- full_packets++;
-
- } else {
- /* fits on one page */
-
- fill_output_last( &(block->u.out.u.full.u.nocross.ol),
-
- /* want completion status on all interesting packets */
- (first_packet || mid_packet || last_packet) ? 1 : 0,
-
- /* want interrupt on all interesting packets */
- (first_packet || mid_packet || last_packet) ? 1 : 0,
-
- 480, /* data size (480 bytes of DV data) */
-
-
- /* DMA address of data_p */
- dma_region_offset_to_bus(&video->dv_buf,
- data_p - (unsigned long) video->dv_buf.kvirt));
-
- if (first_packet)
- f->frame_begin_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
- else if (mid_packet)
- f->mid_frame_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
- else if (last_packet) {
- f->frame_end_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]);
- f->frame_end_branch = &(block->u.out.u.full.u.nocross.ol.q[2]);
- }
-
- branch_address = &(block->u.out.u.full.u.nocross.ol.q[2]);
-
- n_descriptors = 4;
- if (first_packet)
- f->first_n_descriptors = n_descriptors;
-
- full_packets++;
- }
- }
-
- /* link this descriptor block into the DMA program by filling in
- the branch address of the previous block */
-
- /* note: we are not linked into the active DMA chain yet */
-
- if (last_branch_address) {
- *(last_branch_address) = cpu_to_le32(block_dma | n_descriptors);
- }
-
- last_branch_address = branch_address;
-
-
- f->n_packets++;
-
- }
-
- /* when we first assemble a new frame, set the final branch
- to loop back up to the top */
- *(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors);
-
- /* make the latest version of this frame visible to the PCI card */
- dma_region_sync_for_device(&video->dv_buf, f->data - (unsigned long) video->dv_buf.kvirt, video->frame_size);
-
- /* lock against DMA interrupt */
- spin_lock_irqsave(&video->spinlock, irq_flags);
-
- f->state = FRAME_READY;
-
- video->n_clear_frames--;
-
- last_frame = video->first_clear_frame - 1;
- if (last_frame == -1)
- last_frame = video->n_frames-1;
-
- video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
-
- irq_printk(" frame %d prepared, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n last=%d\n",
- this_frame, video->active_frame, video->n_clear_frames, video->first_clear_frame, last_frame);
-
- irq_printk(" begin_ts %08lx mid_ts %08lx end_ts %08lx end_br %08lx\n",
- (unsigned long) f->frame_begin_timestamp,
- (unsigned long) f->mid_frame_timestamp,
- (unsigned long) f->frame_end_timestamp,
- (unsigned long) f->frame_end_branch);
-
- if (video->active_frame != -1) {
-
- /* if DMA is already active, we are almost done */
- /* just link us onto the active DMA chain */
- if (video->frames[last_frame]->frame_end_branch) {
- u32 temp;
-
- /* point the previous frame's tail to this frame's head */
- *(video->frames[last_frame]->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors);
-
- /* this write MUST precede the next one, or we could silently drop frames */
- wmb();
-
- /* disable the want_status semaphore on the last packet */
- temp = le32_to_cpu(*(video->frames[last_frame]->frame_end_branch - 2));
- temp &= 0xF7CFFFFF;
- *(video->frames[last_frame]->frame_end_branch - 2) = cpu_to_le32(temp);
-
- /* flush these writes to memory ASAP */
- flush_pci_write(video->ohci);
-
- /* NOTE:
- ideally the writes should be "atomic": if
- the OHCI card reads the want_status flag in
- between them, we'll falsely report a
- dropped frame. Hopefully this window is too
- small to really matter, and the consequence
- is rather harmless. */
-
-
- irq_printk(" new frame %d linked onto DMA chain\n", this_frame);
-
- } else {
- printk(KERN_ERR "dv1394: last frame not ready???\n");
- }
-
- } else {
-
- u32 transmit_sec, transmit_cyc;
- u32 ts_cyc;
-
- /* DMA is stopped, so this is the very first frame */
- video->active_frame = this_frame;
-
- /* set CommandPtr to address and size of first descriptor block */
- reg_write(video->ohci, video->ohci_IsoXmitCommandPtr,
- video->frames[video->active_frame]->descriptor_pool_dma |
- f->first_n_descriptors);
-
- /* assign a timestamp based on the current cycle time...
- We'll tell the card to begin DMA 100 cycles from now,
- and assign a timestamp 103 cycles from now */
-
- cycleTimer = reg_read(video->ohci, OHCI1394_IsochronousCycleTimer);
-
- ct_sec = cycleTimer >> 25;
- ct_cyc = (cycleTimer >> 12) & 0x1FFF;
- ct_off = cycleTimer & 0xFFF;
-
- transmit_sec = ct_sec;
- transmit_cyc = ct_cyc + 100;
-
- transmit_sec += transmit_cyc/8000;
- transmit_cyc %= 8000;
-
- ts_cyc = transmit_cyc + 3;
- ts_cyc %= 8000;
-
- f->assigned_timestamp = (ts_cyc&0xF) << 12;
-
- /* now actually write the timestamp into the appropriate CIP headers */
- if (f->cip_syt1) {
- f->cip_syt1->b[6] = f->assigned_timestamp >> 8;
- f->cip_syt1->b[7] = f->assigned_timestamp & 0xFF;
- }
- if (f->cip_syt2) {
- f->cip_syt2->b[6] = f->assigned_timestamp >> 8;
- f->cip_syt2->b[7] = f->assigned_timestamp & 0xFF;
- }
-
- /* --- start DMA --- */
-
- /* clear all bits in ContextControl register */
-
- reg_write(video->ohci, video->ohci_IsoXmitContextControlClear, 0xFFFFFFFF);
- wmb();
-
- /* the OHCI card has the ability to start ISO transmission on a
- particular cycle (start-on-cycle). This way we can ensure that
- the first DV frame will have an accurate timestamp.
-
- However, start-on-cycle only appears to work if the OHCI card
- is cycle master! Since the consequences of messing up the first
- timestamp are minimal*, just disable start-on-cycle for now.
-
- * my DV deck drops the first few frames before it "locks in;"
- so the first frame having an incorrect timestamp is inconsequential.
- */
-
-#if 0
- reg_write(video->ohci, video->ohci_IsoXmitContextControlSet,
- (1 << 31) /* enable start-on-cycle */
- | ( (transmit_sec & 0x3) << 29)
- | (transmit_cyc << 16));
- wmb();
-#endif
-
- video->dma_running = 1;
-
- /* set the 'run' bit */
- reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, 0x8000);
- flush_pci_write(video->ohci);
-
- /* --- DMA should be running now --- */
-
- debug_printk(" Cycle = %4u ContextControl = %08x CmdPtr = %08x\n",
- (reg_read(video->ohci, OHCI1394_IsochronousCycleTimer) >> 12) & 0x1FFF,
- reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
- reg_read(video->ohci, video->ohci_IsoXmitCommandPtr));
-
- debug_printk(" DMA start - current cycle %4u, transmit cycle %4u (%2u), assigning ts cycle %2u\n",
- ct_cyc, transmit_cyc, transmit_cyc & 0xF, ts_cyc & 0xF);
-
-#if DV1394_DEBUG_LEVEL >= 2
- {
- /* check if DMA is really running */
- int i = 0;
- while (i < 20) {
- mb();
- mdelay(1);
- if (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) {
- printk("DMA ACTIVE after %d msec\n", i);
- break;
- }
- i++;
- }
-
- printk("set = %08x, cmdPtr = %08x\n",
- reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
- reg_read(video->ohci, video->ohci_IsoXmitCommandPtr)
- );
-
- if ( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) {
- printk("DMA did NOT go active after 20ms, event = %x\n",
- reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & 0x1F);
- } else
- printk("DMA is RUNNING!\n");
- }
-#endif
-
- }
-
-
- spin_unlock_irqrestore(&video->spinlock, irq_flags);
-}
-
-
-
-/*** RECEIVE FUNCTIONS *****************************************************/
-
-/*
- frame method put_packet
-
- map and copy the packet data to its location in the frame
- based upon DIF section and sequence
-*/
-
-static void inline
-frame_put_packet (struct frame *f, struct packet *p)
-{
- int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
- int dif_sequence = p->data[1] >> 4; /* dif sequence number is in bits 4 - 7 */
- int dif_block = p->data[2];
-
- /* sanity check */
- if (dif_sequence > 11 || dif_block > 149) return;
-
- switch (section_type) {
- case 0: /* 1 Header block */
- memcpy( (void *) f->data + dif_sequence * 150 * 80, p->data, 480);
- break;
-
- case 1: /* 2 Subcode blocks */
- memcpy( (void *) f->data + dif_sequence * 150 * 80 + (1 + dif_block) * 80, p->data, 480);
- break;
-
- case 2: /* 3 VAUX blocks */
- memcpy( (void *) f->data + dif_sequence * 150 * 80 + (3 + dif_block) * 80, p->data, 480);
- break;
-
- case 3: /* 9 Audio blocks interleaved with video */
- memcpy( (void *) f->data + dif_sequence * 150 * 80 + (6 + dif_block * 16) * 80, p->data, 480);
- break;
-
- case 4: /* 135 Video blocks interleaved with audio */
- memcpy( (void *) f->data + dif_sequence * 150 * 80 + (7 + (dif_block / 15) + dif_block) * 80, p->data, 480);
- break;
-
- default: /* we can not handle any other data */
- break;
- }
-}
-
-
-static void start_dma_receive(struct video_card *video)
-{
- if (video->first_run == 1) {
- video->first_run = 0;
-
- /* start DMA once all of the frames are READY */
- video->n_clear_frames = 0;
- video->first_clear_frame = -1;
- video->current_packet = 0;
- video->active_frame = 0;
-
- /* reset iso recv control register */
- reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, 0xFFFFFFFF);
- wmb();
-
- /* clear bufferFill, set isochHeader and speed (0=100) */
- reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x40000000);
-
- /* match on all tags, listen on channel */
- reg_write(video->ohci, video->ohci_IsoRcvContextMatch, 0xf0000000 | video->channel);
-
- /* address and first descriptor block + Z=1 */
- reg_write(video->ohci, video->ohci_IsoRcvCommandPtr,
- video->frames[0]->descriptor_pool_dma | 1); /* Z=1 */
- wmb();
-
- video->dma_running = 1;
-
- /* run */
- reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x8000);
- flush_pci_write(video->ohci);
-
- debug_printk("dv1394: DMA started\n");
-
-#if DV1394_DEBUG_LEVEL >= 2
- {
- int i;
-
- for (i = 0; i < 1000; ++i) {
- mdelay(1);
- if (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) {
- printk("DMA ACTIVE after %d msec\n", i);
- break;
- }
- }
- if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) {
- printk("DEAD, event = %x\n",
- reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F);
- } else
- printk("RUNNING!\n");
- }
-#endif
- } else if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) {
- debug_printk("DEAD, event = %x\n",
- reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F);
-
- /* wake */
- reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12));
- }
-}
-
-
-/*
- receive_packets() - build the DMA program for receiving
-*/
-
-static void receive_packets(struct video_card *video)
-{
- struct DMA_descriptor_block *block = NULL;
- dma_addr_t block_dma = 0;
- struct packet *data = NULL;
- dma_addr_t data_dma = 0;
- __le32 *last_branch_address = NULL;
- unsigned long irq_flags;
- int want_interrupt = 0;
- struct frame *f = NULL;
- int i, j;
-
- spin_lock_irqsave(&video->spinlock, irq_flags);
-
- for (j = 0; j < video->n_frames; j++) {
-
- /* connect frames */
- if (j > 0 && f != NULL && f->frame_end_branch != NULL)
- *(f->frame_end_branch) = cpu_to_le32(video->frames[j]->descriptor_pool_dma | 1); /* set Z=1 */
-
- f = video->frames[j];
-
- for (i = 0; i < MAX_PACKETS; i++) {
- /* locate a descriptor block and packet from the buffer */
- block = &(f->descriptor_pool[i]);
- block_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma;
-
- data = ((struct packet*)video->packet_buf.kvirt) + f->frame_num * MAX_PACKETS + i;
- data_dma = dma_region_offset_to_bus( &video->packet_buf,
- ((unsigned long) data - (unsigned long) video->packet_buf.kvirt) );
-
- /* setup DMA descriptor block */
- want_interrupt = ((i % (MAX_PACKETS/2)) == 0 || i == (MAX_PACKETS-1));
- fill_input_last( &(block->u.in.il), want_interrupt, 512, data_dma);
-
- /* link descriptors */
- last_branch_address = f->frame_end_branch;
-
- if (last_branch_address != NULL)
- *(last_branch_address) = cpu_to_le32(block_dma | 1); /* set Z=1 */
-
- f->frame_end_branch = &(block->u.in.il.q[2]);
- }
-
- } /* next j */
-
- spin_unlock_irqrestore(&video->spinlock, irq_flags);
-
-}
-
-
-
-/*** MANAGEMENT FUNCTIONS **************************************************/
-
-static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
-{
- unsigned long flags, new_buf_size;
- int i;
- u64 chan_mask;
- int retval = -EINVAL;
-
- debug_printk("dv1394: initialising %d\n", video->id);
- if (init->api_version != DV1394_API_VERSION)
- return -EINVAL;
-
- /* first sanitize all the parameters */
- if ( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) )
- return -EINVAL;
-
- if ( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) )
- return -EINVAL;
-
- if ( (init->syt_offset == 0) || (init->syt_offset > 50) )
- /* default SYT offset is 3 cycles */
- init->syt_offset = 3;
-
- if (init->channel > 63)
- init->channel = 63;
-
- chan_mask = (u64)1 << init->channel;
-
- /* calculate what size DMA buffer is needed */
- if (init->format == DV1394_NTSC)
- new_buf_size = DV1394_NTSC_FRAME_SIZE * init->n_frames;
- else
- new_buf_size = DV1394_PAL_FRAME_SIZE * init->n_frames;
-
- /* round up to PAGE_SIZE */
- if (new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE);
-
- /* don't allow the user to allocate the DMA buffer more than once */
- if (video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) {
- printk("dv1394: re-sizing the DMA buffer is not allowed\n");
- return -EINVAL;
- }
-
- /* shutdown the card if it's currently active */
- /* (the card should not be reset if the parameters are screwy) */
-
- do_dv1394_shutdown(video, 0);
-
- /* try to claim the ISO channel */
- spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
- if (video->ohci->ISO_channel_usage & chan_mask) {
- spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
- retval = -EBUSY;
- goto err;
- }
- video->ohci->ISO_channel_usage |= chan_mask;
- spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
-
- video->channel = init->channel;
-
- /* initialize misc. fields of video */
- video->n_frames = init->n_frames;
- video->pal_or_ntsc = init->format;
-
- video->cip_accum = 0;
- video->continuity_counter = 0;
-
- video->active_frame = -1;
- video->first_clear_frame = 0;
- video->n_clear_frames = video->n_frames;
- video->dropped_frames = 0;
-
- video->write_off = 0;
-
- video->first_run = 1;
- video->current_packet = -1;
- video->first_frame = 0;
-
- if (video->pal_or_ntsc == DV1394_NTSC) {
- video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_NTSC;
- video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_NTSC;
- video->frame_size = DV1394_NTSC_FRAME_SIZE;
- } else {
- video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_PAL;
- video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_PAL;
- video->frame_size = DV1394_PAL_FRAME_SIZE;
- }
-
- video->syt_offset = init->syt_offset;
-
- /* find and claim DMA contexts on the OHCI card */
-
- if (video->ohci_it_ctx == -1) {
- ohci1394_init_iso_tasklet(&video->it_tasklet, OHCI_ISO_TRANSMIT,
- it_tasklet_func, (unsigned long) video);
-
- if (ohci1394_register_iso_tasklet(video->ohci, &video->it_tasklet) < 0) {
- printk(KERN_ERR "dv1394: could not find an available IT DMA context\n");
- retval = -EBUSY;
- goto err;
- }
-
- video->ohci_it_ctx = video->it_tasklet.context;
- debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx);
- }
-
- if (video->ohci_ir_ctx == -1) {
- ohci1394_init_iso_tasklet(&video->ir_tasklet, OHCI_ISO_RECEIVE,
- ir_tasklet_func, (unsigned long) video);
-
- if (ohci1394_register_iso_tasklet(video->ohci, &video->ir_tasklet) < 0) {
- printk(KERN_ERR "dv1394: could not find an available IR DMA context\n");
- retval = -EBUSY;
- goto err;
- }
- video->ohci_ir_ctx = video->ir_tasklet.context;
- debug_printk("dv1394: claimed IR DMA context %d\n", video->ohci_ir_ctx);
- }
-
- /* allocate struct frames */
- for (i = 0; i < init->n_frames; i++) {
- video->frames[i] = frame_new(i, video);
-
- if (!video->frames[i]) {
- printk(KERN_ERR "dv1394: Cannot allocate frame structs\n");
- retval = -ENOMEM;
- goto err;
- }
- }
-
- if (!video->dv_buf.kvirt) {
- /* allocate the ringbuffer */
- retval = dma_region_alloc(&video->dv_buf, new_buf_size, video->ohci->dev, PCI_DMA_TODEVICE);
- if (retval)
- goto err;
-
- video->dv_buf_size = new_buf_size;
-
- debug_printk("dv1394: Allocated %d frame buffers, total %u pages (%u DMA pages), %lu bytes\n",
- video->n_frames, video->dv_buf.n_pages,
- video->dv_buf.n_dma_pages, video->dv_buf_size);
- }
-
- /* set up the frame->data pointers */
- for (i = 0; i < video->n_frames; i++)
- video->frames[i]->data = (unsigned long) video->dv_buf.kvirt + i * video->frame_size;
-
- if (!video->packet_buf.kvirt) {
- /* allocate packet buffer */
- video->packet_buf_size = sizeof(struct packet) * video->n_frames * MAX_PACKETS;
- if (video->packet_buf_size % PAGE_SIZE)
- video->packet_buf_size += PAGE_SIZE - (video->packet_buf_size % PAGE_SIZE);
-
- retval = dma_region_alloc(&video->packet_buf, video->packet_buf_size,
- video->ohci->dev, PCI_DMA_FROMDEVICE);
- if (retval)
- goto err;
-
- debug_printk("dv1394: Allocated %d packets in buffer, total %u pages (%u DMA pages), %lu bytes\n",
- video->n_frames*MAX_PACKETS, video->packet_buf.n_pages,
- video->packet_buf.n_dma_pages, video->packet_buf_size);
- }
-
- /* set up register offsets for IT context */
- /* IT DMA context registers are spaced 16 bytes apart */
- video->ohci_IsoXmitContextControlSet = OHCI1394_IsoXmitContextControlSet+16*video->ohci_it_ctx;
- video->ohci_IsoXmitContextControlClear = OHCI1394_IsoXmitContextControlClear+16*video->ohci_it_ctx;
- video->ohci_IsoXmitCommandPtr = OHCI1394_IsoXmitCommandPtr+16*video->ohci_it_ctx;
-
- /* enable interrupts for IT context */
- reg_write(video->ohci, OHCI1394_IsoXmitIntMaskSet, (1 << video->ohci_it_ctx));
- debug_printk("dv1394: interrupts enabled for IT context %d\n", video->ohci_it_ctx);
-
- /* set up register offsets for IR context */
- /* IR DMA context registers are spaced 32 bytes apart */
- video->ohci_IsoRcvContextControlSet = OHCI1394_IsoRcvContextControlSet+32*video->ohci_ir_ctx;
- video->ohci_IsoRcvContextControlClear = OHCI1394_IsoRcvContextControlClear+32*video->ohci_ir_ctx;
- video->ohci_IsoRcvCommandPtr = OHCI1394_IsoRcvCommandPtr+32*video->ohci_ir_ctx;
- video->ohci_IsoRcvContextMatch = OHCI1394_IsoRcvContextMatch+32*video->ohci_ir_ctx;
-
- /* enable interrupts for IR context */
- reg_write(video->ohci, OHCI1394_IsoRecvIntMaskSet, (1 << video->ohci_ir_ctx) );
- debug_printk("dv1394: interrupts enabled for IR context %d\n", video->ohci_ir_ctx);
-
- return 0;
-
-err:
- do_dv1394_shutdown(video, 1);
- return retval;
-}
-
-/* if the user doesn't bother to call ioctl(INIT) before starting
- mmap() or read()/write(), just give him some default values */
-
-static int do_dv1394_init_default(struct video_card *video)
-{
- struct dv1394_init init;
-
- init.api_version = DV1394_API_VERSION;
- init.n_frames = DV1394_MAX_FRAMES / 4;
- init.channel = video->channel;
- init.format = video->pal_or_ntsc;
- init.cip_n = video->cip_n;
- init.cip_d = video->cip_d;
- init.syt_offset = video->syt_offset;
-
- return do_dv1394_init(video, &init);
-}
-
-/* do NOT call from interrupt context */
-static void stop_dma(struct video_card *video)
-{
- unsigned long flags;
- int i;
-
- /* no interrupts */
- spin_lock_irqsave(&video->spinlock, flags);
-
- video->dma_running = 0;
-
- if ( (video->ohci_it_ctx == -1) && (video->ohci_ir_ctx == -1) )
- goto out;
-
- /* stop DMA if in progress */
- if ( (video->active_frame != -1) ||
- (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
- (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) {
-
- /* clear the .run bits */
- reg_write(video->ohci, video->ohci_IsoXmitContextControlClear, (1 << 15));
- reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, (1 << 15));
- flush_pci_write(video->ohci);
-
- video->active_frame = -1;
- video->first_run = 1;
-
- /* wait until DMA really stops */
- i = 0;
- while (i < 1000) {
-
- /* wait 0.1 millisecond */
- udelay(100);
-
- if ( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
- (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) {
- /* still active */
- debug_printk("dv1394: stop_dma: DMA not stopped yet\n" );
- mb();
- } else {
- debug_printk("dv1394: stop_dma: DMA stopped safely after %d ms\n", i/10);
- break;
- }
-
- i++;
- }
-
- if (i == 1000) {
- printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10);
- }
- }
- else
- debug_printk("dv1394: stop_dma: already stopped.\n");
-
-out:
- spin_unlock_irqrestore(&video->spinlock, flags);
-}
-
-
-
-static void do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
-{
- int i;
-
- debug_printk("dv1394: shutdown...\n");
-
- /* stop DMA if in progress */
- stop_dma(video);
-
- /* release the DMA contexts */
- if (video->ohci_it_ctx != -1) {
- video->ohci_IsoXmitContextControlSet = 0;
- video->ohci_IsoXmitContextControlClear = 0;
- video->ohci_IsoXmitCommandPtr = 0;
-
- /* disable interrupts for IT context */
- reg_write(video->ohci, OHCI1394_IsoXmitIntMaskClear, (1 << video->ohci_it_ctx));
-
- /* remove tasklet */
- ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet);
- debug_printk("dv1394: IT context %d released\n", video->ohci_it_ctx);
- video->ohci_it_ctx = -1;
- }
-
- if (video->ohci_ir_ctx != -1) {
- video->ohci_IsoRcvContextControlSet = 0;
- video->ohci_IsoRcvContextControlClear = 0;
- video->ohci_IsoRcvCommandPtr = 0;
- video->ohci_IsoRcvContextMatch = 0;
-
- /* disable interrupts for IR context */
- reg_write(video->ohci, OHCI1394_IsoRecvIntMaskClear, (1 << video->ohci_ir_ctx));
-
- /* remove tasklet */
- ohci1394_unregister_iso_tasklet(video->ohci, &video->ir_tasklet);
- debug_printk("dv1394: IR context %d released\n", video->ohci_ir_ctx);
- video->ohci_ir_ctx = -1;
- }
-
- /* release the ISO channel */
- if (video->channel != -1) {
- u64 chan_mask;
- unsigned long flags;
-
- chan_mask = (u64)1 << video->channel;
-
- spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
- video->ohci->ISO_channel_usage &= ~(chan_mask);
- spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
-
- video->channel = -1;
- }
-
- /* free the frame structs */
- for (i = 0; i < DV1394_MAX_FRAMES; i++) {
- if (video->frames[i])
- frame_delete(video->frames[i]);
- video->frames[i] = NULL;
- }
-
- video->n_frames = 0;
-
- /* we can't free the DMA buffer unless it is guaranteed that
- no more user-space mappings exist */
-
- if (free_dv_buf) {
- dma_region_free(&video->dv_buf);
- video->dv_buf_size = 0;
- }
-
- /* free packet buffer */
- dma_region_free(&video->packet_buf);
- video->packet_buf_size = 0;
-
- debug_printk("dv1394: shutdown OK\n");
-}
-
-/*
- **********************************
- *** MMAP() THEORY OF OPERATION ***
- **********************************
-
- The ringbuffer cannot be re-allocated or freed while
- a user program maintains a mapping of it. (note that a mapping
- can persist even after the device fd is closed!)
-
- So, only let the user process allocate the DMA buffer once.
- To resize or deallocate it, you must close the device file
- and open it again.
-
- Previously Dan M. hacked out a scheme that allowed the DMA
- buffer to change by forcefully unmapping it from the user's
- address space. It was prone to error because it's very hard to
- track all the places the buffer could have been mapped (we
- would have had to walk the vma list of every process in the
- system to be sure we found all the mappings!). Instead, we
- force the user to choose one buffer size and stick with
- it. This small sacrifice is worth the huge reduction in
- error-prone code in dv1394.
-*/
-
-static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct video_card *video = file_to_video_card(file);
- int retval = -EINVAL;
-
- /*
- * We cannot use the blocking variant mutex_lock here because .mmap
- * is called with mmap_sem held, while .ioctl, .read, .write acquire
- * video->mtx and subsequently call copy_to/from_user which will
- * grab mmap_sem in case of a page fault.
- */
- if (!mutex_trylock(&video->mtx))
- return -EAGAIN;
-
- if ( ! video_card_initialized(video) ) {
- retval = do_dv1394_init_default(video);
- if (retval)
- goto out;
- }
-
- retval = dma_region_mmap(&video->dv_buf, file, vma);
-out:
- mutex_unlock(&video->mtx);
- return retval;
-}
-
-/*** DEVICE FILE INTERFACE *************************************************/
-
-/* no need to serialize, multiple threads OK */
-static unsigned int dv1394_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct video_card *video = file_to_video_card(file);
- unsigned int mask = 0;
- unsigned long flags;
-
- poll_wait(file, &video->waitq, wait);
-
- spin_lock_irqsave(&video->spinlock, flags);
- if ( video->n_frames == 0 ) {
-
- } else if ( video->active_frame == -1 ) {
- /* nothing going on */
- mask |= POLLOUT;
- } else {
- /* any clear/ready buffers? */
- if (video->n_clear_frames >0)
- mask |= POLLOUT | POLLIN;
- }
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- return mask;
-}
-
-static int dv1394_fasync(int fd, struct file *file, int on)
-{
- /* I just copied this code verbatim from Alan Cox's mouse driver example
- (Documentation/DocBook/) */
-
- struct video_card *video = file_to_video_card(file);
-
- return fasync_helper(fd, file, on, &video->fasync);
-}
-
-static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
- struct video_card *video = file_to_video_card(file);
- DECLARE_WAITQUEUE(wait, current);
- ssize_t ret;
- size_t cnt;
- unsigned long flags;
- int target_frame;
-
- /* serialize this to prevent multi-threaded mayhem */
- if (file->f_flags & O_NONBLOCK) {
- if (!mutex_trylock(&video->mtx))
- return -EAGAIN;
- } else {
- if (mutex_lock_interruptible(&video->mtx))
- return -ERESTARTSYS;
- }
-
- if ( !video_card_initialized(video) ) {
- ret = do_dv1394_init_default(video);
- if (ret) {
- mutex_unlock(&video->mtx);
- return ret;
- }
- }
-
- ret = 0;
- add_wait_queue(&video->waitq, &wait);
-
- while (count > 0) {
-
- /* must set TASK_INTERRUPTIBLE *before* checking for free
- buffers; otherwise we could miss a wakeup if the interrupt
- fires between the check and the schedule() */
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irqsave(&video->spinlock, flags);
-
- target_frame = video->first_clear_frame;
-
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- if (video->frames[target_frame]->state == FRAME_CLEAR) {
-
- /* how much room is left in the target frame buffer */
- cnt = video->frame_size - (video->write_off - target_frame * video->frame_size);
-
- } else {
- /* buffer is already used */
- cnt = 0;
- }
-
- if (cnt > count)
- cnt = count;
-
- if (cnt <= 0) {
- /* no room left, gotta wait */
- if (file->f_flags & O_NONBLOCK) {
- if (!ret)
- ret = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- break;
- }
-
- schedule();
-
- continue; /* start over from 'while(count > 0)...' */
- }
-
- if (copy_from_user(video->dv_buf.kvirt + video->write_off, buffer, cnt)) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
-
- video->write_off = (video->write_off + cnt) % (video->n_frames * video->frame_size);
-
- count -= cnt;
- buffer += cnt;
- ret += cnt;
-
- if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames))
- frame_prepare(video, target_frame);
- }
-
- remove_wait_queue(&video->waitq, &wait);
- set_current_state(TASK_RUNNING);
- mutex_unlock(&video->mtx);
- return ret;
-}
-
-
-static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
- struct video_card *video = file_to_video_card(file);
- DECLARE_WAITQUEUE(wait, current);
- ssize_t ret;
- size_t cnt;
- unsigned long flags;
- int target_frame;
-
- /* serialize this to prevent multi-threaded mayhem */
- if (file->f_flags & O_NONBLOCK) {
- if (!mutex_trylock(&video->mtx))
- return -EAGAIN;
- } else {
- if (mutex_lock_interruptible(&video->mtx))
- return -ERESTARTSYS;
- }
-
- if ( !video_card_initialized(video) ) {
- ret = do_dv1394_init_default(video);
- if (ret) {
- mutex_unlock(&video->mtx);
- return ret;
- }
- video->continuity_counter = -1;
-
- receive_packets(video);
-
- start_dma_receive(video);
- }
-
- ret = 0;
- add_wait_queue(&video->waitq, &wait);
-
- while (count > 0) {
-
- /* must set TASK_INTERRUPTIBLE *before* checking for free
- buffers; otherwise we could miss a wakeup if the interrupt
- fires between the check and the schedule() */
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irqsave(&video->spinlock, flags);
-
- target_frame = video->first_clear_frame;
-
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- if (target_frame >= 0 &&
- video->n_clear_frames > 0 &&
- video->frames[target_frame]->state == FRAME_CLEAR) {
-
- /* how much room is left in the target frame buffer */
- cnt = video->frame_size - (video->write_off - target_frame * video->frame_size);
-
- } else {
- /* buffer is already used */
- cnt = 0;
- }
-
- if (cnt > count)
- cnt = count;
-
- if (cnt <= 0) {
- /* no room left, gotta wait */
- if (file->f_flags & O_NONBLOCK) {
- if (!ret)
- ret = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- break;
- }
-
- schedule();
-
- continue; /* start over from 'while(count > 0)...' */
- }
-
- if (copy_to_user(buffer, video->dv_buf.kvirt + video->write_off, cnt)) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
-
- video->write_off = (video->write_off + cnt) % (video->n_frames * video->frame_size);
-
- count -= cnt;
- buffer += cnt;
- ret += cnt;
-
- if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) {
- spin_lock_irqsave(&video->spinlock, flags);
- video->n_clear_frames--;
- video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
- spin_unlock_irqrestore(&video->spinlock, flags);
- }
- }
-
- remove_wait_queue(&video->waitq, &wait);
- set_current_state(TASK_RUNNING);
- mutex_unlock(&video->mtx);
- return ret;
-}
-
-
-/*** DEVICE IOCTL INTERFACE ************************************************/
-
-static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct video_card *video = file_to_video_card(file);
- unsigned long flags;
- int ret = -EINVAL;
- void __user *argp = (void __user *)arg;
-
- DECLARE_WAITQUEUE(wait, current);
-
- /* serialize this to prevent multi-threaded mayhem */
- if (file->f_flags & O_NONBLOCK) {
- if (!mutex_trylock(&video->mtx))
- return -EAGAIN;
- } else {
- if (mutex_lock_interruptible(&video->mtx))
- return -ERESTARTSYS;
- }
-
- switch(cmd)
- {
- case DV1394_IOC_SUBMIT_FRAMES: {
- unsigned int n_submit;
-
- if ( !video_card_initialized(video) ) {
- ret = do_dv1394_init_default(video);
- if (ret)
- goto out;
- }
-
- n_submit = (unsigned int) arg;
-
- if (n_submit > video->n_frames) {
- ret = -EINVAL;
- goto out;
- }
-
- while (n_submit > 0) {
-
- add_wait_queue(&video->waitq, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irqsave(&video->spinlock, flags);
-
- /* wait until video->first_clear_frame is really CLEAR */
- while (video->frames[video->first_clear_frame]->state != FRAME_CLEAR) {
-
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- if (signal_pending(current)) {
- remove_wait_queue(&video->waitq, &wait);
- set_current_state(TASK_RUNNING);
- ret = -EINTR;
- goto out;
- }
-
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irqsave(&video->spinlock, flags);
- }
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- remove_wait_queue(&video->waitq, &wait);
- set_current_state(TASK_RUNNING);
-
- frame_prepare(video, video->first_clear_frame);
-
- n_submit--;
- }
-
- ret = 0;
- break;
- }
-
- case DV1394_IOC_WAIT_FRAMES: {
- unsigned int n_wait;
-
- if ( !video_card_initialized(video) ) {
- ret = -EINVAL;
- goto out;
- }
-
- n_wait = (unsigned int) arg;
-
- /* since we re-run the last frame on underflow, we will
- never actually have n_frames clear frames; at most only
- n_frames - 1 */
-
- if (n_wait > (video->n_frames-1) ) {
- ret = -EINVAL;
- goto out;
- }
-
- add_wait_queue(&video->waitq, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irqsave(&video->spinlock, flags);
-
- while (video->n_clear_frames < n_wait) {
-
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- if (signal_pending(current)) {
- remove_wait_queue(&video->waitq, &wait);
- set_current_state(TASK_RUNNING);
- ret = -EINTR;
- goto out;
- }
-
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irqsave(&video->spinlock, flags);
- }
-
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- remove_wait_queue(&video->waitq, &wait);
- set_current_state(TASK_RUNNING);
- ret = 0;
- break;
- }
-
- case DV1394_IOC_RECEIVE_FRAMES: {
- unsigned int n_recv;
-
- if ( !video_card_initialized(video) ) {
- ret = -EINVAL;
- goto out;
- }
-
- n_recv = (unsigned int) arg;
-
- /* at least one frame must be active */
- if (n_recv > (video->n_frames-1) ) {
- ret = -EINVAL;
- goto out;
- }
-
- spin_lock_irqsave(&video->spinlock, flags);
-
- /* release the clear frames */
- video->n_clear_frames -= n_recv;
-
- /* advance the clear frame cursor */
- video->first_clear_frame = (video->first_clear_frame + n_recv) % video->n_frames;
-
- /* reset dropped_frames */
- video->dropped_frames = 0;
-
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- ret = 0;
- break;
- }
-
- case DV1394_IOC_START_RECEIVE: {
- if ( !video_card_initialized(video) ) {
- ret = do_dv1394_init_default(video);
- if (ret)
- goto out;
- }
-
- video->continuity_counter = -1;
-
- receive_packets(video);
-
- start_dma_receive(video);
-
- ret = 0;
- break;
- }
-
- case DV1394_IOC_INIT: {
- struct dv1394_init init;
- if (!argp) {
- ret = do_dv1394_init_default(video);
- } else {
- if (copy_from_user(&init, argp, sizeof(init))) {
- ret = -EFAULT;
- goto out;
- }
- ret = do_dv1394_init(video, &init);
- }
- break;
- }
-
- case DV1394_IOC_SHUTDOWN:
- do_dv1394_shutdown(video, 0);
- ret = 0;
- break;
-
-
- case DV1394_IOC_GET_STATUS: {
- struct dv1394_status status;
-
- if ( !video_card_initialized(video) ) {
- ret = -EINVAL;
- goto out;
- }
-
- status.init.api_version = DV1394_API_VERSION;
- status.init.channel = video->channel;
- status.init.n_frames = video->n_frames;
- status.init.format = video->pal_or_ntsc;
- status.init.cip_n = video->cip_n;
- status.init.cip_d = video->cip_d;
- status.init.syt_offset = video->syt_offset;
-
- status.first_clear_frame = video->first_clear_frame;
-
- /* the rest of the fields need to be locked against the interrupt */
- spin_lock_irqsave(&video->spinlock, flags);
-
- status.active_frame = video->active_frame;
- status.n_clear_frames = video->n_clear_frames;
-
- status.dropped_frames = video->dropped_frames;
-
- /* reset dropped_frames */
- video->dropped_frames = 0;
-
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- if (copy_to_user(argp, &status, sizeof(status))) {
- ret = -EFAULT;
- goto out;
- }
-
- ret = 0;
- break;
- }
-
- default:
- break;
- }
-
- out:
- mutex_unlock(&video->mtx);
- return ret;
-}
-
-/*** DEVICE FILE INTERFACE CONTINUED ***************************************/
-
-static int dv1394_open(struct inode *inode, struct file *file)
-{
- struct video_card *video = NULL;
-
- if (file->private_data) {
- video = file->private_data;
-
- } else {
- /* look up the card by ID */
- unsigned long flags;
- int idx = ieee1394_file_to_instance(file);
-
- spin_lock_irqsave(&dv1394_cards_lock, flags);
- if (!list_empty(&dv1394_cards)) {
- struct video_card *p;
- list_for_each_entry(p, &dv1394_cards, list) {
- if ((p->id) == idx) {
- video = p;
- break;
- }
- }
- }
- spin_unlock_irqrestore(&dv1394_cards_lock, flags);
-
- if (!video) {
- debug_printk("dv1394: OHCI card %d not found", idx);
- return -ENODEV;
- }
-
- file->private_data = (void*) video;
- }
-
-#ifndef DV1394_ALLOW_MORE_THAN_ONE_OPEN
-
- if ( test_and_set_bit(0, &video->open) ) {
- /* video is already open by someone else */
- return -EBUSY;
- }
-
-#endif
-
- printk(KERN_INFO "%s: NOTE, the dv1394 interface is unsupported "
- "and will not be available in the new firewire driver stack. "
- "Try libraw1394 based programs instead.\n", current->comm);
-
- return nonseekable_open(inode, file);
-}
-
-
-static int dv1394_release(struct inode *inode, struct file *file)
-{
- struct video_card *video = file_to_video_card(file);
-
- /* OK to free the DMA buffer, no more mappings can exist */
- do_dv1394_shutdown(video, 1);
-
- /* give someone else a turn */
- clear_bit(0, &video->open);
-
- return 0;
-}
-
-
-/*** DEVICE DRIVER HANDLERS ************************************************/
-
-static void it_tasklet_func(unsigned long data)
-{
- int wake = 0;
- struct video_card *video = (struct video_card*) data;
-
- spin_lock(&video->spinlock);
-
- if (!video->dma_running)
- goto out;
-
- irq_printk("ContextControl = %08x, CommandPtr = %08x\n",
- reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
- reg_read(video->ohci, video->ohci_IsoXmitCommandPtr)
- );
-
-
- if ( (video->ohci_it_ctx != -1) &&
- (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) {
-
- struct frame *f;
- unsigned int frame, i;
-
-
- if (video->active_frame == -1)
- frame = 0;
- else
- frame = video->active_frame;
-
- /* check all the DMA-able frames */
- for (i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) {
-
- irq_printk("IRQ checking frame %d...", frame);
- f = video->frames[frame];
- if (f->state != FRAME_READY) {
- irq_printk("clear, skipping\n");
- /* we don't own this frame */
- continue;
- }
-
- irq_printk("DMA\n");
-
- /* check the frame begin semaphore to see if we can free the previous frame */
- if ( *(f->frame_begin_timestamp) ) {
- int prev_frame;
- struct frame *prev_f;
-
-
-
- /* don't reset, need this later *(f->frame_begin_timestamp) = 0; */
- irq_printk(" BEGIN\n");
-
- prev_frame = frame - 1;
- if (prev_frame == -1)
- prev_frame += video->n_frames;
- prev_f = video->frames[prev_frame];
-
- /* make sure we can actually garbage collect
- this frame */
- if ( (prev_f->state == FRAME_READY) &&
- prev_f->done && (!f->done) )
- {
- frame_reset(prev_f);
- video->n_clear_frames++;
- wake = 1;
- video->active_frame = frame;
-
- irq_printk(" BEGIN - freeing previous frame %d, new active frame is %d\n", prev_frame, frame);
- } else {
- irq_printk(" BEGIN - can't free yet\n");
- }
-
- f->done = 1;
- }
-
-
- /* see if we need to set the timestamp for the next frame */
- if ( *(f->mid_frame_timestamp) ) {
- struct frame *next_frame;
- u32 begin_ts, ts_cyc, ts_off;
-
- *(f->mid_frame_timestamp) = 0;
-
- begin_ts = le32_to_cpu(*(f->frame_begin_timestamp));
-
- irq_printk(" MIDDLE - first packet was sent at cycle %4u (%2u), assigned timestamp was (%2u) %4u\n",
- begin_ts & 0x1FFF, begin_ts & 0xF,
- f->assigned_timestamp >> 12, f->assigned_timestamp & 0xFFF);
-
- /* prepare next frame and assign timestamp */
- next_frame = video->frames[ (frame+1) % video->n_frames ];
-
- if (next_frame->state == FRAME_READY) {
- irq_printk(" MIDDLE - next frame is ready, good\n");
- } else {
- debug_printk("dv1394: Underflow! At least one frame has been dropped.\n");
- next_frame = f;
- }
-
- /* set the timestamp to the timestamp of the last frame sent,
- plus the length of the last frame sent, plus the syt latency */
- ts_cyc = begin_ts & 0xF;
- /* advance one frame, plus syt latency (typically 2-3) */
- ts_cyc += f->n_packets + video->syt_offset ;
-
- ts_off = 0;
-
- ts_cyc += ts_off/3072;
- ts_off %= 3072;
-
- next_frame->assigned_timestamp = ((ts_cyc&0xF) << 12) + ts_off;
- if (next_frame->cip_syt1) {
- next_frame->cip_syt1->b[6] = next_frame->assigned_timestamp >> 8;
- next_frame->cip_syt1->b[7] = next_frame->assigned_timestamp & 0xFF;
- }
- if (next_frame->cip_syt2) {
- next_frame->cip_syt2->b[6] = next_frame->assigned_timestamp >> 8;
- next_frame->cip_syt2->b[7] = next_frame->assigned_timestamp & 0xFF;
- }
-
- }
-
- /* see if the frame looped */
- if ( *(f->frame_end_timestamp) ) {
-
- *(f->frame_end_timestamp) = 0;
-
- debug_printk(" END - the frame looped at least once\n");
-
- video->dropped_frames++;
- }
-
- } /* for (each frame) */
- }
-
- if (wake) {
- kill_fasync(&video->fasync, SIGIO, POLL_OUT);
-
- /* wake readers/writers/ioctl'ers */
- wake_up_interruptible(&video->waitq);
- }
-
-out:
- spin_unlock(&video->spinlock);
-}
-
-static void ir_tasklet_func(unsigned long data)
-{
- int wake = 0;
- struct video_card *video = (struct video_card*) data;
-
- spin_lock(&video->spinlock);
-
- if (!video->dma_running)
- goto out;
-
- if ( (video->ohci_ir_ctx != -1) &&
- (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) {
-
- int sof=0; /* start-of-frame flag */
- struct frame *f;
- u16 packet_length;
- int i, dbc=0;
- struct DMA_descriptor_block *block = NULL;
- u16 xferstatus;
-
- int next_i, prev_i;
- struct DMA_descriptor_block *next = NULL;
- dma_addr_t next_dma = 0;
- struct DMA_descriptor_block *prev = NULL;
-
- /* loop over all descriptors in all frames */
- for (i = 0; i < video->n_frames*MAX_PACKETS; i++) {
- struct packet *p = dma_region_i(&video->packet_buf, struct packet, video->current_packet);
-
- /* make sure we are seeing the latest changes to p */
- dma_region_sync_for_cpu(&video->packet_buf,
- (unsigned long) p - (unsigned long) video->packet_buf.kvirt,
- sizeof(struct packet));
-
- packet_length = le16_to_cpu(p->data_length);
-
- /* get the descriptor based on packet_buffer cursor */
- f = video->frames[video->current_packet / MAX_PACKETS];
- block = &(f->descriptor_pool[video->current_packet % MAX_PACKETS]);
- xferstatus = le32_to_cpu(block->u.in.il.q[3]) >> 16;
- xferstatus &= 0x1F;
- irq_printk("ir_tasklet_func: xferStatus/resCount [%d] = 0x%08x\n", i, le32_to_cpu(block->u.in.il.q[3]) );
-
- /* get the current frame */
- f = video->frames[video->active_frame];
-
- /* exclude empty packet */
- if (packet_length > 8 && xferstatus == 0x11) {
- /* check for start of frame */
- /* DRD> Changed to check section type ([0]>>5==0)
- and dif sequence ([1]>>4==0) */
- sof = ( (p->data[0] >> 5) == 0 && (p->data[1] >> 4) == 0);
-
- dbc = (int) (p->cip_h1 >> 24);
- if ( video->continuity_counter != -1 && dbc > ((video->continuity_counter + 1) % 256) )
- {
- printk(KERN_WARNING "dv1394: discontinuity detected, dropping all frames\n" );
- video->dropped_frames += video->n_clear_frames + 1;
- video->first_frame = 0;
- video->n_clear_frames = 0;
- video->first_clear_frame = -1;
- }
- video->continuity_counter = dbc;
-
- if (!video->first_frame) {
- if (sof) {
- video->first_frame = 1;
- }
-
- } else if (sof) {
- /* close current frame */
- frame_reset(f); /* f->state = STATE_CLEAR */
- video->n_clear_frames++;
- if (video->n_clear_frames > video->n_frames) {
- video->dropped_frames++;
- printk(KERN_WARNING "dv1394: dropped a frame during reception\n" );
- video->n_clear_frames = video->n_frames-1;
- video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
- }
- if (video->first_clear_frame == -1)
- video->first_clear_frame = video->active_frame;
-
- /* get the next frame */
- video->active_frame = (video->active_frame + 1) % video->n_frames;
- f = video->frames[video->active_frame];
- irq_printk(" frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n",
- video->active_frame, video->n_clear_frames, video->first_clear_frame);
- }
- if (video->first_frame) {
- if (sof) {
- /* open next frame */
- f->state = FRAME_READY;
- }
-
- /* copy to buffer */
- if (f->n_packets > (video->frame_size / 480)) {
- printk(KERN_ERR "frame buffer overflow during receive\n");
- }
-
- frame_put_packet(f, p);
-
- } /* first_frame */
- }
-
- /* stop, end of ready packets */
- else if (xferstatus == 0) {
- break;
- }
-
- /* reset xferStatus & resCount */
- block->u.in.il.q[3] = cpu_to_le32(512);
-
- /* terminate dma chain at this (next) packet */
- next_i = video->current_packet;
- f = video->frames[next_i / MAX_PACKETS];
- next = &(f->descriptor_pool[next_i % MAX_PACKETS]);
- next_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma;
- next->u.in.il.q[0] |= cpu_to_le32(3 << 20); /* enable interrupt */
- next->u.in.il.q[2] = cpu_to_le32(0); /* disable branch */
-
- /* link previous to next */
- prev_i = (next_i == 0) ? (MAX_PACKETS * video->n_frames - 1) : (next_i - 1);
- f = video->frames[prev_i / MAX_PACKETS];
- prev = &(f->descriptor_pool[prev_i % MAX_PACKETS]);
- if (prev_i % (MAX_PACKETS/2)) {
- prev->u.in.il.q[0] &= ~cpu_to_le32(3 << 20); /* no interrupt */
- } else {
- prev->u.in.il.q[0] |= cpu_to_le32(3 << 20); /* enable interrupt */
- }
- prev->u.in.il.q[2] = cpu_to_le32(next_dma | 1); /* set Z=1 */
- wmb();
-
- /* wake up DMA in case it fell asleep */
- reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12));
-
- /* advance packet_buffer cursor */
- video->current_packet = (video->current_packet + 1) % (MAX_PACKETS * video->n_frames);
-
- } /* for all packets */
-
- wake = 1; /* why the hell not? */
-
- } /* receive interrupt */
-
- if (wake) {
- kill_fasync(&video->fasync, SIGIO, POLL_IN);
-
- /* wake readers/writers/ioctl'ers */
- wake_up_interruptible(&video->waitq);
- }
-
-out:
- spin_unlock(&video->spinlock);
-}
-
-static struct cdev dv1394_cdev;
-static const struct file_operations dv1394_fops=
-{
- .owner = THIS_MODULE,
- .poll = dv1394_poll,
- .unlocked_ioctl = dv1394_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = dv1394_compat_ioctl,
-#endif
- .mmap = dv1394_mmap,
- .open = dv1394_open,
- .write = dv1394_write,
- .read = dv1394_read,
- .release = dv1394_release,
- .fasync = dv1394_fasync,
- .llseek = no_llseek,
-};
-
-
-/*** HOTPLUG STUFF **********************************************************/
-/*
- * Export information about protocols/devices supported by this driver.
- */
-#ifdef MODULE
-static const struct ieee1394_device_id dv1394_id_table[] = {
- {
- .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- { }
-};
-
-MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
-#endif /* MODULE */
-
-static struct hpsb_protocol_driver dv1394_driver = {
- .name = "dv1394",
-};
-
-
-/*** IEEE1394 HPSB CALLBACKS ***********************************************/
-
-static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes mode)
-{
- struct video_card *video;
- unsigned long flags;
- int i;
-
- video = kzalloc(sizeof(*video), GFP_KERNEL);
- if (!video) {
- printk(KERN_ERR "dv1394: cannot allocate video_card\n");
- return -1;
- }
-
- video->ohci = ohci;
- /* lower 2 bits of id indicate which of four "plugs"
- per host */
- video->id = ohci->host->id << 2;
- if (format == DV1394_NTSC)
- video->id |= mode;
- else
- video->id |= 2 + mode;
-
- video->ohci_it_ctx = -1;
- video->ohci_ir_ctx = -1;
-
- video->ohci_IsoXmitContextControlSet = 0;
- video->ohci_IsoXmitContextControlClear = 0;
- video->ohci_IsoXmitCommandPtr = 0;
-
- video->ohci_IsoRcvContextControlSet = 0;
- video->ohci_IsoRcvContextControlClear = 0;
- video->ohci_IsoRcvCommandPtr = 0;
- video->ohci_IsoRcvContextMatch = 0;
-
- video->n_frames = 0; /* flag that video is not initialized */
- video->channel = 63; /* default to broadcast channel */
- video->active_frame = -1;
-
- /* initialize the following */
- video->pal_or_ntsc = format;
- video->cip_n = 0; /* 0 = use builtin default */
- video->cip_d = 0;
- video->syt_offset = 0;
- video->mode = mode;
-
- for (i = 0; i < DV1394_MAX_FRAMES; i++)
- video->frames[i] = NULL;
-
- dma_region_init(&video->dv_buf);
- video->dv_buf_size = 0;
- dma_region_init(&video->packet_buf);
- video->packet_buf_size = 0;
-
- clear_bit(0, &video->open);
- spin_lock_init(&video->spinlock);
- video->dma_running = 0;
- mutex_init(&video->mtx);
- init_waitqueue_head(&video->waitq);
- video->fasync = NULL;
-
- spin_lock_irqsave(&dv1394_cards_lock, flags);
- INIT_LIST_HEAD(&video->list);
- list_add_tail(&video->list, &dv1394_cards);
- spin_unlock_irqrestore(&dv1394_cards_lock, flags);
-
- debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id);
- return 0;
-}
-
-static void dv1394_remove_host(struct hpsb_host *host)
-{
- struct video_card *video, *tmp_video;
- unsigned long flags;
- int found_ohci_card = 0;
-
- do {
- video = NULL;
- spin_lock_irqsave(&dv1394_cards_lock, flags);
- list_for_each_entry(tmp_video, &dv1394_cards, list) {
- if ((tmp_video->id >> 2) == host->id) {
- list_del(&tmp_video->list);
- video = tmp_video;
- found_ohci_card = 1;
- break;
- }
- }
- spin_unlock_irqrestore(&dv1394_cards_lock, flags);
-
- if (video) {
- do_dv1394_shutdown(video, 1);
- kfree(video);
- }
- } while (video);
-
- if (found_ohci_card)
- device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
- IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2)));
-}
-
-static void dv1394_add_host(struct hpsb_host *host)
-{
- struct ti_ohci *ohci;
- int id = host->id;
-
- /* We only work with the OHCI-1394 driver */
- if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
- return;
-
- ohci = (struct ti_ohci *)host->hostdata;
-
- device_create(hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR,
- IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
- NULL, "dv1394-%d", id);
-
- dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
- dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
- dv1394_init(ohci, DV1394_PAL, MODE_RECEIVE);
- dv1394_init(ohci, DV1394_PAL, MODE_TRANSMIT);
-}
-
-
-/* Bus reset handler. In the event of a bus reset, we may need to
- re-start the DMA contexts - otherwise the user program would
- end up waiting forever.
-*/
-
-static void dv1394_host_reset(struct hpsb_host *host)
-{
- struct video_card *video = NULL, *tmp_vid;
- unsigned long flags;
-
- /* We only work with the OHCI-1394 driver */
- if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
- return;
-
- /* find the corresponding video_cards */
- spin_lock_irqsave(&dv1394_cards_lock, flags);
- list_for_each_entry(tmp_vid, &dv1394_cards, list) {
- if ((tmp_vid->id >> 2) == host->id) {
- video = tmp_vid;
- break;
- }
- }
- spin_unlock_irqrestore(&dv1394_cards_lock, flags);
-
- if (!video)
- return;
-
-
- spin_lock_irqsave(&video->spinlock, flags);
-
- if (!video->dma_running)
- goto out;
-
- /* check IT context */
- if (video->ohci_it_ctx != -1) {
- u32 ctx;
-
- ctx = reg_read(video->ohci, video->ohci_IsoXmitContextControlSet);
-
- /* if (RUN but not ACTIVE) */
- if ( (ctx & (1<<15)) &&
- !(ctx & (1<<10)) ) {
-
- debug_printk("dv1394: IT context stopped due to bus reset; waking it up\n");
-
- /* to be safe, assume a frame has been dropped. User-space programs
- should handle this condition like an underflow. */
- video->dropped_frames++;
-
- /* for some reason you must clear, then re-set the RUN bit to restart DMA */
-
- /* clear RUN */
- reg_write(video->ohci, video->ohci_IsoXmitContextControlClear, (1 << 15));
- flush_pci_write(video->ohci);
-
- /* set RUN */
- reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, (1 << 15));
- flush_pci_write(video->ohci);
-
- /* set the WAKE bit (just in case; this isn't strictly necessary) */
- reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, (1 << 12));
- flush_pci_write(video->ohci);
-
- irq_printk("dv1394: AFTER IT restart ctx 0x%08x ptr 0x%08x\n",
- reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
- reg_read(video->ohci, video->ohci_IsoXmitCommandPtr));
- }
- }
-
- /* check IR context */
- if (video->ohci_ir_ctx != -1) {
- u32 ctx;
-
- ctx = reg_read(video->ohci, video->ohci_IsoRcvContextControlSet);
-
- /* if (RUN but not ACTIVE) */
- if ( (ctx & (1<<15)) &&
- !(ctx & (1<<10)) ) {
-
- debug_printk("dv1394: IR context stopped due to bus reset; waking it up\n");
-
- /* to be safe, assume a frame has been dropped. User-space programs
- should handle this condition like an overflow. */
- video->dropped_frames++;
-
- /* for some reason you must clear, then re-set the RUN bit to restart DMA */
- /* XXX this doesn't work for me, I can't get IR DMA to restart :[ */
-
- /* clear RUN */
- reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, (1 << 15));
- flush_pci_write(video->ohci);
-
- /* set RUN */
- reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 15));
- flush_pci_write(video->ohci);
-
- /* set the WAKE bit (just in case; this isn't strictly necessary) */
- reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12));
- flush_pci_write(video->ohci);
-
- irq_printk("dv1394: AFTER IR restart ctx 0x%08x ptr 0x%08x\n",
- reg_read(video->ohci, video->ohci_IsoRcvContextControlSet),
- reg_read(video->ohci, video->ohci_IsoRcvCommandPtr));
- }
- }
-
-out:
- spin_unlock_irqrestore(&video->spinlock, flags);
-
- /* wake readers/writers/ioctl'ers */
- wake_up_interruptible(&video->waitq);
-}
-
-static struct hpsb_highlevel dv1394_highlevel = {
- .name = "dv1394",
- .add_host = dv1394_add_host,
- .remove_host = dv1394_remove_host,
- .host_reset = dv1394_host_reset,
-};
-
-#ifdef CONFIG_COMPAT
-
-#define DV1394_IOC32_INIT _IOW('#', 0x06, struct dv1394_init32)
-#define DV1394_IOC32_GET_STATUS _IOR('#', 0x0c, struct dv1394_status32)
-
-struct dv1394_init32 {
- u32 api_version;
- u32 channel;
- u32 n_frames;
- u32 format;
- u32 cip_n;
- u32 cip_d;
- u32 syt_offset;
-};
-
-struct dv1394_status32 {
- struct dv1394_init32 init;
- s32 active_frame;
- u32 first_clear_frame;
- u32 n_clear_frames;
- u32 dropped_frames;
-};
-
-/* RED-PEN: this should use compat_alloc_userspace instead */
-
-static int handle_dv1394_init(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct dv1394_init32 dv32;
- struct dv1394_init dv;
- mm_segment_t old_fs;
- int ret;
-
- if (file->f_op->unlocked_ioctl != dv1394_ioctl)
- return -EFAULT;
-
- if (copy_from_user(&dv32, (void __user *)arg, sizeof(dv32)))
- return -EFAULT;
-
- dv.api_version = dv32.api_version;
- dv.channel = dv32.channel;
- dv.n_frames = dv32.n_frames;
- dv.format = dv32.format;
- dv.cip_n = (unsigned long)dv32.cip_n;
- dv.cip_d = (unsigned long)dv32.cip_d;
- dv.syt_offset = dv32.syt_offset;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = dv1394_ioctl(file, DV1394_IOC_INIT, (unsigned long)&dv);
- set_fs(old_fs);
-
- return ret;
-}
-
-static int handle_dv1394_get_status(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct dv1394_status32 dv32;
- struct dv1394_status dv;
- mm_segment_t old_fs;
- int ret;
-
- if (file->f_op->unlocked_ioctl != dv1394_ioctl)
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = dv1394_ioctl(file, DV1394_IOC_GET_STATUS, (unsigned long)&dv);
- set_fs(old_fs);
-
- if (!ret) {
- dv32.init.api_version = dv.init.api_version;
- dv32.init.channel = dv.init.channel;
- dv32.init.n_frames = dv.init.n_frames;
- dv32.init.format = dv.init.format;
- dv32.init.cip_n = (u32)dv.init.cip_n;
- dv32.init.cip_d = (u32)dv.init.cip_d;
- dv32.init.syt_offset = dv.init.syt_offset;
- dv32.active_frame = dv.active_frame;
- dv32.first_clear_frame = dv.first_clear_frame;
- dv32.n_clear_frames = dv.n_clear_frames;
- dv32.dropped_frames = dv.dropped_frames;
-
- if (copy_to_user((struct dv1394_status32 __user *)arg, &dv32, sizeof(dv32)))
- ret = -EFAULT;
- }
-
- return ret;
-}
-
-
-
-static long dv1394_compat_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- switch (cmd) {
- case DV1394_IOC_SHUTDOWN:
- case DV1394_IOC_SUBMIT_FRAMES:
- case DV1394_IOC_WAIT_FRAMES:
- case DV1394_IOC_RECEIVE_FRAMES:
- case DV1394_IOC_START_RECEIVE:
- return dv1394_ioctl(file, cmd, arg);
-
- case DV1394_IOC32_INIT:
- return handle_dv1394_init(file, cmd, arg);
- case DV1394_IOC32_GET_STATUS:
- return handle_dv1394_get_status(file, cmd, arg);
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-#endif /* CONFIG_COMPAT */
-
-
-/*** KERNEL MODULE HANDLERS ************************************************/
-
-MODULE_AUTHOR("Dan Maas <dmaas@dcine.com>, Dan Dennedy <dan@dennedy.org>");
-MODULE_DESCRIPTION("driver for DV input/output on OHCI board");
-MODULE_SUPPORTED_DEVICE("dv1394");
-MODULE_LICENSE("GPL");
-
-static void __exit dv1394_exit_module(void)
-{
- hpsb_unregister_protocol(&dv1394_driver);
- hpsb_unregister_highlevel(&dv1394_highlevel);
- cdev_del(&dv1394_cdev);
-}
-
-static int __init dv1394_init_module(void)
-{
- int ret;
-
- cdev_init(&dv1394_cdev, &dv1394_fops);
- dv1394_cdev.owner = THIS_MODULE;
- ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16);
- if (ret) {
- printk(KERN_ERR "dv1394: unable to register character device\n");
- return ret;
- }
-
- hpsb_register_highlevel(&dv1394_highlevel);
-
- ret = hpsb_register_protocol(&dv1394_driver);
- if (ret) {
- printk(KERN_ERR "dv1394: failed to register protocol\n");
- hpsb_unregister_highlevel(&dv1394_highlevel);
- cdev_del(&dv1394_cdev);
- return ret;
- }
-
- return 0;
-}
-
-module_init(dv1394_init_module);
-module_exit(dv1394_exit_module);
diff --git a/drivers/ieee1394/dv1394.h b/drivers/ieee1394/dv1394.h
deleted file mode 100644
index 5807f528981..00000000000
--- a/drivers/ieee1394/dv1394.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * dv1394.h - DV input/output over IEEE 1394 on OHCI chips
- * Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
- * receive by Dan Dennedy <dan@dennedy.org>
- *
- * based on:
- * video1394.h - driver for OHCI 1394 boards
- * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
- * Peter Schlaile <udbz@rz.uni-karlsruhe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef _DV_1394_H
-#define _DV_1394_H
-
-/* This is the public user-space interface. Try not to break it. */
-
-#define DV1394_API_VERSION 0x20011127
-
-/* ********************
- ** **
- ** DV1394 API **
- ** **
- ********************
-
- There are two methods of operating the DV1394 DV output device.
-
- 1)
-
- The simplest is an interface based on write(): simply write
- full DV frames of data to the device, and they will be transmitted
- as quickly as possible. The FD may be set for non-blocking I/O,
- in which case you can use select() or poll() to wait for output
- buffer space.
-
- To set the DV output parameters (e.g. whether you want NTSC or PAL
- video), use the DV1394_INIT ioctl, passing in the parameters you
- want in a struct dv1394_init.
-
- Example 1:
- To play a raw .DV file: cat foo.DV > /dev/dv1394
- (cat will use write() internally)
-
- Example 2:
- static struct dv1394_init init = {
- 0x63, (broadcast channel)
- 4, (four-frame ringbuffer)
- DV1394_NTSC, (send NTSC video)
- 0, 0 (default empty packet rate)
- }
-
- ioctl(fd, DV1394_INIT, &init);
-
- while (1) {
- read( <a raw DV file>, buf, DV1394_NTSC_FRAME_SIZE );
- write( <the dv1394 FD>, buf, DV1394_NTSC_FRAME_SIZE );
- }
-
- 2)
-
- For more control over buffering, and to avoid unnecessary copies
- of the DV data, you can use the more sophisticated the mmap() interface.
- First, call the DV1394_INIT ioctl to specify your parameters,
- including the number of frames in the ringbuffer. Then, calling mmap()
- on the dv1394 device will give you direct access to the ringbuffer
- from which the DV card reads your frame data.
-
- The ringbuffer is simply one large, contiguous region of memory
- containing two or more frames of packed DV data. Each frame of DV data
- is 120000 bytes (NTSC) or 144000 bytes (PAL).
-
- Fill one or more frames in the ringbuffer, then use the DV1394_SUBMIT_FRAMES
- ioctl to begin I/O. You can use either the DV1394_WAIT_FRAMES ioctl
- or select()/poll() to wait until the frames are transmitted. Next, you'll
- need to call the DV1394_GET_STATUS ioctl to determine which ringbuffer
- frames are clear (ready to be filled with new DV data). Finally, use
- DV1394_SUBMIT_FRAMES again to send the new data to the DV output.
-
-
- Example: here is what a four-frame ringbuffer might look like
- during DV transmission:
-
-
- frame 0 frame 1 frame 2 frame 3
-
- *--------------------------------------*
- | CLEAR | DV data | DV data | CLEAR |
- *--------------------------------------*
- <ACTIVE>
-
- transmission goes in this direction --->>>
-
-
- The DV hardware is currently transmitting the data in frame 1.
- Once frame 1 is finished, it will automatically transmit frame 2.
- (if frame 2 finishes before frame 3 is submitted, the device
- will continue to transmit frame 2, and will increase the dropped_frames
- counter each time it repeats the transmission).
-
-
- If you called DV1394_GET_STATUS at this instant, you would
- receive the following values:
-
- n_frames = 4
- active_frame = 1
- first_clear_frame = 3
- n_clear_frames = 2
-
- At this point, you should write new DV data into frame 3 and optionally
- frame 0. Then call DV1394_SUBMIT_FRAMES to inform the device that
- it may transmit the new frames.
-
- ERROR HANDLING
-
- An error (buffer underflow/overflow or a break in the DV stream due
- to a 1394 bus reset) can be detected by checking the dropped_frames
- field of struct dv1394_status (obtained through the
- DV1394_GET_STATUS ioctl).
-
- The best way to recover from such an error is to re-initialize
- dv1394, either by using the DV1394_INIT ioctl call, or closing the
- file descriptor and opening it again. (note that you must unmap all
- ringbuffer mappings when closing the file descriptor, or else
- dv1394 will still be considered 'in use').
-
- MAIN LOOP
-
- For maximum efficiency and robustness against bus errors, you are
- advised to model the main loop of your application after the
- following pseudo-code example:
-
- (checks of system call return values omitted for brevity; always
- check return values in your code!)
-
- while ( frames left ) {
-
- struct pollfd *pfd = ...;
-
- pfd->fd = dv1394_fd;
- pfd->revents = 0;
- pfd->events = POLLOUT | POLLIN; (OUT for transmit, IN for receive)
-
- (add other sources of I/O here)
-
- poll(pfd, 1, -1); (or select(); add a timeout if you want)
-
- if (pfd->revents) {
- struct dv1394_status status;
-
- ioctl(dv1394_fd, DV1394_GET_STATUS, &status);
-
- if (status.dropped_frames > 0) {
- reset_dv1394();
- } else {
- for (int i = 0; i < status.n_clear_frames; i++) {
- copy_DV_frame();
- }
- }
- }
- }
-
- where copy_DV_frame() reads or writes on the dv1394 file descriptor
- (read/write mode) or copies data to/from the mmap ringbuffer and
- then calls ioctl(DV1394_SUBMIT_FRAMES) to notify dv1394 that new
- frames are availble (mmap mode).
-
- reset_dv1394() is called in the event of a buffer
- underflow/overflow or a halt in the DV stream (e.g. due to a 1394
- bus reset). To guarantee recovery from the error, this function
- should close the dv1394 file descriptor (and munmap() all
- ringbuffer mappings, if you are using them), then re-open the
- dv1394 device (and re-map the ringbuffer).
-
-*/
-
-
-/* maximum number of frames in the ringbuffer */
-#define DV1394_MAX_FRAMES 32
-
-/* number of *full* isochronous packets per DV frame */
-#define DV1394_NTSC_PACKETS_PER_FRAME 250
-#define DV1394_PAL_PACKETS_PER_FRAME 300
-
-/* size of one frame's worth of DV data, in bytes */
-#define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME)
-#define DV1394_PAL_FRAME_SIZE (480 * DV1394_PAL_PACKETS_PER_FRAME)
-
-
-/* ioctl() commands */
-#include "ieee1394-ioctl.h"
-
-
-enum pal_or_ntsc {
- DV1394_NTSC = 0,
- DV1394_PAL
-};
-
-
-
-
-/* this is the argument to DV1394_INIT */
-struct dv1394_init {
- /* DV1394_API_VERSION */
- unsigned int api_version;
-
- /* isochronous transmission channel to use */
- unsigned int channel;
-
- /* number of frames in the ringbuffer. Must be at least 2
- and at most DV1394_MAX_FRAMES. */
- unsigned int n_frames;
-
- /* send/receive PAL or NTSC video format */
- enum pal_or_ntsc format;
-
- /* the following are used only for transmission */
-
- /* set these to zero unless you want a
- non-default empty packet rate (see below) */
- unsigned long cip_n;
- unsigned long cip_d;
-
- /* set this to zero unless you want a
- non-default SYT cycle offset (default = 3 cycles) */
- unsigned int syt_offset;
-};
-
-/* NOTE: you may only allocate the DV frame ringbuffer once each time
- you open the dv1394 device. DV1394_INIT will fail if you call it a
- second time with different 'n_frames' or 'format' arguments (which
- would imply a different size for the ringbuffer). If you need a
- different buffer size, simply close and re-open the device, then
- initialize it with your new settings. */
-
-/* Q: What are cip_n and cip_d? */
-
-/*
- A: DV video streams do not utilize 100% of the potential bandwidth offered
- by IEEE 1394 (FireWire). To achieve the correct rate of data transmission,
- DV devices must periodically insert empty packets into the 1394 data stream.
- Typically there is one empty packet per 14-16 data-carrying packets.
-
- Some DV devices will accept a wide range of empty packet rates, while others
- require a precise rate. If the dv1394 driver produces empty packets at
- a rate that your device does not accept, you may see ugly patterns on the
- DV output, or even no output at all.
-
- The default empty packet insertion rate seems to work for many people; if
- your DV output is stable, you can simply ignore this discussion. However,
- we have exposed the empty packet rate as a parameter to support devices that
- do not work with the default rate.
-
- The decision to insert an empty packet is made with a numerator/denominator
- algorithm. Empty packets are produced at an average rate of CIP_N / CIP_D.
- You can alter the empty packet rate by passing non-zero values for cip_n
- and cip_d to the INIT ioctl.
-
- */
-
-
-
-struct dv1394_status {
- /* this embedded init struct returns the current dv1394
- parameters in use */
- struct dv1394_init init;
-
- /* the ringbuffer frame that is currently being
- displayed. (-1 if the device is not transmitting anything) */
- int active_frame;
-
- /* index of the first buffer (ahead of active_frame) that
- is ready to be filled with data */
- unsigned int first_clear_frame;
-
- /* how many buffers, including first_clear_buffer, are
- ready to be filled with data */
- unsigned int n_clear_frames;
-
- /* how many times the DV stream has underflowed, overflowed,
- or otherwise encountered an error, since the previous call
- to DV1394_GET_STATUS */
- unsigned int dropped_frames;
-
- /* N.B. The dropped_frames counter is only a lower bound on the actual
- number of dropped frames, with the special case that if dropped_frames
- is zero, then it is guaranteed that NO frames have been dropped
- since the last call to DV1394_GET_STATUS.
- */
-};
-
-
-#endif /* _DV_1394_H */
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
deleted file mode 100644
index 63403822330..00000000000
--- a/drivers/ieee1394/eth1394.c
+++ /dev/null
@@ -1,1720 +0,0 @@
-/*
- * eth1394.c -- IPv4 driver for Linux IEEE-1394 Subsystem
- *
- * Copyright (C) 2001-2003 Ben Collins <bcollins@debian.org>
- * 2000 Bonin Franck <boninf@free.fr>
- * 2003 Steve Kinneberg <kinnebergsteve@acmsystems.com>
- *
- * Mainly based on work by Emanuel Pirker and Andreas E. Bombe
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- * This driver intends to support RFC 2734, which describes a method for
- * transporting IPv4 datagrams over IEEE-1394 serial busses.
- *
- * TODO:
- * RFC 2734 related:
- * - Add MCAP. Limited Multicast exists only to 224.0.0.1 and 224.0.0.2.
- *
- * Non-RFC 2734 related:
- * - Handle fragmented skb's coming from the networking layer.
- * - Move generic GASP reception to core 1394 code
- * - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead
- * - Stability improvements
- * - Performance enhancements
- * - Consider garbage collecting old partial datagrams after X amount of time
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/workqueue.h>
-
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/if_arp.h>
-#include <linux/if_ether.h>
-#include <linux/ip.h>
-#include <linux/in.h>
-#include <linux/tcp.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-#include <asm/uaccess.h>
-#include <asm/delay.h>
-#include <asm/unaligned.h>
-#include <net/arp.h>
-
-#include "config_roms.h"
-#include "csr1212.h"
-#include "eth1394.h"
-#include "highlevel.h"
-#include "ieee1394.h"
-#include "ieee1394_core.h"
-#include "ieee1394_hotplug.h"
-#include "ieee1394_transactions.h"
-#include "ieee1394_types.h"
-#include "iso.h"
-#include "nodemgr.h"
-
-#define ETH1394_PRINT_G(level, fmt, args...) \
- printk(level "%s: " fmt, driver_name, ## args)
-
-#define ETH1394_PRINT(level, dev_name, fmt, args...) \
- printk(level "%s: %s: " fmt, driver_name, dev_name, ## args)
-
-struct fragment_info {
- struct list_head list;
- int offset;
- int len;
-};
-
-struct partial_datagram {
- struct list_head list;
- u16 dgl;
- u16 dg_size;
- __be16 ether_type;
- struct sk_buff *skb;
- char *pbuf;
- struct list_head frag_info;
-};
-
-struct pdg_list {
- struct list_head list; /* partial datagram list per node */
- unsigned int sz; /* partial datagram list size per node */
- spinlock_t lock; /* partial datagram lock */
-};
-
-struct eth1394_host_info {
- struct hpsb_host *host;
- struct net_device *dev;
-};
-
-struct eth1394_node_ref {
- struct unit_directory *ud;
- struct list_head list;
-};
-
-struct eth1394_node_info {
- u16 maxpayload; /* max payload */
- u8 sspd; /* max speed */
- u64 fifo; /* FIFO address */
- struct pdg_list pdg; /* partial RX datagram lists */
- int dgl; /* outgoing datagram label */
-};
-
-static const char driver_name[] = "eth1394";
-
-static struct kmem_cache *packet_task_cache;
-
-static struct hpsb_highlevel eth1394_highlevel;
-
-/* Use common.lf to determine header len */
-static const int hdr_type_len[] = {
- sizeof(struct eth1394_uf_hdr),
- sizeof(struct eth1394_ff_hdr),
- sizeof(struct eth1394_sf_hdr),
- sizeof(struct eth1394_sf_hdr)
-};
-
-static const u16 eth1394_speedto_maxpayload[] = {
-/* S100, S200, S400, S800, S1600, S3200 */
- 512, 1024, 2048, 4096, 4096, 4096
-};
-
-MODULE_AUTHOR("Ben Collins (bcollins@debian.org)");
-MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)");
-MODULE_LICENSE("GPL");
-
-/*
- * The max_partial_datagrams parameter is the maximum number of fragmented
- * datagrams per node that eth1394 will keep in memory. Providing an upper
- * bound allows us to limit the amount of memory that partial datagrams
- * consume in the event that some partial datagrams are never completed.
- */
-static int max_partial_datagrams = 25;
-module_param(max_partial_datagrams, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(max_partial_datagrams,
- "Maximum number of partially received fragmented datagrams "
- "(default = 25).");
-
-
-static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, const void *daddr,
- const void *saddr, unsigned len);
-static int ether1394_rebuild_header(struct sk_buff *skb);
-static int ether1394_header_parse(const struct sk_buff *skb,
- unsigned char *haddr);
-static int ether1394_header_cache(const struct neighbour *neigh,
- struct hh_cache *hh);
-static void ether1394_header_cache_update(struct hh_cache *hh,
- const struct net_device *dev,
- const unsigned char *haddr);
-static netdev_tx_t ether1394_tx(struct sk_buff *skb,
- struct net_device *dev);
-static void ether1394_iso(struct hpsb_iso *iso);
-
-static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
- quadlet_t *data, u64 addr, size_t len, u16 flags);
-static void ether1394_add_host(struct hpsb_host *host);
-static void ether1394_remove_host(struct hpsb_host *host);
-static void ether1394_host_reset(struct hpsb_host *host);
-
-/* Function for incoming 1394 packets */
-static const struct hpsb_address_ops addr_ops = {
- .write = ether1394_write,
-};
-
-/* Ieee1394 highlevel driver functions */
-static struct hpsb_highlevel eth1394_highlevel = {
- .name = driver_name,
- .add_host = ether1394_add_host,
- .remove_host = ether1394_remove_host,
- .host_reset = ether1394_host_reset,
-};
-
-static int ether1394_recv_init(struct eth1394_priv *priv)
-{
- unsigned int iso_buf_size;
-
- /* FIXME: rawiso limits us to PAGE_SIZE */
- iso_buf_size = min((unsigned int)PAGE_SIZE,
- 2 * (1U << (priv->host->csr.max_rec + 1)));
-
- priv->iso = hpsb_iso_recv_init(priv->host,
- ETHER1394_GASP_BUFFERS * iso_buf_size,
- ETHER1394_GASP_BUFFERS,
- priv->broadcast_channel,
- HPSB_ISO_DMA_PACKET_PER_BUFFER,
- 1, ether1394_iso);
- if (priv->iso == NULL) {
- ETH1394_PRINT_G(KERN_ERR, "Failed to allocate IR context\n");
- priv->bc_state = ETHER1394_BC_ERROR;
- return -EAGAIN;
- }
-
- if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0)
- priv->bc_state = ETHER1394_BC_STOPPED;
- else
- priv->bc_state = ETHER1394_BC_RUNNING;
- return 0;
-}
-
-/* This is called after an "ifup" */
-static int ether1394_open(struct net_device *dev)
-{
- struct eth1394_priv *priv = netdev_priv(dev);
- int ret;
-
- if (priv->bc_state == ETHER1394_BC_ERROR) {
- ret = ether1394_recv_init(priv);
- if (ret)
- return ret;
- }
- netif_start_queue(dev);
- return 0;
-}
-
-/* This is called after an "ifdown" */
-static int ether1394_stop(struct net_device *dev)
-{
- /* flush priv->wake */
- flush_scheduled_work();
-
- netif_stop_queue(dev);
- return 0;
-}
-
-/* FIXME: What to do if we timeout? I think a host reset is probably in order,
- * so that's what we do. Should we increment the stat counters too? */
-static void ether1394_tx_timeout(struct net_device *dev)
-{
- struct hpsb_host *host =
- ((struct eth1394_priv *)netdev_priv(dev))->host;
-
- ETH1394_PRINT(KERN_ERR, dev->name, "Timeout, resetting host\n");
- ether1394_host_reset(host);
-}
-
-static inline int ether1394_max_mtu(struct hpsb_host* host)
-{
- return (1 << (host->csr.max_rec + 1))
- - sizeof(union eth1394_hdr) - ETHER1394_GASP_OVERHEAD;
-}
-
-static int ether1394_change_mtu(struct net_device *dev, int new_mtu)
-{
- int max_mtu;
-
- if (new_mtu < 68)
- return -EINVAL;
-
- max_mtu = ether1394_max_mtu(
- ((struct eth1394_priv *)netdev_priv(dev))->host);
- if (new_mtu > max_mtu) {
- ETH1394_PRINT(KERN_INFO, dev->name,
- "Local node constrains MTU to %d\n", max_mtu);
- return -ERANGE;
- }
-
- dev->mtu = new_mtu;
- return 0;
-}
-
-static void purge_partial_datagram(struct list_head *old)
-{
- struct partial_datagram *pd;
- struct list_head *lh, *n;
- struct fragment_info *fi;
-
- pd = list_entry(old, struct partial_datagram, list);
-
- list_for_each_safe(lh, n, &pd->frag_info) {
- fi = list_entry(lh, struct fragment_info, list);
- list_del(lh);
- kfree(fi);
- }
- list_del(old);
- kfree_skb(pd->skb);
- kfree(pd);
-}
-
-/******************************************
- * 1394 bus activity functions
- ******************************************/
-
-static struct eth1394_node_ref *eth1394_find_node(struct list_head *inl,
- struct unit_directory *ud)
-{
- struct eth1394_node_ref *node;
-
- list_for_each_entry(node, inl, list)
- if (node->ud == ud)
- return node;
-
- return NULL;
-}
-
-static struct eth1394_node_ref *eth1394_find_node_guid(struct list_head *inl,
- u64 guid)
-{
- struct eth1394_node_ref *node;
-
- list_for_each_entry(node, inl, list)
- if (node->ud->ne->guid == guid)
- return node;
-
- return NULL;
-}
-
-static struct eth1394_node_ref *eth1394_find_node_nodeid(struct list_head *inl,
- nodeid_t nodeid)
-{
- struct eth1394_node_ref *node;
-
- list_for_each_entry(node, inl, list)
- if (node->ud->ne->nodeid == nodeid)
- return node;
-
- return NULL;
-}
-
-static int eth1394_new_node(struct eth1394_host_info *hi,
- struct unit_directory *ud)
-{
- struct eth1394_priv *priv;
- struct eth1394_node_ref *new_node;
- struct eth1394_node_info *node_info;
-
- new_node = kmalloc(sizeof(*new_node), GFP_KERNEL);
- if (!new_node)
- return -ENOMEM;
-
- node_info = kmalloc(sizeof(*node_info), GFP_KERNEL);
- if (!node_info) {
- kfree(new_node);
- return -ENOMEM;
- }
-
- spin_lock_init(&node_info->pdg.lock);
- INIT_LIST_HEAD(&node_info->pdg.list);
- node_info->pdg.sz = 0;
- node_info->fifo = CSR1212_INVALID_ADDR_SPACE;
-
- dev_set_drvdata(&ud->device, node_info);
- new_node->ud = ud;
-
- priv = netdev_priv(hi->dev);
- list_add_tail(&new_node->list, &priv->ip_node_list);
- return 0;
-}
-
-static int eth1394_probe(struct device *dev)
-{
- struct unit_directory *ud;
- struct eth1394_host_info *hi;
-
- ud = container_of(dev, struct unit_directory, device);
- hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host);
- if (!hi)
- return -ENOENT;
-
- return eth1394_new_node(hi, ud);
-}
-
-static int eth1394_remove(struct device *dev)
-{
- struct unit_directory *ud;
- struct eth1394_host_info *hi;
- struct eth1394_priv *priv;
- struct eth1394_node_ref *old_node;
- struct eth1394_node_info *node_info;
- struct list_head *lh, *n;
- unsigned long flags;
-
- ud = container_of(dev, struct unit_directory, device);
- hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host);
- if (!hi)
- return -ENOENT;
-
- priv = netdev_priv(hi->dev);
-
- old_node = eth1394_find_node(&priv->ip_node_list, ud);
- if (!old_node)
- return 0;
-
- list_del(&old_node->list);
- kfree(old_node);
-
- node_info = dev_get_drvdata(&ud->device);
-
- spin_lock_irqsave(&node_info->pdg.lock, flags);
- /* The partial datagram list should be empty, but we'll just
- * make sure anyway... */
- list_for_each_safe(lh, n, &node_info->pdg.list)
- purge_partial_datagram(lh);
- spin_unlock_irqrestore(&node_info->pdg.lock, flags);
-
- kfree(node_info);
- dev_set_drvdata(&ud->device, NULL);
- return 0;
-}
-
-static int eth1394_update(struct unit_directory *ud)
-{
- struct eth1394_host_info *hi;
- struct eth1394_priv *priv;
- struct eth1394_node_ref *node;
-
- hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host);
- if (!hi)
- return -ENOENT;
-
- priv = netdev_priv(hi->dev);
- node = eth1394_find_node(&priv->ip_node_list, ud);
- if (node)
- return 0;
-
- return eth1394_new_node(hi, ud);
-}
-
-static const struct ieee1394_device_id eth1394_id_table[] = {
- {
- .match_flags = (IEEE1394_MATCH_SPECIFIER_ID |
- IEEE1394_MATCH_VERSION),
- .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
- .version = ETHER1394_GASP_VERSION,
- },
- {}
-};
-
-MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
-
-static struct hpsb_protocol_driver eth1394_proto_driver = {
- .name = driver_name,
- .id_table = eth1394_id_table,
- .update = eth1394_update,
- .driver = {
- .probe = eth1394_probe,
- .remove = eth1394_remove,
- },
-};
-
-static void ether1394_reset_priv(struct net_device *dev, int set_mtu)
-{
- unsigned long flags;
- int i;
- struct eth1394_priv *priv = netdev_priv(dev);
- struct hpsb_host *host = priv->host;
- u64 guid = get_unaligned((u64 *)&(host->csr.rom->bus_info_data[3]));
- int max_speed = IEEE1394_SPEED_MAX;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- memset(priv->ud_list, 0, sizeof(priv->ud_list));
- priv->bc_maxpayload = 512;
-
- /* Determine speed limit */
- /* FIXME: This is broken for nodes with link speed < PHY speed,
- * and it is suboptimal for S200B...S800B hardware.
- * The result of nodemgr's speed probe should be used somehow. */
- for (i = 0; i < host->node_count; i++) {
- /* take care of S100B...S400B PHY ports */
- if (host->speed[i] == SELFID_SPEED_UNKNOWN) {
- max_speed = IEEE1394_SPEED_100;
- break;
- }
- if (max_speed > host->speed[i])
- max_speed = host->speed[i];
- }
- priv->bc_sspd = max_speed;
-
- if (set_mtu) {
- /* Use the RFC 2734 default 1500 octets or the maximum payload
- * as initial MTU */
- dev->mtu = min(1500, ether1394_max_mtu(host));
-
- /* Set our hardware address while we're at it */
- memcpy(dev->dev_addr, &guid, sizeof(u64));
- memset(dev->broadcast, 0xff, sizeof(u64));
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static const struct header_ops ether1394_header_ops = {
- .create = ether1394_header,
- .rebuild = ether1394_rebuild_header,
- .cache = ether1394_header_cache,
- .cache_update = ether1394_header_cache_update,
- .parse = ether1394_header_parse,
-};
-
-static const struct net_device_ops ether1394_netdev_ops = {
- .ndo_open = ether1394_open,
- .ndo_stop = ether1394_stop,
- .ndo_start_xmit = ether1394_tx,
- .ndo_tx_timeout = ether1394_tx_timeout,
- .ndo_change_mtu = ether1394_change_mtu,
-};
-
-static void ether1394_init_dev(struct net_device *dev)
-{
-
- dev->header_ops = &ether1394_header_ops;
- dev->netdev_ops = &ether1394_netdev_ops;
-
- dev->watchdog_timeo = ETHER1394_TIMEOUT;
- dev->flags = IFF_BROADCAST | IFF_MULTICAST;
- dev->features = NETIF_F_HIGHDMA;
- dev->addr_len = ETH1394_ALEN;
- dev->hard_header_len = ETH1394_HLEN;
- dev->type = ARPHRD_IEEE1394;
-
- /* FIXME: This value was copied from ether_setup(). Is it too much? */
- dev->tx_queue_len = 1000;
-}
-
-/*
- * Wake the queue up after commonly encountered transmit failure conditions are
- * hopefully over. Currently only tlabel exhaustion is accounted for.
- */
-static void ether1394_wake_queue(struct work_struct *work)
-{
- struct eth1394_priv *priv;
- struct hpsb_packet *packet;
-
- priv = container_of(work, struct eth1394_priv, wake);
- packet = hpsb_alloc_packet(0);
-
- /* This is really bad, but unjam the queue anyway. */
- if (!packet)
- goto out;
-
- packet->host = priv->host;
- packet->node_id = priv->wake_node;
- /*
- * A transaction label is all we really want. If we get one, it almost
- * always means we can get a lot more because the ieee1394 core recycled
- * a whole batch of tlabels, at last.
- */
- if (hpsb_get_tlabel(packet) == 0)
- hpsb_free_tlabel(packet);
-
- hpsb_free_packet(packet);
-out:
- netif_wake_queue(priv->wake_dev);
-}
-
-/*
- * This function is called every time a card is found. It is generally called
- * when the module is installed. This is where we add all of our ethernet
- * devices. One for each host.
- */
-static void ether1394_add_host(struct hpsb_host *host)
-{
- struct eth1394_host_info *hi = NULL;
- struct net_device *dev = NULL;
- struct eth1394_priv *priv;
- u64 fifo_addr;
-
- if (hpsb_config_rom_ip1394_add(host) != 0) {
- ETH1394_PRINT_G(KERN_ERR, "Can't add IP-over-1394 ROM entry\n");
- return;
- }
-
- fifo_addr = hpsb_allocate_and_register_addrspace(
- &eth1394_highlevel, host, &addr_ops,
- ETHER1394_REGION_ADDR_LEN, ETHER1394_REGION_ADDR_LEN,
- CSR1212_INVALID_ADDR_SPACE, CSR1212_INVALID_ADDR_SPACE);
- if (fifo_addr == CSR1212_INVALID_ADDR_SPACE) {
- ETH1394_PRINT_G(KERN_ERR, "Cannot register CSR space\n");
- hpsb_config_rom_ip1394_remove(host);
- return;
- }
-
- dev = alloc_netdev(sizeof(*priv), "eth%d", ether1394_init_dev);
- if (dev == NULL) {
- ETH1394_PRINT_G(KERN_ERR, "Out of memory\n");
- goto out;
- }
-
- SET_NETDEV_DEV(dev, &host->device);
-
- priv = netdev_priv(dev);
- INIT_LIST_HEAD(&priv->ip_node_list);
- spin_lock_init(&priv->lock);
- priv->host = host;
- priv->local_fifo = fifo_addr;
- INIT_WORK(&priv->wake, ether1394_wake_queue);
- priv->wake_dev = dev;
-
- hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
- if (hi == NULL) {
- ETH1394_PRINT_G(KERN_ERR, "Out of memory\n");
- goto out;
- }
-
- ether1394_reset_priv(dev, 1);
-
- if (register_netdev(dev)) {
- ETH1394_PRINT_G(KERN_ERR, "Cannot register the driver\n");
- goto out;
- }
-
- ETH1394_PRINT(KERN_INFO, dev->name, "IPv4 over IEEE 1394 (fw-host%d)\n",
- host->id);
-
- hi->host = host;
- hi->dev = dev;
-
- /* Ignore validity in hopes that it will be set in the future. It'll
- * be checked when the eth device is opened. */
- priv->broadcast_channel = host->csr.broadcast_channel & 0x3f;
-
- ether1394_recv_init(priv);
- return;
-out:
- if (dev)
- free_netdev(dev);
- if (hi)
- hpsb_destroy_hostinfo(&eth1394_highlevel, host);
- hpsb_unregister_addrspace(&eth1394_highlevel, host, fifo_addr);
- hpsb_config_rom_ip1394_remove(host);
-}
-
-/* Remove a card from our list */
-static void ether1394_remove_host(struct hpsb_host *host)
-{
- struct eth1394_host_info *hi;
- struct eth1394_priv *priv;
-
- hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
- if (!hi)
- return;
- priv = netdev_priv(hi->dev);
- hpsb_unregister_addrspace(&eth1394_highlevel, host, priv->local_fifo);
- hpsb_config_rom_ip1394_remove(host);
- if (priv->iso)
- hpsb_iso_shutdown(priv->iso);
- unregister_netdev(hi->dev);
- free_netdev(hi->dev);
-}
-
-/* A bus reset happened */
-static void ether1394_host_reset(struct hpsb_host *host)
-{
- struct eth1394_host_info *hi;
- struct eth1394_priv *priv;
- struct net_device *dev;
- struct list_head *lh, *n;
- struct eth1394_node_ref *node;
- struct eth1394_node_info *node_info;
- unsigned long flags;
-
- hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
-
- /* This can happen for hosts that we don't use */
- if (!hi)
- return;
-
- dev = hi->dev;
- priv = netdev_priv(dev);
-
- /* Reset our private host data, but not our MTU */
- netif_stop_queue(dev);
- ether1394_reset_priv(dev, 0);
-
- list_for_each_entry(node, &priv->ip_node_list, list) {
- node_info = dev_get_drvdata(&node->ud->device);
-
- spin_lock_irqsave(&node_info->pdg.lock, flags);
-
- list_for_each_safe(lh, n, &node_info->pdg.list)
- purge_partial_datagram(lh);
-
- INIT_LIST_HEAD(&(node_info->pdg.list));
- node_info->pdg.sz = 0;
-
- spin_unlock_irqrestore(&node_info->pdg.lock, flags);
- }
-
- netif_wake_queue(dev);
-}
-
-/******************************************
- * HW Header net device functions
- ******************************************/
-/* These functions have been adapted from net/ethernet/eth.c */
-
-/* Create a fake MAC header for an arbitrary protocol layer.
- * saddr=NULL means use device source address
- * daddr=NULL means leave destination address (eg unresolved arp). */
-static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, const void *daddr,
- const void *saddr, unsigned len)
-{
- struct eth1394hdr *eth =
- (struct eth1394hdr *)skb_push(skb, ETH1394_HLEN);
-
- eth->h_proto = htons(type);
-
- if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
- memset(eth->h_dest, 0, dev->addr_len);
- return dev->hard_header_len;
- }
-
- if (daddr) {
- memcpy(eth->h_dest, daddr, dev->addr_len);
- return dev->hard_header_len;
- }
-
- return -dev->hard_header_len;
-}
-
-/* Rebuild the faked MAC header. This is called after an ARP
- * (or in future other address resolution) has completed on this
- * sk_buff. We now let ARP fill in the other fields.
- *
- * This routine CANNOT use cached dst->neigh!
- * Really, it is used only when dst->neigh is wrong.
- */
-static int ether1394_rebuild_header(struct sk_buff *skb)
-{
- struct eth1394hdr *eth = (struct eth1394hdr *)skb->data;
-
- if (eth->h_proto == htons(ETH_P_IP))
- return arp_find((unsigned char *)&eth->h_dest, skb);
-
- ETH1394_PRINT(KERN_DEBUG, skb->dev->name,
- "unable to resolve type %04x addresses\n",
- ntohs(eth->h_proto));
- return 0;
-}
-
-static int ether1394_header_parse(const struct sk_buff *skb,
- unsigned char *haddr)
-{
- memcpy(haddr, skb->dev->dev_addr, ETH1394_ALEN);
- return ETH1394_ALEN;
-}
-
-static int ether1394_header_cache(const struct neighbour *neigh,
- struct hh_cache *hh)
-{
- __be16 type = hh->hh_type;
- struct net_device *dev = neigh->dev;
- struct eth1394hdr *eth =
- (struct eth1394hdr *)((u8 *)hh->hh_data + 16 - ETH1394_HLEN);
-
- if (type == htons(ETH_P_802_3))
- return -1;
-
- eth->h_proto = type;
- memcpy(eth->h_dest, neigh->ha, dev->addr_len);
-
- hh->hh_len = ETH1394_HLEN;
- return 0;
-}
-
-/* Called by Address Resolution module to notify changes in address. */
-static void ether1394_header_cache_update(struct hh_cache *hh,
- const struct net_device *dev,
- const unsigned char * haddr)
-{
- memcpy((u8 *)hh->hh_data + 16 - ETH1394_HLEN, haddr, dev->addr_len);
-}
-
-/******************************************
- * Datagram reception code
- ******************************************/
-
-/* Copied from net/ethernet/eth.c */
-static __be16 ether1394_type_trans(struct sk_buff *skb, struct net_device *dev)
-{
- struct eth1394hdr *eth;
- unsigned char *rawp;
-
- skb_reset_mac_header(skb);
- skb_pull(skb, ETH1394_HLEN);
- eth = eth1394_hdr(skb);
-
- if (*eth->h_dest & 1) {
- if (memcmp(eth->h_dest, dev->broadcast, dev->addr_len) == 0)
- skb->pkt_type = PACKET_BROADCAST;
-#if 0
- else
- skb->pkt_type = PACKET_MULTICAST;
-#endif
- } else {
- if (memcmp(eth->h_dest, dev->dev_addr, dev->addr_len))
- skb->pkt_type = PACKET_OTHERHOST;
- }
-
- if (ntohs(eth->h_proto) >= 1536)
- return eth->h_proto;
-
- rawp = skb->data;
-
- if (*(unsigned short *)rawp == 0xFFFF)
- return htons(ETH_P_802_3);
-
- return htons(ETH_P_802_2);
-}
-
-/* Parse an encapsulated IP1394 header into an ethernet frame packet.
- * We also perform ARP translation here, if need be. */
-static __be16 ether1394_parse_encap(struct sk_buff *skb, struct net_device *dev,
- nodeid_t srcid, nodeid_t destid,
- __be16 ether_type)
-{
- struct eth1394_priv *priv = netdev_priv(dev);
- __be64 dest_hw;
- __be16 ret = 0;
-
- /* Setup our hw addresses. We use these to build the ethernet header. */
- if (destid == (LOCAL_BUS | ALL_NODES))
- dest_hw = ~cpu_to_be64(0); /* broadcast */
- else
- dest_hw = cpu_to_be64((u64)priv->host->csr.guid_hi << 32 |
- priv->host->csr.guid_lo);
-
- /* If this is an ARP packet, convert it. First, we want to make
- * use of some of the fields, since they tell us a little bit
- * about the sending machine. */
- if (ether_type == htons(ETH_P_ARP)) {
- struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data;
- struct arphdr *arp = (struct arphdr *)skb->data;
- unsigned char *arp_ptr = (unsigned char *)(arp + 1);
- u64 fifo_addr = (u64)ntohs(arp1394->fifo_hi) << 32 |
- ntohl(arp1394->fifo_lo);
- u8 max_rec = min(priv->host->csr.max_rec,
- (u8)(arp1394->max_rec));
- int sspd = arp1394->sspd;
- u16 maxpayload;
- struct eth1394_node_ref *node;
- struct eth1394_node_info *node_info;
- __be64 guid;
-
- /* Sanity check. MacOSX seems to be sending us 131 in this
- * field (atleast on my Panther G5). Not sure why. */
- if (sspd > 5 || sspd < 0)
- sspd = 0;
-
- maxpayload = min(eth1394_speedto_maxpayload[sspd],
- (u16)(1 << (max_rec + 1)));
-
- guid = get_unaligned(&arp1394->s_uniq_id);
- node = eth1394_find_node_guid(&priv->ip_node_list,
- be64_to_cpu(guid));
- if (!node)
- return cpu_to_be16(0);
-
- node_info = dev_get_drvdata(&node->ud->device);
-
- /* Update our speed/payload/fifo_offset table */
- node_info->maxpayload = maxpayload;
- node_info->sspd = sspd;
- node_info->fifo = fifo_addr;
-
- /* Now that we're done with the 1394 specific stuff, we'll
- * need to alter some of the data. Believe it or not, all
- * that needs to be done is sender_IP_address needs to be
- * moved, the destination hardware address get stuffed
- * in and the hardware address length set to 8.
- *
- * IMPORTANT: The code below overwrites 1394 specific data
- * needed above so keep the munging of the data for the
- * higher level IP stack last. */
-
- arp->ar_hln = 8;
- arp_ptr += arp->ar_hln; /* skip over sender unique id */
- *(u32 *)arp_ptr = arp1394->sip; /* move sender IP addr */
- arp_ptr += arp->ar_pln; /* skip over sender IP addr */
-
- if (arp->ar_op == htons(ARPOP_REQUEST))
- memset(arp_ptr, 0, sizeof(u64));
- else
- memcpy(arp_ptr, dev->dev_addr, sizeof(u64));
- }
-
- /* Now add the ethernet header. */
- if (dev_hard_header(skb, dev, ntohs(ether_type), &dest_hw, NULL,
- skb->len) >= 0)
- ret = ether1394_type_trans(skb, dev);
-
- return ret;
-}
-
-static int fragment_overlap(struct list_head *frag_list, int offset, int len)
-{
- struct fragment_info *fi;
- int end = offset + len;
-
- list_for_each_entry(fi, frag_list, list)
- if (offset < fi->offset + fi->len && end > fi->offset)
- return 1;
-
- return 0;
-}
-
-static struct list_head *find_partial_datagram(struct list_head *pdgl, int dgl)
-{
- struct partial_datagram *pd;
-
- list_for_each_entry(pd, pdgl, list)
- if (pd->dgl == dgl)
- return &pd->list;
-
- return NULL;
-}
-
-/* Assumes that new fragment does not overlap any existing fragments */
-static int new_fragment(struct list_head *frag_info, int offset, int len)
-{
- struct list_head *lh;
- struct fragment_info *fi, *fi2, *new;
-
- list_for_each(lh, frag_info) {
- fi = list_entry(lh, struct fragment_info, list);
- if (fi->offset + fi->len == offset) {
- /* The new fragment can be tacked on to the end */
- fi->len += len;
- /* Did the new fragment plug a hole? */
- fi2 = list_entry(lh->next, struct fragment_info, list);
- if (fi->offset + fi->len == fi2->offset) {
- /* glue fragments together */
- fi->len += fi2->len;
- list_del(lh->next);
- kfree(fi2);
- }
- return 0;
- } else if (offset + len == fi->offset) {
- /* The new fragment can be tacked on to the beginning */
- fi->offset = offset;
- fi->len += len;
- /* Did the new fragment plug a hole? */
- fi2 = list_entry(lh->prev, struct fragment_info, list);
- if (fi2->offset + fi2->len == fi->offset) {
- /* glue fragments together */
- fi2->len += fi->len;
- list_del(lh);
- kfree(fi);
- }
- return 0;
- } else if (offset > fi->offset + fi->len) {
- break;
- } else if (offset + len < fi->offset) {
- lh = lh->prev;
- break;
- }
- }
-
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
- if (!new)
- return -ENOMEM;
-
- new->offset = offset;
- new->len = len;
-
- list_add(&new->list, lh);
- return 0;
-}
-
-static int new_partial_datagram(struct net_device *dev, struct list_head *pdgl,
- int dgl, int dg_size, char *frag_buf,
- int frag_off, int frag_len)
-{
- struct partial_datagram *new;
-
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
- if (!new)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&new->frag_info);
-
- if (new_fragment(&new->frag_info, frag_off, frag_len) < 0) {
- kfree(new);
- return -ENOMEM;
- }
-
- new->dgl = dgl;
- new->dg_size = dg_size;
-
- new->skb = dev_alloc_skb(dg_size + dev->hard_header_len + 15);
- if (!new->skb) {
- struct fragment_info *fi = list_entry(new->frag_info.next,
- struct fragment_info,
- list);
- kfree(fi);
- kfree(new);
- return -ENOMEM;
- }
-
- skb_reserve(new->skb, (dev->hard_header_len + 15) & ~15);
- new->pbuf = skb_put(new->skb, dg_size);
- memcpy(new->pbuf + frag_off, frag_buf, frag_len);
-
- list_add(&new->list, pdgl);
- return 0;
-}
-
-static int update_partial_datagram(struct list_head *pdgl, struct list_head *lh,
- char *frag_buf, int frag_off, int frag_len)
-{
- struct partial_datagram *pd =
- list_entry(lh, struct partial_datagram, list);
-
- if (new_fragment(&pd->frag_info, frag_off, frag_len) < 0)
- return -ENOMEM;
-
- memcpy(pd->pbuf + frag_off, frag_buf, frag_len);
-
- /* Move list entry to beginnig of list so that oldest partial
- * datagrams percolate to the end of the list */
- list_move(lh, pdgl);
- return 0;
-}
-
-static int is_datagram_complete(struct list_head *lh, int dg_size)
-{
- struct partial_datagram *pd;
- struct fragment_info *fi;
-
- pd = list_entry(lh, struct partial_datagram, list);
- fi = list_entry(pd->frag_info.next, struct fragment_info, list);
-
- return (fi->len == dg_size);
-}
-
-/* Packet reception. We convert the IP1394 encapsulation header to an
- * ethernet header, and fill it with some of our other fields. This is
- * an incoming packet from the 1394 bus. */
-static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
- char *buf, int len)
-{
- struct sk_buff *skb;
- unsigned long flags;
- struct eth1394_priv *priv = netdev_priv(dev);
- union eth1394_hdr *hdr = (union eth1394_hdr *)buf;
- __be16 ether_type = cpu_to_be16(0); /* initialized to clear warning */
- int hdr_len;
- struct unit_directory *ud = priv->ud_list[NODEID_TO_NODE(srcid)];
- struct eth1394_node_info *node_info;
-
- if (!ud) {
- struct eth1394_node_ref *node;
- node = eth1394_find_node_nodeid(&priv->ip_node_list, srcid);
- if (unlikely(!node)) {
- HPSB_PRINT(KERN_ERR, "ether1394 rx: sender nodeid "
- "lookup failure: " NODE_BUS_FMT,
- NODE_BUS_ARGS(priv->host, srcid));
- dev->stats.rx_dropped++;
- return -1;
- }
- ud = node->ud;
-
- priv->ud_list[NODEID_TO_NODE(srcid)] = ud;
- }
-
- node_info = dev_get_drvdata(&ud->device);
-
- /* First, did we receive a fragmented or unfragmented datagram? */
- hdr->words.word1 = ntohs(hdr->words.word1);
-
- hdr_len = hdr_type_len[hdr->common.lf];
-
- if (hdr->common.lf == ETH1394_HDR_LF_UF) {
- /* An unfragmented datagram has been received by the ieee1394
- * bus. Build an skbuff around it so we can pass it to the
- * high level network layer. */
-
- skb = dev_alloc_skb(len + dev->hard_header_len + 15);
- if (unlikely(!skb)) {
- ETH1394_PRINT_G(KERN_ERR, "Out of memory\n");
- dev->stats.rx_dropped++;
- return -1;
- }
- skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
- memcpy(skb_put(skb, len - hdr_len), buf + hdr_len,
- len - hdr_len);
- ether_type = hdr->uf.ether_type;
- } else {
- /* A datagram fragment has been received, now the fun begins. */
-
- struct list_head *pdgl, *lh;
- struct partial_datagram *pd;
- int fg_off;
- int fg_len = len - hdr_len;
- int dg_size;
- int dgl;
- int retval;
- struct pdg_list *pdg = &(node_info->pdg);
-
- hdr->words.word3 = ntohs(hdr->words.word3);
- /* The 4th header word is reserved so no need to do ntohs() */
-
- if (hdr->common.lf == ETH1394_HDR_LF_FF) {
- ether_type = hdr->ff.ether_type;
- dgl = hdr->ff.dgl;
- dg_size = hdr->ff.dg_size + 1;
- fg_off = 0;
- } else {
- hdr->words.word2 = ntohs(hdr->words.word2);
- dgl = hdr->sf.dgl;
- dg_size = hdr->sf.dg_size + 1;
- fg_off = hdr->sf.fg_off;
- }
- spin_lock_irqsave(&pdg->lock, flags);
-
- pdgl = &(pdg->list);
- lh = find_partial_datagram(pdgl, dgl);
-
- if (lh == NULL) {
- while (pdg->sz >= max_partial_datagrams) {
- /* remove the oldest */
- purge_partial_datagram(pdgl->prev);
- pdg->sz--;
- }
-
- retval = new_partial_datagram(dev, pdgl, dgl, dg_size,
- buf + hdr_len, fg_off,
- fg_len);
- if (retval < 0) {
- spin_unlock_irqrestore(&pdg->lock, flags);
- goto bad_proto;
- }
- pdg->sz++;
- lh = find_partial_datagram(pdgl, dgl);
- } else {
- pd = list_entry(lh, struct partial_datagram, list);
-
- if (fragment_overlap(&pd->frag_info, fg_off, fg_len)) {
- /* Overlapping fragments, obliterate old
- * datagram and start new one. */
- purge_partial_datagram(lh);
- retval = new_partial_datagram(dev, pdgl, dgl,
- dg_size,
- buf + hdr_len,
- fg_off, fg_len);
- if (retval < 0) {
- pdg->sz--;
- spin_unlock_irqrestore(&pdg->lock, flags);
- goto bad_proto;
- }
- } else {
- retval = update_partial_datagram(pdgl, lh,
- buf + hdr_len,
- fg_off, fg_len);
- if (retval < 0) {
- /* Couldn't save off fragment anyway
- * so might as well obliterate the
- * datagram now. */
- purge_partial_datagram(lh);
- pdg->sz--;
- spin_unlock_irqrestore(&pdg->lock, flags);
- goto bad_proto;
- }
- } /* fragment overlap */
- } /* new datagram or add to existing one */
-
- pd = list_entry(lh, struct partial_datagram, list);
-
- if (hdr->common.lf == ETH1394_HDR_LF_FF)
- pd->ether_type = ether_type;
-
- if (is_datagram_complete(lh, dg_size)) {
- ether_type = pd->ether_type;
- pdg->sz--;
- skb = skb_get(pd->skb);
- purge_partial_datagram(lh);
- spin_unlock_irqrestore(&pdg->lock, flags);
- } else {
- /* Datagram is not complete, we're done for the
- * moment. */
- spin_unlock_irqrestore(&pdg->lock, flags);
- return 0;
- }
- } /* unframgented datagram or fragmented one */
-
- /* Write metadata, and then pass to the receive level */
- skb->dev = dev;
- skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
-
- /* Parse the encapsulation header. This actually does the job of
- * converting to an ethernet frame header, aswell as arp
- * conversion if needed. ARP conversion is easier in this
- * direction, since we are using ethernet as our backend. */
- skb->protocol = ether1394_parse_encap(skb, dev, srcid, destid,
- ether_type);
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (!skb->protocol) {
- dev->stats.rx_errors++;
- dev->stats.rx_dropped++;
- dev_kfree_skb_any(skb);
- } else if (netif_rx(skb) == NET_RX_DROP) {
- dev->stats.rx_errors++;
- dev->stats.rx_dropped++;
- } else {
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += skb->len;
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
-bad_proto:
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
-
- return 0;
-}
-
-static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
- quadlet_t *data, u64 addr, size_t len, u16 flags)
-{
- struct eth1394_host_info *hi;
-
- hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
- if (unlikely(!hi)) {
- ETH1394_PRINT_G(KERN_ERR, "No net device at fw-host%d\n",
- host->id);
- return RCODE_ADDRESS_ERROR;
- }
-
- if (ether1394_data_handler(hi->dev, srcid, destid, (char*)data, len))
- return RCODE_ADDRESS_ERROR;
- else
- return RCODE_COMPLETE;
-}
-
-static void ether1394_iso(struct hpsb_iso *iso)
-{
- __be32 *data;
- char *buf;
- struct eth1394_host_info *hi;
- struct net_device *dev;
- unsigned int len;
- u32 specifier_id;
- u16 source_id;
- int i;
- int nready;
-
- hi = hpsb_get_hostinfo(&eth1394_highlevel, iso->host);
- if (unlikely(!hi)) {
- ETH1394_PRINT_G(KERN_ERR, "No net device at fw-host%d\n",
- iso->host->id);
- return;
- }
-
- dev = hi->dev;
-
- nready = hpsb_iso_n_ready(iso);
- for (i = 0; i < nready; i++) {
- struct hpsb_iso_packet_info *info =
- &iso->infos[(iso->first_packet + i) % iso->buf_packets];
- data = (__be32 *)(iso->data_buf.kvirt + info->offset);
-
- /* skip over GASP header */
- buf = (char *)data + 8;
- len = info->len - 8;
-
- specifier_id = (be32_to_cpu(data[0]) & 0xffff) << 8 |
- (be32_to_cpu(data[1]) & 0xff000000) >> 24;
- source_id = be32_to_cpu(data[0]) >> 16;
-
- if (info->channel != (iso->host->csr.broadcast_channel & 0x3f)
- || specifier_id != ETHER1394_GASP_SPECIFIER_ID) {
- /* This packet is not for us */
- continue;
- }
- ether1394_data_handler(dev, source_id, LOCAL_BUS | ALL_NODES,
- buf, len);
- }
-
- hpsb_iso_recv_release_packets(iso, i);
-
-}
-
-/******************************************
- * Datagram transmission code
- ******************************************/
-
-/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the entire
- * arphdr) is the same format as the ip1394 header, so they overlap. The rest
- * needs to be munged a bit. The remainder of the arphdr is formatted based
- * on hwaddr len and ipaddr len. We know what they'll be, so it's easy to
- * judge.
- *
- * Now that the EUI is used for the hardware address all we need to do to make
- * this work for 1394 is to insert 2 quadlets that contain max_rec size,
- * speed, and unicast FIFO address information between the sender_unique_id
- * and the IP addresses.
- */
-static void ether1394_arp_to_1394arp(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct eth1394_priv *priv = netdev_priv(dev);
- struct arphdr *arp = (struct arphdr *)skb->data;
- unsigned char *arp_ptr = (unsigned char *)(arp + 1);
- struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data;
-
- arp1394->hw_addr_len = 16;
- arp1394->sip = *(u32*)(arp_ptr + ETH1394_ALEN);
- arp1394->max_rec = priv->host->csr.max_rec;
- arp1394->sspd = priv->host->csr.lnk_spd;
- arp1394->fifo_hi = htons(priv->local_fifo >> 32);
- arp1394->fifo_lo = htonl(priv->local_fifo & ~0x0);
-}
-
-/* We need to encapsulate the standard header with our own. We use the
- * ethernet header's proto for our own. */
-static unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
- __be16 proto,
- union eth1394_hdr *hdr,
- u16 dg_size, u16 dgl)
-{
- unsigned int adj_max_payload =
- max_payload - hdr_type_len[ETH1394_HDR_LF_UF];
-
- /* Does it all fit in one packet? */
- if (dg_size <= adj_max_payload) {
- hdr->uf.lf = ETH1394_HDR_LF_UF;
- hdr->uf.ether_type = proto;
- } else {
- hdr->ff.lf = ETH1394_HDR_LF_FF;
- hdr->ff.ether_type = proto;
- hdr->ff.dg_size = dg_size - 1;
- hdr->ff.dgl = dgl;
- adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF];
- }
- return DIV_ROUND_UP(dg_size, adj_max_payload);
-}
-
-static unsigned int ether1394_encapsulate(struct sk_buff *skb,
- unsigned int max_payload,
- union eth1394_hdr *hdr)
-{
- union eth1394_hdr *bufhdr;
- int ftype = hdr->common.lf;
- int hdrsz = hdr_type_len[ftype];
- unsigned int adj_max_payload = max_payload - hdrsz;
-
- switch (ftype) {
- case ETH1394_HDR_LF_UF:
- bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz);
- bufhdr->words.word1 = htons(hdr->words.word1);
- bufhdr->words.word2 = hdr->words.word2;
- break;
-
- case ETH1394_HDR_LF_FF:
- bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz);
- bufhdr->words.word1 = htons(hdr->words.word1);
- bufhdr->words.word2 = hdr->words.word2;
- bufhdr->words.word3 = htons(hdr->words.word3);
- bufhdr->words.word4 = 0;
-
- /* Set frag type here for future interior fragments */
- hdr->common.lf = ETH1394_HDR_LF_IF;
- hdr->sf.fg_off = 0;
- break;
-
- default:
- hdr->sf.fg_off += adj_max_payload;
- bufhdr = (union eth1394_hdr *)skb_pull(skb, adj_max_payload);
- if (max_payload >= skb->len)
- hdr->common.lf = ETH1394_HDR_LF_LF;
- bufhdr->words.word1 = htons(hdr->words.word1);
- bufhdr->words.word2 = htons(hdr->words.word2);
- bufhdr->words.word3 = htons(hdr->words.word3);
- bufhdr->words.word4 = 0;
- }
- return min(max_payload, skb->len);
-}
-
-static struct hpsb_packet *ether1394_alloc_common_packet(struct hpsb_host *host)
-{
- struct hpsb_packet *p;
-
- p = hpsb_alloc_packet(0);
- if (p) {
- p->host = host;
- p->generation = get_hpsb_generation(host);
- p->type = hpsb_async;
- }
- return p;
-}
-
-static int ether1394_prep_write_packet(struct hpsb_packet *p,
- struct hpsb_host *host, nodeid_t node,
- u64 addr, void *data, int tx_len)
-{
- p->node_id = node;
-
- if (hpsb_get_tlabel(p))
- return -EAGAIN;
-
- p->tcode = TCODE_WRITEB;
- p->header_size = 16;
- p->expect_response = 1;
- p->header[0] =
- p->node_id << 16 | p->tlabel << 10 | 1 << 8 | TCODE_WRITEB << 4;
- p->header[1] = host->node_id << 16 | addr >> 32;
- p->header[2] = addr & 0xffffffff;
- p->header[3] = tx_len << 16;
- p->data_size = (tx_len + 3) & ~3;
- p->data = data;
-
- return 0;
-}
-
-static void ether1394_prep_gasp_packet(struct hpsb_packet *p,
- struct eth1394_priv *priv,
- struct sk_buff *skb, int length)
-{
- p->header_size = 4;
- p->tcode = TCODE_STREAM_DATA;
-
- p->header[0] = length << 16 | 3 << 14 | priv->broadcast_channel << 8 |
- TCODE_STREAM_DATA << 4;
- p->data_size = length;
- p->data = (quadlet_t *)skb->data - 2;
- p->data[0] = cpu_to_be32(priv->host->node_id << 16 |
- ETHER1394_GASP_SPECIFIER_ID_HI);
- p->data[1] = cpu_to_be32(ETHER1394_GASP_SPECIFIER_ID_LO << 24 |
- ETHER1394_GASP_VERSION);
-
- p->speed_code = priv->bc_sspd;
-
- /* prevent hpsb_send_packet() from overriding our speed code */
- p->node_id = LOCAL_BUS | ALL_NODES;
-}
-
-static void ether1394_free_packet(struct hpsb_packet *packet)
-{
- if (packet->tcode != TCODE_STREAM_DATA)
- hpsb_free_tlabel(packet);
- hpsb_free_packet(packet);
-}
-
-static void ether1394_complete_cb(void *__ptask);
-
-static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
-{
- struct eth1394_priv *priv = ptask->priv;
- struct hpsb_packet *packet = NULL;
-
- packet = ether1394_alloc_common_packet(priv->host);
- if (!packet)
- return -ENOMEM;
-
- if (ptask->tx_type == ETH1394_GASP) {
- int length = tx_len + 2 * sizeof(quadlet_t);
-
- ether1394_prep_gasp_packet(packet, priv, ptask->skb, length);
- } else if (ether1394_prep_write_packet(packet, priv->host,
- ptask->dest_node,
- ptask->addr, ptask->skb->data,
- tx_len)) {
- hpsb_free_packet(packet);
- return -EAGAIN;
- }
-
- ptask->packet = packet;
- hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb,
- ptask);
-
- if (hpsb_send_packet(packet) < 0) {
- ether1394_free_packet(packet);
- return -EIO;
- }
-
- return 0;
-}
-
-/* Task function to be run when a datagram transmission is completed */
-static void ether1394_dg_complete(struct packet_task *ptask, int fail)
-{
- struct sk_buff *skb = ptask->skb;
- struct net_device *dev = skb->dev;
- struct eth1394_priv *priv = netdev_priv(dev);
- unsigned long flags;
-
- /* Statistics */
- spin_lock_irqsave(&priv->lock, flags);
- if (fail) {
- dev->stats.tx_dropped++;
- dev->stats.tx_errors++;
- } else {
- dev->stats.tx_bytes += skb->len;
- dev->stats.tx_packets++;
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
- dev_kfree_skb_any(skb);
- kmem_cache_free(packet_task_cache, ptask);
-}
-
-/* Callback for when a packet has been sent and the status of that packet is
- * known */
-static void ether1394_complete_cb(void *__ptask)
-{
- struct packet_task *ptask = (struct packet_task *)__ptask;
- struct hpsb_packet *packet = ptask->packet;
- int fail = 0;
-
- if (packet->tcode != TCODE_STREAM_DATA)
- fail = hpsb_packet_success(packet);
-
- ether1394_free_packet(packet);
-
- ptask->outstanding_pkts--;
- if (ptask->outstanding_pkts > 0 && !fail) {
- int tx_len, err;
-
- /* Add the encapsulation header to the fragment */
- tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload,
- &ptask->hdr);
- err = ether1394_send_packet(ptask, tx_len);
- if (err) {
- if (err == -EAGAIN)
- ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
-
- ether1394_dg_complete(ptask, 1);
- }
- } else {
- ether1394_dg_complete(ptask, fail);
- }
-}
-
-/* Transmit a packet (called by kernel) */
-static netdev_tx_t ether1394_tx(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct eth1394hdr hdr_buf;
- struct eth1394_priv *priv = netdev_priv(dev);
- __be16 proto;
- unsigned long flags;
- nodeid_t dest_node;
- eth1394_tx_type tx_type;
- unsigned int tx_len;
- unsigned int max_payload;
- u16 dg_size;
- u16 dgl;
- struct packet_task *ptask;
- struct eth1394_node_ref *node;
- struct eth1394_node_info *node_info = NULL;
-
- ptask = kmem_cache_alloc(packet_task_cache, GFP_ATOMIC);
- if (ptask == NULL)
- goto fail;
-
- /* XXX Ignore this for now. Noticed that when MacOSX is the IRM,
- * it does not set our validity bit. We need to compensate for
- * that somewhere else, but not in eth1394. */
-#if 0
- if ((priv->host->csr.broadcast_channel & 0xc0000000) != 0xc0000000)
- goto fail;
-#endif
-
- skb = skb_share_check(skb, GFP_ATOMIC);
- if (!skb)
- goto fail;
-
- /* Get rid of the fake eth1394 header, but first make a copy.
- * We might need to rebuild the header on tx failure. */
- memcpy(&hdr_buf, skb->data, sizeof(hdr_buf));
- skb_pull(skb, ETH1394_HLEN);
-
- proto = hdr_buf.h_proto;
- dg_size = skb->len;
-
- /* Set the transmission type for the packet. ARP packets and IP
- * broadcast packets are sent via GASP. */
- if (memcmp(hdr_buf.h_dest, dev->broadcast, ETH1394_ALEN) == 0 ||
- proto == htons(ETH_P_ARP) ||
- (proto == htons(ETH_P_IP) &&
- IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) {
- tx_type = ETH1394_GASP;
- dest_node = LOCAL_BUS | ALL_NODES;
- max_payload = priv->bc_maxpayload - ETHER1394_GASP_OVERHEAD;
- BUG_ON(max_payload < 512 - ETHER1394_GASP_OVERHEAD);
- dgl = priv->bc_dgl;
- if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF])
- priv->bc_dgl++;
- } else {
- __be64 guid = get_unaligned((__be64 *)hdr_buf.h_dest);
-
- node = eth1394_find_node_guid(&priv->ip_node_list,
- be64_to_cpu(guid));
- if (!node)
- goto fail;
-
- node_info = dev_get_drvdata(&node->ud->device);
- if (node_info->fifo == CSR1212_INVALID_ADDR_SPACE)
- goto fail;
-
- dest_node = node->ud->ne->nodeid;
- max_payload = node_info->maxpayload;
- BUG_ON(max_payload < 512 - ETHER1394_GASP_OVERHEAD);
-
- dgl = node_info->dgl;
- if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF])
- node_info->dgl++;
- tx_type = ETH1394_WRREQ;
- }
-
- /* If this is an ARP packet, convert it */
- if (proto == htons(ETH_P_ARP))
- ether1394_arp_to_1394arp(skb, dev);
-
- ptask->hdr.words.word1 = 0;
- ptask->hdr.words.word2 = 0;
- ptask->hdr.words.word3 = 0;
- ptask->hdr.words.word4 = 0;
- ptask->skb = skb;
- ptask->priv = priv;
- ptask->tx_type = tx_type;
-
- if (tx_type != ETH1394_GASP) {
- u64 addr;
-
- spin_lock_irqsave(&priv->lock, flags);
- addr = node_info->fifo;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- ptask->addr = addr;
- ptask->dest_node = dest_node;
- }
-
- ptask->tx_type = tx_type;
- ptask->max_payload = max_payload;
- ptask->outstanding_pkts = ether1394_encapsulate_prep(max_payload,
- proto, &ptask->hdr, dg_size, dgl);
-
- /* Add the encapsulation header to the fragment */
- tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr);
- dev->trans_start = jiffies;
- if (ether1394_send_packet(ptask, tx_len)) {
- if (dest_node == (LOCAL_BUS | ALL_NODES))
- goto fail;
-
- /* At this point we want to restore the packet. When we return
- * here with NETDEV_TX_BUSY we will get another entrance in this
- * routine with the same skb and we need it to look the same.
- * So we pull 4 more bytes, then build the header again. */
- skb_pull(skb, 4);
- ether1394_header(skb, dev, ntohs(hdr_buf.h_proto),
- hdr_buf.h_dest, NULL, 0);
-
- /* Most failures of ether1394_send_packet are recoverable. */
- netif_stop_queue(dev);
- priv->wake_node = dest_node;
- schedule_work(&priv->wake);
- kmem_cache_free(packet_task_cache, ptask);
- return NETDEV_TX_BUSY;
- }
-
- return NETDEV_TX_OK;
-fail:
- if (ptask)
- kmem_cache_free(packet_task_cache, ptask);
-
- if (skb != NULL)
- dev_kfree_skb(skb);
-
- spin_lock_irqsave(&priv->lock, flags);
- dev->stats.tx_dropped++;
- dev->stats.tx_errors++;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return NETDEV_TX_OK;
-}
-
-static int __init ether1394_init_module(void)
-{
- int err;
-
- packet_task_cache = kmem_cache_create("packet_task",
- sizeof(struct packet_task),
- 0, 0, NULL);
- if (!packet_task_cache)
- return -ENOMEM;
-
- hpsb_register_highlevel(&eth1394_highlevel);
- err = hpsb_register_protocol(&eth1394_proto_driver);
- if (err) {
- hpsb_unregister_highlevel(&eth1394_highlevel);
- kmem_cache_destroy(packet_task_cache);
- }
- return err;
-}
-
-static void __exit ether1394_exit_module(void)
-{
- hpsb_unregister_protocol(&eth1394_proto_driver);
- hpsb_unregister_highlevel(&eth1394_highlevel);
- kmem_cache_destroy(packet_task_cache);
-}
-
-module_init(ether1394_init_module);
-module_exit(ether1394_exit_module);
diff --git a/drivers/ieee1394/eth1394.h b/drivers/ieee1394/eth1394.h
deleted file mode 100644
index d53bac47b86..00000000000
--- a/drivers/ieee1394/eth1394.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * eth1394.h -- Ethernet driver for Linux IEEE-1394 Subsystem
- *
- * Copyright (C) 2000 Bonin Franck <boninf@free.fr>
- * (C) 2001 Ben Collins <bcollins@debian.org>
- *
- * Mainly based on work by Emanuel Pirker and Andreas E. Bombe
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __ETH1394_H
-#define __ETH1394_H
-
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <asm/byteorder.h>
-
-#include "ieee1394.h"
-#include "ieee1394_types.h"
-
-/* Register for incoming packets. This is 4096 bytes, which supports up to
- * S3200 (per Table 16-3 of IEEE 1394b-2002). */
-#define ETHER1394_REGION_ADDR_LEN 4096
-
-/* GASP identifier numbers for IPv4 over IEEE 1394 */
-#define ETHER1394_GASP_SPECIFIER_ID 0x00005E
-#define ETHER1394_GASP_SPECIFIER_ID_HI ((0x00005E >> 8) & 0xffff)
-#define ETHER1394_GASP_SPECIFIER_ID_LO (0x00005E & 0xff)
-#define ETHER1394_GASP_VERSION 1
-
-#define ETHER1394_GASP_OVERHEAD (2 * sizeof(quadlet_t)) /* for GASP header */
-
-#define ETHER1394_GASP_BUFFERS 16
-
-#define NODE_SET (ALL_NODES + 1) /* Node set == 64 */
-
-enum eth1394_bc_states { ETHER1394_BC_ERROR,
- ETHER1394_BC_RUNNING,
- ETHER1394_BC_STOPPED };
-
-
-/* Private structure for our ethernet driver */
-struct eth1394_priv {
- struct hpsb_host *host; /* The card for this dev */
- u16 bc_maxpayload; /* Max broadcast payload */
- u8 bc_sspd; /* Max broadcast speed */
- u64 local_fifo; /* Local FIFO Address */
- spinlock_t lock; /* Private lock */
- int broadcast_channel; /* Async stream Broadcast Channel */
- enum eth1394_bc_states bc_state; /* broadcast channel state */
- struct hpsb_iso *iso; /* Async stream recv handle */
- int bc_dgl; /* Outgoing broadcast datagram label */
- struct list_head ip_node_list; /* List of IP capable nodes */
- struct unit_directory *ud_list[ALL_NODES]; /* Cached unit dir list */
-
- struct work_struct wake; /* Wake up after xmit failure */
- struct net_device *wake_dev; /* Stupid backlink for .wake */
- nodeid_t wake_node; /* Destination of failed xmit */
-};
-
-
-/* Define a fake hardware header format for the networking core. Note that
- * header size cannot exceed 16 bytes as that is the size of the header cache.
- * Also, we do not need the source address in the header so we omit it and
- * keep the header to under 16 bytes */
-#define ETH1394_ALEN (8)
-#define ETH1394_HLEN (10)
-
-struct eth1394hdr {
- unsigned char h_dest[ETH1394_ALEN]; /* destination eth1394 addr */
- __be16 h_proto; /* packet type ID field */
-} __attribute__((packed));
-
-static inline struct eth1394hdr *eth1394_hdr(const struct sk_buff *skb)
-{
- return (struct eth1394hdr *)skb_mac_header(skb);
-}
-
-typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type;
-
-/* IP1394 headers */
-
-/* Unfragmented */
-#if defined __BIG_ENDIAN_BITFIELD
-struct eth1394_uf_hdr {
- u16 lf:2;
- u16 res:14;
- __be16 ether_type; /* Ethernet packet type */
-} __attribute__((packed));
-#elif defined __LITTLE_ENDIAN_BITFIELD
-struct eth1394_uf_hdr {
- u16 res:14;
- u16 lf:2;
- __be16 ether_type;
-} __attribute__((packed));
-#else
-#error Unknown bit field type
-#endif
-
-/* First fragment */
-#if defined __BIG_ENDIAN_BITFIELD
-struct eth1394_ff_hdr {
- u16 lf:2;
- u16 res1:2;
- u16 dg_size:12; /* Datagram size */
- __be16 ether_type; /* Ethernet packet type */
- u16 dgl; /* Datagram label */
- u16 res2;
-} __attribute__((packed));
-#elif defined __LITTLE_ENDIAN_BITFIELD
-struct eth1394_ff_hdr {
- u16 dg_size:12;
- u16 res1:2;
- u16 lf:2;
- __be16 ether_type;
- u16 dgl;
- u16 res2;
-} __attribute__((packed));
-#else
-#error Unknown bit field type
-#endif
-
-/* XXX: Subsequent fragments, including last */
-#if defined __BIG_ENDIAN_BITFIELD
-struct eth1394_sf_hdr {
- u16 lf:2;
- u16 res1:2;
- u16 dg_size:12; /* Datagram size */
- u16 res2:4;
- u16 fg_off:12; /* Fragment offset */
- u16 dgl; /* Datagram label */
- u16 res3;
-} __attribute__((packed));
-#elif defined __LITTLE_ENDIAN_BITFIELD
-struct eth1394_sf_hdr {
- u16 dg_size:12;
- u16 res1:2;
- u16 lf:2;
- u16 fg_off:12;
- u16 res2:4;
- u16 dgl;
- u16 res3;
-} __attribute__((packed));
-#else
-#error Unknown bit field type
-#endif
-
-#if defined __BIG_ENDIAN_BITFIELD
-struct eth1394_common_hdr {
- u16 lf:2;
- u16 pad1:14;
-} __attribute__((packed));
-#elif defined __LITTLE_ENDIAN_BITFIELD
-struct eth1394_common_hdr {
- u16 pad1:14;
- u16 lf:2;
-} __attribute__((packed));
-#else
-#error Unknown bit field type
-#endif
-
-struct eth1394_hdr_words {
- u16 word1;
- u16 word2;
- u16 word3;
- u16 word4;
-};
-
-union eth1394_hdr {
- struct eth1394_common_hdr common;
- struct eth1394_uf_hdr uf;
- struct eth1394_ff_hdr ff;
- struct eth1394_sf_hdr sf;
- struct eth1394_hdr_words words;
-};
-
-/* End of IP1394 headers */
-
-/* Fragment types */
-#define ETH1394_HDR_LF_UF 0 /* unfragmented */
-#define ETH1394_HDR_LF_FF 1 /* first fragment */
-#define ETH1394_HDR_LF_LF 2 /* last fragment */
-#define ETH1394_HDR_LF_IF 3 /* interior fragment */
-
-#define IP1394_HW_ADDR_LEN 16 /* As per RFC */
-
-/* Our arp packet (ARPHRD_IEEE1394) */
-struct eth1394_arp {
- u16 hw_type; /* 0x0018 */
- u16 proto_type; /* 0x0806 */
- u8 hw_addr_len; /* 16 */
- u8 ip_addr_len; /* 4 */
- u16 opcode; /* ARP Opcode */
- /* Above is exactly the same format as struct arphdr */
-
- __be64 s_uniq_id; /* Sender's 64bit EUI */
- u8 max_rec; /* Sender's max packet size */
- u8 sspd; /* Sender's max speed */
- __be16 fifo_hi; /* hi 16bits of sender's FIFO addr */
- __be32 fifo_lo; /* lo 32bits of sender's FIFO addr */
- u32 sip; /* Sender's IP Address */
- u32 tip; /* IP Address of requested hw addr */
-};
-
-/* Network timeout */
-#define ETHER1394_TIMEOUT 100000
-
-/* This is our task struct. It's used for the packet complete callback. */
-struct packet_task {
- struct sk_buff *skb;
- int outstanding_pkts;
- eth1394_tx_type tx_type;
- int max_payload;
- struct hpsb_packet *packet;
- struct eth1394_priv *priv;
- union eth1394_hdr hdr;
- u64 addr;
- u16 dest_node;
-};
-
-#endif /* __ETH1394_H */
diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c
deleted file mode 100644
index 4bc443546e0..00000000000
--- a/drivers/ieee1394/highlevel.c
+++ /dev/null
@@ -1,691 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * Copyright (C) 1999 Andreas E. Bombe
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- *
- *
- * Contributions:
- *
- * Christian Toegel <christian.toegel@gmx.at>
- * unregister address space
- *
- * Manfred Weihs <weihs@ict.tuwien.ac.at>
- * unregister address space
- *
- */
-
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/bitops.h>
-
-#include "ieee1394.h"
-#include "ieee1394_types.h"
-#include "hosts.h"
-#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "nodemgr.h"
-
-
-struct hl_host_info {
- struct list_head list;
- struct hpsb_host *host;
- size_t size;
- unsigned long key;
- void *data;
-};
-
-
-static LIST_HEAD(hl_drivers);
-static DECLARE_RWSEM(hl_drivers_sem);
-
-static LIST_HEAD(hl_irqs);
-static DEFINE_RWLOCK(hl_irqs_lock);
-
-static DEFINE_RWLOCK(addr_space_lock);
-
-
-static struct hl_host_info *hl_get_hostinfo(struct hpsb_highlevel *hl,
- struct hpsb_host *host)
-{
- struct hl_host_info *hi = NULL;
-
- if (!hl || !host)
- return NULL;
-
- read_lock(&hl->host_info_lock);
- list_for_each_entry(hi, &hl->host_info_list, list) {
- if (hi->host == host) {
- read_unlock(&hl->host_info_lock);
- return hi;
- }
- }
- read_unlock(&hl->host_info_lock);
- return NULL;
-}
-
-/**
- * hpsb_get_hostinfo - retrieve a hostinfo pointer bound to this driver/host
- *
- * Returns a per @host and @hl driver data structure that was previously stored
- * by hpsb_create_hostinfo.
- */
-void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host)
-{
- struct hl_host_info *hi = hl_get_hostinfo(hl, host);
-
- return hi ? hi->data : NULL;
-}
-
-/**
- * hpsb_create_hostinfo - allocate a hostinfo pointer bound to this driver/host
- *
- * Allocate a hostinfo pointer backed by memory with @data_size and bind it to
- * to this @hl driver and @host. If @data_size is zero, then the return here is
- * only valid for error checking.
- */
-void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
- size_t data_size)
-{
- struct hl_host_info *hi;
- void *data;
- unsigned long flags;
-
- hi = hl_get_hostinfo(hl, host);
- if (hi) {
- HPSB_ERR("%s called hpsb_create_hostinfo when hostinfo already"
- " exists", hl->name);
- return NULL;
- }
-
- hi = kzalloc(sizeof(*hi) + data_size, GFP_ATOMIC);
- if (!hi)
- return NULL;
-
- if (data_size) {
- data = hi->data = hi + 1;
- hi->size = data_size;
- } else
- data = hi;
-
- hi->host = host;
-
- write_lock_irqsave(&hl->host_info_lock, flags);
- list_add_tail(&hi->list, &hl->host_info_list);
- write_unlock_irqrestore(&hl->host_info_lock, flags);
-
- return data;
-}
-
-/**
- * hpsb_set_hostinfo - set the hostinfo pointer to something useful
- *
- * Usually follows a call to hpsb_create_hostinfo, where the size is 0.
- */
-int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
- void *data)
-{
- struct hl_host_info *hi;
-
- hi = hl_get_hostinfo(hl, host);
- if (hi) {
- if (!hi->size && !hi->data) {
- hi->data = data;
- return 0;
- } else
- HPSB_ERR("%s called hpsb_set_hostinfo when hostinfo "
- "already has data", hl->name);
- } else
- HPSB_ERR("%s called hpsb_set_hostinfo when no hostinfo exists",
- hl->name);
- return -EINVAL;
-}
-
-/**
- * hpsb_destroy_hostinfo - free and remove a hostinfo pointer
- *
- * Free and remove the hostinfo pointer bound to this @hl driver and @host.
- */
-void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host)
-{
- struct hl_host_info *hi;
-
- hi = hl_get_hostinfo(hl, host);
- if (hi) {
- unsigned long flags;
- write_lock_irqsave(&hl->host_info_lock, flags);
- list_del(&hi->list);
- write_unlock_irqrestore(&hl->host_info_lock, flags);
- kfree(hi);
- }
- return;
-}
-
-/**
- * hpsb_set_hostinfo_key - set an alternate lookup key for an hostinfo
- *
- * Sets an alternate lookup key for the hostinfo bound to this @hl driver and
- * @host.
- */
-void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host,
- unsigned long key)
-{
- struct hl_host_info *hi;
-
- hi = hl_get_hostinfo(hl, host);
- if (hi)
- hi->key = key;
- return;
-}
-
-/**
- * hpsb_get_hostinfo_bykey - retrieve a hostinfo pointer by its alternate key
- */
-void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key)
-{
- struct hl_host_info *hi;
- void *data = NULL;
-
- if (!hl)
- return NULL;
-
- read_lock(&hl->host_info_lock);
- list_for_each_entry(hi, &hl->host_info_list, list) {
- if (hi->key == key) {
- data = hi->data;
- break;
- }
- }
- read_unlock(&hl->host_info_lock);
- return data;
-}
-
-static int highlevel_for_each_host_reg(struct hpsb_host *host, void *__data)
-{
- struct hpsb_highlevel *hl = __data;
-
- hl->add_host(host);
-
- if (host->update_config_rom && hpsb_update_config_rom_image(host) < 0)
- HPSB_ERR("Failed to generate Configuration ROM image for host "
- "%s-%d", hl->name, host->id);
- return 0;
-}
-
-/**
- * hpsb_register_highlevel - register highlevel driver
- *
- * The name pointer in @hl has to stay valid at all times because the string is
- * not copied.
- */
-void hpsb_register_highlevel(struct hpsb_highlevel *hl)
-{
- unsigned long flags;
-
- hpsb_init_highlevel(hl);
- INIT_LIST_HEAD(&hl->addr_list);
-
- down_write(&hl_drivers_sem);
- list_add_tail(&hl->hl_list, &hl_drivers);
- up_write(&hl_drivers_sem);
-
- write_lock_irqsave(&hl_irqs_lock, flags);
- list_add_tail(&hl->irq_list, &hl_irqs);
- write_unlock_irqrestore(&hl_irqs_lock, flags);
-
- if (hl->add_host)
- nodemgr_for_each_host(hl, highlevel_for_each_host_reg);
- return;
-}
-
-static void __delete_addr(struct hpsb_address_serve *as)
-{
- list_del(&as->host_list);
- list_del(&as->hl_list);
- kfree(as);
-}
-
-static void __unregister_host(struct hpsb_highlevel *hl, struct hpsb_host *host,
- int update_cr)
-{
- unsigned long flags;
- struct list_head *lh, *next;
- struct hpsb_address_serve *as;
-
- /* First, let the highlevel driver unreg */
- if (hl->remove_host)
- hl->remove_host(host);
-
- /* Remove any addresses that are matched for this highlevel driver
- * and this particular host. */
- write_lock_irqsave(&addr_space_lock, flags);
- list_for_each_safe (lh, next, &hl->addr_list) {
- as = list_entry(lh, struct hpsb_address_serve, hl_list);
- if (as->host == host)
- __delete_addr(as);
- }
- write_unlock_irqrestore(&addr_space_lock, flags);
-
- /* Now update the config-rom to reflect anything removed by the
- * highlevel driver. */
- if (update_cr && host->update_config_rom &&
- hpsb_update_config_rom_image(host) < 0)
- HPSB_ERR("Failed to generate Configuration ROM image for host "
- "%s-%d", hl->name, host->id);
-
- /* Finally remove all the host info associated between these two. */
- hpsb_destroy_hostinfo(hl, host);
-}
-
-static int highlevel_for_each_host_unreg(struct hpsb_host *host, void *__data)
-{
- struct hpsb_highlevel *hl = __data;
-
- __unregister_host(hl, host, 1);
- return 0;
-}
-
-/**
- * hpsb_unregister_highlevel - unregister highlevel driver
- */
-void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
-{
- unsigned long flags;
-
- write_lock_irqsave(&hl_irqs_lock, flags);
- list_del(&hl->irq_list);
- write_unlock_irqrestore(&hl_irqs_lock, flags);
-
- down_write(&hl_drivers_sem);
- list_del(&hl->hl_list);
- up_write(&hl_drivers_sem);
-
- nodemgr_for_each_host(hl, highlevel_for_each_host_unreg);
-}
-
-/**
- * hpsb_allocate_and_register_addrspace - alloc' and reg' a host address space
- *
- * @start and @end are 48 bit pointers and have to be quadlet aligned.
- * @end points to the first address behind the handled addresses. This
- * function can be called multiple times for a single hpsb_highlevel @hl to
- * implement sparse register sets. The requested region must not overlap any
- * previously allocated region, otherwise registering will fail.
- *
- * It returns true for successful allocation. Address spaces can be
- * unregistered with hpsb_unregister_addrspace. All remaining address spaces
- * are automatically deallocated together with the hpsb_highlevel @hl.
- */
-u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
- struct hpsb_host *host,
- const struct hpsb_address_ops *ops,
- u64 size, u64 alignment,
- u64 start, u64 end)
-{
- struct hpsb_address_serve *as, *a1, *a2;
- struct list_head *entry;
- u64 retval = CSR1212_INVALID_ADDR_SPACE;
- unsigned long flags;
- u64 align_mask = ~(alignment - 1);
-
- if ((alignment & 3) || (alignment > 0x800000000000ULL) ||
- (hweight64(alignment) != 1)) {
- HPSB_ERR("%s called with invalid alignment: 0x%048llx",
- __func__, (unsigned long long)alignment);
- return retval;
- }
-
- /* default range,
- * avoids controller's posted write area (see OHCI 1.1 clause 1.5) */
- if (start == CSR1212_INVALID_ADDR_SPACE &&
- end == CSR1212_INVALID_ADDR_SPACE) {
- start = host->middle_addr_space;
- end = CSR1212_ALL_SPACE_END;
- }
-
- if (((start|end) & ~align_mask) || (start >= end) ||
- (end > CSR1212_ALL_SPACE_END)) {
- HPSB_ERR("%s called with invalid addresses "
- "(start = %012Lx end = %012Lx)", __func__,
- (unsigned long long)start,(unsigned long long)end);
- return retval;
- }
-
- as = kmalloc(sizeof(*as), GFP_KERNEL);
- if (!as)
- return retval;
-
- INIT_LIST_HEAD(&as->host_list);
- INIT_LIST_HEAD(&as->hl_list);
- as->op = ops;
- as->host = host;
-
- write_lock_irqsave(&addr_space_lock, flags);
- list_for_each(entry, &host->addr_space) {
- u64 a1sa, a1ea;
- u64 a2sa, a2ea;
-
- a1 = list_entry(entry, struct hpsb_address_serve, host_list);
- a2 = list_entry(entry->next, struct hpsb_address_serve,
- host_list);
-
- a1sa = a1->start & align_mask;
- a1ea = (a1->end + alignment -1) & align_mask;
- a2sa = a2->start & align_mask;
- a2ea = (a2->end + alignment -1) & align_mask;
-
- if ((a2sa - a1ea >= size) && (a2sa - start >= size) &&
- (a2sa > start)) {
- as->start = max(start, a1ea);
- as->end = as->start + size;
- list_add(&as->host_list, entry);
- list_add_tail(&as->hl_list, &hl->addr_list);
- retval = as->start;
- break;
- }
- }
- write_unlock_irqrestore(&addr_space_lock, flags);
-
- if (retval == CSR1212_INVALID_ADDR_SPACE)
- kfree(as);
- return retval;
-}
-
-/**
- * hpsb_register_addrspace - register a host address space
- *
- * @start and @end are 48 bit pointers and have to be quadlet aligned.
- * @end points to the first address behind the handled addresses. This
- * function can be called multiple times for a single hpsb_highlevel @hl to
- * implement sparse register sets. The requested region must not overlap any
- * previously allocated region, otherwise registering will fail.
- *
- * It returns true for successful allocation. Address spaces can be
- * unregistered with hpsb_unregister_addrspace. All remaining address spaces
- * are automatically deallocated together with the hpsb_highlevel @hl.
- */
-int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
- const struct hpsb_address_ops *ops,
- u64 start, u64 end)
-{
- struct hpsb_address_serve *as;
- struct list_head *lh;
- int retval = 0;
- unsigned long flags;
-
- if (((start|end) & 3) || (start >= end) ||
- (end > CSR1212_ALL_SPACE_END)) {
- HPSB_ERR("%s called with invalid addresses", __func__);
- return 0;
- }
-
- as = kmalloc(sizeof(*as), GFP_KERNEL);
- if (!as)
- return 0;
-
- INIT_LIST_HEAD(&as->host_list);
- INIT_LIST_HEAD(&as->hl_list);
- as->op = ops;
- as->start = start;
- as->end = end;
- as->host = host;
-
- write_lock_irqsave(&addr_space_lock, flags);
- list_for_each(lh, &host->addr_space) {
- struct hpsb_address_serve *as_this =
- list_entry(lh, struct hpsb_address_serve, host_list);
- struct hpsb_address_serve *as_next =
- list_entry(lh->next, struct hpsb_address_serve,
- host_list);
-
- if (as_this->end > as->start)
- break;
-
- if (as_next->start >= as->end) {
- list_add(&as->host_list, lh);
- list_add_tail(&as->hl_list, &hl->addr_list);
- retval = 1;
- break;
- }
- }
- write_unlock_irqrestore(&addr_space_lock, flags);
-
- if (retval == 0)
- kfree(as);
- return retval;
-}
-
-int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
- u64 start)
-{
- int retval = 0;
- struct hpsb_address_serve *as;
- struct list_head *lh, *next;
- unsigned long flags;
-
- write_lock_irqsave(&addr_space_lock, flags);
- list_for_each_safe (lh, next, &hl->addr_list) {
- as = list_entry(lh, struct hpsb_address_serve, hl_list);
- if (as->start == start && as->host == host) {
- __delete_addr(as);
- retval = 1;
- break;
- }
- }
- write_unlock_irqrestore(&addr_space_lock, flags);
- return retval;
-}
-
-static const struct hpsb_address_ops dummy_ops;
-
-/* dummy address spaces as lower and upper bounds of the host's a.s. list */
-static void init_hpsb_highlevel(struct hpsb_host *host)
-{
- INIT_LIST_HEAD(&host->dummy_zero_addr.host_list);
- INIT_LIST_HEAD(&host->dummy_zero_addr.hl_list);
- INIT_LIST_HEAD(&host->dummy_max_addr.host_list);
- INIT_LIST_HEAD(&host->dummy_max_addr.hl_list);
-
- host->dummy_zero_addr.op = host->dummy_max_addr.op = &dummy_ops;
-
- host->dummy_zero_addr.start = host->dummy_zero_addr.end = 0;
- host->dummy_max_addr.start = host->dummy_max_addr.end = ((u64) 1) << 48;
-
- list_add_tail(&host->dummy_zero_addr.host_list, &host->addr_space);
- list_add_tail(&host->dummy_max_addr.host_list, &host->addr_space);
-}
-
-void highlevel_add_host(struct hpsb_host *host)
-{
- struct hpsb_highlevel *hl;
-
- init_hpsb_highlevel(host);
-
- down_read(&hl_drivers_sem);
- list_for_each_entry(hl, &hl_drivers, hl_list) {
- if (hl->add_host)
- hl->add_host(host);
- }
- up_read(&hl_drivers_sem);
- if (host->update_config_rom && hpsb_update_config_rom_image(host) < 0)
- HPSB_ERR("Failed to generate Configuration ROM image for host "
- "%s-%d", hl->name, host->id);
-}
-
-void highlevel_remove_host(struct hpsb_host *host)
-{
- struct hpsb_highlevel *hl;
-
- down_read(&hl_drivers_sem);
- list_for_each_entry(hl, &hl_drivers, hl_list)
- __unregister_host(hl, host, 0);
- up_read(&hl_drivers_sem);
-}
-
-void highlevel_host_reset(struct hpsb_host *host)
-{
- unsigned long flags;
- struct hpsb_highlevel *hl;
-
- read_lock_irqsave(&hl_irqs_lock, flags);
- list_for_each_entry(hl, &hl_irqs, irq_list) {
- if (hl->host_reset)
- hl->host_reset(host);
- }
- read_unlock_irqrestore(&hl_irqs_lock, flags);
-}
-
-void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
- void *data, size_t length)
-{
- unsigned long flags;
- struct hpsb_highlevel *hl;
- int cts = ((quadlet_t *)data)[0] >> 4;
-
- read_lock_irqsave(&hl_irqs_lock, flags);
- list_for_each_entry(hl, &hl_irqs, irq_list) {
- if (hl->fcp_request)
- hl->fcp_request(host, nodeid, direction, cts, data,
- length);
- }
- read_unlock_irqrestore(&hl_irqs_lock, flags);
-}
-
-/*
- * highlevel_read, highlevel_write, highlevel_lock, highlevel_lock64:
- *
- * These functions are called to handle transactions. They are called when a
- * packet arrives. The flags argument contains the second word of the first
- * header quadlet of the incoming packet (containing transaction label, retry
- * code, transaction code and priority). These functions either return a
- * response code or a negative number. In the first case a response will be
- * generated. In the latter case, no response will be sent and the driver which
- * handled the request will send the response itself.
- */
-int highlevel_read(struct hpsb_host *host, int nodeid, void *data, u64 addr,
- unsigned int length, u16 flags)
-{
- struct hpsb_address_serve *as;
- unsigned int partlength;
- int rcode = RCODE_ADDRESS_ERROR;
-
- read_lock(&addr_space_lock);
- list_for_each_entry(as, &host->addr_space, host_list) {
- if (as->start > addr)
- break;
-
- if (as->end > addr) {
- partlength = min(as->end - addr, (u64) length);
-
- if (as->op->read)
- rcode = as->op->read(host, nodeid, data,
- addr, partlength, flags);
- else
- rcode = RCODE_TYPE_ERROR;
-
- data += partlength;
- length -= partlength;
- addr += partlength;
-
- if ((rcode != RCODE_COMPLETE) || !length)
- break;
- }
- }
- read_unlock(&addr_space_lock);
-
- if (length && (rcode == RCODE_COMPLETE))
- rcode = RCODE_ADDRESS_ERROR;
- return rcode;
-}
-
-int highlevel_write(struct hpsb_host *host, int nodeid, int destid, void *data,
- u64 addr, unsigned int length, u16 flags)
-{
- struct hpsb_address_serve *as;
- unsigned int partlength;
- int rcode = RCODE_ADDRESS_ERROR;
-
- read_lock(&addr_space_lock);
- list_for_each_entry(as, &host->addr_space, host_list) {
- if (as->start > addr)
- break;
-
- if (as->end > addr) {
- partlength = min(as->end - addr, (u64) length);
-
- if (as->op->write)
- rcode = as->op->write(host, nodeid, destid,
- data, addr, partlength,
- flags);
- else
- rcode = RCODE_TYPE_ERROR;
-
- data += partlength;
- length -= partlength;
- addr += partlength;
-
- if ((rcode != RCODE_COMPLETE) || !length)
- break;
- }
- }
- read_unlock(&addr_space_lock);
-
- if (length && (rcode == RCODE_COMPLETE))
- rcode = RCODE_ADDRESS_ERROR;
- return rcode;
-}
-
-int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
- u16 flags)
-{
- struct hpsb_address_serve *as;
- int rcode = RCODE_ADDRESS_ERROR;
-
- read_lock(&addr_space_lock);
- list_for_each_entry(as, &host->addr_space, host_list) {
- if (as->start > addr)
- break;
-
- if (as->end > addr) {
- if (as->op->lock)
- rcode = as->op->lock(host, nodeid, store, addr,
- data, arg, ext_tcode,
- flags);
- else
- rcode = RCODE_TYPE_ERROR;
- break;
- }
- }
- read_unlock(&addr_space_lock);
- return rcode;
-}
-
-int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
- u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
- u16 flags)
-{
- struct hpsb_address_serve *as;
- int rcode = RCODE_ADDRESS_ERROR;
-
- read_lock(&addr_space_lock);
-
- list_for_each_entry(as, &host->addr_space, host_list) {
- if (as->start > addr)
- break;
-
- if (as->end > addr) {
- if (as->op->lock64)
- rcode = as->op->lock64(host, nodeid, store,
- addr, data, arg,
- ext_tcode, flags);
- else
- rcode = RCODE_TYPE_ERROR;
- break;
- }
- }
- read_unlock(&addr_space_lock);
- return rcode;
-}
diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h
deleted file mode 100644
index 9dba89fc60a..00000000000
--- a/drivers/ieee1394/highlevel.h
+++ /dev/null
@@ -1,141 +0,0 @@
-#ifndef IEEE1394_HIGHLEVEL_H
-#define IEEE1394_HIGHLEVEL_H
-
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-
-struct module;
-
-#include "ieee1394_types.h"
-
-struct hpsb_host;
-
-/* internal to ieee1394 core */
-struct hpsb_address_serve {
- struct list_head host_list; /* per host list */
- struct list_head hl_list; /* hpsb_highlevel list */
- const struct hpsb_address_ops *op;
- struct hpsb_host *host;
- u64 start; /* first address handled, quadlet aligned */
- u64 end; /* first address behind, quadlet aligned */
-};
-
-/* Only the following structures are of interest to actual highlevel drivers. */
-
-struct hpsb_highlevel {
- const char *name;
-
- /* Any of the following pointers can legally be NULL. */
-
- /* New host initialized. Will also be called during
- * hpsb_register_highlevel for all hosts already installed. */
- void (*add_host)(struct hpsb_host *host);
-
- /* Host about to be removed. Will also be called during
- * hpsb_unregister_highlevel once for each host. */
- void (*remove_host)(struct hpsb_host *host);
-
- /* Host experienced bus reset with possible configuration changes.
- * Note that this one may occur during interrupt/bottom half handling.
- * You can not expect to be able to do stock hpsb_reads. */
- void (*host_reset)(struct hpsb_host *host);
-
- /* A write request was received on either the FCP_COMMAND (direction =
- * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
- * contains the cts field (first byte of data). */
- void (*fcp_request)(struct hpsb_host *host, int nodeid, int direction,
- int cts, u8 *data, size_t length);
-
- /* These are initialized by the subsystem when the
- * hpsb_higlevel is registered. */
- struct list_head hl_list;
- struct list_head irq_list;
- struct list_head addr_list;
-
- struct list_head host_info_list;
- rwlock_t host_info_lock;
-};
-
-struct hpsb_address_ops {
- /*
- * Null function pointers will make the respective operation complete
- * with RCODE_TYPE_ERROR. Makes for easy to implement read-only
- * registers (just leave everything but read NULL).
- *
- * All functions shall return appropriate IEEE 1394 rcodes.
- */
-
- /* These functions have to implement block reads for themselves.
- *
- * These functions either return a response code or a negative number.
- * In the first case a response will be generated. In the latter case,
- * no response will be sent and the driver which handled the request
- * will send the response itself. */
- int (*read)(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
- u64 addr, size_t length, u16 flags);
- int (*write)(struct hpsb_host *host, int nodeid, int destid,
- quadlet_t *data, u64 addr, size_t length, u16 flags);
-
- /* Lock transactions: write results of ext_tcode operation into
- * *store. */
- int (*lock)(struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
- u16 flags);
- int (*lock64)(struct hpsb_host *host, int nodeid, octlet_t *store,
- u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
- u16 flags);
-};
-
-void highlevel_add_host(struct hpsb_host *host);
-void highlevel_remove_host(struct hpsb_host *host);
-void highlevel_host_reset(struct hpsb_host *host);
-int highlevel_read(struct hpsb_host *host, int nodeid, void *data, u64 addr,
- unsigned int length, u16 flags);
-int highlevel_write(struct hpsb_host *host, int nodeid, int destid, void *data,
- u64 addr, unsigned int length, u16 flags);
-int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
- u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
- u16 flags);
-int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
- u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
- u16 flags);
-void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
- void *data, size_t length);
-
-/**
- * hpsb_init_highlevel - initialize a struct hpsb_highlevel
- *
- * This is only necessary if hpsb_get_hostinfo_bykey can be called
- * before hpsb_register_highlevel.
- */
-static inline void hpsb_init_highlevel(struct hpsb_highlevel *hl)
-{
- rwlock_init(&hl->host_info_lock);
- INIT_LIST_HEAD(&hl->host_info_list);
-}
-void hpsb_register_highlevel(struct hpsb_highlevel *hl);
-void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
-
-u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
- struct hpsb_host *host,
- const struct hpsb_address_ops *ops,
- u64 size, u64 alignment,
- u64 start, u64 end);
-int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
- const struct hpsb_address_ops *ops,
- u64 start, u64 end);
-int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
- u64 start);
-
-void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
-void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
- size_t data_size);
-void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
-void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host,
- unsigned long key);
-void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key);
-int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
- void *data);
-
-#endif /* IEEE1394_HIGHLEVEL_H */
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
deleted file mode 100644
index e947d8ffac8..00000000000
--- a/drivers/ieee1394/hosts.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * Low level (host adapter) management.
- *
- * Copyright (C) 1999 Andreas E. Bombe
- * Copyright (C) 1999 Emanuel Pirker
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
-#include <linux/jiffies.h>
-#include <linux/mutex.h>
-
-#include "csr1212.h"
-#include "ieee1394.h"
-#include "ieee1394_types.h"
-#include "hosts.h"
-#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "nodemgr.h"
-#include "csr.h"
-#include "config_roms.h"
-
-
-static void delayed_reset_bus(struct work_struct *work)
-{
- struct hpsb_host *host =
- container_of(work, struct hpsb_host, delayed_reset.work);
- u8 generation = host->csr.generation + 1;
-
- /* The generation field rolls over to 2 rather than 0 per IEEE
- * 1394a-2000. */
- if (generation > 0xf || generation < 2)
- generation = 2;
-
- csr_set_bus_info_generation(host->csr.rom, generation);
- if (csr1212_generate_csr_image(host->csr.rom) != CSR1212_SUCCESS) {
- /* CSR image creation failed.
- * Reset generation field and do not issue a bus reset. */
- csr_set_bus_info_generation(host->csr.rom,
- host->csr.generation);
- return;
- }
-
- host->csr.generation = generation;
-
- host->update_config_rom = 0;
- if (host->driver->set_hw_config_rom)
- host->driver->set_hw_config_rom(host,
- host->csr.rom->bus_info_data);
-
- host->csr.gen_timestamp[host->csr.generation] = jiffies;
- hpsb_reset_bus(host, SHORT_RESET);
-}
-
-static int dummy_transmit_packet(struct hpsb_host *h, struct hpsb_packet *p)
-{
- return 0;
-}
-
-static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg)
-{
- return -1;
-}
-
-static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command,
- unsigned long arg)
-{
- return -1;
-}
-
-static struct hpsb_host_driver dummy_driver = {
- .transmit_packet = dummy_transmit_packet,
- .devctl = dummy_devctl,
- .isoctl = dummy_isoctl
-};
-
-static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
-{
- int *hostnum = __data;
-
- if (host->id == *hostnum)
- return 1;
-
- return 0;
-}
-
-static DEFINE_MUTEX(host_num_alloc);
-
-/**
- * hpsb_alloc_host - allocate a new host controller.
- * @drv: the driver that will manage the host controller
- * @extra: number of extra bytes to allocate for the driver
- *
- * Allocate a &hpsb_host and initialize the general subsystem specific
- * fields. If the driver needs to store per host data, as drivers
- * usually do, the amount of memory required can be specified by the
- * @extra parameter. Once allocated, the driver should initialize the
- * driver specific parts, enable the controller and make it available
- * to the general subsystem using hpsb_add_host().
- *
- * Return Value: a pointer to the &hpsb_host if successful, %NULL if
- * no memory was available.
- */
-struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
- struct device *dev)
-{
- struct hpsb_host *h;
- int i;
- int hostnum = 0;
-
- h = kzalloc(sizeof(*h) + extra, GFP_KERNEL);
- if (!h)
- return NULL;
-
- h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h);
- if (!h->csr.rom)
- goto fail;
-
- h->hostdata = h + 1;
- h->driver = drv;
-
- INIT_LIST_HEAD(&h->pending_packets);
- INIT_LIST_HEAD(&h->addr_space);
-
- for (i = 2; i < 16; i++)
- h->csr.gen_timestamp[i] = jiffies - 60 * HZ;
-
- atomic_set(&h->generation, 0);
-
- INIT_DELAYED_WORK(&h->delayed_reset, delayed_reset_bus);
-
- init_timer(&h->timeout);
- h->timeout.data = (unsigned long) h;
- h->timeout.function = abort_timedouts;
- h->timeout_interval = HZ / 20; /* 50ms, half of minimum SPLIT_TIMEOUT */
-
- h->topology_map = h->csr.topology_map + 3;
- h->speed_map = (u8 *)(h->csr.speed_map + 2);
-
- mutex_lock(&host_num_alloc);
- while (nodemgr_for_each_host(&hostnum, alloc_hostnum_cb))
- hostnum++;
- mutex_unlock(&host_num_alloc);
- h->id = hostnum;
-
- memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device));
- h->device.parent = dev;
- set_dev_node(&h->device, dev_to_node(dev));
- dev_set_name(&h->device, "fw-host%d", h->id);
-
- h->host_dev.parent = &h->device;
- h->host_dev.class = &hpsb_host_class;
- dev_set_name(&h->host_dev, "fw-host%d", h->id);
-
- if (device_register(&h->device))
- goto fail;
- if (device_register(&h->host_dev)) {
- device_unregister(&h->device);
- goto fail;
- }
- get_device(&h->device);
-
- return h;
-
-fail:
- kfree(h);
- return NULL;
-}
-
-int hpsb_add_host(struct hpsb_host *host)
-{
- if (hpsb_default_host_entry(host))
- return -ENOMEM;
-
- highlevel_add_host(host);
- return 0;
-}
-
-void hpsb_resume_host(struct hpsb_host *host)
-{
- if (host->driver->set_hw_config_rom)
- host->driver->set_hw_config_rom(host,
- host->csr.rom->bus_info_data);
- host->driver->devctl(host, RESET_BUS, SHORT_RESET);
-}
-
-void hpsb_remove_host(struct hpsb_host *host)
-{
- host->is_shutdown = 1;
-
- cancel_delayed_work(&host->delayed_reset);
- flush_scheduled_work();
-
- host->driver = &dummy_driver;
- highlevel_remove_host(host);
-
- device_unregister(&host->host_dev);
- device_unregister(&host->device);
-}
-
-/**
- * hpsb_update_config_rom_image - updates configuration ROM image of a host
- *
- * Updates the configuration ROM image of a host. rom_version must be the
- * current version, otherwise it will fail with return value -1. If this
- * host does not support config-rom-update, it will return -%EINVAL.
- * Return value 0 indicates success.
- */
-int hpsb_update_config_rom_image(struct hpsb_host *host)
-{
- unsigned long reset_delay;
- int next_gen = host->csr.generation + 1;
-
- if (!host->update_config_rom)
- return -EINVAL;
-
- if (next_gen > 0xf)
- next_gen = 2;
-
- /* Stop the delayed interrupt, we're about to change the config rom and
- * it would be a waste to do a bus reset twice. */
- cancel_delayed_work(&host->delayed_reset);
-
- /* IEEE 1394a-2000 prohibits using the same generation number
- * twice in a 60 second period. */
- if (time_before(jiffies, host->csr.gen_timestamp[next_gen] + 60 * HZ))
- /* Wait 60 seconds from the last time this generation number was
- * used. */
- reset_delay =
- (60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
- else
- /* Wait 1 second in case some other code wants to change the
- * Config ROM in the near future. */
- reset_delay = HZ;
-
- PREPARE_DELAYED_WORK(&host->delayed_reset, delayed_reset_bus);
- schedule_delayed_work(&host->delayed_reset, reset_delay);
-
- return 0;
-}
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
deleted file mode 100644
index 49c359022c5..00000000000
--- a/drivers/ieee1394/hosts.h
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifndef _IEEE1394_HOSTS_H
-#define _IEEE1394_HOSTS_H
-
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/types.h>
-#include <linux/workqueue.h>
-#include <asm/atomic.h>
-
-struct pci_dev;
-struct module;
-
-#include "ieee1394_types.h"
-#include "csr.h"
-#include "highlevel.h"
-
-struct hpsb_packet;
-struct hpsb_iso;
-
-struct hpsb_host {
- struct list_head host_list;
-
- void *hostdata;
-
- atomic_t generation;
-
- struct list_head pending_packets;
- struct timer_list timeout;
- unsigned long timeout_interval;
-
- int node_count; /* number of identified nodes on this bus */
- int selfid_count; /* total number of SelfIDs received */
- int nodes_active; /* number of nodes with active link layer */
-
- nodeid_t node_id; /* node ID of this host */
- nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
- nodeid_t busmgr_id; /* ID of this bus' bus manager */
-
- /* this nodes state */
- unsigned in_bus_reset:1;
- unsigned is_shutdown:1;
- unsigned resume_packet_sent:1;
-
- /* this nodes' duties on the bus */
- unsigned is_root:1;
- unsigned is_cycmst:1;
- unsigned is_irm:1;
- unsigned is_busmgr:1;
-
- int reset_retries;
- quadlet_t *topology_map;
- u8 *speed_map;
-
- int id;
- struct hpsb_host_driver *driver;
- struct pci_dev *pdev;
- struct device device;
- struct device host_dev;
-
- struct delayed_work delayed_reset;
- unsigned config_roms:31;
- unsigned update_config_rom:1;
-
- struct list_head addr_space;
- u64 low_addr_space; /* upper bound of physical DMA area */
- u64 middle_addr_space; /* upper bound of posted write area */
-
- u8 speed[ALL_NODES]; /* speed between each node and local node */
-
- /* per node tlabel allocation */
- u8 next_tl[ALL_NODES];
- struct { DECLARE_BITMAP(map, 64); } tl_pool[ALL_NODES];
-
- struct csr_control csr;
-
- struct hpsb_address_serve dummy_zero_addr;
- struct hpsb_address_serve dummy_max_addr;
-};
-
-enum devctl_cmd {
- /* Host is requested to reset its bus and cancel all outstanding async
- * requests. If arg == 1, it shall also attempt to become root on the
- * bus. Return void. */
- RESET_BUS,
-
- /* Arg is void, return value is the hardware cycle counter value. */
- GET_CYCLE_COUNTER,
-
- /* Set the hardware cycle counter to the value in arg, return void.
- * FIXME - setting is probably not required. */
- SET_CYCLE_COUNTER,
-
- /* Configure hardware for new bus ID in arg, return void. */
- SET_BUS_ID,
-
- /* If arg true, start sending cycle start packets, stop if arg == 0.
- * Return void. */
- ACT_CYCLE_MASTER,
-
- /* Cancel all outstanding async requests without resetting the bus.
- * Return void. */
- CANCEL_REQUESTS,
-};
-
-enum isoctl_cmd {
- /* rawiso API - see iso.h for the meanings of these commands
- * (they correspond exactly to the hpsb_iso_* API functions)
- * INIT = allocate resources
- * START = begin transmission/reception
- * STOP = halt transmission/reception
- * QUEUE/RELEASE = produce/consume packets
- * SHUTDOWN = deallocate resources
- */
-
- XMIT_INIT,
- XMIT_START,
- XMIT_STOP,
- XMIT_QUEUE,
- XMIT_SHUTDOWN,
-
- RECV_INIT,
- RECV_LISTEN_CHANNEL, /* multi-channel only */
- RECV_UNLISTEN_CHANNEL, /* multi-channel only */
- RECV_SET_CHANNEL_MASK, /* multi-channel only; arg is a *u64 */
- RECV_START,
- RECV_STOP,
- RECV_RELEASE,
- RECV_SHUTDOWN,
- RECV_FLUSH
-};
-
-enum reset_types {
- /* 166 microsecond reset -- only type of reset available on
- non-1394a capable controllers */
- LONG_RESET,
-
- /* Short (arbitrated) reset -- only available on 1394a capable
- controllers */
- SHORT_RESET,
-
- /* Variants that set force_root before issueing the bus reset */
- LONG_RESET_FORCE_ROOT, SHORT_RESET_FORCE_ROOT,
-
- /* Variants that clear force_root before issueing the bus reset */
- LONG_RESET_NO_FORCE_ROOT, SHORT_RESET_NO_FORCE_ROOT
-};
-
-struct hpsb_host_driver {
- struct module *owner;
- const char *name;
-
- /* The hardware driver may optionally support a function that is used
- * to set the hardware ConfigROM if the hardware supports handling
- * reads to the ConfigROM on its own. */
- void (*set_hw_config_rom)(struct hpsb_host *host,
- __be32 *config_rom);
-
- /* This function shall implement packet transmission based on
- * packet->type. It shall CRC both parts of the packet (unless
- * packet->type == raw) and do byte-swapping as necessary or instruct
- * the hardware to do so. It can return immediately after the packet
- * was queued for sending. After sending, hpsb_sent_packet() has to be
- * called. Return 0 on success, negative errno on failure.
- * NOTE: The function must be callable in interrupt context.
- */
- int (*transmit_packet)(struct hpsb_host *host,
- struct hpsb_packet *packet);
-
- /* This function requests miscellanous services from the driver, see
- * above for command codes and expected actions. Return -1 for unknown
- * command, though that should never happen.
- */
- int (*devctl)(struct hpsb_host *host, enum devctl_cmd command, int arg);
-
- /* ISO transmission/reception functions. Return 0 on success, -1
- * (or -EXXX errno code) on failure. If the low-level driver does not
- * support the new ISO API, set isoctl to NULL.
- */
- int (*isoctl)(struct hpsb_iso *iso, enum isoctl_cmd command,
- unsigned long arg);
-
- /* This function is mainly to redirect local CSR reads/locks to the iso
- * management registers (bus manager id, bandwidth available, channels
- * available) to the hardware registers in OHCI. reg is 0,1,2,3 for bus
- * mgr, bwdth avail, ch avail hi, ch avail lo respectively (the same ids
- * as OHCI uses). data and compare are the new data and expected data
- * respectively, return value is the old value.
- */
- quadlet_t (*hw_csr_reg) (struct hpsb_host *host, int reg,
- quadlet_t data, quadlet_t compare);
-};
-
-struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
- struct device *dev);
-int hpsb_add_host(struct hpsb_host *host);
-void hpsb_resume_host(struct hpsb_host *host);
-void hpsb_remove_host(struct hpsb_host *host);
-int hpsb_update_config_rom_image(struct hpsb_host *host);
-
-#endif /* _IEEE1394_HOSTS_H */
diff --git a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h
deleted file mode 100644
index 46878fef136..00000000000
--- a/drivers/ieee1394/ieee1394-ioctl.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Base file for all ieee1394 ioctl's.
- * Linux-1394 has allocated base '#' with a range of 0x00-0x3f.
- */
-
-#ifndef __IEEE1394_IOCTL_H
-#define __IEEE1394_IOCTL_H
-
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
-/* DV1394 Gets 10 */
-
-/* Get the driver ready to transmit video. pass a struct dv1394_init* as
- * the parameter (see below), or NULL to get default parameters */
-#define DV1394_IOC_INIT _IOW('#', 0x06, struct dv1394_init)
-
-/* Stop transmitting video and free the ringbuffer */
-#define DV1394_IOC_SHUTDOWN _IO ('#', 0x07)
-
-/* Submit N new frames to be transmitted, where the index of the first new
- * frame is first_clear_buffer, and the index of the last new frame is
- * (first_clear_buffer + N) % n_frames */
-#define DV1394_IOC_SUBMIT_FRAMES _IO ('#', 0x08)
-
-/* Block until N buffers are clear (pass N as the parameter) Because we
- * re-transmit the last frame on underrun, there will at most be n_frames
- * - 1 clear frames at any time */
-#define DV1394_IOC_WAIT_FRAMES _IO ('#', 0x09)
-
-/* Capture new frames that have been received, where the index of the
- * first new frame is first_clear_buffer, and the index of the last new
- * frame is (first_clear_buffer + N) % n_frames */
-#define DV1394_IOC_RECEIVE_FRAMES _IO ('#', 0x0a)
-
-/* Tell card to start receiving DMA */
-#define DV1394_IOC_START_RECEIVE _IO ('#', 0x0b)
-
-/* Pass a struct dv1394_status* as the parameter */
-#define DV1394_IOC_GET_STATUS _IOR('#', 0x0c, struct dv1394_status)
-
-
-/* Video1394 Gets 10 */
-
-#define VIDEO1394_IOC_LISTEN_CHANNEL \
- _IOWR('#', 0x10, struct video1394_mmap)
-#define VIDEO1394_IOC_UNLISTEN_CHANNEL \
- _IOW ('#', 0x11, int)
-#define VIDEO1394_IOC_LISTEN_QUEUE_BUFFER \
- _IOW ('#', 0x12, struct video1394_wait)
-#define VIDEO1394_IOC_LISTEN_WAIT_BUFFER \
- _IOWR('#', 0x13, struct video1394_wait)
-#define VIDEO1394_IOC_TALK_CHANNEL \
- _IOWR('#', 0x14, struct video1394_mmap)
-#define VIDEO1394_IOC_UNTALK_CHANNEL \
- _IOW ('#', 0x15, int)
-/*
- * This one is broken: it really wanted
- * "sizeof (struct video1394_wait) + sizeof (struct video1394_queue_variable)"
- * but got just a "size_t"
- */
-#define VIDEO1394_IOC_TALK_QUEUE_BUFFER \
- _IOW ('#', 0x16, size_t)
-#define VIDEO1394_IOC_TALK_WAIT_BUFFER \
- _IOW ('#', 0x17, struct video1394_wait)
-#define VIDEO1394_IOC_LISTEN_POLL_BUFFER \
- _IOWR('#', 0x18, struct video1394_wait)
-
-
-/* Raw1394's ISO interface */
-#define RAW1394_IOC_ISO_XMIT_INIT \
- _IOW ('#', 0x1a, struct raw1394_iso_status)
-#define RAW1394_IOC_ISO_RECV_INIT \
- _IOWR('#', 0x1b, struct raw1394_iso_status)
-#define RAW1394_IOC_ISO_RECV_START \
- _IOC (_IOC_WRITE, '#', 0x1c, sizeof(int) * 3)
-#define RAW1394_IOC_ISO_XMIT_START \
- _IOC (_IOC_WRITE, '#', 0x1d, sizeof(int) * 2)
-#define RAW1394_IOC_ISO_XMIT_RECV_STOP \
- _IO ('#', 0x1e)
-#define RAW1394_IOC_ISO_GET_STATUS \
- _IOR ('#', 0x1f, struct raw1394_iso_status)
-#define RAW1394_IOC_ISO_SHUTDOWN \
- _IO ('#', 0x20)
-#define RAW1394_IOC_ISO_QUEUE_ACTIVITY \
- _IO ('#', 0x21)
-#define RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL \
- _IOW ('#', 0x22, unsigned char)
-#define RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL \
- _IOW ('#', 0x23, unsigned char)
-#define RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK \
- _IOW ('#', 0x24, __u64)
-#define RAW1394_IOC_ISO_RECV_PACKETS \
- _IOW ('#', 0x25, struct raw1394_iso_packets)
-#define RAW1394_IOC_ISO_RECV_RELEASE_PACKETS \
- _IOW ('#', 0x26, unsigned int)
-#define RAW1394_IOC_ISO_XMIT_PACKETS \
- _IOW ('#', 0x27, struct raw1394_iso_packets)
-#define RAW1394_IOC_ISO_XMIT_SYNC \
- _IO ('#', 0x28)
-#define RAW1394_IOC_ISO_RECV_FLUSH \
- _IO ('#', 0x29)
-#define RAW1394_IOC_GET_CYCLE_TIMER \
- _IOR ('#', 0x30, struct raw1394_cycle_timer)
-
-#endif /* __IEEE1394_IOCTL_H */
diff --git a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h
deleted file mode 100644
index af320e2c507..00000000000
--- a/drivers/ieee1394/ieee1394.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Generic IEEE 1394 definitions
- */
-
-#ifndef _IEEE1394_IEEE1394_H
-#define _IEEE1394_IEEE1394_H
-
-#define TCODE_WRITEQ 0x0
-#define TCODE_WRITEB 0x1
-#define TCODE_WRITE_RESPONSE 0x2
-#define TCODE_READQ 0x4
-#define TCODE_READB 0x5
-#define TCODE_READQ_RESPONSE 0x6
-#define TCODE_READB_RESPONSE 0x7
-#define TCODE_CYCLE_START 0x8
-#define TCODE_LOCK_REQUEST 0x9
-#define TCODE_ISO_DATA 0xa
-#define TCODE_STREAM_DATA 0xa
-#define TCODE_LOCK_RESPONSE 0xb
-
-#define RCODE_COMPLETE 0x0
-#define RCODE_CONFLICT_ERROR 0x4
-#define RCODE_DATA_ERROR 0x5
-#define RCODE_TYPE_ERROR 0x6
-#define RCODE_ADDRESS_ERROR 0x7
-
-#define EXTCODE_MASK_SWAP 0x1
-#define EXTCODE_COMPARE_SWAP 0x2
-#define EXTCODE_FETCH_ADD 0x3
-#define EXTCODE_LITTLE_ADD 0x4
-#define EXTCODE_BOUNDED_ADD 0x5
-#define EXTCODE_WRAP_ADD 0x6
-
-#define ACK_COMPLETE 0x1
-#define ACK_PENDING 0x2
-#define ACK_BUSY_X 0x4
-#define ACK_BUSY_A 0x5
-#define ACK_BUSY_B 0x6
-#define ACK_TARDY 0xb
-#define ACK_CONFLICT_ERROR 0xc
-#define ACK_DATA_ERROR 0xd
-#define ACK_TYPE_ERROR 0xe
-#define ACK_ADDRESS_ERROR 0xf
-
-/* Non-standard "ACK codes" for internal use */
-#define ACKX_NONE (-1)
-#define ACKX_SEND_ERROR (-2)
-#define ACKX_ABORTED (-3)
-#define ACKX_TIMEOUT (-4)
-
-#define IEEE1394_SPEED_100 0x00
-#define IEEE1394_SPEED_200 0x01
-#define IEEE1394_SPEED_400 0x02
-#define IEEE1394_SPEED_800 0x03
-#define IEEE1394_SPEED_1600 0x04
-#define IEEE1394_SPEED_3200 0x05
-#define IEEE1394_SPEED_MAX IEEE1394_SPEED_3200
-
-/* Maps speed values above to a string representation */
-extern const char *hpsb_speedto_str[];
-
-/* 1394a cable PHY packets */
-#define SELFID_PWRCL_NO_POWER 0x0
-#define SELFID_PWRCL_PROVIDE_15W 0x1
-#define SELFID_PWRCL_PROVIDE_30W 0x2
-#define SELFID_PWRCL_PROVIDE_45W 0x3
-#define SELFID_PWRCL_USE_1W 0x4
-#define SELFID_PWRCL_USE_3W 0x5
-#define SELFID_PWRCL_USE_6W 0x6
-#define SELFID_PWRCL_USE_10W 0x7
-
-#define SELFID_PORT_CHILD 0x3
-#define SELFID_PORT_PARENT 0x2
-#define SELFID_PORT_NCONN 0x1
-#define SELFID_PORT_NONE 0x0
-
-#define SELFID_SPEED_UNKNOWN 0x3 /* 1394b PHY */
-
-#define PHYPACKET_LINKON 0x40000000
-#define PHYPACKET_PHYCONFIG_R 0x00800000
-#define PHYPACKET_PHYCONFIG_T 0x00400000
-#define EXTPHYPACKET_TYPE_PING 0x00000000
-#define EXTPHYPACKET_TYPE_REMOTEACCESS_BASE 0x00040000
-#define EXTPHYPACKET_TYPE_REMOTEACCESS_PAGED 0x00140000
-#define EXTPHYPACKET_TYPE_REMOTEREPLY_BASE 0x000C0000
-#define EXTPHYPACKET_TYPE_REMOTEREPLY_PAGED 0x001C0000
-#define EXTPHYPACKET_TYPE_REMOTECOMMAND 0x00200000
-#define EXTPHYPACKET_TYPE_REMOTECONFIRMATION 0x00280000
-#define EXTPHYPACKET_TYPE_RESUME 0x003C0000
-
-#define EXTPHYPACKET_TYPEMASK 0xC0FC0000
-
-#define PHYPACKET_PORT_SHIFT 24
-#define PHYPACKET_GAPCOUNT_SHIFT 16
-
-/* 1394a PHY register map bitmasks */
-#define PHY_00_PHYSICAL_ID 0xFC
-#define PHY_00_R 0x02 /* Root */
-#define PHY_00_PS 0x01 /* Power Status*/
-#define PHY_01_RHB 0x80 /* Root Hold-Off */
-#define PHY_01_IBR 0x80 /* Initiate Bus Reset */
-#define PHY_01_GAP_COUNT 0x3F
-#define PHY_02_EXTENDED 0xE0 /* 0x7 for 1394a-compliant PHY */
-#define PHY_02_TOTAL_PORTS 0x1F
-#define PHY_03_MAX_SPEED 0xE0
-#define PHY_03_DELAY 0x0F
-#define PHY_04_LCTRL 0x80 /* Link Active Report Control */
-#define PHY_04_CONTENDER 0x40
-#define PHY_04_JITTER 0x38
-#define PHY_04_PWR_CLASS 0x07 /* Power Class */
-#define PHY_05_WATCHDOG 0x80
-#define PHY_05_ISBR 0x40 /* Initiate Short Bus Reset */
-#define PHY_05_LOOP 0x20 /* Loop Detect */
-#define PHY_05_PWR_FAIL 0x10 /* Cable Power Failure Detect */
-#define PHY_05_TIMEOUT 0x08 /* Arbitration State Machine Timeout */
-#define PHY_05_PORT_EVENT 0x04 /* Port Event Detect */
-#define PHY_05_ENAB_ACCEL 0x02 /* Enable Arbitration Acceleration */
-#define PHY_05_ENAB_MULTI 0x01 /* Ena. Multispeed Packet Concatenation */
-
-#include <asm/byteorder.h>
-
-/* '1' '3' '9' '4' in ASCII */
-#define IEEE1394_BUSID_MAGIC cpu_to_be32(0x31333934)
-
-#ifdef __BIG_ENDIAN_BITFIELD
-
-struct selfid {
- u32 packet_identifier:2; /* always binary 10 */
- u32 phy_id:6;
- /* byte */
- u32 extended:1; /* if true is struct ext_selfid */
- u32 link_active:1;
- u32 gap_count:6;
- /* byte */
- u32 speed:2;
- u32 phy_delay:2;
- u32 contender:1;
- u32 power_class:3;
- /* byte */
- u32 port0:2;
- u32 port1:2;
- u32 port2:2;
- u32 initiated_reset:1;
- u32 more_packets:1;
-} __attribute__((packed));
-
-struct ext_selfid {
- u32 packet_identifier:2; /* always binary 10 */
- u32 phy_id:6;
- /* byte */
- u32 extended:1; /* if false is struct selfid */
- u32 seq_nr:3;
- u32 reserved:2;
- u32 porta:2;
- /* byte */
- u32 portb:2;
- u32 portc:2;
- u32 portd:2;
- u32 porte:2;
- /* byte */
- u32 portf:2;
- u32 portg:2;
- u32 porth:2;
- u32 reserved2:1;
- u32 more_packets:1;
-} __attribute__((packed));
-
-#elif defined __LITTLE_ENDIAN_BITFIELD /* __BIG_ENDIAN_BITFIELD */
-
-/*
- * Note: these mean to be bit fields of a big endian SelfID as seen on a little
- * endian machine. Without swapping.
- */
-
-struct selfid {
- u32 phy_id:6;
- u32 packet_identifier:2; /* always binary 10 */
- /* byte */
- u32 gap_count:6;
- u32 link_active:1;
- u32 extended:1; /* if true is struct ext_selfid */
- /* byte */
- u32 power_class:3;
- u32 contender:1;
- u32 phy_delay:2;
- u32 speed:2;
- /* byte */
- u32 more_packets:1;
- u32 initiated_reset:1;
- u32 port2:2;
- u32 port1:2;
- u32 port0:2;
-} __attribute__((packed));
-
-struct ext_selfid {
- u32 phy_id:6;
- u32 packet_identifier:2; /* always binary 10 */
- /* byte */
- u32 porta:2;
- u32 reserved:2;
- u32 seq_nr:3;
- u32 extended:1; /* if false is struct selfid */
- /* byte */
- u32 porte:2;
- u32 portd:2;
- u32 portc:2;
- u32 portb:2;
- /* byte */
- u32 more_packets:1;
- u32 reserved2:1;
- u32 porth:2;
- u32 portg:2;
- u32 portf:2;
-} __attribute__((packed));
-
-#else
-#error What? PDP endian?
-#endif /* __BIG_ENDIAN_BITFIELD */
-
-#endif /* _IEEE1394_IEEE1394_H */
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
deleted file mode 100644
index 87233800372..00000000000
--- a/drivers/ieee1394/ieee1394_core.c
+++ /dev/null
@@ -1,1380 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * Core support: hpsb_packet management, packet handling and forwarding to
- * highlevel or lowlevel code
- *
- * Copyright (C) 1999, 2000 Andreas E. Bombe
- * 2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- *
- *
- * Contributions:
- *
- * Manfred Weihs <weihs@ict.tuwien.ac.at>
- * loopback functionality in hpsb_send_packet
- * allow highlevel drivers to disable automatic response generation
- * and to generate responses themselves (deferred)
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/bitops.h>
-#include <linux/kdev_t.h>
-#include <linux/freezer.h>
-#include <linux/suspend.h>
-#include <linux/kthread.h>
-#include <linux/preempt.h>
-#include <linux/time.h>
-
-#include <asm/system.h>
-#include <asm/byteorder.h>
-
-#include "ieee1394_types.h"
-#include "ieee1394.h"
-#include "hosts.h"
-#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "ieee1394_transactions.h"
-#include "csr.h"
-#include "nodemgr.h"
-#include "dma.h"
-#include "iso.h"
-#include "config_roms.h"
-
-/*
- * Disable the nodemgr detection and config rom reading functionality.
- */
-static int disable_nodemgr;
-module_param(disable_nodemgr, int, 0444);
-MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
-
-/* Disable Isochronous Resource Manager functionality */
-int hpsb_disable_irm = 0;
-module_param_named(disable_irm, hpsb_disable_irm, bool, 0444);
-MODULE_PARM_DESC(disable_irm,
- "Disable Isochronous Resource Manager functionality.");
-
-/* We are GPL, so treat us special */
-MODULE_LICENSE("GPL");
-
-/* Some globals used */
-const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
-struct class *hpsb_protocol_class;
-
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-static void dump_packet(const char *text, quadlet_t *data, int size, int speed)
-{
- int i;
-
- size /= 4;
- size = (size > 4 ? 4 : size);
-
- printk(KERN_DEBUG "ieee1394: %s", text);
- if (speed > -1 && speed < 6)
- printk(" at %s", hpsb_speedto_str[speed]);
- printk(":");
- for (i = 0; i < size; i++)
- printk(" %08x", data[i]);
- printk("\n");
-}
-#else
-#define dump_packet(a,b,c,d) do {} while (0)
-#endif
-
-static void abort_requests(struct hpsb_host *host);
-static void queue_packet_complete(struct hpsb_packet *packet);
-
-
-/**
- * hpsb_set_packet_complete_task - set task that runs when a packet completes
- * @packet: the packet whose completion we want the task added to
- * @routine: function to call
- * @data: data (if any) to pass to the above function
- *
- * Set the task that runs when a packet completes. You cannot call this more
- * than once on a single packet before it is sent.
- *
- * Typically, the complete @routine is responsible to call hpsb_free_packet().
- */
-void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
- void (*routine)(void *), void *data)
-{
- WARN_ON(packet->complete_routine != NULL);
- packet->complete_routine = routine;
- packet->complete_data = data;
- return;
-}
-
-/**
- * hpsb_alloc_packet - allocate new packet structure
- * @data_size: size of the data block to be allocated, in bytes
- *
- * This function allocates, initializes and returns a new &struct hpsb_packet.
- * It can be used in interrupt context. A header block is always included and
- * initialized with zeros. Its size is big enough to contain all possible 1394
- * headers. The data block is only allocated if @data_size is not zero.
- *
- * For packets for which responses will be received the @data_size has to be big
- * enough to contain the response's data block since no further allocation
- * occurs at response matching time.
- *
- * The packet's generation value will be set to the current generation number
- * for ease of use. Remember to overwrite it with your own recorded generation
- * number if you can not be sure that your code will not race with a bus reset.
- *
- * Return value: A pointer to a &struct hpsb_packet or NULL on allocation
- * failure.
- */
-struct hpsb_packet *hpsb_alloc_packet(size_t data_size)
-{
- struct hpsb_packet *packet;
-
- data_size = ((data_size + 3) & ~3);
-
- packet = kzalloc(sizeof(*packet) + data_size, GFP_ATOMIC);
- if (!packet)
- return NULL;
-
- packet->state = hpsb_unused;
- packet->generation = -1;
- INIT_LIST_HEAD(&packet->driver_list);
- INIT_LIST_HEAD(&packet->queue);
- atomic_set(&packet->refcnt, 1);
-
- if (data_size) {
- packet->data = packet->embedded_data;
- packet->allocated_data_size = data_size;
- }
- return packet;
-}
-
-/**
- * hpsb_free_packet - free packet and data associated with it
- * @packet: packet to free (is NULL safe)
- *
- * Frees @packet->data only if it was allocated through hpsb_alloc_packet().
- */
-void hpsb_free_packet(struct hpsb_packet *packet)
-{
- if (packet && atomic_dec_and_test(&packet->refcnt)) {
- BUG_ON(!list_empty(&packet->driver_list) ||
- !list_empty(&packet->queue));
- kfree(packet);
- }
-}
-
-/**
- * hpsb_reset_bus - initiate bus reset on the given host
- * @host: host controller whose bus to reset
- * @type: one of enum reset_types
- *
- * Returns 1 if bus reset already in progress, 0 otherwise.
- */
-int hpsb_reset_bus(struct hpsb_host *host, int type)
-{
- if (!host->in_bus_reset) {
- host->driver->devctl(host, RESET_BUS, type);
- return 0;
- } else {
- return 1;
- }
-}
-
-/**
- * hpsb_read_cycle_timer - read cycle timer register and system time
- * @host: host whose isochronous cycle timer register is read
- * @cycle_timer: address of bitfield to return the register contents
- * @local_time: address to return the system time
- *
- * The format of * @cycle_timer, is described in OHCI 1.1 clause 5.13. This
- * format is also read from non-OHCI controllers. * @local_time contains the
- * system time in microseconds since the Epoch, read at the moment when the
- * cycle timer was read.
- *
- * Return value: 0 for success or error number otherwise.
- */
-int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
- u64 *local_time)
-{
- int ctr;
- struct timeval tv;
- unsigned long flags;
-
- if (!host || !cycle_timer || !local_time)
- return -EINVAL;
-
- preempt_disable();
- local_irq_save(flags);
-
- ctr = host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
- if (ctr)
- do_gettimeofday(&tv);
-
- local_irq_restore(flags);
- preempt_enable();
-
- if (!ctr)
- return -EIO;
- *cycle_timer = ctr;
- *local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
- return 0;
-}
-
-/**
- * hpsb_bus_reset - notify a bus reset to the core
- *
- * For host driver module usage. Safe to use in interrupt context, although
- * quite complex; so you may want to run it in the bottom rather than top half.
- *
- * Returns 1 if bus reset already in progress, 0 otherwise.
- */
-int hpsb_bus_reset(struct hpsb_host *host)
-{
- if (host->in_bus_reset) {
- HPSB_NOTICE("%s called while bus reset already in progress",
- __func__);
- return 1;
- }
-
- abort_requests(host);
- host->in_bus_reset = 1;
- host->irm_id = -1;
- host->is_irm = 0;
- host->busmgr_id = -1;
- host->is_busmgr = 0;
- host->is_cycmst = 0;
- host->node_count = 0;
- host->selfid_count = 0;
-
- return 0;
-}
-
-
-/*
- * Verify num_of_selfids SelfIDs and return number of nodes. Return zero in
- * case verification failed.
- */
-static int check_selfids(struct hpsb_host *host)
-{
- int nodeid = -1;
- int rest_of_selfids = host->selfid_count;
- struct selfid *sid = (struct selfid *)host->topology_map;
- struct ext_selfid *esid;
- int esid_seq = 23;
-
- host->nodes_active = 0;
-
- while (rest_of_selfids--) {
- if (!sid->extended) {
- nodeid++;
- esid_seq = 0;
-
- if (sid->phy_id != nodeid) {
- HPSB_INFO("SelfIDs failed monotony check with "
- "%d", sid->phy_id);
- return 0;
- }
-
- if (sid->link_active) {
- host->nodes_active++;
- if (sid->contender)
- host->irm_id = LOCAL_BUS | sid->phy_id;
- }
- } else {
- esid = (struct ext_selfid *)sid;
-
- if ((esid->phy_id != nodeid)
- || (esid->seq_nr != esid_seq)) {
- HPSB_INFO("SelfIDs failed monotony check with "
- "%d/%d", esid->phy_id, esid->seq_nr);
- return 0;
- }
- esid_seq++;
- }
- sid++;
- }
-
- esid = (struct ext_selfid *)(sid - 1);
- while (esid->extended) {
- if ((esid->porta == SELFID_PORT_PARENT) ||
- (esid->portb == SELFID_PORT_PARENT) ||
- (esid->portc == SELFID_PORT_PARENT) ||
- (esid->portd == SELFID_PORT_PARENT) ||
- (esid->porte == SELFID_PORT_PARENT) ||
- (esid->portf == SELFID_PORT_PARENT) ||
- (esid->portg == SELFID_PORT_PARENT) ||
- (esid->porth == SELFID_PORT_PARENT)) {
- HPSB_INFO("SelfIDs failed root check on "
- "extended SelfID");
- return 0;
- }
- esid--;
- }
-
- sid = (struct selfid *)esid;
- if ((sid->port0 == SELFID_PORT_PARENT) ||
- (sid->port1 == SELFID_PORT_PARENT) ||
- (sid->port2 == SELFID_PORT_PARENT)) {
- HPSB_INFO("SelfIDs failed root check");
- return 0;
- }
-
- host->node_count = nodeid + 1;
- return 1;
-}
-
-static void build_speed_map(struct hpsb_host *host, int nodecount)
-{
- u8 cldcnt[nodecount];
- u8 *map = host->speed_map;
- u8 *speedcap = host->speed;
- u8 local_link_speed = host->csr.lnk_spd;
- struct selfid *sid;
- struct ext_selfid *esid;
- int i, j, n;
-
- for (i = 0; i < (nodecount * 64); i += 64) {
- for (j = 0; j < nodecount; j++) {
- map[i+j] = IEEE1394_SPEED_MAX;
- }
- }
-
- for (i = 0; i < nodecount; i++) {
- cldcnt[i] = 0;
- }
-
- /* find direct children count and speed */
- for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1],
- n = nodecount - 1;
- (void *)sid >= (void *)host->topology_map; sid--) {
- if (sid->extended) {
- esid = (struct ext_selfid *)sid;
-
- if (esid->porta == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portb == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portc == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portd == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->porte == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portf == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portg == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->porth == SELFID_PORT_CHILD) cldcnt[n]++;
- } else {
- if (sid->port0 == SELFID_PORT_CHILD) cldcnt[n]++;
- if (sid->port1 == SELFID_PORT_CHILD) cldcnt[n]++;
- if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++;
-
- speedcap[n] = sid->speed;
- if (speedcap[n] > local_link_speed)
- speedcap[n] = local_link_speed;
- n--;
- }
- }
-
- /* set self mapping */
- for (i = 0; i < nodecount; i++) {
- map[64*i + i] = speedcap[i];
- }
-
- /* fix up direct children count to total children count;
- * also fix up speedcaps for sibling and parent communication */
- for (i = 1; i < nodecount; i++) {
- for (j = cldcnt[i], n = i - 1; j > 0; j--) {
- cldcnt[i] += cldcnt[n];
- speedcap[n] = min(speedcap[n], speedcap[i]);
- n -= cldcnt[n] + 1;
- }
- }
-
- for (n = 0; n < nodecount; n++) {
- for (i = n - cldcnt[n]; i <= n; i++) {
- for (j = 0; j < (n - cldcnt[n]); j++) {
- map[j*64 + i] = map[i*64 + j] =
- min(map[i*64 + j], speedcap[n]);
- }
- for (j = n + 1; j < nodecount; j++) {
- map[j*64 + i] = map[i*64 + j] =
- min(map[i*64 + j], speedcap[n]);
- }
- }
- }
-
- /* assume a maximum speed for 1394b PHYs, nodemgr will correct it */
- if (local_link_speed > SELFID_SPEED_UNKNOWN)
- for (i = 0; i < nodecount; i++)
- if (speedcap[i] == SELFID_SPEED_UNKNOWN)
- speedcap[i] = local_link_speed;
-}
-
-
-/**
- * hpsb_selfid_received - hand over received selfid packet to the core
- *
- * For host driver module usage. Safe to use in interrupt context.
- *
- * The host driver should have done a successful complement check (second
- * quadlet is complement of first) beforehand.
- */
-void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
-{
- if (host->in_bus_reset) {
- HPSB_VERBOSE("Including SelfID 0x%x", sid);
- host->topology_map[host->selfid_count++] = sid;
- } else {
- HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
- sid, NODEID_TO_BUS(host->node_id));
- }
-}
-
-/**
- * hpsb_selfid_complete - notify completion of SelfID stage to the core
- *
- * For host driver module usage. Safe to use in interrupt context, although
- * quite complex; so you may want to run it in the bottom rather than top half.
- *
- * Notify completion of SelfID stage to the core and report new physical ID
- * and whether host is root now.
- */
-void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
-{
- if (!host->in_bus_reset)
- HPSB_NOTICE("SelfID completion called outside of bus reset!");
-
- host->node_id = LOCAL_BUS | phyid;
- host->is_root = isroot;
-
- if (!check_selfids(host)) {
- if (host->reset_retries++ < 20) {
- /* selfid stage did not complete without error */
- HPSB_NOTICE("Error in SelfID stage, resetting");
- host->in_bus_reset = 0;
- /* this should work from ohci1394 now... */
- hpsb_reset_bus(host, LONG_RESET);
- return;
- } else {
- HPSB_NOTICE("Stopping out-of-control reset loop");
- HPSB_NOTICE("Warning - topology map and speed map will not be valid");
- host->reset_retries = 0;
- }
- } else {
- host->reset_retries = 0;
- build_speed_map(host, host->node_count);
- }
-
- HPSB_VERBOSE("selfid_complete called with successful SelfID stage "
- "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id);
-
- /* irm_id is kept up to date by check_selfids() */
- if (host->irm_id == host->node_id) {
- host->is_irm = 1;
- } else {
- host->is_busmgr = 0;
- host->is_irm = 0;
- }
-
- if (isroot) {
- host->driver->devctl(host, ACT_CYCLE_MASTER, 1);
- host->is_cycmst = 1;
- }
- atomic_inc(&host->generation);
- host->in_bus_reset = 0;
- highlevel_host_reset(host);
-}
-
-static DEFINE_SPINLOCK(pending_packets_lock);
-
-/**
- * hpsb_packet_sent - notify core of sending a packet
- *
- * For host driver module usage. Safe to call from within a transmit packet
- * routine.
- *
- * Notify core of sending a packet. Ackcode is the ack code returned for async
- * transmits or ACKX_SEND_ERROR if the transmission failed completely; ACKX_NONE
- * for other cases (internal errors that don't justify a panic).
- */
-void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
- int ackcode)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&pending_packets_lock, flags);
-
- packet->ack_code = ackcode;
-
- if (packet->no_waiter || packet->state == hpsb_complete) {
- /* if packet->no_waiter, must not have a tlabel allocated */
- spin_unlock_irqrestore(&pending_packets_lock, flags);
- hpsb_free_packet(packet);
- return;
- }
-
- atomic_dec(&packet->refcnt); /* drop HC's reference */
- /* here the packet must be on the host->pending_packets queue */
-
- if (ackcode != ACK_PENDING || !packet->expect_response) {
- packet->state = hpsb_complete;
- list_del_init(&packet->queue);
- spin_unlock_irqrestore(&pending_packets_lock, flags);
- queue_packet_complete(packet);
- return;
- }
-
- packet->state = hpsb_pending;
- packet->sendtime = jiffies;
-
- spin_unlock_irqrestore(&pending_packets_lock, flags);
-
- mod_timer(&host->timeout, jiffies + host->timeout_interval);
-}
-
-/**
- * hpsb_send_phy_config - transmit a PHY configuration packet on the bus
- * @host: host that PHY config packet gets sent through
- * @rootid: root whose force_root bit should get set (-1 = don't set force_root)
- * @gapcnt: gap count value to set (-1 = don't set gap count)
- *
- * This function sends a PHY config packet on the bus through the specified
- * host.
- *
- * Return value: 0 for success or negative error number otherwise.
- */
-int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
-{
- struct hpsb_packet *packet;
- quadlet_t d = 0;
- int retval = 0;
-
- if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 ||
- (rootid == -1 && gapcnt == -1)) {
- HPSB_DEBUG("Invalid Parameter: rootid = %d gapcnt = %d",
- rootid, gapcnt);
- return -EINVAL;
- }
-
- if (rootid != -1)
- d |= PHYPACKET_PHYCONFIG_R | rootid << PHYPACKET_PORT_SHIFT;
- if (gapcnt != -1)
- d |= PHYPACKET_PHYCONFIG_T | gapcnt << PHYPACKET_GAPCOUNT_SHIFT;
-
- packet = hpsb_make_phypacket(host, d);
- if (!packet)
- return -ENOMEM;
-
- packet->generation = get_hpsb_generation(host);
- retval = hpsb_send_packet_and_wait(packet);
- hpsb_free_packet(packet);
-
- return retval;
-}
-
-/**
- * hpsb_send_packet - transmit a packet on the bus
- * @packet: packet to send
- *
- * The packet is sent through the host specified in the packet->host field.
- * Before sending, the packet's transmit speed is automatically determined
- * using the local speed map when it is an async, non-broadcast packet.
- *
- * Possibilities for failure are that host is either not initialized, in bus
- * reset, the packet's generation number doesn't match the current generation
- * number or the host reports a transmit error.
- *
- * Return value: 0 on success, negative errno on failure.
- */
-int hpsb_send_packet(struct hpsb_packet *packet)
-{
- struct hpsb_host *host = packet->host;
-
- if (host->is_shutdown)
- return -EINVAL;
- if (host->in_bus_reset ||
- (packet->generation != get_hpsb_generation(host)))
- return -EAGAIN;
-
- packet->state = hpsb_queued;
-
- /* This just seems silly to me */
- WARN_ON(packet->no_waiter && packet->expect_response);
-
- if (!packet->no_waiter || packet->expect_response) {
- unsigned long flags;
-
- atomic_inc(&packet->refcnt);
- /* Set the initial "sendtime" to 10 seconds from now, to
- prevent premature expiry. If a packet takes more than
- 10 seconds to hit the wire, we have bigger problems :) */
- packet->sendtime = jiffies + 10 * HZ;
- spin_lock_irqsave(&pending_packets_lock, flags);
- list_add_tail(&packet->queue, &host->pending_packets);
- spin_unlock_irqrestore(&pending_packets_lock, flags);
- }
-
- if (packet->node_id == host->node_id) {
- /* it is a local request, so handle it locally */
-
- quadlet_t *data;
- size_t size = packet->data_size + packet->header_size;
-
- data = kmalloc(size, GFP_ATOMIC);
- if (!data) {
- HPSB_ERR("unable to allocate memory for concatenating header and data");
- return -ENOMEM;
- }
-
- memcpy(data, packet->header, packet->header_size);
-
- if (packet->data_size)
- memcpy(((u8*)data) + packet->header_size, packet->data, packet->data_size);
-
- dump_packet("send packet local", packet->header, packet->header_size, -1);
-
- hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE);
- hpsb_packet_received(host, data, size, 0);
-
- kfree(data);
-
- return 0;
- }
-
- if (packet->type == hpsb_async &&
- NODEID_TO_NODE(packet->node_id) != ALL_NODES)
- packet->speed_code =
- host->speed[NODEID_TO_NODE(packet->node_id)];
-
- dump_packet("send packet", packet->header, packet->header_size, packet->speed_code);
-
- return host->driver->transmit_packet(host, packet);
-}
-
-/* We could just use complete() directly as the packet complete
- * callback, but this is more typesafe, in the sense that we get a
- * compiler error if the prototype for complete() changes. */
-
-static void complete_packet(void *data)
-{
- complete((struct completion *) data);
-}
-
-/**
- * hpsb_send_packet_and_wait - enqueue packet, block until transaction completes
- * @packet: packet to send
- *
- * Return value: 0 on success, negative errno on failure.
- */
-int hpsb_send_packet_and_wait(struct hpsb_packet *packet)
-{
- struct completion done;
- int retval;
-
- init_completion(&done);
- hpsb_set_packet_complete_task(packet, complete_packet, &done);
- retval = hpsb_send_packet(packet);
- if (retval == 0)
- wait_for_completion(&done);
-
- return retval;
-}
-
-static void send_packet_nocare(struct hpsb_packet *packet)
-{
- if (hpsb_send_packet(packet) < 0) {
- hpsb_free_packet(packet);
- }
-}
-
-static size_t packet_size_to_data_size(size_t packet_size, size_t header_size,
- size_t buffer_size, int tcode)
-{
- size_t ret = packet_size <= header_size ? 0 : packet_size - header_size;
-
- if (unlikely(ret > buffer_size))
- ret = buffer_size;
-
- if (unlikely(ret + header_size != packet_size))
- HPSB_ERR("unexpected packet size %zd (tcode %d), bug?",
- packet_size, tcode);
- return ret;
-}
-
-static void handle_packet_response(struct hpsb_host *host, int tcode,
- quadlet_t *data, size_t size)
-{
- struct hpsb_packet *packet;
- int tlabel = (data[0] >> 10) & 0x3f;
- size_t header_size;
- unsigned long flags;
-
- spin_lock_irqsave(&pending_packets_lock, flags);
-
- list_for_each_entry(packet, &host->pending_packets, queue)
- if (packet->tlabel == tlabel &&
- packet->node_id == (data[1] >> 16))
- goto found;
-
- spin_unlock_irqrestore(&pending_packets_lock, flags);
- HPSB_DEBUG("unsolicited response packet received - %s",
- "no tlabel match");
- dump_packet("contents", data, 16, -1);
- return;
-
-found:
- switch (packet->tcode) {
- case TCODE_WRITEQ:
- case TCODE_WRITEB:
- if (unlikely(tcode != TCODE_WRITE_RESPONSE))
- break;
- header_size = 12;
- size = 0;
- goto dequeue;
-
- case TCODE_READQ:
- if (unlikely(tcode != TCODE_READQ_RESPONSE))
- break;
- header_size = 16;
- size = 0;
- goto dequeue;
-
- case TCODE_READB:
- if (unlikely(tcode != TCODE_READB_RESPONSE))
- break;
- header_size = 16;
- size = packet_size_to_data_size(size, header_size,
- packet->allocated_data_size,
- tcode);
- goto dequeue;
-
- case TCODE_LOCK_REQUEST:
- if (unlikely(tcode != TCODE_LOCK_RESPONSE))
- break;
- header_size = 16;
- size = packet_size_to_data_size(min(size, (size_t)(16 + 8)),
- header_size,
- packet->allocated_data_size,
- tcode);
- goto dequeue;
- }
-
- spin_unlock_irqrestore(&pending_packets_lock, flags);
- HPSB_DEBUG("unsolicited response packet received - %s",
- "tcode mismatch");
- dump_packet("contents", data, 16, -1);
- return;
-
-dequeue:
- list_del_init(&packet->queue);
- spin_unlock_irqrestore(&pending_packets_lock, flags);
-
- if (packet->state == hpsb_queued) {
- packet->sendtime = jiffies;
- packet->ack_code = ACK_PENDING;
- }
- packet->state = hpsb_complete;
-
- memcpy(packet->header, data, header_size);
- if (size)
- memcpy(packet->data, data + 4, size);
-
- queue_packet_complete(packet);
-}
-
-
-static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
- quadlet_t *data, size_t dsize)
-{
- struct hpsb_packet *p;
-
- p = hpsb_alloc_packet(dsize);
- if (unlikely(p == NULL)) {
- /* FIXME - send data_error response */
- HPSB_ERR("out of memory, cannot send response packet");
- return NULL;
- }
-
- p->type = hpsb_async;
- p->state = hpsb_unused;
- p->host = host;
- p->node_id = data[1] >> 16;
- p->tlabel = (data[0] >> 10) & 0x3f;
- p->no_waiter = 1;
-
- p->generation = get_hpsb_generation(host);
-
- if (dsize % 4)
- p->data[dsize / 4] = 0;
-
- return p;
-}
-
-#define PREP_ASYNC_HEAD_RCODE(tc) \
- packet->tcode = tc; \
- packet->header[0] = (packet->node_id << 16) | (packet->tlabel << 10) \
- | (1 << 8) | (tc << 4); \
- packet->header[1] = (packet->host->node_id << 16) | (rcode << 12); \
- packet->header[2] = 0
-
-static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
- quadlet_t data)
-{
- PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE);
- packet->header[3] = data;
- packet->header_size = 16;
- packet->data_size = 0;
-}
-
-static void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode,
- int length)
-{
- if (rcode != RCODE_COMPLETE)
- length = 0;
-
- PREP_ASYNC_HEAD_RCODE(TCODE_READB_RESPONSE);
- packet->header[3] = length << 16;
- packet->header_size = 16;
- packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
-}
-
-static void fill_async_write_resp(struct hpsb_packet *packet, int rcode)
-{
- PREP_ASYNC_HEAD_RCODE(TCODE_WRITE_RESPONSE);
- packet->header_size = 12;
- packet->data_size = 0;
-}
-
-static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode,
- int length)
-{
- if (rcode != RCODE_COMPLETE)
- length = 0;
-
- PREP_ASYNC_HEAD_RCODE(TCODE_LOCK_RESPONSE);
- packet->header[3] = (length << 16) | extcode;
- packet->header_size = 16;
- packet->data_size = length;
-}
-
-static void handle_incoming_packet(struct hpsb_host *host, int tcode,
- quadlet_t *data, size_t size,
- int write_acked)
-{
- struct hpsb_packet *packet;
- int length, rcode, extcode;
- quadlet_t buffer;
- nodeid_t source = data[1] >> 16;
- nodeid_t dest = data[0] >> 16;
- u16 flags = (u16) data[0];
- u64 addr;
-
- /* FIXME?
- * Out-of-bounds lengths are left for highlevel_read|write to cap. */
-
- switch (tcode) {
- case TCODE_WRITEQ:
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_write(host, source, dest, data + 3,
- addr, 4, flags);
- goto handle_write_request;
-
- case TCODE_WRITEB:
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_write(host, source, dest, data + 4,
- addr, data[3] >> 16, flags);
-handle_write_request:
- if (rcode < 0 || write_acked ||
- NODEID_TO_NODE(data[0] >> 16) == NODE_MASK)
- return;
- /* not a broadcast write, reply */
- packet = create_reply_packet(host, data, 0);
- if (packet) {
- fill_async_write_resp(packet, rcode);
- send_packet_nocare(packet);
- }
- return;
-
- case TCODE_READQ:
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
- if (rcode < 0)
- return;
-
- packet = create_reply_packet(host, data, 0);
- if (packet) {
- fill_async_readquad_resp(packet, rcode, buffer);
- send_packet_nocare(packet);
- }
- return;
-
- case TCODE_READB:
- length = data[3] >> 16;
- packet = create_reply_packet(host, data, length);
- if (!packet)
- return;
-
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_read(host, source, packet->data, addr,
- length, flags);
- if (rcode < 0) {
- hpsb_free_packet(packet);
- return;
- }
- fill_async_readblock_resp(packet, rcode, length);
- send_packet_nocare(packet);
- return;
-
- case TCODE_LOCK_REQUEST:
- length = data[3] >> 16;
- extcode = data[3] & 0xffff;
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
-
- packet = create_reply_packet(host, data, 8);
- if (!packet)
- return;
-
- if (extcode == 0 || extcode >= 7) {
- /* let switch default handle error */
- length = 0;
- }
-
- switch (length) {
- case 4:
- rcode = highlevel_lock(host, source, packet->data, addr,
- data[4], 0, extcode, flags);
- fill_async_lock_resp(packet, rcode, extcode, 4);
- break;
- case 8:
- if (extcode != EXTCODE_FETCH_ADD &&
- extcode != EXTCODE_LITTLE_ADD) {
- rcode = highlevel_lock(host, source,
- packet->data, addr,
- data[5], data[4],
- extcode, flags);
- fill_async_lock_resp(packet, rcode, extcode, 4);
- } else {
- rcode = highlevel_lock64(host, source,
- (octlet_t *)packet->data, addr,
- *(octlet_t *)(data + 4), 0ULL,
- extcode, flags);
- fill_async_lock_resp(packet, rcode, extcode, 8);
- }
- break;
- case 16:
- rcode = highlevel_lock64(host, source,
- (octlet_t *)packet->data, addr,
- *(octlet_t *)(data + 6),
- *(octlet_t *)(data + 4),
- extcode, flags);
- fill_async_lock_resp(packet, rcode, extcode, 8);
- break;
- default:
- rcode = RCODE_TYPE_ERROR;
- fill_async_lock_resp(packet, rcode, extcode, 0);
- }
-
- if (rcode < 0)
- hpsb_free_packet(packet);
- else
- send_packet_nocare(packet);
- return;
- }
-}
-
-/**
- * hpsb_packet_received - hand over received packet to the core
- *
- * For host driver module usage.
- *
- * The contents of data are expected to be the full packet but with the CRCs
- * left out (data block follows header immediately), with the header (i.e. the
- * first four quadlets) in machine byte order and the data block in big endian.
- * *@data can be safely overwritten after this call.
- *
- * If the packet is a write request, @write_acked is to be set to true if it was
- * ack_complete'd already, false otherwise. This argument is ignored for any
- * other packet type.
- */
-void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
- int write_acked)
-{
- int tcode;
-
- if (unlikely(host->in_bus_reset)) {
- HPSB_DEBUG("received packet during reset; ignoring");
- return;
- }
-
- dump_packet("received packet", data, size, -1);
-
- tcode = (data[0] >> 4) & 0xf;
-
- switch (tcode) {
- case TCODE_WRITE_RESPONSE:
- case TCODE_READQ_RESPONSE:
- case TCODE_READB_RESPONSE:
- case TCODE_LOCK_RESPONSE:
- handle_packet_response(host, tcode, data, size);
- break;
-
- case TCODE_WRITEQ:
- case TCODE_WRITEB:
- case TCODE_READQ:
- case TCODE_READB:
- case TCODE_LOCK_REQUEST:
- handle_incoming_packet(host, tcode, data, size, write_acked);
- break;
-
- case TCODE_CYCLE_START:
- /* simply ignore this packet if it is passed on */
- break;
-
- default:
- HPSB_DEBUG("received packet with bogus transaction code %d",
- tcode);
- break;
- }
-}
-
-static void abort_requests(struct hpsb_host *host)
-{
- struct hpsb_packet *packet, *p;
- struct list_head tmp;
- unsigned long flags;
-
- host->driver->devctl(host, CANCEL_REQUESTS, 0);
-
- INIT_LIST_HEAD(&tmp);
- spin_lock_irqsave(&pending_packets_lock, flags);
- list_splice_init(&host->pending_packets, &tmp);
- spin_unlock_irqrestore(&pending_packets_lock, flags);
-
- list_for_each_entry_safe(packet, p, &tmp, queue) {
- list_del_init(&packet->queue);
- packet->state = hpsb_complete;
- packet->ack_code = ACKX_ABORTED;
- queue_packet_complete(packet);
- }
-}
-
-void abort_timedouts(unsigned long __opaque)
-{
- struct hpsb_host *host = (struct hpsb_host *)__opaque;
- struct hpsb_packet *packet, *p;
- struct list_head tmp;
- unsigned long flags, expire, j;
-
- spin_lock_irqsave(&host->csr.lock, flags);
- expire = host->csr.expire;
- spin_unlock_irqrestore(&host->csr.lock, flags);
-
- j = jiffies;
- INIT_LIST_HEAD(&tmp);
- spin_lock_irqsave(&pending_packets_lock, flags);
-
- list_for_each_entry_safe(packet, p, &host->pending_packets, queue) {
- if (time_before(packet->sendtime + expire, j))
- list_move_tail(&packet->queue, &tmp);
- else
- /* Since packets are added to the tail, the oldest
- * ones are first, always. When we get to one that
- * isn't timed out, the rest aren't either. */
- break;
- }
- if (!list_empty(&host->pending_packets))
- mod_timer(&host->timeout, j + host->timeout_interval);
-
- spin_unlock_irqrestore(&pending_packets_lock, flags);
-
- list_for_each_entry_safe(packet, p, &tmp, queue) {
- list_del_init(&packet->queue);
- packet->state = hpsb_complete;
- packet->ack_code = ACKX_TIMEOUT;
- queue_packet_complete(packet);
- }
-}
-
-static struct task_struct *khpsbpkt_thread;
-static LIST_HEAD(hpsbpkt_queue);
-
-static void queue_packet_complete(struct hpsb_packet *packet)
-{
- unsigned long flags;
-
- if (packet->no_waiter) {
- hpsb_free_packet(packet);
- return;
- }
- if (packet->complete_routine != NULL) {
- spin_lock_irqsave(&pending_packets_lock, flags);
- list_add_tail(&packet->queue, &hpsbpkt_queue);
- spin_unlock_irqrestore(&pending_packets_lock, flags);
- wake_up_process(khpsbpkt_thread);
- }
- return;
-}
-
-/*
- * Kernel thread which handles packets that are completed. This way the
- * packet's "complete" function is asynchronously run in process context.
- * Only packets which have a "complete" function may be sent here.
- */
-static int hpsbpkt_thread(void *__hi)
-{
- struct hpsb_packet *packet, *p;
- struct list_head tmp;
- int may_schedule;
-
- while (!kthread_should_stop()) {
-
- INIT_LIST_HEAD(&tmp);
- spin_lock_irq(&pending_packets_lock);
- list_splice_init(&hpsbpkt_queue, &tmp);
- spin_unlock_irq(&pending_packets_lock);
-
- list_for_each_entry_safe(packet, p, &tmp, queue) {
- list_del_init(&packet->queue);
- packet->complete_routine(packet->complete_data);
- }
-
- set_current_state(TASK_INTERRUPTIBLE);
- spin_lock_irq(&pending_packets_lock);
- may_schedule = list_empty(&hpsbpkt_queue);
- spin_unlock_irq(&pending_packets_lock);
- if (may_schedule)
- schedule();
- __set_current_state(TASK_RUNNING);
- }
- return 0;
-}
-
-static int __init ieee1394_init(void)
-{
- int i, ret;
-
- /* non-fatal error */
- if (hpsb_init_config_roms()) {
- HPSB_ERR("Failed to initialize some config rom entries.\n");
- HPSB_ERR("Some features may not be available\n");
- }
-
- khpsbpkt_thread = kthread_run(hpsbpkt_thread, NULL, "khpsbpkt");
- if (IS_ERR(khpsbpkt_thread)) {
- HPSB_ERR("Failed to start hpsbpkt thread!\n");
- ret = PTR_ERR(khpsbpkt_thread);
- goto exit_cleanup_config_roms;
- }
-
- if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) {
- HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR);
- ret = -ENODEV;
- goto exit_release_kernel_thread;
- }
-
- ret = bus_register(&ieee1394_bus_type);
- if (ret < 0) {
- HPSB_INFO("bus register failed");
- goto release_chrdev;
- }
-
- for (i = 0; fw_bus_attrs[i]; i++) {
- ret = bus_create_file(&ieee1394_bus_type, fw_bus_attrs[i]);
- if (ret < 0) {
- while (i >= 0) {
- bus_remove_file(&ieee1394_bus_type,
- fw_bus_attrs[i--]);
- }
- bus_unregister(&ieee1394_bus_type);
- goto release_chrdev;
- }
- }
-
- ret = class_register(&hpsb_host_class);
- if (ret < 0)
- goto release_all_bus;
-
- hpsb_protocol_class = class_create(THIS_MODULE, "ieee1394_protocol");
- if (IS_ERR(hpsb_protocol_class)) {
- ret = PTR_ERR(hpsb_protocol_class);
- goto release_class_host;
- }
-
- ret = init_csr();
- if (ret) {
- HPSB_INFO("init csr failed");
- ret = -ENOMEM;
- goto release_class_protocol;
- }
-
- if (disable_nodemgr) {
- HPSB_INFO("nodemgr and IRM functionality disabled");
- /* We shouldn't contend for IRM with nodemgr disabled, since
- nodemgr implements functionality required of ieee1394a-2000
- IRMs */
- hpsb_disable_irm = 1;
-
- return 0;
- }
-
- if (hpsb_disable_irm) {
- HPSB_INFO("IRM functionality disabled");
- }
-
- ret = init_ieee1394_nodemgr();
- if (ret < 0) {
- HPSB_INFO("init nodemgr failed");
- goto cleanup_csr;
- }
-
- return 0;
-
-cleanup_csr:
- cleanup_csr();
-release_class_protocol:
- class_destroy(hpsb_protocol_class);
-release_class_host:
- class_unregister(&hpsb_host_class);
-release_all_bus:
- for (i = 0; fw_bus_attrs[i]; i++)
- bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
- bus_unregister(&ieee1394_bus_type);
-release_chrdev:
- unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
-exit_release_kernel_thread:
- kthread_stop(khpsbpkt_thread);
-exit_cleanup_config_roms:
- hpsb_cleanup_config_roms();
- return ret;
-}
-
-static void __exit ieee1394_cleanup(void)
-{
- int i;
-
- if (!disable_nodemgr)
- cleanup_ieee1394_nodemgr();
-
- cleanup_csr();
-
- class_destroy(hpsb_protocol_class);
- class_unregister(&hpsb_host_class);
- for (i = 0; fw_bus_attrs[i]; i++)
- bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
- bus_unregister(&ieee1394_bus_type);
-
- kthread_stop(khpsbpkt_thread);
-
- hpsb_cleanup_config_roms();
-
- unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
-}
-
-fs_initcall(ieee1394_init);
-module_exit(ieee1394_cleanup);
-
-/* Exported symbols */
-
-/** hosts.c **/
-EXPORT_SYMBOL(hpsb_alloc_host);
-EXPORT_SYMBOL(hpsb_add_host);
-EXPORT_SYMBOL(hpsb_resume_host);
-EXPORT_SYMBOL(hpsb_remove_host);
-EXPORT_SYMBOL(hpsb_update_config_rom_image);
-
-/** ieee1394_core.c **/
-EXPORT_SYMBOL(hpsb_speedto_str);
-EXPORT_SYMBOL(hpsb_protocol_class);
-EXPORT_SYMBOL(hpsb_set_packet_complete_task);
-EXPORT_SYMBOL(hpsb_alloc_packet);
-EXPORT_SYMBOL(hpsb_free_packet);
-EXPORT_SYMBOL(hpsb_send_packet);
-EXPORT_SYMBOL(hpsb_reset_bus);
-EXPORT_SYMBOL(hpsb_read_cycle_timer);
-EXPORT_SYMBOL(hpsb_bus_reset);
-EXPORT_SYMBOL(hpsb_selfid_received);
-EXPORT_SYMBOL(hpsb_selfid_complete);
-EXPORT_SYMBOL(hpsb_packet_sent);
-EXPORT_SYMBOL(hpsb_packet_received);
-EXPORT_SYMBOL_GPL(hpsb_disable_irm);
-
-/** ieee1394_transactions.c **/
-EXPORT_SYMBOL(hpsb_get_tlabel);
-EXPORT_SYMBOL(hpsb_free_tlabel);
-EXPORT_SYMBOL(hpsb_make_readpacket);
-EXPORT_SYMBOL(hpsb_make_writepacket);
-EXPORT_SYMBOL(hpsb_make_streampacket);
-EXPORT_SYMBOL(hpsb_make_lockpacket);
-EXPORT_SYMBOL(hpsb_make_lock64packet);
-EXPORT_SYMBOL(hpsb_make_phypacket);
-EXPORT_SYMBOL(hpsb_read);
-EXPORT_SYMBOL(hpsb_write);
-EXPORT_SYMBOL(hpsb_lock);
-EXPORT_SYMBOL(hpsb_packet_success);
-
-/** highlevel.c **/
-EXPORT_SYMBOL(hpsb_register_highlevel);
-EXPORT_SYMBOL(hpsb_unregister_highlevel);
-EXPORT_SYMBOL(hpsb_register_addrspace);
-EXPORT_SYMBOL(hpsb_unregister_addrspace);
-EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace);
-EXPORT_SYMBOL(hpsb_get_hostinfo);
-EXPORT_SYMBOL(hpsb_create_hostinfo);
-EXPORT_SYMBOL(hpsb_destroy_hostinfo);
-EXPORT_SYMBOL(hpsb_set_hostinfo_key);
-EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
-EXPORT_SYMBOL(hpsb_set_hostinfo);
-
-/** nodemgr.c **/
-EXPORT_SYMBOL(hpsb_node_fill_packet);
-EXPORT_SYMBOL(hpsb_node_write);
-EXPORT_SYMBOL(__hpsb_register_protocol);
-EXPORT_SYMBOL(hpsb_unregister_protocol);
-
-/** csr.c **/
-EXPORT_SYMBOL(hpsb_update_config_rom);
-
-/** dma.c **/
-EXPORT_SYMBOL(dma_prog_region_init);
-EXPORT_SYMBOL(dma_prog_region_alloc);
-EXPORT_SYMBOL(dma_prog_region_free);
-EXPORT_SYMBOL(dma_region_init);
-EXPORT_SYMBOL(dma_region_alloc);
-EXPORT_SYMBOL(dma_region_free);
-EXPORT_SYMBOL(dma_region_sync_for_cpu);
-EXPORT_SYMBOL(dma_region_sync_for_device);
-EXPORT_SYMBOL(dma_region_mmap);
-EXPORT_SYMBOL(dma_region_offset_to_bus);
-
-/** iso.c **/
-EXPORT_SYMBOL(hpsb_iso_xmit_init);
-EXPORT_SYMBOL(hpsb_iso_recv_init);
-EXPORT_SYMBOL(hpsb_iso_xmit_start);
-EXPORT_SYMBOL(hpsb_iso_recv_start);
-EXPORT_SYMBOL(hpsb_iso_recv_listen_channel);
-EXPORT_SYMBOL(hpsb_iso_recv_unlisten_channel);
-EXPORT_SYMBOL(hpsb_iso_recv_set_channel_mask);
-EXPORT_SYMBOL(hpsb_iso_stop);
-EXPORT_SYMBOL(hpsb_iso_shutdown);
-EXPORT_SYMBOL(hpsb_iso_xmit_queue_packet);
-EXPORT_SYMBOL(hpsb_iso_xmit_sync);
-EXPORT_SYMBOL(hpsb_iso_recv_release_packets);
-EXPORT_SYMBOL(hpsb_iso_n_ready);
-EXPORT_SYMBOL(hpsb_iso_packet_sent);
-EXPORT_SYMBOL(hpsb_iso_packet_received);
-EXPORT_SYMBOL(hpsb_iso_wake);
-EXPORT_SYMBOL(hpsb_iso_recv_flush);
-
-/** csr1212.c **/
-EXPORT_SYMBOL(csr1212_attach_keyval_to_directory);
-EXPORT_SYMBOL(csr1212_detach_keyval_from_directory);
-EXPORT_SYMBOL(csr1212_get_keyval);
-EXPORT_SYMBOL(csr1212_new_directory);
-EXPORT_SYMBOL(csr1212_parse_keyval);
-EXPORT_SYMBOL(csr1212_read);
-EXPORT_SYMBOL(csr1212_release_keyval);
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
deleted file mode 100644
index 28b9f58bafd..00000000000
--- a/drivers/ieee1394/ieee1394_core.h
+++ /dev/null
@@ -1,172 +0,0 @@
-#ifndef _IEEE1394_CORE_H
-#define _IEEE1394_CORE_H
-
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/types.h>
-#include <linux/cdev.h>
-#include <asm/atomic.h>
-
-#include "hosts.h"
-#include "ieee1394_types.h"
-
-struct hpsb_packet {
- /* This struct is basically read-only for hosts with the exception of
- * the data buffer contents and driver_list. */
-
- /* This can be used for host driver internal linking.
- *
- * NOTE: This must be left in init state when the driver is done
- * with it (e.g. by using list_del_init()), since the core does
- * some sanity checks to make sure the packet is not on a
- * driver_list when free'ing it. */
- struct list_head driver_list;
-
- nodeid_t node_id;
-
- /* hpsb_raw = send as-is, do not CRC (but still byte-swap it) */
- enum { hpsb_async, hpsb_raw } __attribute__((packed)) type;
-
- /* Okay, this is core internal and a no care for hosts.
- * queued = queued for sending
- * pending = sent, waiting for response
- * complete = processing completed, successful or not
- */
- enum {
- hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete
- } __attribute__((packed)) state;
-
- /* These are core-internal. */
- signed char tlabel;
- signed char ack_code;
- unsigned char tcode;
-
- unsigned expect_response:1;
- unsigned no_waiter:1;
-
- /* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */
- unsigned speed_code:2;
-
- struct hpsb_host *host;
- unsigned int generation;
-
- atomic_t refcnt;
- struct list_head queue;
-
- /* Function (and possible data to pass to it) to call when this
- * packet is completed. */
- void (*complete_routine)(void *);
- void *complete_data;
-
- /* Store jiffies for implementing bus timeouts. */
- unsigned long sendtime;
-
- /* Core-internal. */
- size_t allocated_data_size; /* as allocated */
-
- /* Sizes are in bytes. To be set by caller of hpsb_alloc_packet. */
- size_t data_size; /* as filled in */
- size_t header_size; /* as filled in, not counting the CRC */
-
- /* Buffers */
- quadlet_t *data; /* can be DMA-mapped */
- quadlet_t header[5];
- quadlet_t embedded_data[0]; /* keep as last member */
-};
-
-void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
- void (*routine)(void *), void *data);
-static inline struct hpsb_packet *driver_packet(struct list_head *l)
-{
- return list_entry(l, struct hpsb_packet, driver_list);
-}
-void abort_timedouts(unsigned long __opaque);
-struct hpsb_packet *hpsb_alloc_packet(size_t data_size);
-void hpsb_free_packet(struct hpsb_packet *packet);
-
-/**
- * get_hpsb_generation - generation counter for the complete 1394 subsystem
- *
- * Generation gets incremented on every change in the subsystem (notably on bus
- * resets). Use the functions, not the variable.
- */
-static inline unsigned int get_hpsb_generation(struct hpsb_host *host)
-{
- return atomic_read(&host->generation);
-}
-
-int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt);
-int hpsb_send_packet(struct hpsb_packet *packet);
-int hpsb_send_packet_and_wait(struct hpsb_packet *packet);
-int hpsb_reset_bus(struct hpsb_host *host, int type);
-int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
- u64 *local_time);
-
-int hpsb_bus_reset(struct hpsb_host *host);
-void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid);
-void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot);
-void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
- int ackcode);
-void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
- int write_acked);
-
-/*
- * CHARACTER DEVICE DISPATCHING
- *
- * All ieee1394 character device drivers share the same major number
- * (major 171). The 256 minor numbers are allocated to the various
- * task-specific interfaces (raw1394, video1394, dv1394, etc) in
- * blocks of 16.
- *
- * The core ieee1394.o module allocates the device number region
- * 171:0-255, the various drivers must then cdev_add() their cdev
- * objects to handle their respective sub-regions.
- *
- * Minor device number block allocations:
- *
- * Block 0 ( 0- 15) raw1394
- * Block 1 ( 16- 31) video1394
- * Block 2 ( 32- 47) dv1394
- *
- * Blocks 3-14 free for future allocation
- *
- * Block 15 (240-255) reserved for drivers under development, etc.
- */
-
-#define IEEE1394_MAJOR 171
-
-#define IEEE1394_MINOR_BLOCK_RAW1394 0
-#define IEEE1394_MINOR_BLOCK_VIDEO1394 1
-#define IEEE1394_MINOR_BLOCK_DV1394 2
-#define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15
-
-#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0)
-#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, \
- IEEE1394_MINOR_BLOCK_RAW1394 * 16)
-#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, \
- IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
-#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, \
- IEEE1394_MINOR_BLOCK_DV1394 * 16)
-#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, \
- IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
-
-/**
- * ieee1394_file_to_instance - get the index within a minor number block
- */
-static inline unsigned char ieee1394_file_to_instance(struct file *file)
-{
- int idx = cdev_index(file->f_path.dentry->d_inode);
- if (idx < 0)
- idx = 0;
- return idx;
-}
-
-extern int hpsb_disable_irm;
-
-/* Our sysfs bus entry */
-extern struct bus_type ieee1394_bus_type;
-extern struct class hpsb_host_class;
-extern struct class *hpsb_protocol_class;
-
-#endif /* _IEEE1394_CORE_H */
diff --git a/drivers/ieee1394/ieee1394_hotplug.h b/drivers/ieee1394/ieee1394_hotplug.h
deleted file mode 100644
index dd5500ed832..00000000000
--- a/drivers/ieee1394/ieee1394_hotplug.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _IEEE1394_HOTPLUG_H
-#define _IEEE1394_HOTPLUG_H
-
-/* Unit spec id and sw version entry for some protocols */
-#define AVC_UNIT_SPEC_ID_ENTRY 0x0000A02D
-#define AVC_SW_VERSION_ENTRY 0x00010001
-#define CAMERA_UNIT_SPEC_ID_ENTRY 0x0000A02D
-#define CAMERA_SW_VERSION_ENTRY 0x00000100
-
-/* /include/linux/mod_devicetable.h defines:
- * IEEE1394_MATCH_VENDOR_ID
- * IEEE1394_MATCH_MODEL_ID
- * IEEE1394_MATCH_SPECIFIER_ID
- * IEEE1394_MATCH_VERSION
- * struct ieee1394_device_id
- */
-#include <linux/mod_devicetable.h>
-
-#endif /* _IEEE1394_HOTPLUG_H */
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
deleted file mode 100644
index 675b3135d5f..00000000000
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * Transaction support.
- *
- * Copyright (C) 1999 Andreas E. Bombe
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#include <linux/bitops.h>
-#include <linux/compiler.h>
-#include <linux/hardirq.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/sched.h> /* because linux/wait.h is broken if CONFIG_SMP=n */
-#include <linux/wait.h>
-
-#include <asm/bug.h>
-#include <asm/errno.h>
-#include <asm/system.h>
-
-#include "ieee1394.h"
-#include "ieee1394_types.h"
-#include "hosts.h"
-#include "ieee1394_core.h"
-#include "ieee1394_transactions.h"
-
-#define PREP_ASYNC_HEAD_ADDRESS(tc) \
- packet->tcode = tc; \
- packet->header[0] = (packet->node_id << 16) | (packet->tlabel << 10) \
- | (1 << 8) | (tc << 4); \
- packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \
- packet->header[2] = addr & 0xffffffff
-
-#ifndef HPSB_DEBUG_TLABELS
-static
-#endif
-DEFINE_SPINLOCK(hpsb_tlabel_lock);
-
-static DECLARE_WAIT_QUEUE_HEAD(tlabel_wq);
-
-static void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
-{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
- packet->header_size = 12;
- packet->data_size = 0;
- packet->expect_response = 1;
-}
-
-static void fill_async_readblock(struct hpsb_packet *packet, u64 addr,
- int length)
-{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_READB);
- packet->header[3] = length << 16;
- packet->header_size = 16;
- packet->data_size = 0;
- packet->expect_response = 1;
-}
-
-static void fill_async_writequad(struct hpsb_packet *packet, u64 addr,
- quadlet_t data)
-{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ);
- packet->header[3] = data;
- packet->header_size = 16;
- packet->data_size = 0;
- packet->expect_response = 1;
-}
-
-static void fill_async_writeblock(struct hpsb_packet *packet, u64 addr,
- int length)
-{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB);
- packet->header[3] = length << 16;
- packet->header_size = 16;
- packet->expect_response = 1;
- packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
-}
-
-static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
- int length)
-{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST);
- packet->header[3] = (length << 16) | extcode;
- packet->header_size = 16;
- packet->data_size = length;
- packet->expect_response = 1;
-}
-
-static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
-{
- packet->header[0] = data;
- packet->header[1] = ~data;
- packet->header_size = 8;
- packet->data_size = 0;
- packet->expect_response = 0;
- packet->type = hpsb_raw; /* No CRC added */
- packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */
-}
-
-static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
- int channel, int tag, int sync)
-{
- packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
- | (TCODE_STREAM_DATA << 4) | sync;
-
- packet->header_size = 4;
- packet->data_size = length;
- packet->type = hpsb_async;
- packet->tcode = TCODE_ISO_DATA;
-}
-
-/* same as hpsb_get_tlabel, except that it returns immediately */
-static int hpsb_get_tlabel_atomic(struct hpsb_packet *packet)
-{
- unsigned long flags, *tp;
- u8 *next;
- int tlabel, n = NODEID_TO_NODE(packet->node_id);
-
- /* Broadcast transactions are complete once the request has been sent.
- * Use the same transaction label for all broadcast transactions. */
- if (unlikely(n == ALL_NODES)) {
- packet->tlabel = 0;
- return 0;
- }
- tp = packet->host->tl_pool[n].map;
- next = &packet->host->next_tl[n];
-
- spin_lock_irqsave(&hpsb_tlabel_lock, flags);
- tlabel = find_next_zero_bit(tp, 64, *next);
- if (tlabel > 63)
- tlabel = find_first_zero_bit(tp, 64);
- if (tlabel > 63) {
- spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
- return -EAGAIN;
- }
- __set_bit(tlabel, tp);
- *next = (tlabel + 1) & 63;
- spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
-
- packet->tlabel = tlabel;
- return 0;
-}
-
-/**
- * hpsb_get_tlabel - allocate a transaction label
- * @packet: the packet whose tlabel and tl_pool we set
- *
- * Every asynchronous transaction on the 1394 bus needs a transaction
- * label to match the response to the request. This label has to be
- * different from any other transaction label in an outstanding request to
- * the same node to make matching possible without ambiguity.
- *
- * There are 64 different tlabels, so an allocated tlabel has to be freed
- * with hpsb_free_tlabel() after the transaction is complete (unless it's
- * reused again for the same target node).
- *
- * Return value: Zero on success, otherwise non-zero. A non-zero return
- * generally means there are no available tlabels. If this is called out
- * of interrupt or atomic context, then it will sleep until can return a
- * tlabel or a signal is received.
- */
-int hpsb_get_tlabel(struct hpsb_packet *packet)
-{
- if (irqs_disabled() || in_atomic())
- return hpsb_get_tlabel_atomic(packet);
-
- /* NB: The macro wait_event_interruptible() is called with a condition
- * argument with side effect. This is only possible because the side
- * effect does not occur until the condition became true, and
- * wait_event_interruptible() won't evaluate the condition again after
- * that. */
- return wait_event_interruptible(tlabel_wq,
- !hpsb_get_tlabel_atomic(packet));
-}
-
-/**
- * hpsb_free_tlabel - free an allocated transaction label
- * @packet: packet whose tlabel and tl_pool needs to be cleared
- *
- * Frees the transaction label allocated with hpsb_get_tlabel(). The
- * tlabel has to be freed after the transaction is complete (i.e. response
- * was received for a split transaction or packet was sent for a unified
- * transaction).
- *
- * A tlabel must not be freed twice.
- */
-void hpsb_free_tlabel(struct hpsb_packet *packet)
-{
- unsigned long flags, *tp;
- int tlabel, n = NODEID_TO_NODE(packet->node_id);
-
- if (unlikely(n == ALL_NODES))
- return;
- tp = packet->host->tl_pool[n].map;
- tlabel = packet->tlabel;
- BUG_ON(tlabel > 63 || tlabel < 0);
-
- spin_lock_irqsave(&hpsb_tlabel_lock, flags);
- BUG_ON(!__test_and_clear_bit(tlabel, tp));
- spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
-
- wake_up_interruptible(&tlabel_wq);
-}
-
-/**
- * hpsb_packet_success - Make sense of the ack and reply codes
- *
- * Make sense of the ack and reply codes and return more convenient error codes:
- * 0 = success. -%EBUSY = node is busy, try again. -%EAGAIN = error which can
- * probably resolved by retry. -%EREMOTEIO = node suffers from an internal
- * error. -%EACCES = this transaction is not allowed on requested address.
- * -%EINVAL = invalid address at node.
- */
-int hpsb_packet_success(struct hpsb_packet *packet)
-{
- switch (packet->ack_code) {
- case ACK_PENDING:
- switch ((packet->header[1] >> 12) & 0xf) {
- case RCODE_COMPLETE:
- return 0;
- case RCODE_CONFLICT_ERROR:
- return -EAGAIN;
- case RCODE_DATA_ERROR:
- return -EREMOTEIO;
- case RCODE_TYPE_ERROR:
- return -EACCES;
- case RCODE_ADDRESS_ERROR:
- return -EINVAL;
- default:
- HPSB_ERR("received reserved rcode %d from node %d",
- (packet->header[1] >> 12) & 0xf,
- packet->node_id);
- return -EAGAIN;
- }
-
- case ACK_BUSY_X:
- case ACK_BUSY_A:
- case ACK_BUSY_B:
- return -EBUSY;
-
- case ACK_TYPE_ERROR:
- return -EACCES;
-
- case ACK_COMPLETE:
- if (packet->tcode == TCODE_WRITEQ
- || packet->tcode == TCODE_WRITEB) {
- return 0;
- } else {
- HPSB_ERR("impossible ack_complete from node %d "
- "(tcode %d)", packet->node_id, packet->tcode);
- return -EAGAIN;
- }
-
- case ACK_DATA_ERROR:
- if (packet->tcode == TCODE_WRITEB
- || packet->tcode == TCODE_LOCK_REQUEST) {
- return -EAGAIN;
- } else {
- HPSB_ERR("impossible ack_data_error from node %d "
- "(tcode %d)", packet->node_id, packet->tcode);
- return -EAGAIN;
- }
-
- case ACK_ADDRESS_ERROR:
- return -EINVAL;
-
- case ACK_TARDY:
- case ACK_CONFLICT_ERROR:
- case ACKX_NONE:
- case ACKX_SEND_ERROR:
- case ACKX_ABORTED:
- case ACKX_TIMEOUT:
- /* error while sending */
- return -EAGAIN;
-
- default:
- HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
- packet->ack_code, packet->node_id, packet->tcode);
- return -EAGAIN;
- }
-}
-
-struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
- u64 addr, size_t length)
-{
- struct hpsb_packet *packet;
-
- if (length == 0)
- return NULL;
-
- packet = hpsb_alloc_packet(length);
- if (!packet)
- return NULL;
-
- packet->host = host;
- packet->node_id = node;
-
- if (hpsb_get_tlabel(packet)) {
- hpsb_free_packet(packet);
- return NULL;
- }
-
- if (length == 4)
- fill_async_readquad(packet, addr);
- else
- fill_async_readblock(packet, addr, length);
-
- return packet;
-}
-
-struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node,
- u64 addr, quadlet_t * buffer,
- size_t length)
-{
- struct hpsb_packet *packet;
-
- if (length == 0)
- return NULL;
-
- packet = hpsb_alloc_packet(length);
- if (!packet)
- return NULL;
-
- if (length % 4) { /* zero padding bytes */
- packet->data[length >> 2] = 0;
- }
- packet->host = host;
- packet->node_id = node;
-
- if (hpsb_get_tlabel(packet)) {
- hpsb_free_packet(packet);
- return NULL;
- }
-
- if (length == 4) {
- fill_async_writequad(packet, addr, buffer ? *buffer : 0);
- } else {
- fill_async_writeblock(packet, addr, length);
- if (buffer)
- memcpy(packet->data, buffer, length);
- }
-
- return packet;
-}
-
-struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 * buffer,
- int length, int channel, int tag,
- int sync)
-{
- struct hpsb_packet *packet;
-
- if (length == 0)
- return NULL;
-
- packet = hpsb_alloc_packet(length);
- if (!packet)
- return NULL;
-
- if (length % 4) { /* zero padding bytes */
- packet->data[length >> 2] = 0;
- }
- packet->host = host;
-
- /* Because it is too difficult to determine all PHY speeds and link
- * speeds here, we use S100... */
- packet->speed_code = IEEE1394_SPEED_100;
-
- /* ...and prevent hpsb_send_packet() from overriding it. */
- packet->node_id = LOCAL_BUS | ALL_NODES;
-
- if (hpsb_get_tlabel(packet)) {
- hpsb_free_packet(packet);
- return NULL;
- }
-
- fill_async_stream_packet(packet, length, channel, tag, sync);
- if (buffer)
- memcpy(packet->data, buffer, length);
-
- return packet;
-}
-
-struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
- u64 addr, int extcode,
- quadlet_t * data, quadlet_t arg)
-{
- struct hpsb_packet *p;
- u32 length;
-
- p = hpsb_alloc_packet(8);
- if (!p)
- return NULL;
-
- p->host = host;
- p->node_id = node;
- if (hpsb_get_tlabel(p)) {
- hpsb_free_packet(p);
- return NULL;
- }
-
- switch (extcode) {
- case EXTCODE_FETCH_ADD:
- case EXTCODE_LITTLE_ADD:
- length = 4;
- if (data)
- p->data[0] = *data;
- break;
- default:
- length = 8;
- if (data) {
- p->data[0] = arg;
- p->data[1] = *data;
- }
- break;
- }
- fill_async_lock(p, addr, extcode, length);
-
- return p;
-}
-
-struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
- nodeid_t node, u64 addr, int extcode,
- octlet_t * data, octlet_t arg)
-{
- struct hpsb_packet *p;
- u32 length;
-
- p = hpsb_alloc_packet(16);
- if (!p)
- return NULL;
-
- p->host = host;
- p->node_id = node;
- if (hpsb_get_tlabel(p)) {
- hpsb_free_packet(p);
- return NULL;
- }
-
- switch (extcode) {
- case EXTCODE_FETCH_ADD:
- case EXTCODE_LITTLE_ADD:
- length = 8;
- if (data) {
- p->data[0] = *data >> 32;
- p->data[1] = *data & 0xffffffff;
- }
- break;
- default:
- length = 16;
- if (data) {
- p->data[0] = arg >> 32;
- p->data[1] = arg & 0xffffffff;
- p->data[2] = *data >> 32;
- p->data[3] = *data & 0xffffffff;
- }
- break;
- }
- fill_async_lock(p, addr, extcode, length);
-
- return p;
-}
-
-struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data)
-{
- struct hpsb_packet *p;
-
- p = hpsb_alloc_packet(0);
- if (!p)
- return NULL;
-
- p->host = host;
- fill_phy_packet(p, data);
-
- return p;
-}
-
-/*
- * FIXME - these functions should probably read from / write to user space to
- * avoid in kernel buffers for user space callers
- */
-
-/**
- * hpsb_read - generic read function
- *
- * Recognizes the local node ID and act accordingly. Automatically uses a
- * quadlet read request if @length == 4 and and a block read request otherwise.
- * It does not yet support lengths that are not a multiple of 4.
- *
- * You must explicitly specifiy the @generation for which the node ID is valid,
- * to avoid sending packets to the wrong nodes when we race with a bus reset.
- */
-int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, quadlet_t * buffer, size_t length)
-{
- struct hpsb_packet *packet;
- int retval = 0;
-
- if (length == 0)
- return -EINVAL;
-
- packet = hpsb_make_readpacket(host, node, addr, length);
-
- if (!packet) {
- return -ENOMEM;
- }
-
- packet->generation = generation;
- retval = hpsb_send_packet_and_wait(packet);
- if (retval < 0)
- goto hpsb_read_fail;
-
- retval = hpsb_packet_success(packet);
-
- if (retval == 0) {
- if (length == 4) {
- *buffer = packet->header[3];
- } else {
- memcpy(buffer, packet->data, length);
- }
- }
-
- hpsb_read_fail:
- hpsb_free_tlabel(packet);
- hpsb_free_packet(packet);
-
- return retval;
-}
-
-/**
- * hpsb_write - generic write function
- *
- * Recognizes the local node ID and act accordingly. Automatically uses a
- * quadlet write request if @length == 4 and and a block write request
- * otherwise. It does not yet support lengths that are not a multiple of 4.
- *
- * You must explicitly specifiy the @generation for which the node ID is valid,
- * to avoid sending packets to the wrong nodes when we race with a bus reset.
- */
-int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, quadlet_t * buffer, size_t length)
-{
- struct hpsb_packet *packet;
- int retval;
-
- if (length == 0)
- return -EINVAL;
-
- packet = hpsb_make_writepacket(host, node, addr, buffer, length);
-
- if (!packet)
- return -ENOMEM;
-
- packet->generation = generation;
- retval = hpsb_send_packet_and_wait(packet);
- if (retval < 0)
- goto hpsb_write_fail;
-
- retval = hpsb_packet_success(packet);
-
- hpsb_write_fail:
- hpsb_free_tlabel(packet);
- hpsb_free_packet(packet);
-
- return retval;
-}
-
-int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
-{
- struct hpsb_packet *packet;
- int retval = 0;
-
- packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
- if (!packet)
- return -ENOMEM;
-
- packet->generation = generation;
- retval = hpsb_send_packet_and_wait(packet);
- if (retval < 0)
- goto hpsb_lock_fail;
-
- retval = hpsb_packet_success(packet);
-
- if (retval == 0)
- *data = packet->data[0];
-
-hpsb_lock_fail:
- hpsb_free_tlabel(packet);
- hpsb_free_packet(packet);
-
- return retval;
-}
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h
deleted file mode 100644
index 20b693be14b..00000000000
--- a/drivers/ieee1394/ieee1394_transactions.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _IEEE1394_TRANSACTIONS_H
-#define _IEEE1394_TRANSACTIONS_H
-
-#include <linux/types.h>
-
-#include "ieee1394_types.h"
-
-struct hpsb_packet;
-struct hpsb_host;
-
-int hpsb_get_tlabel(struct hpsb_packet *packet);
-void hpsb_free_tlabel(struct hpsb_packet *packet);
-struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
- u64 addr, size_t length);
-struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
- u64 addr, int extcode, quadlet_t *data,
- quadlet_t arg);
-struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
- nodeid_t node, u64 addr, int extcode,
- octlet_t *data, octlet_t arg);
-struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data);
-struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host,
- nodeid_t node, u64 addr,
- quadlet_t *buffer, size_t length);
-struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer,
- int length, int channel, int tag,
- int sync);
-int hpsb_packet_success(struct hpsb_packet *packet);
-int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, quadlet_t *buffer, size_t length);
-int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, quadlet_t *buffer, size_t length);
-int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, int extcode, quadlet_t *data, quadlet_t arg);
-
-#ifdef HPSB_DEBUG_TLABELS
-extern spinlock_t hpsb_tlabel_lock;
-#endif
-
-#endif /* _IEEE1394_TRANSACTIONS_H */
diff --git a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h
deleted file mode 100644
index 9803aaa15be..00000000000
--- a/drivers/ieee1394/ieee1394_types.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _IEEE1394_TYPES_H
-#define _IEEE1394_TYPES_H
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-typedef u32 quadlet_t;
-typedef u64 octlet_t;
-typedef u16 nodeid_t;
-
-typedef u8 byte_t;
-typedef u64 nodeaddr_t;
-typedef u16 arm_length_t;
-
-#define BUS_MASK 0xffc0
-#define BUS_SHIFT 6
-#define NODE_MASK 0x003f
-#define LOCAL_BUS 0xffc0
-#define ALL_NODES 0x003f
-
-#define NODEID_TO_BUS(nodeid) ((nodeid & BUS_MASK) >> BUS_SHIFT)
-#define NODEID_TO_NODE(nodeid) (nodeid & NODE_MASK)
-
-/* Can be used to consistently print a node/bus ID. */
-#define NODE_BUS_FMT "%d-%02d:%04d"
-#define NODE_BUS_ARGS(__host, __nodeid) \
- __host->id, NODEID_TO_NODE(__nodeid), NODEID_TO_BUS(__nodeid)
-
-#define HPSB_PRINT(level, fmt, args...) \
- printk(level "ieee1394: " fmt "\n" , ## args)
-
-#define HPSB_DEBUG(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
-#define HPSB_INFO(fmt, args...) HPSB_PRINT(KERN_INFO, fmt , ## args)
-#define HPSB_NOTICE(fmt, args...) HPSB_PRINT(KERN_NOTICE, fmt , ## args)
-#define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args)
-#define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args)
-
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-#define HPSB_VERBOSE(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
-#define HPSB_DEBUG_TLABELS
-#else
-#define HPSB_VERBOSE(fmt, args...) do {} while (0)
-#endif
-
-#ifdef __BIG_ENDIAN
-
-static inline void *memcpy_le32(u32 *dest, const u32 *__src, size_t count)
-{
- void *tmp = dest;
- u32 *src = (u32 *)__src;
-
- count /= 4;
- while (count--)
- *dest++ = swab32p(src++);
- return tmp;
-}
-
-#else
-
-static __inline__ void *memcpy_le32(u32 *dest, const u32 *src, size_t count)
-{
- return memcpy(dest, src, count);
-}
-
-#endif /* __BIG_ENDIAN */
-
-#endif /* _IEEE1394_TYPES_H */
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c
deleted file mode 100644
index 1cf6487b65b..00000000000
--- a/drivers/ieee1394/iso.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * kernel ISO transmission/reception
- *
- * Copyright (C) 2002 Maas Digital LLC
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-#include "hosts.h"
-#include "iso.h"
-
-/**
- * hpsb_iso_stop - stop DMA
- */
-void hpsb_iso_stop(struct hpsb_iso *iso)
-{
- if (!(iso->flags & HPSB_ISO_DRIVER_STARTED))
- return;
-
- iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ?
- XMIT_STOP : RECV_STOP, 0);
- iso->flags &= ~HPSB_ISO_DRIVER_STARTED;
-}
-
-/**
- * hpsb_iso_shutdown - deallocate buffer and DMA context
- */
-void hpsb_iso_shutdown(struct hpsb_iso *iso)
-{
- if (iso->flags & HPSB_ISO_DRIVER_INIT) {
- hpsb_iso_stop(iso);
- iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ?
- XMIT_SHUTDOWN : RECV_SHUTDOWN, 0);
- iso->flags &= ~HPSB_ISO_DRIVER_INIT;
- }
-
- dma_region_free(&iso->data_buf);
- kfree(iso);
-}
-
-static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
- enum hpsb_iso_type type,
- unsigned int data_buf_size,
- unsigned int buf_packets,
- int channel, int dma_mode,
- int irq_interval,
- void (*callback) (struct hpsb_iso
- *))
-{
- struct hpsb_iso *iso;
- int dma_direction;
-
- /* make sure driver supports the ISO API */
- if (!host->driver->isoctl) {
- printk(KERN_INFO
- "ieee1394: host driver '%s' does not support the rawiso API\n",
- host->driver->name);
- return NULL;
- }
-
- /* sanitize parameters */
-
- if (buf_packets < 2)
- buf_packets = 2;
-
- if ((dma_mode < HPSB_ISO_DMA_DEFAULT)
- || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
- dma_mode = HPSB_ISO_DMA_DEFAULT;
-
- if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
- irq_interval = buf_packets / 4;
- if (irq_interval == 0) /* really interrupt for each packet */
- irq_interval = 1;
-
- if (channel < -1 || channel >= 64)
- return NULL;
-
- /* channel = -1 is OK for multi-channel recv but not for xmit */
- if (type == HPSB_ISO_XMIT && channel < 0)
- return NULL;
-
- /* allocate and write the struct hpsb_iso */
-
- iso =
- kmalloc(sizeof(*iso) +
- buf_packets * sizeof(struct hpsb_iso_packet_info),
- GFP_KERNEL);
- if (!iso)
- return NULL;
-
- iso->infos = (struct hpsb_iso_packet_info *)(iso + 1);
-
- iso->type = type;
- iso->host = host;
- iso->hostdata = NULL;
- iso->callback = callback;
- init_waitqueue_head(&iso->waitq);
- iso->channel = channel;
- iso->irq_interval = irq_interval;
- iso->dma_mode = dma_mode;
- dma_region_init(&iso->data_buf);
- iso->buf_size = PAGE_ALIGN(data_buf_size);
- iso->buf_packets = buf_packets;
- iso->pkt_dma = 0;
- iso->first_packet = 0;
- spin_lock_init(&iso->lock);
-
- if (iso->type == HPSB_ISO_XMIT) {
- iso->n_ready_packets = iso->buf_packets;
- dma_direction = PCI_DMA_TODEVICE;
- } else {
- iso->n_ready_packets = 0;
- dma_direction = PCI_DMA_FROMDEVICE;
- }
-
- atomic_set(&iso->overflows, 0);
- iso->bytes_discarded = 0;
- iso->flags = 0;
- iso->prebuffer = 0;
-
- /* allocate the packet buffer */
- if (dma_region_alloc
- (&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
- goto err;
-
- return iso;
-
- err:
- hpsb_iso_shutdown(iso);
- return NULL;
-}
-
-/**
- * hpsb_iso_n_ready - returns number of packets ready to send or receive
- */
-int hpsb_iso_n_ready(struct hpsb_iso *iso)
-{
- unsigned long flags;
- int val;
-
- spin_lock_irqsave(&iso->lock, flags);
- val = iso->n_ready_packets;
- spin_unlock_irqrestore(&iso->lock, flags);
-
- return val;
-}
-
-/**
- * hpsb_iso_xmit_init - allocate the buffer and DMA context
- */
-struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host,
- unsigned int data_buf_size,
- unsigned int buf_packets,
- int channel,
- int speed,
- int irq_interval,
- void (*callback) (struct hpsb_iso *))
-{
- struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
- data_buf_size, buf_packets,
- channel,
- HPSB_ISO_DMA_DEFAULT,
- irq_interval, callback);
- if (!iso)
- return NULL;
-
- iso->speed = speed;
-
- /* tell the driver to start working */
- if (host->driver->isoctl(iso, XMIT_INIT, 0))
- goto err;
-
- iso->flags |= HPSB_ISO_DRIVER_INIT;
- return iso;
-
- err:
- hpsb_iso_shutdown(iso);
- return NULL;
-}
-
-/**
- * hpsb_iso_recv_init - allocate the buffer and DMA context
- *
- * Note, if channel = -1, multi-channel receive is enabled.
- */
-struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host,
- unsigned int data_buf_size,
- unsigned int buf_packets,
- int channel,
- int dma_mode,
- int irq_interval,
- void (*callback) (struct hpsb_iso *))
-{
- struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
- data_buf_size, buf_packets,
- channel, dma_mode,
- irq_interval, callback);
- if (!iso)
- return NULL;
-
- /* tell the driver to start working */
- if (host->driver->isoctl(iso, RECV_INIT, 0))
- goto err;
-
- iso->flags |= HPSB_ISO_DRIVER_INIT;
- return iso;
-
- err:
- hpsb_iso_shutdown(iso);
- return NULL;
-}
-
-/**
- * hpsb_iso_recv_listen_channel
- *
- * multi-channel only
- */
-int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
-{
- if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
- return -EINVAL;
- return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel);
-}
-
-/**
- * hpsb_iso_recv_unlisten_channel
- *
- * multi-channel only
- */
-int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
-{
- if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
- return -EINVAL;
- return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
-}
-
-/**
- * hpsb_iso_recv_set_channel_mask
- *
- * multi-channel only
- */
-int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
-{
- if (iso->type != HPSB_ISO_RECV || iso->channel != -1)
- return -EINVAL;
- return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK,
- (unsigned long)&mask);
-}
-
-/**
- * hpsb_iso_recv_flush - check for arrival of new packets
- *
- * check for arrival of new packets immediately (even if irq_interval
- * has not yet been reached)
- */
-int hpsb_iso_recv_flush(struct hpsb_iso *iso)
-{
- if (iso->type != HPSB_ISO_RECV)
- return -EINVAL;
- return iso->host->driver->isoctl(iso, RECV_FLUSH, 0);
-}
-
-static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle)
-{
- int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle);
- if (retval)
- return retval;
-
- iso->flags |= HPSB_ISO_DRIVER_STARTED;
- return retval;
-}
-
-/**
- * hpsb_iso_xmit_start - start DMA
- */
-int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
-{
- if (iso->type != HPSB_ISO_XMIT)
- return -1;
-
- if (iso->flags & HPSB_ISO_DRIVER_STARTED)
- return 0;
-
- if (cycle < -1)
- cycle = -1;
- else if (cycle >= 8000)
- cycle %= 8000;
-
- iso->xmit_cycle = cycle;
-
- if (prebuffer < 0)
- prebuffer = iso->buf_packets - 1;
- else if (prebuffer == 0)
- prebuffer = 1;
-
- if (prebuffer >= iso->buf_packets)
- prebuffer = iso->buf_packets - 1;
-
- iso->prebuffer = prebuffer;
-
- /* remember the starting cycle; DMA will commence from xmit_queue_packets()
- once enough packets have been buffered */
- iso->start_cycle = cycle;
-
- return 0;
-}
-
-/**
- * hpsb_iso_recv_start - start DMA
- */
-int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
-{
- int retval = 0;
- int isoctl_args[3];
-
- if (iso->type != HPSB_ISO_RECV)
- return -1;
-
- if (iso->flags & HPSB_ISO_DRIVER_STARTED)
- return 0;
-
- if (cycle < -1)
- cycle = -1;
- else if (cycle >= 8000)
- cycle %= 8000;
-
- isoctl_args[0] = cycle;
-
- if (tag_mask < 0)
- /* match all tags */
- tag_mask = 0xF;
- isoctl_args[1] = tag_mask;
-
- isoctl_args[2] = sync;
-
- retval =
- iso->host->driver->isoctl(iso, RECV_START,
- (unsigned long)&isoctl_args[0]);
- if (retval)
- return retval;
-
- iso->flags |= HPSB_ISO_DRIVER_STARTED;
- return retval;
-}
-
-/* check to make sure the user has not supplied bogus values of offset/len
- * that would cause the kernel to access memory outside the buffer */
-static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
- unsigned int offset, unsigned short len,
- unsigned int *out_offset,
- unsigned short *out_len)
-{
- if (offset >= iso->buf_size)
- return -EFAULT;
-
- /* make sure the packet does not go beyond the end of the buffer */
- if (offset + len > iso->buf_size)
- return -EFAULT;
-
- /* check for wrap-around */
- if (offset + len < offset)
- return -EFAULT;
-
- /* now we can trust 'offset' and 'length' */
- *out_offset = offset;
- *out_len = len;
-
- return 0;
-}
-
-/**
- * hpsb_iso_xmit_queue_packet - queue a packet for transmission.
- *
- * @offset is relative to the beginning of the DMA buffer, where the packet's
- * data payload should already have been placed.
- */
-int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
- u8 tag, u8 sy)
-{
- struct hpsb_iso_packet_info *info;
- unsigned long flags;
- int rv;
-
- if (iso->type != HPSB_ISO_XMIT)
- return -EINVAL;
-
- /* is there space in the buffer? */
- if (iso->n_ready_packets <= 0) {
- return -EBUSY;
- }
-
- info = &iso->infos[iso->first_packet];
-
- /* check for bogus offset/length */
- if (hpsb_iso_check_offset_len
- (iso, offset, len, &info->offset, &info->len))
- return -EFAULT;
-
- info->tag = tag;
- info->sy = sy;
-
- spin_lock_irqsave(&iso->lock, flags);
-
- rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long)info);
- if (rv)
- goto out;
-
- /* increment cursors */
- iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
- iso->xmit_cycle = (iso->xmit_cycle + 1) % 8000;
- iso->n_ready_packets--;
-
- if (iso->prebuffer != 0) {
- iso->prebuffer--;
- if (iso->prebuffer <= 0) {
- iso->prebuffer = 0;
- rv = do_iso_xmit_start(iso, iso->start_cycle);
- }
- }
-
- out:
- spin_unlock_irqrestore(&iso->lock, flags);
- return rv;
-}
-
-/**
- * hpsb_iso_xmit_sync - wait until all queued packets have been transmitted
- */
-int hpsb_iso_xmit_sync(struct hpsb_iso *iso)
-{
- if (iso->type != HPSB_ISO_XMIT)
- return -EINVAL;
-
- return wait_event_interruptible(iso->waitq,
- hpsb_iso_n_ready(iso) ==
- iso->buf_packets);
-}
-
-/**
- * hpsb_iso_packet_sent
- *
- * Available to low-level drivers.
- *
- * Call after a packet has been transmitted to the bus (interrupt context is
- * OK). @cycle is the _exact_ cycle the packet was sent on. @error should be
- * non-zero if some sort of error occurred when sending the packet.
- */
-void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
-{
- unsigned long flags;
- spin_lock_irqsave(&iso->lock, flags);
-
- /* predict the cycle of the next packet to be queued */
-
- /* jump ahead by the number of packets that are already buffered */
- cycle += iso->buf_packets - iso->n_ready_packets;
- cycle %= 8000;
-
- iso->xmit_cycle = cycle;
- iso->n_ready_packets++;
- iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
-
- if (iso->n_ready_packets == iso->buf_packets || error != 0) {
- /* the buffer has run empty! */
- atomic_inc(&iso->overflows);
- }
-
- spin_unlock_irqrestore(&iso->lock, flags);
-}
-
-/**
- * hpsb_iso_packet_received
- *
- * Available to low-level drivers.
- *
- * Call after a packet has been received (interrupt context is OK).
- */
-void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
- u16 total_len, u16 cycle, u8 channel, u8 tag,
- u8 sy)
-{
- unsigned long flags;
- spin_lock_irqsave(&iso->lock, flags);
-
- if (iso->n_ready_packets == iso->buf_packets) {
- /* overflow! */
- atomic_inc(&iso->overflows);
- /* Record size of this discarded packet */
- iso->bytes_discarded += total_len;
- } else {
- struct hpsb_iso_packet_info *info = &iso->infos[iso->pkt_dma];
- info->offset = offset;
- info->len = len;
- info->total_len = total_len;
- info->cycle = cycle;
- info->channel = channel;
- info->tag = tag;
- info->sy = sy;
-
- iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
- iso->n_ready_packets++;
- }
-
- spin_unlock_irqrestore(&iso->lock, flags);
-}
-
-/**
- * hpsb_iso_recv_release_packets - release packets, reuse buffer
- *
- * @n_packets have been read out of the buffer, re-use the buffer space
- */
-int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
-{
- unsigned long flags;
- unsigned int i;
- int rv = 0;
-
- if (iso->type != HPSB_ISO_RECV)
- return -1;
-
- spin_lock_irqsave(&iso->lock, flags);
- for (i = 0; i < n_packets; i++) {
- rv = iso->host->driver->isoctl(iso, RECV_RELEASE,
- (unsigned long)&iso->infos[iso->
- first_packet]);
- if (rv)
- break;
-
- iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
- iso->n_ready_packets--;
-
- /* release memory from packets discarded when queue was full */
- if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */
- if (iso->bytes_discarded != 0) {
- struct hpsb_iso_packet_info inf;
- inf.total_len = iso->bytes_discarded;
- iso->host->driver->isoctl(iso, RECV_RELEASE,
- (unsigned long)&inf);
- iso->bytes_discarded = 0;
- }
- }
- }
- spin_unlock_irqrestore(&iso->lock, flags);
- return rv;
-}
-
-/**
- * hpsb_iso_wake
- *
- * Available to low-level drivers.
- *
- * Call to wake waiting processes after buffer space has opened up.
- */
-void hpsb_iso_wake(struct hpsb_iso *iso)
-{
- wake_up_interruptible(&iso->waitq);
-
- if (iso->callback)
- iso->callback(iso);
-}
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h
deleted file mode 100644
index c2089c093aa..00000000000
--- a/drivers/ieee1394/iso.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * kernel ISO transmission/reception
- *
- * Copyright (C) 2002 Maas Digital LLC
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#ifndef IEEE1394_ISO_H
-#define IEEE1394_ISO_H
-
-#include <linux/spinlock_types.h>
-#include <linux/wait.h>
-#include <asm/atomic.h>
-#include <asm/types.h>
-
-#include "dma.h"
-
-struct hpsb_host;
-
-/* high-level ISO interface */
-
-/*
- * This API sends and receives isochronous packets on a large,
- * virtually-contiguous kernel memory buffer. The buffer may be mapped
- * into a user-space process for zero-copy transmission and reception.
- *
- * There are no explicit boundaries between packets in the buffer. A
- * packet may be transmitted or received at any location. However,
- * low-level drivers may impose certain restrictions on alignment or
- * size of packets. (e.g. in OHCI no packet may cross a page boundary,
- * and packets should be quadlet-aligned)
- */
-
-/* Packet descriptor - the API maintains a ring buffer of these packet
- * descriptors in kernel memory (hpsb_iso.infos[]). */
-struct hpsb_iso_packet_info {
- /* offset of data payload relative to the first byte of the buffer */
- __u32 offset;
-
- /* length of the data payload, in bytes (not including the isochronous
- * header) */
- __u16 len;
-
- /* (recv only) the cycle number (mod 8000) on which the packet was
- * received */
- __u16 cycle;
-
- /* (recv only) channel on which the packet was received */
- __u8 channel;
-
- /* 2-bit 'tag' and 4-bit 'sy' fields of the isochronous header */
- __u8 tag;
- __u8 sy;
-
- /* length in bytes of the packet including header/trailer.
- * MUST be at structure end, since the first part of this structure is
- * also defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is
- * copied to userspace and is accessed there through libraw1394. */
- __u16 total_len;
-};
-
-enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 };
-
-/* The mode of the dma when receiving iso data. Must be supported by chip */
-enum raw1394_iso_dma_recv_mode {
- HPSB_ISO_DMA_DEFAULT = -1,
- HPSB_ISO_DMA_OLD_ABI = 0,
- HPSB_ISO_DMA_BUFFERFILL = 1,
- HPSB_ISO_DMA_PACKET_PER_BUFFER = 2
-};
-
-struct hpsb_iso {
- enum hpsb_iso_type type;
-
- /* pointer to low-level driver and its private data */
- struct hpsb_host *host;
- void *hostdata;
-
- /* a function to be called (from interrupt context) after
- * outgoing packets have been sent, or incoming packets have
- * arrived */
- void (*callback)(struct hpsb_iso*);
-
- /* wait for buffer space */
- wait_queue_head_t waitq;
-
- int speed; /* IEEE1394_SPEED_100, 200, or 400 */
- int channel; /* -1 if multichannel */
- int dma_mode; /* dma receive mode */
-
-
- /* greatest # of packets between interrupts - controls
- * the maximum latency of the buffer */
- int irq_interval;
-
- /* the buffer for packet data payloads */
- struct dma_region data_buf;
-
- /* size of data_buf, in bytes (always a multiple of PAGE_SIZE) */
- unsigned int buf_size;
-
- /* # of packets in the ringbuffer */
- unsigned int buf_packets;
-
- /* protects packet cursors */
- spinlock_t lock;
-
- /* the index of the next packet that will be produced
- or consumed by the user */
- int first_packet;
-
- /* the index of the next packet that will be transmitted
- or received by the 1394 hardware */
- int pkt_dma;
-
- /* how many packets, starting at first_packet:
- * (transmit) are ready to be filled with data
- * (receive) contain received data */
- int n_ready_packets;
-
- /* how many times the buffer has overflowed or underflowed */
- atomic_t overflows;
- /* how many cycles were skipped for a given context */
- atomic_t skips;
-
- /* Current number of bytes lost in discarded packets */
- int bytes_discarded;
-
- /* private flags to track initialization progress */
-#define HPSB_ISO_DRIVER_INIT (1<<0)
-#define HPSB_ISO_DRIVER_STARTED (1<<1)
- unsigned int flags;
-
- /* # of packets left to prebuffer (xmit only) */
- int prebuffer;
-
- /* starting cycle for DMA (xmit only) */
- int start_cycle;
-
- /* cycle at which next packet will be transmitted,
- * -1 if not known */
- int xmit_cycle;
-
- /* ringbuffer of packet descriptors in regular kernel memory
- * XXX Keep this last, since we use over-allocated memory from
- * this entry to fill this field. */
- struct hpsb_iso_packet_info *infos;
-};
-
-/* functions available to high-level drivers (e.g. raw1394) */
-
-struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
- unsigned int data_buf_size,
- unsigned int buf_packets,
- int channel,
- int speed,
- int irq_interval,
- void (*callback)(struct hpsb_iso*));
-struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
- unsigned int data_buf_size,
- unsigned int buf_packets,
- int channel,
- int dma_mode,
- int irq_interval,
- void (*callback)(struct hpsb_iso*));
-int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel);
-int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel);
-int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask);
-int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle,
- int prebuffer);
-int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle,
- int tag_mask, int sync);
-void hpsb_iso_stop(struct hpsb_iso *iso);
-void hpsb_iso_shutdown(struct hpsb_iso *iso);
-int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
- u8 tag, u8 sy);
-int hpsb_iso_xmit_sync(struct hpsb_iso *iso);
-int hpsb_iso_recv_release_packets(struct hpsb_iso *recv,
- unsigned int n_packets);
-int hpsb_iso_recv_flush(struct hpsb_iso *iso);
-int hpsb_iso_n_ready(struct hpsb_iso *iso);
-
-/* the following are callbacks available to low-level drivers */
-
-void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error);
-void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
- u16 total_len, u16 cycle, u8 channel, u8 tag,
- u8 sy);
-void hpsb_iso_wake(struct hpsb_iso *iso);
-
-#endif /* IEEE1394_ISO_H */
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
deleted file mode 100644
index 18350213479..00000000000
--- a/drivers/ieee1394/nodemgr.c
+++ /dev/null
@@ -1,1901 +0,0 @@
-/*
- * Node information (ConfigROM) collection and management.
- *
- * Copyright (C) 2000 Andreas E. Bombe
- * 2001-2003 Ben Collins <bcollins@debian.net>
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#include <linux/bitmap.h>
-#include <linux/kernel.h>
-#include <linux/kmemcheck.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/mutex.h>
-#include <linux/freezer.h>
-#include <asm/atomic.h>
-
-#include "csr.h"
-#include "highlevel.h"
-#include "hosts.h"
-#include "ieee1394.h"
-#include "ieee1394_core.h"
-#include "ieee1394_hotplug.h"
-#include "ieee1394_types.h"
-#include "ieee1394_transactions.h"
-#include "nodemgr.h"
-
-static int ignore_drivers;
-module_param(ignore_drivers, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(ignore_drivers, "Disable automatic probing for drivers.");
-
-struct nodemgr_csr_info {
- struct hpsb_host *host;
- nodeid_t nodeid;
- unsigned int generation;
-
- kmemcheck_bitfield_begin(flags);
- unsigned int speed_unverified:1;
- kmemcheck_bitfield_end(flags);
-};
-
-
-/*
- * Correct the speed map entry. This is necessary
- * - for nodes with link speed < phy speed,
- * - for 1394b nodes with negotiated phy port speed < IEEE1394_SPEED_MAX.
- * A possible speed is determined by trial and error, using quadlet reads.
- */
-static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
- quadlet_t *buffer)
-{
- quadlet_t q;
- u8 i, *speed, old_speed, good_speed;
- int error;
-
- speed = &(ci->host->speed[NODEID_TO_NODE(ci->nodeid)]);
- old_speed = *speed;
- good_speed = IEEE1394_SPEED_MAX + 1;
-
- /* Try every speed from S100 to old_speed.
- * If we did it the other way around, a too low speed could be caught
- * if the retry succeeded for some other reason, e.g. because the link
- * just finished its initialization. */
- for (i = IEEE1394_SPEED_100; i <= old_speed; i++) {
- *speed = i;
- error = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
- &q, 4);
- if (error)
- break;
- *buffer = q;
- good_speed = i;
- }
- if (good_speed <= IEEE1394_SPEED_MAX) {
- HPSB_DEBUG("Speed probe of node " NODE_BUS_FMT " yields %s",
- NODE_BUS_ARGS(ci->host, ci->nodeid),
- hpsb_speedto_str[good_speed]);
- *speed = good_speed;
- ci->speed_unverified = 0;
- return 0;
- }
- *speed = old_speed;
- return error;
-}
-
-static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr,
- void *buffer, void *__ci)
-{
- struct nodemgr_csr_info *ci = (struct nodemgr_csr_info*)__ci;
- int i, error;
-
- for (i = 1; ; i++) {
- error = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
- buffer, 4);
- if (!error) {
- ci->speed_unverified = 0;
- break;
- }
- /* Give up after 3rd failure. */
- if (i == 3)
- break;
-
- /* The ieee1394_core guessed the node's speed capability from
- * the self ID. Check whether a lower speed works. */
- if (ci->speed_unverified) {
- error = nodemgr_check_speed(ci, addr, buffer);
- if (!error)
- break;
- }
- if (msleep_interruptible(334))
- return -EINTR;
- }
- return error;
-}
-
-static struct csr1212_bus_ops nodemgr_csr_ops = {
- .bus_read = nodemgr_bus_read,
-};
-
-
-/*
- * Basically what we do here is start off retrieving the bus_info block.
- * From there will fill in some info about the node, verify it is of IEEE
- * 1394 type, and that the crc checks out ok. After that we start off with
- * the root directory, and subdirectories. To do this, we retrieve the
- * quadlet header for a directory, find out the length, and retrieve the
- * complete directory entry (be it a leaf or a directory). We then process
- * it and add the info to our structure for that particular node.
- *
- * We verify CRC's along the way for each directory/block/leaf. The entire
- * node structure is generic, and simply stores the information in a way
- * that's easy to parse by the protocol interface.
- */
-
-/*
- * The nodemgr relies heavily on the Driver Model for device callbacks and
- * driver/device mappings. The old nodemgr used to handle all this itself,
- * but now we are much simpler because of the LDM.
- */
-
-struct host_info {
- struct hpsb_host *host;
- struct list_head list;
- struct task_struct *thread;
-};
-
-static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
-static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env);
-
-struct bus_type ieee1394_bus_type = {
- .name = "ieee1394",
- .match = nodemgr_bus_match,
-};
-
-static void host_cls_release(struct device *dev)
-{
- put_device(&container_of((dev), struct hpsb_host, host_dev)->device);
-}
-
-struct class hpsb_host_class = {
- .name = "ieee1394_host",
- .dev_release = host_cls_release,
-};
-
-static void ne_cls_release(struct device *dev)
-{
- put_device(&container_of((dev), struct node_entry, node_dev)->device);
-}
-
-static struct class nodemgr_ne_class = {
- .name = "ieee1394_node",
- .dev_release = ne_cls_release,
-};
-
-static void ud_cls_release(struct device *dev)
-{
- put_device(&container_of((dev), struct unit_directory, unit_dev)->device);
-}
-
-/* The name here is only so that unit directory hotplug works with old
- * style hotplug, which only ever did unit directories anyway.
- */
-static struct class nodemgr_ud_class = {
- .name = "ieee1394",
- .dev_release = ud_cls_release,
- .dev_uevent = nodemgr_uevent,
-};
-
-static struct hpsb_highlevel nodemgr_highlevel;
-
-
-static void nodemgr_release_ud(struct device *dev)
-{
- struct unit_directory *ud = container_of(dev, struct unit_directory, device);
-
- if (ud->vendor_name_kv)
- csr1212_release_keyval(ud->vendor_name_kv);
- if (ud->model_name_kv)
- csr1212_release_keyval(ud->model_name_kv);
-
- kfree(ud);
-}
-
-static void nodemgr_release_ne(struct device *dev)
-{
- struct node_entry *ne = container_of(dev, struct node_entry, device);
-
- if (ne->vendor_name_kv)
- csr1212_release_keyval(ne->vendor_name_kv);
-
- kfree(ne);
-}
-
-
-static void nodemgr_release_host(struct device *dev)
-{
- struct hpsb_host *host = container_of(dev, struct hpsb_host, device);
-
- csr1212_destroy_csr(host->csr.rom);
-
- kfree(host);
-}
-
-static int nodemgr_ud_platform_data;
-
-static struct device nodemgr_dev_template_ud = {
- .bus = &ieee1394_bus_type,
- .release = nodemgr_release_ud,
- .platform_data = &nodemgr_ud_platform_data,
-};
-
-static struct device nodemgr_dev_template_ne = {
- .bus = &ieee1394_bus_type,
- .release = nodemgr_release_ne,
-};
-
-/* This dummy driver prevents the host devices from being scanned. We have no
- * useful drivers for them yet, and there would be a deadlock possible if the
- * driver core scans the host device while the host's low-level driver (i.e.
- * the host's parent device) is being removed. */
-static struct device_driver nodemgr_mid_layer_driver = {
- .bus = &ieee1394_bus_type,
- .name = "nodemgr",
- .owner = THIS_MODULE,
-};
-
-struct device nodemgr_dev_template_host = {
- .bus = &ieee1394_bus_type,
- .release = nodemgr_release_host,
-};
-
-
-#define fw_attr(class, class_type, field, type, format_string) \
-static ssize_t fw_show_##class##_##field (struct device *dev, struct device_attribute *attr, char *buf)\
-{ \
- class_type *class; \
- class = container_of(dev, class_type, device); \
- return sprintf(buf, format_string, (type)class->field); \
-} \
-static struct device_attribute dev_attr_##class##_##field = { \
- .attr = {.name = __stringify(field), .mode = S_IRUGO }, \
- .show = fw_show_##class##_##field, \
-};
-
-#define fw_attr_td(class, class_type, td_kv) \
-static ssize_t fw_show_##class##_##td_kv (struct device *dev, struct device_attribute *attr, char *buf)\
-{ \
- int len; \
- class_type *class = container_of(dev, class_type, device); \
- len = (class->td_kv->value.leaf.len - 2) * sizeof(quadlet_t); \
- memcpy(buf, \
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(class->td_kv), \
- len); \
- while (buf[len - 1] == '\0') \
- len--; \
- buf[len++] = '\n'; \
- buf[len] = '\0'; \
- return len; \
-} \
-static struct device_attribute dev_attr_##class##_##td_kv = { \
- .attr = {.name = __stringify(td_kv), .mode = S_IRUGO }, \
- .show = fw_show_##class##_##td_kv, \
-};
-
-
-#define fw_drv_attr(field, type, format_string) \
-static ssize_t fw_drv_show_##field (struct device_driver *drv, char *buf) \
-{ \
- struct hpsb_protocol_driver *driver; \
- driver = container_of(drv, struct hpsb_protocol_driver, driver); \
- return sprintf(buf, format_string, (type)driver->field);\
-} \
-static struct driver_attribute driver_attr_drv_##field = { \
- .attr = {.name = __stringify(field), .mode = S_IRUGO }, \
- .show = fw_drv_show_##field, \
-};
-
-
-static ssize_t fw_show_ne_bus_options(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct node_entry *ne = container_of(dev, struct node_entry, device);
-
- return sprintf(buf, "IRMC(%d) CMC(%d) ISC(%d) BMC(%d) PMC(%d) GEN(%d) "
- "LSPD(%d) MAX_REC(%d) MAX_ROM(%d) CYC_CLK_ACC(%d)\n",
- ne->busopt.irmc,
- ne->busopt.cmc, ne->busopt.isc, ne->busopt.bmc,
- ne->busopt.pmc, ne->busopt.generation, ne->busopt.lnkspd,
- ne->busopt.max_rec,
- ne->busopt.max_rom,
- ne->busopt.cyc_clk_acc);
-}
-static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL);
-
-
-#ifdef HPSB_DEBUG_TLABELS
-static ssize_t fw_show_ne_tlabels_free(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct node_entry *ne = container_of(dev, struct node_entry, device);
- unsigned long flags;
- unsigned long *tp = ne->host->tl_pool[NODEID_TO_NODE(ne->nodeid)].map;
- int tf;
-
- spin_lock_irqsave(&hpsb_tlabel_lock, flags);
- tf = 64 - bitmap_weight(tp, 64);
- spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
-
- return sprintf(buf, "%d\n", tf);
-}
-static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL);
-
-
-static ssize_t fw_show_ne_tlabels_mask(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct node_entry *ne = container_of(dev, struct node_entry, device);
- unsigned long flags;
- unsigned long *tp = ne->host->tl_pool[NODEID_TO_NODE(ne->nodeid)].map;
- u64 tm;
-
- spin_lock_irqsave(&hpsb_tlabel_lock, flags);
-#if (BITS_PER_LONG <= 32)
- tm = ((u64)tp[0] << 32) + tp[1];
-#else
- tm = tp[0];
-#endif
- spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
-
- return sprintf(buf, "0x%016llx\n", (unsigned long long)tm);
-}
-static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
-#endif /* HPSB_DEBUG_TLABELS */
-
-
-static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct unit_directory *ud = container_of(dev, struct unit_directory, device);
- int state = simple_strtoul(buf, NULL, 10);
-
- if (state == 1) {
- ud->ignore_driver = 1;
- device_release_driver(dev);
- } else if (state == 0)
- ud->ignore_driver = 0;
-
- return count;
-}
-static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct unit_directory *ud = container_of(dev, struct unit_directory, device);
-
- return sprintf(buf, "%d\n", ud->ignore_driver);
-}
-static DEVICE_ATTR(ignore_driver, S_IWUSR | S_IRUGO, fw_get_ignore_driver, fw_set_ignore_driver);
-
-
-static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf,
- size_t count)
-{
- int error = 0;
-
- if (simple_strtoul(buf, NULL, 10) == 1)
- error = bus_rescan_devices(&ieee1394_bus_type);
- return error ? error : count;
-}
-static ssize_t fw_get_rescan(struct bus_type *bus, char *buf)
-{
- return sprintf(buf, "You can force a rescan of the bus for "
- "drivers by writing a 1 to this file\n");
-}
-static BUS_ATTR(rescan, S_IWUSR | S_IRUGO, fw_get_rescan, fw_set_rescan);
-
-
-static ssize_t fw_set_ignore_drivers(struct bus_type *bus, const char *buf, size_t count)
-{
- int state = simple_strtoul(buf, NULL, 10);
-
- if (state == 1)
- ignore_drivers = 1;
- else if (state == 0)
- ignore_drivers = 0;
-
- return count;
-}
-static ssize_t fw_get_ignore_drivers(struct bus_type *bus, char *buf)
-{
- return sprintf(buf, "%d\n", ignore_drivers);
-}
-static BUS_ATTR(ignore_drivers, S_IWUSR | S_IRUGO, fw_get_ignore_drivers, fw_set_ignore_drivers);
-
-
-struct bus_attribute *const fw_bus_attrs[] = {
- &bus_attr_rescan,
- &bus_attr_ignore_drivers,
- NULL
-};
-
-
-fw_attr(ne, struct node_entry, capabilities, unsigned int, "0x%06x\n")
-fw_attr(ne, struct node_entry, nodeid, unsigned int, "0x%04x\n")
-
-fw_attr(ne, struct node_entry, vendor_id, unsigned int, "0x%06x\n")
-fw_attr_td(ne, struct node_entry, vendor_name_kv)
-
-fw_attr(ne, struct node_entry, guid, unsigned long long, "0x%016Lx\n")
-fw_attr(ne, struct node_entry, guid_vendor_id, unsigned int, "0x%06x\n")
-fw_attr(ne, struct node_entry, in_limbo, int, "%d\n");
-
-static struct device_attribute *const fw_ne_attrs[] = {
- &dev_attr_ne_guid,
- &dev_attr_ne_guid_vendor_id,
- &dev_attr_ne_capabilities,
- &dev_attr_ne_vendor_id,
- &dev_attr_ne_nodeid,
- &dev_attr_bus_options,
-#ifdef HPSB_DEBUG_TLABELS
- &dev_attr_tlabels_free,
- &dev_attr_tlabels_mask,
-#endif
-};
-
-
-
-fw_attr(ud, struct unit_directory, address, unsigned long long, "0x%016Lx\n")
-fw_attr(ud, struct unit_directory, length, int, "%d\n")
-/* These are all dependent on the value being provided */
-fw_attr(ud, struct unit_directory, vendor_id, unsigned int, "0x%06x\n")
-fw_attr(ud, struct unit_directory, model_id, unsigned int, "0x%06x\n")
-fw_attr(ud, struct unit_directory, specifier_id, unsigned int, "0x%06x\n")
-fw_attr(ud, struct unit_directory, version, unsigned int, "0x%06x\n")
-fw_attr_td(ud, struct unit_directory, vendor_name_kv)
-fw_attr_td(ud, struct unit_directory, model_name_kv)
-
-static struct device_attribute *const fw_ud_attrs[] = {
- &dev_attr_ud_address,
- &dev_attr_ud_length,
- &dev_attr_ignore_driver,
-};
-
-
-fw_attr(host, struct hpsb_host, node_count, int, "%d\n")
-fw_attr(host, struct hpsb_host, selfid_count, int, "%d\n")
-fw_attr(host, struct hpsb_host, nodes_active, int, "%d\n")
-fw_attr(host, struct hpsb_host, in_bus_reset, int, "%d\n")
-fw_attr(host, struct hpsb_host, is_root, int, "%d\n")
-fw_attr(host, struct hpsb_host, is_cycmst, int, "%d\n")
-fw_attr(host, struct hpsb_host, is_irm, int, "%d\n")
-fw_attr(host, struct hpsb_host, is_busmgr, int, "%d\n")
-
-static struct device_attribute *const fw_host_attrs[] = {
- &dev_attr_host_node_count,
- &dev_attr_host_selfid_count,
- &dev_attr_host_nodes_active,
- &dev_attr_host_in_bus_reset,
- &dev_attr_host_is_root,
- &dev_attr_host_is_cycmst,
- &dev_attr_host_is_irm,
- &dev_attr_host_is_busmgr,
-};
-
-
-static ssize_t fw_show_drv_device_ids(struct device_driver *drv, char *buf)
-{
- struct hpsb_protocol_driver *driver;
- const struct ieee1394_device_id *id;
- int length = 0;
- char *scratch = buf;
-
- driver = container_of(drv, struct hpsb_protocol_driver, driver);
- id = driver->id_table;
- if (!id)
- return 0;
-
- for (; id->match_flags != 0; id++) {
- int need_coma = 0;
-
- if (id->match_flags & IEEE1394_MATCH_VENDOR_ID) {
- length += sprintf(scratch, "vendor_id=0x%06x", id->vendor_id);
- scratch = buf + length;
- need_coma++;
- }
-
- if (id->match_flags & IEEE1394_MATCH_MODEL_ID) {
- length += sprintf(scratch, "%smodel_id=0x%06x",
- need_coma++ ? "," : "",
- id->model_id);
- scratch = buf + length;
- }
-
- if (id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) {
- length += sprintf(scratch, "%sspecifier_id=0x%06x",
- need_coma++ ? "," : "",
- id->specifier_id);
- scratch = buf + length;
- }
-
- if (id->match_flags & IEEE1394_MATCH_VERSION) {
- length += sprintf(scratch, "%sversion=0x%06x",
- need_coma++ ? "," : "",
- id->version);
- scratch = buf + length;
- }
-
- if (need_coma) {
- *scratch++ = '\n';
- length++;
- }
- }
-
- return length;
-}
-static DRIVER_ATTR(device_ids,S_IRUGO,fw_show_drv_device_ids,NULL);
-
-
-fw_drv_attr(name, const char *, "%s\n")
-
-static struct driver_attribute *const fw_drv_attrs[] = {
- &driver_attr_drv_name,
- &driver_attr_device_ids,
-};
-
-
-static void nodemgr_create_drv_files(struct hpsb_protocol_driver *driver)
-{
- struct device_driver *drv = &driver->driver;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(fw_drv_attrs); i++)
- if (driver_create_file(drv, fw_drv_attrs[i]))
- goto fail;
- return;
-fail:
- HPSB_ERR("Failed to add sysfs attribute");
-}
-
-
-static void nodemgr_remove_drv_files(struct hpsb_protocol_driver *driver)
-{
- struct device_driver *drv = &driver->driver;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(fw_drv_attrs); i++)
- driver_remove_file(drv, fw_drv_attrs[i]);
-}
-
-
-static void nodemgr_create_ne_dev_files(struct node_entry *ne)
-{
- struct device *dev = &ne->device;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(fw_ne_attrs); i++)
- if (device_create_file(dev, fw_ne_attrs[i]))
- goto fail;
- return;
-fail:
- HPSB_ERR("Failed to add sysfs attribute");
-}
-
-
-static void nodemgr_create_host_dev_files(struct hpsb_host *host)
-{
- struct device *dev = &host->device;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(fw_host_attrs); i++)
- if (device_create_file(dev, fw_host_attrs[i]))
- goto fail;
- return;
-fail:
- HPSB_ERR("Failed to add sysfs attribute");
-}
-
-
-static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
- nodeid_t nodeid);
-
-static void nodemgr_update_host_dev_links(struct hpsb_host *host)
-{
- struct device *dev = &host->device;
- struct node_entry *ne;
-
- sysfs_remove_link(&dev->kobj, "irm_id");
- sysfs_remove_link(&dev->kobj, "busmgr_id");
- sysfs_remove_link(&dev->kobj, "host_id");
-
- if ((ne = find_entry_by_nodeid(host, host->irm_id)) &&
- sysfs_create_link(&dev->kobj, &ne->device.kobj, "irm_id"))
- goto fail;
- if ((ne = find_entry_by_nodeid(host, host->busmgr_id)) &&
- sysfs_create_link(&dev->kobj, &ne->device.kobj, "busmgr_id"))
- goto fail;
- if ((ne = find_entry_by_nodeid(host, host->node_id)) &&
- sysfs_create_link(&dev->kobj, &ne->device.kobj, "host_id"))
- goto fail;
- return;
-fail:
- HPSB_ERR("Failed to update sysfs attributes for host %d", host->id);
-}
-
-static void nodemgr_create_ud_dev_files(struct unit_directory *ud)
-{
- struct device *dev = &ud->device;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++)
- if (device_create_file(dev, fw_ud_attrs[i]))
- goto fail;
- if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
- if (device_create_file(dev, &dev_attr_ud_specifier_id))
- goto fail;
- if (ud->flags & UNIT_DIRECTORY_VERSION)
- if (device_create_file(dev, &dev_attr_ud_version))
- goto fail;
- if (ud->flags & UNIT_DIRECTORY_VENDOR_ID) {
- if (device_create_file(dev, &dev_attr_ud_vendor_id))
- goto fail;
- if (ud->vendor_name_kv &&
- device_create_file(dev, &dev_attr_ud_vendor_name_kv))
- goto fail;
- }
- if (ud->flags & UNIT_DIRECTORY_MODEL_ID) {
- if (device_create_file(dev, &dev_attr_ud_model_id))
- goto fail;
- if (ud->model_name_kv &&
- device_create_file(dev, &dev_attr_ud_model_name_kv))
- goto fail;
- }
- return;
-fail:
- HPSB_ERR("Failed to add sysfs attribute");
-}
-
-
-static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
-{
- struct hpsb_protocol_driver *driver;
- struct unit_directory *ud;
- const struct ieee1394_device_id *id;
-
- /* We only match unit directories */
- if (dev->platform_data != &nodemgr_ud_platform_data)
- return 0;
-
- ud = container_of(dev, struct unit_directory, device);
- if (ud->ne->in_limbo || ud->ignore_driver)
- return 0;
-
- /* We only match drivers of type hpsb_protocol_driver */
- if (drv == &nodemgr_mid_layer_driver)
- return 0;
-
- driver = container_of(drv, struct hpsb_protocol_driver, driver);
- id = driver->id_table;
- if (!id)
- return 0;
-
- for (; id->match_flags != 0; id++) {
- if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
- id->vendor_id != ud->vendor_id)
- continue;
-
- if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
- id->model_id != ud->model_id)
- continue;
-
- if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
- id->specifier_id != ud->specifier_id)
- continue;
-
- if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
- id->version != ud->version)
- continue;
-
- return 1;
- }
-
- return 0;
-}
-
-
-static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
-
-static int match_ne(struct device *dev, void *data)
-{
- struct unit_directory *ud;
- struct node_entry *ne = data;
-
- ud = container_of(dev, struct unit_directory, unit_dev);
- return ud->ne == ne;
-}
-
-static void nodemgr_remove_uds(struct node_entry *ne)
-{
- struct device *dev;
- struct unit_directory *ud;
-
- /* Use class_find device to iterate the devices. Since this code
- * may be called from other contexts besides the knodemgrds,
- * protect it by nodemgr_serialize_remove_uds.
- */
- mutex_lock(&nodemgr_serialize_remove_uds);
- for (;;) {
- dev = class_find_device(&nodemgr_ud_class, NULL, ne, match_ne);
- if (!dev)
- break;
- ud = container_of(dev, struct unit_directory, unit_dev);
- put_device(dev);
- device_unregister(&ud->unit_dev);
- device_unregister(&ud->device);
- }
- mutex_unlock(&nodemgr_serialize_remove_uds);
-}
-
-
-static void nodemgr_remove_ne(struct node_entry *ne)
-{
- struct device *dev;
-
- dev = get_device(&ne->device);
- if (!dev)
- return;
-
- HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
- NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
- nodemgr_remove_uds(ne);
-
- device_unregister(&ne->node_dev);
- device_unregister(dev);
-
- put_device(dev);
-}
-
-static int remove_host_dev(struct device *dev, void *data)
-{
- if (dev->bus == &ieee1394_bus_type)
- nodemgr_remove_ne(container_of(dev, struct node_entry,
- device));
- return 0;
-}
-
-static void nodemgr_remove_host_dev(struct device *dev)
-{
- device_for_each_child(dev, NULL, remove_host_dev);
- sysfs_remove_link(&dev->kobj, "irm_id");
- sysfs_remove_link(&dev->kobj, "busmgr_id");
- sysfs_remove_link(&dev->kobj, "host_id");
-}
-
-
-static void nodemgr_update_bus_options(struct node_entry *ne)
-{
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
- static const u16 mr[] = { 4, 64, 1024, 0};
-#endif
- quadlet_t busoptions = be32_to_cpu(ne->csr->bus_info_data[2]);
-
- ne->busopt.irmc = (busoptions >> 31) & 1;
- ne->busopt.cmc = (busoptions >> 30) & 1;
- ne->busopt.isc = (busoptions >> 29) & 1;
- ne->busopt.bmc = (busoptions >> 28) & 1;
- ne->busopt.pmc = (busoptions >> 27) & 1;
- ne->busopt.cyc_clk_acc = (busoptions >> 16) & 0xff;
- ne->busopt.max_rec = 1 << (((busoptions >> 12) & 0xf) + 1);
- ne->busopt.max_rom = (busoptions >> 8) & 0x3;
- ne->busopt.generation = (busoptions >> 4) & 0xf;
- ne->busopt.lnkspd = busoptions & 0x7;
-
- HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
- "cyc_clk_acc=%d max_rec=%d max_rom=%d gen=%d lspd=%d",
- busoptions, ne->busopt.irmc, ne->busopt.cmc,
- ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc,
- ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
- mr[ne->busopt.max_rom],
- ne->busopt.generation, ne->busopt.lnkspd);
-}
-
-
-static struct node_entry *nodemgr_create_node(octlet_t guid,
- struct csr1212_csr *csr, struct hpsb_host *host,
- nodeid_t nodeid, unsigned int generation)
-{
- struct node_entry *ne;
-
- ne = kzalloc(sizeof(*ne), GFP_KERNEL);
- if (!ne)
- goto fail_alloc;
-
- ne->host = host;
- ne->nodeid = nodeid;
- ne->generation = generation;
- ne->needs_probe = true;
-
- ne->guid = guid;
- ne->guid_vendor_id = (guid >> 40) & 0xffffff;
- ne->csr = csr;
-
- memcpy(&ne->device, &nodemgr_dev_template_ne,
- sizeof(ne->device));
- ne->device.parent = &host->device;
- dev_set_name(&ne->device, "%016Lx", (unsigned long long)(ne->guid));
-
- ne->node_dev.parent = &ne->device;
- ne->node_dev.class = &nodemgr_ne_class;
- dev_set_name(&ne->node_dev, "%016Lx", (unsigned long long)(ne->guid));
-
- if (device_register(&ne->device))
- goto fail_devreg;
- if (device_register(&ne->node_dev))
- goto fail_classdevreg;
- get_device(&ne->device);
-
- nodemgr_create_ne_dev_files(ne);
-
- nodemgr_update_bus_options(ne);
-
- HPSB_DEBUG("%s added: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
- (host->node_id == nodeid) ? "Host" : "Node",
- NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
-
- return ne;
-
-fail_classdevreg:
- device_unregister(&ne->device);
-fail_devreg:
- kfree(ne);
-fail_alloc:
- HPSB_ERR("Failed to create node ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
- NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
-
- return NULL;
-}
-
-static int match_ne_guid(struct device *dev, void *data)
-{
- struct node_entry *ne;
- u64 *guid = data;
-
- ne = container_of(dev, struct node_entry, node_dev);
- return ne->guid == *guid;
-}
-
-static struct node_entry *find_entry_by_guid(u64 guid)
-{
- struct device *dev;
- struct node_entry *ne;
-
- dev = class_find_device(&nodemgr_ne_class, NULL, &guid, match_ne_guid);
- if (!dev)
- return NULL;
- ne = container_of(dev, struct node_entry, node_dev);
- put_device(dev);
-
- return ne;
-}
-
-struct match_nodeid_parameter {
- struct hpsb_host *host;
- nodeid_t nodeid;
-};
-
-static int match_ne_nodeid(struct device *dev, void *data)
-{
- int found = 0;
- struct node_entry *ne;
- struct match_nodeid_parameter *p = data;
-
- if (!dev)
- goto ret;
- ne = container_of(dev, struct node_entry, node_dev);
- if (ne->host == p->host && ne->nodeid == p->nodeid)
- found = 1;
-ret:
- return found;
-}
-
-static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
- nodeid_t nodeid)
-{
- struct device *dev;
- struct node_entry *ne;
- struct match_nodeid_parameter p;
-
- p.host = host;
- p.nodeid = nodeid;
-
- dev = class_find_device(&nodemgr_ne_class, NULL, &p, match_ne_nodeid);
- if (!dev)
- return NULL;
- ne = container_of(dev, struct node_entry, node_dev);
- put_device(dev);
-
- return ne;
-}
-
-
-static void nodemgr_register_device(struct node_entry *ne,
- struct unit_directory *ud, struct device *parent)
-{
- memcpy(&ud->device, &nodemgr_dev_template_ud,
- sizeof(ud->device));
-
- ud->device.parent = parent;
-
- dev_set_name(&ud->device, "%s-%u", dev_name(&ne->device), ud->id);
-
- ud->unit_dev.parent = &ud->device;
- ud->unit_dev.class = &nodemgr_ud_class;
- dev_set_name(&ud->unit_dev, "%s-%u", dev_name(&ne->device), ud->id);
-
- if (device_register(&ud->device))
- goto fail_devreg;
- if (device_register(&ud->unit_dev))
- goto fail_classdevreg;
- get_device(&ud->device);
-
- nodemgr_create_ud_dev_files(ud);
-
- return;
-
-fail_classdevreg:
- device_unregister(&ud->device);
-fail_devreg:
- HPSB_ERR("Failed to create unit %s", dev_name(&ud->device));
-}
-
-
-/* This implementation currently only scans the config rom and its
- * immediate unit directories looking for software_id and
- * software_version entries, in order to get driver autoloading working. */
-static struct unit_directory *nodemgr_process_unit_directory
- (struct node_entry *ne, struct csr1212_keyval *ud_kv,
- unsigned int *id, struct unit_directory *parent)
-{
- struct unit_directory *ud;
- struct unit_directory *ud_child = NULL;
- struct csr1212_dentry *dentry;
- struct csr1212_keyval *kv;
- u8 last_key_id = 0;
-
- ud = kzalloc(sizeof(*ud), GFP_KERNEL);
- if (!ud)
- goto unit_directory_error;
-
- ud->ne = ne;
- ud->ignore_driver = ignore_drivers;
- ud->address = ud_kv->offset + CSR1212_REGISTER_SPACE_BASE;
- ud->directory_id = ud->address & 0xffffff;
- ud->ud_kv = ud_kv;
- ud->id = (*id)++;
-
- /* inherit vendor_id from root directory if none exists in unit dir */
- ud->vendor_id = ne->vendor_id;
-
- csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) {
- switch (kv->key.id) {
- case CSR1212_KV_ID_VENDOR:
- if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
- ud->vendor_id = kv->value.immediate;
- ud->flags |= UNIT_DIRECTORY_VENDOR_ID;
- }
- break;
-
- case CSR1212_KV_ID_MODEL:
- ud->model_id = kv->value.immediate;
- ud->flags |= UNIT_DIRECTORY_MODEL_ID;
- break;
-
- case CSR1212_KV_ID_SPECIFIER_ID:
- ud->specifier_id = kv->value.immediate;
- ud->flags |= UNIT_DIRECTORY_SPECIFIER_ID;
- break;
-
- case CSR1212_KV_ID_VERSION:
- ud->version = kv->value.immediate;
- ud->flags |= UNIT_DIRECTORY_VERSION;
- break;
-
- case CSR1212_KV_ID_DESCRIPTOR:
- if (kv->key.type == CSR1212_KV_TYPE_LEAF &&
- CSR1212_DESCRIPTOR_LEAF_TYPE(kv) == 0 &&
- CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID(kv) == 0 &&
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_WIDTH(kv) == 0 &&
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_CHAR_SET(kv) == 0 &&
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_LANGUAGE(kv) == 0) {
- switch (last_key_id) {
- case CSR1212_KV_ID_VENDOR:
- csr1212_keep_keyval(kv);
- ud->vendor_name_kv = kv;
- break;
-
- case CSR1212_KV_ID_MODEL:
- csr1212_keep_keyval(kv);
- ud->model_name_kv = kv;
- break;
-
- }
- } /* else if (kv->key.type == CSR1212_KV_TYPE_DIRECTORY) ... */
- break;
-
- case CSR1212_KV_ID_DEPENDENT_INFO:
- /* Logical Unit Number */
- if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
- if (ud->flags & UNIT_DIRECTORY_HAS_LUN) {
- ud_child = kmemdup(ud, sizeof(*ud_child), GFP_KERNEL);
- if (!ud_child)
- goto unit_directory_error;
- nodemgr_register_device(ne, ud_child, &ne->device);
- ud_child = NULL;
-
- ud->id = (*id)++;
- }
- ud->lun = kv->value.immediate;
- ud->flags |= UNIT_DIRECTORY_HAS_LUN;
-
- /* Logical Unit Directory */
- } else if (kv->key.type == CSR1212_KV_TYPE_DIRECTORY) {
- /* This should really be done in SBP2 as this is
- * doing SBP2 specific parsing.
- */
-
- /* first register the parent unit */
- ud->flags |= UNIT_DIRECTORY_HAS_LUN_DIRECTORY;
- if (ud->device.bus != &ieee1394_bus_type)
- nodemgr_register_device(ne, ud, &ne->device);
-
- /* process the child unit */
- ud_child = nodemgr_process_unit_directory(ne, kv, id, ud);
-
- if (ud_child == NULL)
- break;
-
- /* inherit unspecified values, the driver core picks it up */
- if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) &&
- !(ud_child->flags & UNIT_DIRECTORY_MODEL_ID))
- {
- ud_child->flags |= UNIT_DIRECTORY_MODEL_ID;
- ud_child->model_id = ud->model_id;
- }
- if ((ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) &&
- !(ud_child->flags & UNIT_DIRECTORY_SPECIFIER_ID))
- {
- ud_child->flags |= UNIT_DIRECTORY_SPECIFIER_ID;
- ud_child->specifier_id = ud->specifier_id;
- }
- if ((ud->flags & UNIT_DIRECTORY_VERSION) &&
- !(ud_child->flags & UNIT_DIRECTORY_VERSION))
- {
- ud_child->flags |= UNIT_DIRECTORY_VERSION;
- ud_child->version = ud->version;
- }
-
- /* register the child unit */
- ud_child->flags |= UNIT_DIRECTORY_LUN_DIRECTORY;
- nodemgr_register_device(ne, ud_child, &ud->device);
- }
-
- break;
-
- case CSR1212_KV_ID_DIRECTORY_ID:
- ud->directory_id = kv->value.immediate;
- break;
-
- default:
- break;
- }
- last_key_id = kv->key.id;
- }
-
- /* do not process child units here and only if not already registered */
- if (!parent && ud->device.bus != &ieee1394_bus_type)
- nodemgr_register_device(ne, ud, &ne->device);
-
- return ud;
-
-unit_directory_error:
- kfree(ud);
- return NULL;
-}
-
-
-static void nodemgr_process_root_directory(struct node_entry *ne)
-{
- unsigned int ud_id = 0;
- struct csr1212_dentry *dentry;
- struct csr1212_keyval *kv, *vendor_name_kv = NULL;
- u8 last_key_id = 0;
-
- ne->needs_probe = false;
-
- csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) {
- switch (kv->key.id) {
- case CSR1212_KV_ID_VENDOR:
- ne->vendor_id = kv->value.immediate;
- break;
-
- case CSR1212_KV_ID_NODE_CAPABILITIES:
- ne->capabilities = kv->value.immediate;
- break;
-
- case CSR1212_KV_ID_UNIT:
- nodemgr_process_unit_directory(ne, kv, &ud_id, NULL);
- break;
-
- case CSR1212_KV_ID_DESCRIPTOR:
- if (last_key_id == CSR1212_KV_ID_VENDOR) {
- if (kv->key.type == CSR1212_KV_TYPE_LEAF &&
- CSR1212_DESCRIPTOR_LEAF_TYPE(kv) == 0 &&
- CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID(kv) == 0 &&
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_WIDTH(kv) == 0 &&
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_CHAR_SET(kv) == 0 &&
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_LANGUAGE(kv) == 0) {
- csr1212_keep_keyval(kv);
- vendor_name_kv = kv;
- }
- }
- break;
- }
- last_key_id = kv->key.id;
- }
-
- if (ne->vendor_name_kv) {
- kv = ne->vendor_name_kv;
- ne->vendor_name_kv = vendor_name_kv;
- csr1212_release_keyval(kv);
- } else if (vendor_name_kv) {
- ne->vendor_name_kv = vendor_name_kv;
- if (device_create_file(&ne->device,
- &dev_attr_ne_vendor_name_kv) != 0)
- HPSB_ERR("Failed to add sysfs attribute");
- }
-}
-
-#ifdef CONFIG_HOTPLUG
-
-static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- struct unit_directory *ud;
- int retval = 0;
- /* ieee1394:venNmoNspNverN */
- char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1];
-
- if (!dev)
- return -ENODEV;
-
- ud = container_of(dev, struct unit_directory, unit_dev);
-
- if (ud->ne->in_limbo || ud->ignore_driver)
- return -ENODEV;
-
-#define PUT_ENVP(fmt,val) \
-do { \
- retval = add_uevent_var(env, fmt, val); \
- if (retval) \
- return retval; \
-} while (0)
-
- PUT_ENVP("VENDOR_ID=%06x", ud->vendor_id);
- PUT_ENVP("MODEL_ID=%06x", ud->model_id);
- PUT_ENVP("GUID=%016Lx", (unsigned long long)ud->ne->guid);
- PUT_ENVP("SPECIFIER_ID=%06x", ud->specifier_id);
- PUT_ENVP("VERSION=%06x", ud->version);
- snprintf(buf, sizeof(buf), "ieee1394:ven%08Xmo%08Xsp%08Xver%08X",
- ud->vendor_id,
- ud->model_id,
- ud->specifier_id,
- ud->version);
- PUT_ENVP("MODALIAS=%s", buf);
-
-#undef PUT_ENVP
-
- return 0;
-}
-
-#else
-
-static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- return -ENODEV;
-}
-
-#endif /* CONFIG_HOTPLUG */
-
-
-int __hpsb_register_protocol(struct hpsb_protocol_driver *drv,
- struct module *owner)
-{
- int error;
-
- drv->driver.bus = &ieee1394_bus_type;
- drv->driver.owner = owner;
- drv->driver.name = drv->name;
-
- /* This will cause a probe for devices */
- error = driver_register(&drv->driver);
- if (!error)
- nodemgr_create_drv_files(drv);
- return error;
-}
-
-void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
-{
- nodemgr_remove_drv_files(driver);
- /* This will subsequently disconnect all devices that our driver
- * is attached to. */
- driver_unregister(&driver->driver);
-}
-
-
-/*
- * This function updates nodes that were present on the bus before the
- * reset and still are after the reset. The nodeid and the config rom
- * may have changed, and the drivers managing this device must be
- * informed that this device just went through a bus reset, to allow
- * the to take whatever actions required.
- */
-static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
- nodeid_t nodeid, unsigned int generation)
-{
- if (ne->nodeid != nodeid) {
- HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT,
- NODE_BUS_ARGS(ne->host, ne->nodeid),
- NODE_BUS_ARGS(ne->host, nodeid));
- ne->nodeid = nodeid;
- }
-
- if (ne->busopt.generation != ((be32_to_cpu(csr->bus_info_data[2]) >> 4) & 0xf)) {
- kfree(ne->csr->private);
- csr1212_destroy_csr(ne->csr);
- ne->csr = csr;
-
- /* If the node's configrom generation has changed, we
- * unregister all the unit directories. */
- nodemgr_remove_uds(ne);
-
- nodemgr_update_bus_options(ne);
-
- /* Mark the node as new, so it gets re-probed */
- ne->needs_probe = true;
- } else {
- /* old cache is valid, so update its generation */
- struct nodemgr_csr_info *ci = ne->csr->private;
- ci->generation = generation;
- /* free the partially filled now unneeded new cache */
- kfree(csr->private);
- csr1212_destroy_csr(csr);
- }
-
- /* Finally, mark the node current */
- smp_wmb();
- ne->generation = generation;
-
- if (ne->in_limbo) {
- device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
- ne->in_limbo = false;
-
- HPSB_DEBUG("Node reactivated: "
- "ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
- NODE_BUS_ARGS(ne->host, ne->nodeid),
- (unsigned long long)ne->guid);
- }
-}
-
-static void nodemgr_node_scan_one(struct hpsb_host *host,
- nodeid_t nodeid, int generation)
-{
- struct node_entry *ne;
- octlet_t guid;
- struct csr1212_csr *csr;
- struct nodemgr_csr_info *ci;
- u8 *speed;
-
- ci = kmalloc(sizeof(*ci), GFP_KERNEL);
- kmemcheck_annotate_bitfield(ci, flags);
- if (!ci)
- return;
-
- ci->host = host;
- ci->nodeid = nodeid;
- ci->generation = generation;
-
- /* Prepare for speed probe which occurs when reading the ROM */
- speed = &(host->speed[NODEID_TO_NODE(nodeid)]);
- if (*speed > host->csr.lnk_spd)
- *speed = host->csr.lnk_spd;
- ci->speed_unverified = *speed > IEEE1394_SPEED_100;
-
- /* We need to detect when the ConfigROM's generation has changed,
- * so we only update the node's info when it needs to be. */
-
- csr = csr1212_create_csr(&nodemgr_csr_ops, 5 * sizeof(quadlet_t), ci);
- if (!csr || csr1212_parse_csr(csr) != CSR1212_SUCCESS) {
- HPSB_ERR("Error parsing configrom for node " NODE_BUS_FMT,
- NODE_BUS_ARGS(host, nodeid));
- if (csr)
- csr1212_destroy_csr(csr);
- kfree(ci);
- return;
- }
-
- if (csr->bus_info_data[1] != IEEE1394_BUSID_MAGIC) {
- /* This isn't a 1394 device, but we let it slide. There
- * was a report of a device with broken firmware which
- * reported '2394' instead of '1394', which is obviously a
- * mistake. One would hope that a non-1394 device never
- * gets connected to Firewire bus. If someone does, we
- * shouldn't be held responsible, so we'll allow it with a
- * warning. */
- HPSB_WARN("Node " NODE_BUS_FMT " has invalid busID magic [0x%08x]",
- NODE_BUS_ARGS(host, nodeid), csr->bus_info_data[1]);
- }
-
- guid = ((u64)be32_to_cpu(csr->bus_info_data[3]) << 32) | be32_to_cpu(csr->bus_info_data[4]);
- ne = find_entry_by_guid(guid);
-
- if (ne && ne->host != host && ne->in_limbo) {
- /* Must have moved this device from one host to another */
- nodemgr_remove_ne(ne);
- ne = NULL;
- }
-
- if (!ne)
- nodemgr_create_node(guid, csr, host, nodeid, generation);
- else
- nodemgr_update_node(ne, csr, nodeid, generation);
-}
-
-
-static void nodemgr_node_scan(struct hpsb_host *host, int generation)
-{
- int count;
- struct selfid *sid = (struct selfid *)host->topology_map;
- nodeid_t nodeid = LOCAL_BUS;
-
- /* Scan each node on the bus */
- for (count = host->selfid_count; count; count--, sid++) {
- if (sid->extended)
- continue;
-
- if (!sid->link_active) {
- nodeid++;
- continue;
- }
- nodemgr_node_scan_one(host, nodeid++, generation);
- }
-}
-
-static void nodemgr_pause_ne(struct node_entry *ne)
-{
- HPSB_DEBUG("Node paused: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
- NODE_BUS_ARGS(ne->host, ne->nodeid),
- (unsigned long long)ne->guid);
-
- ne->in_limbo = true;
- WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
-}
-
-static int update_pdrv(struct device *dev, void *data)
-{
- struct unit_directory *ud;
- struct device_driver *drv;
- struct hpsb_protocol_driver *pdrv;
- struct node_entry *ne = data;
- int error;
-
- ud = container_of(dev, struct unit_directory, unit_dev);
- if (ud->ne == ne) {
- drv = get_driver(ud->device.driver);
- if (drv) {
- error = 0;
- pdrv = container_of(drv, struct hpsb_protocol_driver,
- driver);
- if (pdrv->update) {
- device_lock(&ud->device);
- error = pdrv->update(ud);
- device_unlock(&ud->device);
- }
- if (error)
- device_release_driver(&ud->device);
- put_driver(drv);
- }
- }
-
- return 0;
-}
-
-static void nodemgr_update_pdrv(struct node_entry *ne)
-{
- class_for_each_device(&nodemgr_ud_class, NULL, ne, update_pdrv);
-}
-
-/* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This
- * seems like an optional service but in the end it is practically mandatory
- * as a consequence of these clauses.
- *
- * Note that we cannot do a broadcast write to all nodes at once because some
- * pre-1394a devices would hang. */
-static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
-{
- const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
- quadlet_t bc_remote, bc_local;
- int error;
-
- if (!ne->host->is_irm || ne->generation != generation ||
- ne->nodeid == ne->host->node_id)
- return;
-
- bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
-
- /* Check if the register is implemented and 1394a compliant. */
- error = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
- sizeof(bc_remote));
- if (!error && bc_remote & cpu_to_be32(0x80000000) &&
- bc_remote != bc_local)
- hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
-}
-
-
-static void nodemgr_probe_ne(struct hpsb_host *host, struct node_entry *ne,
- int generation)
-{
- struct device *dev;
-
- if (ne->host != host || ne->in_limbo)
- return;
-
- dev = get_device(&ne->device);
- if (!dev)
- return;
-
- nodemgr_irm_write_bc(ne, generation);
-
- /* If "needs_probe", then this is either a new or changed node we
- * rescan totally. If the generation matches for an existing node
- * (one that existed prior to the bus reset) we send update calls
- * down to the drivers. Otherwise, this is a dead node and we
- * suspend it. */
- if (ne->needs_probe)
- nodemgr_process_root_directory(ne);
- else if (ne->generation == generation)
- nodemgr_update_pdrv(ne);
- else
- nodemgr_pause_ne(ne);
-
- put_device(dev);
-}
-
-struct node_probe_parameter {
- struct hpsb_host *host;
- int generation;
- bool probe_now;
-};
-
-static int node_probe(struct device *dev, void *data)
-{
- struct node_probe_parameter *p = data;
- struct node_entry *ne;
-
- if (p->generation != get_hpsb_generation(p->host))
- return -EAGAIN;
-
- ne = container_of(dev, struct node_entry, node_dev);
- if (ne->needs_probe == p->probe_now)
- nodemgr_probe_ne(p->host, ne, p->generation);
- return 0;
-}
-
-static int nodemgr_node_probe(struct hpsb_host *host, int generation)
-{
- struct node_probe_parameter p;
-
- p.host = host;
- p.generation = generation;
- /*
- * Do some processing of the nodes we've probed. This pulls them
- * into the sysfs layer if needed, and can result in processing of
- * unit-directories, or just updating the node and it's
- * unit-directories.
- *
- * Run updates before probes. Usually, updates are time-critical
- * while probes are time-consuming.
- *
- * Meanwhile, another bus reset may have happened. In this case we
- * skip everything here and let the next bus scan handle it.
- * Otherwise we may prematurely remove nodes which are still there.
- */
- p.probe_now = false;
- if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
- return 0;
-
- p.probe_now = true;
- if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
- return 0;
- /*
- * Now let's tell the bus to rescan our devices. This may seem
- * like overhead, but the driver-model core will only scan a
- * device for a driver when either the device is added, or when a
- * new driver is added. A bus reset is a good reason to rescan
- * devices that were there before. For example, an sbp2 device
- * may become available for login, if the host that held it was
- * just removed.
- */
- if (bus_rescan_devices(&ieee1394_bus_type) != 0)
- HPSB_DEBUG("bus_rescan_devices had an error");
-
- return 1;
-}
-
-static int remove_nodes_in_limbo(struct device *dev, void *data)
-{
- struct node_entry *ne;
-
- if (dev->bus != &ieee1394_bus_type)
- return 0;
-
- ne = container_of(dev, struct node_entry, device);
- if (ne->in_limbo)
- nodemgr_remove_ne(ne);
-
- return 0;
-}
-
-static void nodemgr_remove_nodes_in_limbo(struct hpsb_host *host)
-{
- device_for_each_child(&host->device, NULL, remove_nodes_in_limbo);
-}
-
-static int nodemgr_send_resume_packet(struct hpsb_host *host)
-{
- struct hpsb_packet *packet;
- int error = -ENOMEM;
-
- packet = hpsb_make_phypacket(host,
- EXTPHYPACKET_TYPE_RESUME |
- NODEID_TO_NODE(host->node_id) << PHYPACKET_PORT_SHIFT);
- if (packet) {
- packet->no_waiter = 1;
- packet->generation = get_hpsb_generation(host);
- error = hpsb_send_packet(packet);
- }
- if (error)
- HPSB_WARN("fw-host%d: Failed to broadcast resume packet",
- host->id);
- return error;
-}
-
-/* Perform a few high-level IRM responsibilities. */
-static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
-{
- quadlet_t bc;
-
- /* if irm_id == -1 then there is no IRM on this bus */
- if (!host->is_irm || host->irm_id == (nodeid_t)-1)
- return 1;
-
- /* We are a 1394a-2000 compliant IRM. Set the validity bit. */
- host->csr.broadcast_channel |= 0x40000000;
-
- /* If there is no bus manager then we should set the root node's
- * force_root bit to promote bus stability per the 1394
- * spec. (8.4.2.6) */
- if (host->busmgr_id == 0xffff && host->node_count > 1)
- {
- u16 root_node = host->node_count - 1;
-
- /* get cycle master capability flag from root node */
- if (host->is_cycmst ||
- (!hpsb_read(host, LOCAL_BUS | root_node, get_hpsb_generation(host),
- (CSR_REGISTER_BASE + CSR_CONFIG_ROM + 2 * sizeof(quadlet_t)),
- &bc, sizeof(quadlet_t)) &&
- be32_to_cpu(bc) & 1 << CSR_CMC_SHIFT))
- hpsb_send_phy_config(host, root_node, -1);
- else {
- HPSB_DEBUG("The root node is not cycle master capable; "
- "selecting a new root node and resetting...");
-
- if (cycles >= 5) {
- /* Oh screw it! Just leave the bus as it is */
- HPSB_DEBUG("Stopping reset loop for IRM sanity");
- return 1;
- }
-
- hpsb_send_phy_config(host, NODEID_TO_NODE(host->node_id), -1);
- hpsb_reset_bus(host, LONG_RESET_FORCE_ROOT);
-
- return 0;
- }
- }
-
- /* Some devices suspend their ports while being connected to an inactive
- * host adapter, i.e. if connected before the low-level driver is
- * loaded. They become visible either when physically unplugged and
- * replugged, or when receiving a resume packet. Send one once. */
- if (!host->resume_packet_sent && !nodemgr_send_resume_packet(host))
- host->resume_packet_sent = 1;
-
- return 1;
-}
-
-/* We need to ensure that if we are not the IRM, that the IRM node is capable of
- * everything we can do, otherwise issue a bus reset and try to become the IRM
- * ourselves. */
-static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles)
-{
- quadlet_t bc;
- int status;
-
- if (hpsb_disable_irm || host->is_irm)
- return 1;
-
- status = hpsb_read(host, LOCAL_BUS | (host->irm_id),
- get_hpsb_generation(host),
- (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL),
- &bc, sizeof(quadlet_t));
-
- if (status < 0 || !(be32_to_cpu(bc) & 0x80000000)) {
- /* The current irm node does not have a valid BROADCAST_CHANNEL
- * register and we do, so reset the bus with force_root set */
- HPSB_DEBUG("Current remote IRM is not 1394a-2000 compliant, resetting...");
-
- if (cycles >= 5) {
- /* Oh screw it! Just leave the bus as it is */
- HPSB_DEBUG("Stopping reset loop for IRM sanity");
- return 1;
- }
-
- hpsb_send_phy_config(host, NODEID_TO_NODE(host->node_id), -1);
- hpsb_reset_bus(host, LONG_RESET_FORCE_ROOT);
-
- return 0;
- }
-
- return 1;
-}
-
-static int nodemgr_host_thread(void *data)
-{
- struct hpsb_host *host = data;
- unsigned int g, generation = 0;
- int i, reset_cycles = 0;
-
- set_freezable();
- /* Setup our device-model entries */
- nodemgr_create_host_dev_files(host);
-
- for (;;) {
- /* Sleep until next bus reset */
- set_current_state(TASK_INTERRUPTIBLE);
- if (get_hpsb_generation(host) == generation &&
- !kthread_should_stop())
- schedule();
- __set_current_state(TASK_RUNNING);
-
- /* Thread may have been woken up to freeze or to exit */
- if (try_to_freeze())
- continue;
- if (kthread_should_stop())
- goto exit;
-
- /* Pause for 1/4 second in 1/16 second intervals,
- * to make sure things settle down. */
- g = get_hpsb_generation(host);
- for (i = 0; i < 4 ; i++) {
- msleep_interruptible(63);
- try_to_freeze();
- if (kthread_should_stop())
- goto exit;
-
- /* Now get the generation in which the node ID's we collect
- * are valid. During the bus scan we will use this generation
- * for the read transactions, so that if another reset occurs
- * during the scan the transactions will fail instead of
- * returning bogus data. */
- generation = get_hpsb_generation(host);
-
- /* If we get a reset before we are done waiting, then
- * start the waiting over again */
- if (generation != g)
- g = generation, i = 0;
- }
-
- if (!nodemgr_check_irm_capability(host, reset_cycles) ||
- !nodemgr_do_irm_duties(host, reset_cycles)) {
- reset_cycles++;
- continue;
- }
- reset_cycles = 0;
-
- /* Scan our nodes to get the bus options and create node
- * entries. This does not do the sysfs stuff, since that
- * would trigger uevents and such, which is a bad idea at
- * this point. */
- nodemgr_node_scan(host, generation);
-
- /* This actually does the full probe, with sysfs
- * registration. */
- if (!nodemgr_node_probe(host, generation))
- continue;
-
- /* Update some of our sysfs symlinks */
- nodemgr_update_host_dev_links(host);
-
- /* Sleep 3 seconds */
- for (i = 3000/200; i; i--) {
- msleep_interruptible(200);
- try_to_freeze();
- if (kthread_should_stop())
- goto exit;
-
- if (generation != get_hpsb_generation(host))
- break;
- }
- /* Remove nodes which are gone, unless a bus reset happened */
- if (!i)
- nodemgr_remove_nodes_in_limbo(host);
- }
-exit:
- HPSB_VERBOSE("NodeMgr: Exiting thread");
- return 0;
-}
-
-struct per_host_parameter {
- void *data;
- int (*cb)(struct hpsb_host *, void *);
-};
-
-static int per_host(struct device *dev, void *data)
-{
- struct hpsb_host *host;
- struct per_host_parameter *p = data;
-
- host = container_of(dev, struct hpsb_host, host_dev);
- return p->cb(host, p->data);
-}
-
-/**
- * nodemgr_for_each_host - call a function for each IEEE 1394 host
- * @data: an address to supply to the callback
- * @cb: function to call for each host
- *
- * Iterate the hosts, calling a given function with supplied data for each host.
- * If the callback fails on a host, i.e. if it returns a non-zero value, the
- * iteration is stopped.
- *
- * Return value: 0 on success, non-zero on failure (same as returned by last run
- * of the callback).
- */
-int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
-{
- struct per_host_parameter p;
-
- p.cb = cb;
- p.data = data;
- return class_for_each_device(&hpsb_host_class, NULL, &p, per_host);
-}
-
-/* The following two convenience functions use a struct node_entry
- * for addressing a node on the bus. They are intended for use by any
- * process context, not just the nodemgr thread, so we need to be a
- * little careful when reading out the node ID and generation. The
- * thing that can go wrong is that we get the node ID, then a bus
- * reset occurs, and then we read the generation. The node ID is
- * possibly invalid, but the generation is current, and we end up
- * sending a packet to a the wrong node.
- *
- * The solution is to make sure we read the generation first, so that
- * if a reset occurs in the process, we end up with a stale generation
- * and the transactions will fail instead of silently using wrong node
- * ID's.
- */
-
-/**
- * hpsb_node_fill_packet - fill some destination information into a packet
- * @ne: destination node
- * @packet: packet to fill in
- *
- * This will fill in the given, pre-initialised hpsb_packet with the current
- * information from the node entry (host, node ID, bus generation number).
- */
-void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet)
-{
- packet->host = ne->host;
- packet->generation = ne->generation;
- smp_rmb();
- packet->node_id = ne->nodeid;
-}
-
-int hpsb_node_write(struct node_entry *ne, u64 addr,
- quadlet_t *buffer, size_t length)
-{
- unsigned int generation = ne->generation;
-
- smp_rmb();
- return hpsb_write(ne->host, ne->nodeid, generation,
- addr, buffer, length);
-}
-
-static void nodemgr_add_host(struct hpsb_host *host)
-{
- struct host_info *hi;
-
- hi = hpsb_create_hostinfo(&nodemgr_highlevel, host, sizeof(*hi));
- if (!hi) {
- HPSB_ERR("NodeMgr: out of memory in add host");
- return;
- }
- hi->host = host;
- hi->thread = kthread_run(nodemgr_host_thread, host, "knodemgrd_%d",
- host->id);
- if (IS_ERR(hi->thread)) {
- HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id);
- hpsb_destroy_hostinfo(&nodemgr_highlevel, host);
- }
-}
-
-static void nodemgr_host_reset(struct hpsb_host *host)
-{
- struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
-
- if (hi) {
- HPSB_VERBOSE("NodeMgr: Processing reset for host %d", host->id);
- wake_up_process(hi->thread);
- }
-}
-
-static void nodemgr_remove_host(struct hpsb_host *host)
-{
- struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
-
- if (hi) {
- kthread_stop(hi->thread);
- nodemgr_remove_host_dev(&host->device);
- }
-}
-
-static struct hpsb_highlevel nodemgr_highlevel = {
- .name = "Node manager",
- .add_host = nodemgr_add_host,
- .host_reset = nodemgr_host_reset,
- .remove_host = nodemgr_remove_host,
-};
-
-int init_ieee1394_nodemgr(void)
-{
- int error;
-
- error = class_register(&nodemgr_ne_class);
- if (error)
- goto fail_ne;
- error = class_register(&nodemgr_ud_class);
- if (error)
- goto fail_ud;
- error = driver_register(&nodemgr_mid_layer_driver);
- if (error)
- goto fail_ml;
- /* This driver is not used if nodemgr is off (disable_nodemgr=1). */
- nodemgr_dev_template_host.driver = &nodemgr_mid_layer_driver;
-
- hpsb_register_highlevel(&nodemgr_highlevel);
- return 0;
-
-fail_ml:
- class_unregister(&nodemgr_ud_class);
-fail_ud:
- class_unregister(&nodemgr_ne_class);
-fail_ne:
- return error;
-}
-
-void cleanup_ieee1394_nodemgr(void)
-{
- hpsb_unregister_highlevel(&nodemgr_highlevel);
- driver_unregister(&nodemgr_mid_layer_driver);
- class_unregister(&nodemgr_ud_class);
- class_unregister(&nodemgr_ne_class);
-}
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
deleted file mode 100644
index 749b271d310..00000000000
--- a/drivers/ieee1394/nodemgr.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2000 Andreas E. Bombe
- * 2001 Ben Collins <bcollins@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef _IEEE1394_NODEMGR_H
-#define _IEEE1394_NODEMGR_H
-
-#include <linux/device.h>
-#include <asm/system.h>
-#include <asm/types.h>
-
-#include "ieee1394_core.h"
-#include "ieee1394_transactions.h"
-#include "ieee1394_types.h"
-
-struct csr1212_csr;
-struct csr1212_keyval;
-struct hpsb_host;
-struct ieee1394_device_id;
-
-/* This is the start of a Node entry structure. It should be a stable API
- * for which to gather info from the Node Manager about devices attached
- * to the bus. */
-struct bus_options {
- u8 irmc; /* Iso Resource Manager Capable */
- u8 cmc; /* Cycle Master Capable */
- u8 isc; /* Iso Capable */
- u8 bmc; /* Bus Master Capable */
- u8 pmc; /* Power Manager Capable (PNP spec) */
- u8 cyc_clk_acc; /* Cycle clock accuracy */
- u8 max_rom; /* Maximum block read supported in the CSR */
- u8 generation; /* Incremented when configrom changes */
- u8 lnkspd; /* Link speed */
- u16 max_rec; /* Maximum packet size node can receive */
-};
-
-#define UNIT_DIRECTORY_VENDOR_ID 0x01
-#define UNIT_DIRECTORY_MODEL_ID 0x02
-#define UNIT_DIRECTORY_SPECIFIER_ID 0x04
-#define UNIT_DIRECTORY_VERSION 0x08
-#define UNIT_DIRECTORY_HAS_LUN_DIRECTORY 0x10
-#define UNIT_DIRECTORY_LUN_DIRECTORY 0x20
-#define UNIT_DIRECTORY_HAS_LUN 0x40
-
-/*
- * A unit directory corresponds to a protocol supported by the
- * node. If a node supports eg. IP/1394 and AV/C, its config rom has a
- * unit directory for each of these protocols.
- */
-struct unit_directory {
- struct node_entry *ne; /* The node which this directory belongs to */
- octlet_t address; /* Address of the unit directory on the node */
- u8 flags; /* Indicates which entries were read */
-
- quadlet_t vendor_id;
- struct csr1212_keyval *vendor_name_kv;
-
- quadlet_t model_id;
- struct csr1212_keyval *model_name_kv;
- quadlet_t specifier_id;
- quadlet_t version;
- quadlet_t directory_id;
-
- unsigned int id;
-
- int ignore_driver;
-
- int length; /* Number of quadlets */
-
- struct device device;
- struct device unit_dev;
-
- struct csr1212_keyval *ud_kv;
- u32 lun; /* logical unit number immediate value */
-};
-
-struct node_entry {
- u64 guid; /* GUID of this node */
- u32 guid_vendor_id; /* Top 24bits of guid */
-
- struct hpsb_host *host; /* Host this node is attached to */
- nodeid_t nodeid; /* NodeID */
- struct bus_options busopt; /* Bus Options */
- bool needs_probe;
- unsigned int generation; /* Synced with hpsb generation */
-
- /* The following is read from the config rom */
- u32 vendor_id;
- struct csr1212_keyval *vendor_name_kv;
-
- u32 capabilities;
-
- struct device device;
- struct device node_dev;
-
- /* Means this node is not attached anymore */
- bool in_limbo;
-
- struct csr1212_csr *csr;
-};
-
-struct hpsb_protocol_driver {
- /* The name of the driver, e.g. SBP2 or IP1394 */
- const char *name;
-
- /*
- * The device id table describing the protocols and/or devices
- * supported by this driver. This is used by the nodemgr to
- * decide if a driver could support a given node, but the
- * probe function below can implement further protocol
- * dependent or vendor dependent checking.
- */
- const struct ieee1394_device_id *id_table;
-
- /*
- * The update function is called when the node has just
- * survived a bus reset, i.e. it is still present on the bus.
- * However, it may be necessary to reestablish the connection
- * or login into the node again, depending on the protocol. If the
- * probe fails (returns non-zero), we unbind the driver from this
- * device.
- */
- int (*update)(struct unit_directory *ud);
-
- /* Our LDM structure */
- struct device_driver driver;
-};
-
-int __hpsb_register_protocol(struct hpsb_protocol_driver *, struct module *);
-static inline int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
-{
- return __hpsb_register_protocol(driver, THIS_MODULE);
-}
-
-void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
-
-static inline int hpsb_node_entry_valid(struct node_entry *ne)
-{
- return ne->generation == get_hpsb_generation(ne->host);
-}
-void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet);
-int hpsb_node_write(struct node_entry *ne, u64 addr,
- quadlet_t *buffer, size_t length);
-static inline int hpsb_node_read(struct node_entry *ne, u64 addr,
- quadlet_t *buffer, size_t length)
-{
- unsigned int g = ne->generation;
-
- smp_rmb();
- return hpsb_read(ne->host, ne->nodeid, g, addr, buffer, length);
-}
-static inline int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode,
- quadlet_t *buffer, quadlet_t arg)
-{
- unsigned int g = ne->generation;
-
- smp_rmb();
- return hpsb_lock(ne->host, ne->nodeid, g, addr, extcode, buffer, arg);
-}
-int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *));
-
-int init_ieee1394_nodemgr(void);
-void cleanup_ieee1394_nodemgr(void);
-
-/* The template for a host device */
-extern struct device nodemgr_dev_template_host;
-
-/* Bus attributes we export */
-extern struct bus_attribute *const fw_bus_attrs[];
-
-#endif /* _IEEE1394_NODEMGR_H */
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
deleted file mode 100644
index 50815022cff..00000000000
--- a/drivers/ieee1394/ohci1394.c
+++ /dev/null
@@ -1,3590 +0,0 @@
-/*
- * ohci1394.c - driver for OHCI 1394 boards
- * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
- * Gord Peters <GordPeters@smarttech.com>
- * 2001 Ben Collins <bcollins@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- * Things known to be working:
- * . Async Request Transmit
- * . Async Response Receive
- * . Async Request Receive
- * . Async Response Transmit
- * . Iso Receive
- * . DMA mmap for iso receive
- * . Config ROM generation
- *
- * Things implemented, but still in test phase:
- * . Iso Transmit
- * . Async Stream Packets Transmit (Receive done via Iso interface)
- *
- * Things not implemented:
- * . DMA error recovery
- *
- * Known bugs:
- * . devctl BUS_RESET arg confusion (reset type or root holdoff?)
- * added LONG_RESET_ROOT and SHORT_RESET_ROOT for root holdoff --kk
- */
-
-/*
- * Acknowledgments:
- *
- * Adam J Richter <adam@yggdrasil.com>
- * . Use of pci_class to find device
- *
- * Emilie Chung <emilie.chung@axis.com>
- * . Tip on Async Request Filter
- *
- * Pascal Drolet <pascal.drolet@informission.ca>
- * . Various tips for optimization and functionnalities
- *
- * Robert Ficklin <rficklin@westengineering.com>
- * . Loop in irq_handler
- *
- * James Goodwin <jamesg@Filanet.com>
- * . Various tips on initialization, self-id reception, etc.
- *
- * Albrecht Dress <ad@mpifr-bonn.mpg.de>
- * . Apple PowerBook detection
- *
- * Daniel Kobras <daniel.kobras@student.uni-tuebingen.de>
- * . Reset the board properly before leaving + misc cleanups
- *
- * Leon van Stuivenberg <leonvs@iae.nl>
- * . Bug fixes
- *
- * Ben Collins <bcollins@debian.org>
- * . Working big-endian support
- * . Updated to 2.4.x module scheme (PCI aswell)
- * . Config ROM generation
- *
- * Manfred Weihs <weihs@ict.tuwien.ac.at>
- * . Reworked code for initiating bus resets
- * (long, short, with or without hold-off)
- *
- * Nandu Santhi <contactnandu@users.sourceforge.net>
- * . Added support for nVidia nForce2 onboard Firewire chipset
- *
- */
-
-#include <linux/bitops.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
-#include <asm/byteorder.h>
-#include <asm/atomic.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/irq.h>
-#include <linux/types.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-
-#ifdef CONFIG_PPC_PMAC
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#endif
-
-#include "csr1212.h"
-#include "ieee1394.h"
-#include "ieee1394_types.h"
-#include "hosts.h"
-#include "dma.h"
-#include "iso.h"
-#include "ieee1394_core.h"
-#include "highlevel.h"
-#include "ohci1394.h"
-
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-#define OHCI1394_DEBUG
-#endif
-
-#ifdef DBGMSG
-#undef DBGMSG
-#endif
-
-#ifdef OHCI1394_DEBUG
-#define DBGMSG(fmt, args...) \
-printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
-#else
-#define DBGMSG(fmt, args...) do {} while (0)
-#endif
-
-/* print general (card independent) information */
-#define PRINT_G(level, fmt, args...) \
-printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
-
-/* print card specific information */
-#define PRINT(level, fmt, args...) \
-printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
-
-/* Module Parameters */
-static int phys_dma = 1;
-module_param(phys_dma, int, 0444);
-MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
-
-static void dma_trm_tasklet(unsigned long data);
-static void dma_trm_reset(struct dma_trm_ctx *d);
-
-static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
- enum context_type type, int ctx, int num_desc,
- int buf_size, int split_buf_size, int context_base);
-static void free_dma_rcv_ctx(struct dma_rcv_ctx *d);
-
-static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
- enum context_type type, int ctx, int num_desc,
- int context_base);
-
-static void ohci1394_pci_remove(struct pci_dev *pdev);
-
-#ifndef __LITTLE_ENDIAN
-static const size_t hdr_sizes[] = {
- 3, /* TCODE_WRITEQ */
- 4, /* TCODE_WRITEB */
- 3, /* TCODE_WRITE_RESPONSE */
- 0, /* reserved */
- 3, /* TCODE_READQ */
- 4, /* TCODE_READB */
- 3, /* TCODE_READQ_RESPONSE */
- 4, /* TCODE_READB_RESPONSE */
- 1, /* TCODE_CYCLE_START */
- 4, /* TCODE_LOCK_REQUEST */
- 2, /* TCODE_ISO_DATA */
- 4, /* TCODE_LOCK_RESPONSE */
- /* rest is reserved or link-internal */
-};
-
-static inline void header_le32_to_cpu(quadlet_t *data, unsigned char tcode)
-{
- size_t size;
-
- if (unlikely(tcode >= ARRAY_SIZE(hdr_sizes)))
- return;
-
- size = hdr_sizes[tcode];
- while (size--)
- data[size] = le32_to_cpu(data[size]);
-}
-#else
-#define header_le32_to_cpu(w,x) do {} while (0)
-#endif /* !LITTLE_ENDIAN */
-
-/***********************************
- * IEEE-1394 functionality section *
- ***********************************/
-
-static u8 get_phy_reg(struct ti_ohci *ohci, u8 addr)
-{
- int i;
- unsigned long flags;
- quadlet_t r;
-
- spin_lock_irqsave (&ohci->phy_reg_lock, flags);
-
- reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000);
-
- for (i = 0; i < OHCI_LOOP_COUNT; i++) {
- if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000)
- break;
-
- mdelay(1);
- }
-
- r = reg_read(ohci, OHCI1394_PhyControl);
-
- if (i >= OHCI_LOOP_COUNT)
- PRINT (KERN_ERR, "Get PHY Reg timeout [0x%08x/0x%08x/%d]",
- r, r & 0x80000000, i);
-
- spin_unlock_irqrestore (&ohci->phy_reg_lock, flags);
-
- return (r & 0x00ff0000) >> 16;
-}
-
-static void set_phy_reg(struct ti_ohci *ohci, u8 addr, u8 data)
-{
- int i;
- unsigned long flags;
- u32 r = 0;
-
- spin_lock_irqsave (&ohci->phy_reg_lock, flags);
-
- reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000);
-
- for (i = 0; i < OHCI_LOOP_COUNT; i++) {
- r = reg_read(ohci, OHCI1394_PhyControl);
- if (!(r & 0x00004000))
- break;
-
- mdelay(1);
- }
-
- if (i == OHCI_LOOP_COUNT)
- PRINT (KERN_ERR, "Set PHY Reg timeout [0x%08x/0x%08x/%d]",
- r, r & 0x00004000, i);
-
- spin_unlock_irqrestore (&ohci->phy_reg_lock, flags);
-
- return;
-}
-
-/* Or's our value into the current value */
-static void set_phy_reg_mask(struct ti_ohci *ohci, u8 addr, u8 data)
-{
- u8 old;
-
- old = get_phy_reg (ohci, addr);
- old |= data;
- set_phy_reg (ohci, addr, old);
-
- return;
-}
-
-static void handle_selfid(struct ti_ohci *ohci, struct hpsb_host *host,
- int phyid, int isroot)
-{
- quadlet_t *q = ohci->selfid_buf_cpu;
- quadlet_t self_id_count=reg_read(ohci, OHCI1394_SelfIDCount);
- size_t size;
- quadlet_t q0, q1;
-
- /* Check status of self-id reception */
-
- if (ohci->selfid_swap)
- q0 = le32_to_cpu(q[0]);
- else
- q0 = q[0];
-
- if ((self_id_count & 0x80000000) ||
- ((self_id_count & 0x00FF0000) != (q0 & 0x00FF0000))) {
- PRINT(KERN_ERR,
- "Error in reception of SelfID packets [0x%08x/0x%08x] (count: %d)",
- self_id_count, q0, ohci->self_id_errors);
-
- /* Tip by James Goodwin <jamesg@Filanet.com>:
- * We had an error, generate another bus reset in response. */
- if (ohci->self_id_errors<OHCI1394_MAX_SELF_ID_ERRORS) {
- set_phy_reg_mask (ohci, 1, 0x40);
- ohci->self_id_errors++;
- } else {
- PRINT(KERN_ERR,
- "Too many errors on SelfID error reception, giving up!");
- }
- return;
- }
-
- /* SelfID Ok, reset error counter. */
- ohci->self_id_errors = 0;
-
- size = ((self_id_count & 0x00001FFC) >> 2) - 1;
- q++;
-
- while (size > 0) {
- if (ohci->selfid_swap) {
- q0 = le32_to_cpu(q[0]);
- q1 = le32_to_cpu(q[1]);
- } else {
- q0 = q[0];
- q1 = q[1];
- }
-
- if (q0 == ~q1) {
- DBGMSG ("SelfID packet 0x%x received", q0);
- hpsb_selfid_received(host, cpu_to_be32(q0));
- if (((q0 & 0x3f000000) >> 24) == phyid)
- DBGMSG ("SelfID for this node is 0x%08x", q0);
- } else {
- PRINT(KERN_ERR,
- "SelfID is inconsistent [0x%08x/0x%08x]", q0, q1);
- }
- q += 2;
- size -= 2;
- }
-
- DBGMSG("SelfID complete");
-
- return;
-}
-
-static void ohci_soft_reset(struct ti_ohci *ohci) {
- int i;
-
- reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
-
- for (i = 0; i < OHCI_LOOP_COUNT; i++) {
- if (!(reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_softReset))
- break;
- mdelay(1);
- }
- DBGMSG ("Soft reset finished");
-}
-
-
-/* Generate the dma receive prgs and start the context */
-static void initialize_dma_rcv_ctx(struct dma_rcv_ctx *d, int generate_irq)
-{
- struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
- int i;
-
- ohci1394_stop_context(ohci, d->ctrlClear, NULL);
-
- for (i=0; i<d->num_desc; i++) {
- u32 c;
-
- c = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | DMA_CTL_BRANCH;
- if (generate_irq)
- c |= DMA_CTL_IRQ;
-
- d->prg_cpu[i]->control = cpu_to_le32(c | d->buf_size);
-
- /* End of descriptor list? */
- if (i + 1 < d->num_desc) {
- d->prg_cpu[i]->branchAddress =
- cpu_to_le32((d->prg_bus[i+1] & 0xfffffff0) | 0x1);
- } else {
- d->prg_cpu[i]->branchAddress =
- cpu_to_le32((d->prg_bus[0] & 0xfffffff0));
- }
-
- d->prg_cpu[i]->address = cpu_to_le32(d->buf_bus[i]);
- d->prg_cpu[i]->status = cpu_to_le32(d->buf_size);
- }
-
- d->buf_ind = 0;
- d->buf_offset = 0;
-
- if (d->type == DMA_CTX_ISO) {
- /* Clear contextControl */
- reg_write(ohci, d->ctrlClear, 0xffffffff);
-
- /* Set bufferFill, isochHeader, multichannel for IR context */
- reg_write(ohci, d->ctrlSet, 0xd0000000);
-
- /* Set the context match register to match on all tags */
- reg_write(ohci, d->ctxtMatch, 0xf0000000);
-
- /* Clear the multi channel mask high and low registers */
- reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear, 0xffffffff);
- reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear, 0xffffffff);
-
- /* Set up isoRecvIntMask to generate interrupts */
- reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << d->ctx);
- }
-
- /* Tell the controller where the first AR program is */
- reg_write(ohci, d->cmdPtr, d->prg_bus[0] | 0x1);
-
- /* Run context */
- reg_write(ohci, d->ctrlSet, 0x00008000);
-
- DBGMSG("Receive DMA ctx=%d initialized", d->ctx);
-}
-
-/* Initialize the dma transmit context */
-static void initialize_dma_trm_ctx(struct dma_trm_ctx *d)
-{
- struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
-
- /* Stop the context */
- ohci1394_stop_context(ohci, d->ctrlClear, NULL);
-
- d->prg_ind = 0;
- d->sent_ind = 0;
- d->free_prgs = d->num_desc;
- d->branchAddrPtr = NULL;
- INIT_LIST_HEAD(&d->fifo_list);
- INIT_LIST_HEAD(&d->pending_list);
-
- if (d->type == DMA_CTX_ISO) {
- /* enable interrupts */
- reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << d->ctx);
- }
-
- DBGMSG("Transmit DMA ctx=%d initialized", d->ctx);
-}
-
-/* Count the number of available iso contexts */
-static int get_nb_iso_ctx(struct ti_ohci *ohci, int reg)
-{
- u32 tmp;
-
- reg_write(ohci, reg, 0xffffffff);
- tmp = reg_read(ohci, reg);
-
- DBGMSG("Iso contexts reg: %08x implemented: %08x", reg, tmp);
-
- /* Count the number of contexts */
- return hweight32(tmp);
-}
-
-/* Global initialization */
-static void ohci_initialize(struct ti_ohci *ohci)
-{
- quadlet_t buf;
- int num_ports, i;
-
- spin_lock_init(&ohci->phy_reg_lock);
-
- /* Put some defaults to these undefined bus options */
- buf = reg_read(ohci, OHCI1394_BusOptions);
- buf |= 0x60000000; /* Enable CMC and ISC */
- if (hpsb_disable_irm)
- buf &= ~0x80000000;
- else
- buf |= 0x80000000; /* Enable IRMC */
- buf &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */
- buf &= ~0x18000000; /* Disable PMC and BMC */
- reg_write(ohci, OHCI1394_BusOptions, buf);
-
- /* Set the bus number */
- reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0);
-
- /* Enable posted writes */
- reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_postedWriteEnable);
-
- /* Clear link control register */
- reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
-
- /* Enable cycle timer and cycle master and set the IRM
- * contender bit in our self ID packets if appropriate. */
- reg_write(ohci, OHCI1394_LinkControlSet,
- OHCI1394_LinkControl_CycleTimerEnable |
- OHCI1394_LinkControl_CycleMaster);
- i = get_phy_reg(ohci, 4) | PHY_04_LCTRL;
- if (hpsb_disable_irm)
- i &= ~PHY_04_CONTENDER;
- else
- i |= PHY_04_CONTENDER;
- set_phy_reg(ohci, 4, i);
-
- /* Set up self-id dma buffer */
- reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->selfid_buf_bus);
-
- /* enable self-id */
- reg_write(ohci, OHCI1394_LinkControlSet, OHCI1394_LinkControl_RcvSelfID);
-
- /* Set the Config ROM mapping register */
- reg_write(ohci, OHCI1394_ConfigROMmap, ohci->csr_config_rom_bus);
-
- /* Now get our max packet size */
- ohci->max_packet_size =
- 1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1);
-
- /* Clear the interrupt mask */
- reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff);
- reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff);
-
- /* Clear the interrupt mask */
- reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff);
- reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);
-
- /* Initialize AR dma */
- initialize_dma_rcv_ctx(&ohci->ar_req_context, 0);
- initialize_dma_rcv_ctx(&ohci->ar_resp_context, 0);
-
- /* Initialize AT dma */
- initialize_dma_trm_ctx(&ohci->at_req_context);
- initialize_dma_trm_ctx(&ohci->at_resp_context);
-
- /* Accept AR requests from all nodes */
- reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);
-
- /* Set the address range of the physical response unit.
- * Most controllers do not implement it as a writable register though.
- * They will keep a hardwired offset of 0x00010000 and show 0x0 as
- * register content.
- * To actually enable physical responses is the job of our interrupt
- * handler which programs the physical request filter. */
- reg_write(ohci, OHCI1394_PhyUpperBound,
- OHCI1394_PHYS_UPPER_BOUND_PROGRAMMED >> 16);
-
- DBGMSG("physUpperBoundOffset=%08x",
- reg_read(ohci, OHCI1394_PhyUpperBound));
-
- /* Specify AT retries */
- reg_write(ohci, OHCI1394_ATRetries,
- OHCI1394_MAX_AT_REQ_RETRIES |
- (OHCI1394_MAX_AT_RESP_RETRIES<<4) |
- (OHCI1394_MAX_PHYS_RESP_RETRIES<<8));
-
- /* We don't want hardware swapping */
- reg_write(ohci, OHCI1394_HCControlClear, OHCI1394_HCControl_noByteSwap);
-
- /* Enable interrupts */
- reg_write(ohci, OHCI1394_IntMaskSet,
- OHCI1394_unrecoverableError |
- OHCI1394_masterIntEnable |
- OHCI1394_busReset |
- OHCI1394_selfIDComplete |
- OHCI1394_RSPkt |
- OHCI1394_RQPkt |
- OHCI1394_respTxComplete |
- OHCI1394_reqTxComplete |
- OHCI1394_isochRx |
- OHCI1394_isochTx |
- OHCI1394_postedWriteErr |
- OHCI1394_cycleTooLong |
- OHCI1394_cycleInconsistent);
-
- /* Enable link */
- reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
-
- buf = reg_read(ohci, OHCI1394_Version);
- PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%d] "
- "MMIO=[%llx-%llx] Max Packet=[%d] IR/IT contexts=[%d/%d]",
- ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
- ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq,
- (unsigned long long)pci_resource_start(ohci->dev, 0),
- (unsigned long long)pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1,
- ohci->max_packet_size,
- ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx);
-
- /* Check all of our ports to make sure that if anything is
- * connected, we enable that port. */
- num_ports = get_phy_reg(ohci, 2) & 0xf;
- for (i = 0; i < num_ports; i++) {
- unsigned int status;
-
- set_phy_reg(ohci, 7, i);
- status = get_phy_reg(ohci, 8);
-
- if (status & 0x20)
- set_phy_reg(ohci, 8, status & ~1);
- }
-
- /* Serial EEPROM Sanity check. */
- if ((ohci->max_packet_size < 512) ||
- (ohci->max_packet_size > 4096)) {
- /* Serial EEPROM contents are suspect, set a sane max packet
- * size and print the raw contents for bug reports if verbose
- * debug is enabled. */
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
- int i;
-#endif
-
- PRINT(KERN_DEBUG, "Serial EEPROM has suspicious values, "
- "attempting to set max_packet_size to 512 bytes");
- reg_write(ohci, OHCI1394_BusOptions,
- (reg_read(ohci, OHCI1394_BusOptions) & 0xf007) | 0x8002);
- ohci->max_packet_size = 512;
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
- PRINT(KERN_DEBUG, " EEPROM Present: %d",
- (reg_read(ohci, OHCI1394_Version) >> 24) & 0x1);
- reg_write(ohci, OHCI1394_GUID_ROM, 0x80000000);
-
- for (i = 0;
- ((i < 1000) &&
- (reg_read(ohci, OHCI1394_GUID_ROM) & 0x80000000)); i++)
- udelay(10);
-
- for (i = 0; i < 0x20; i++) {
- reg_write(ohci, OHCI1394_GUID_ROM, 0x02000000);
- PRINT(KERN_DEBUG, " EEPROM %02x: %02x", i,
- (reg_read(ohci, OHCI1394_GUID_ROM) >> 16) & 0xff);
- }
-#endif
- }
-}
-
-/*
- * Insert a packet in the DMA fifo and generate the DMA prg
- * FIXME: rewrite the program in order to accept packets crossing
- * page boundaries.
- * check also that a single dma descriptor doesn't cross a
- * page boundary.
- */
-static void insert_packet(struct ti_ohci *ohci,
- struct dma_trm_ctx *d, struct hpsb_packet *packet)
-{
- u32 cycleTimer;
- int idx = d->prg_ind;
-
- DBGMSG("Inserting packet for node " NODE_BUS_FMT
- ", tlabel=%d, tcode=0x%x, speed=%d",
- NODE_BUS_ARGS(ohci->host, packet->node_id), packet->tlabel,
- packet->tcode, packet->speed_code);
-
- d->prg_cpu[idx]->begin.address = 0;
- d->prg_cpu[idx]->begin.branchAddress = 0;
-
- if (d->type == DMA_CTX_ASYNC_RESP) {
- /*
- * For response packets, we need to put a timeout value in
- * the 16 lower bits of the status... let's try 1 sec timeout
- */
- cycleTimer = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
- d->prg_cpu[idx]->begin.status = cpu_to_le32(
- (((((cycleTimer>>25)&0x7)+1)&0x7)<<13) |
- ((cycleTimer&0x01fff000)>>12));
-
- DBGMSG("cycleTimer: %08x timeStamp: %08x",
- cycleTimer, d->prg_cpu[idx]->begin.status);
- } else
- d->prg_cpu[idx]->begin.status = 0;
-
- if ( (packet->type == hpsb_async) || (packet->type == hpsb_raw) ) {
-
- if (packet->type == hpsb_raw) {
- d->prg_cpu[idx]->data[0] = cpu_to_le32(OHCI1394_TCODE_PHY<<4);
- d->prg_cpu[idx]->data[1] = cpu_to_le32(packet->header[0]);
- d->prg_cpu[idx]->data[2] = cpu_to_le32(packet->header[1]);
- } else {
- d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
- (packet->header[0] & 0xFFFF);
-
- if (packet->tcode == TCODE_ISO_DATA) {
- /* Sending an async stream packet */
- d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000;
- } else {
- /* Sending a normal async request or response */
- d->prg_cpu[idx]->data[1] =
- (packet->header[1] & 0xFFFF) |
- (packet->header[0] & 0xFFFF0000);
- d->prg_cpu[idx]->data[2] = packet->header[2];
- d->prg_cpu[idx]->data[3] = packet->header[3];
- }
- header_le32_to_cpu(d->prg_cpu[idx]->data, packet->tcode);
- }
-
- if (packet->data_size) { /* block transmit */
- if (packet->tcode == TCODE_STREAM_DATA){
- d->prg_cpu[idx]->begin.control =
- cpu_to_le32(DMA_CTL_OUTPUT_MORE |
- DMA_CTL_IMMEDIATE | 0x8);
- } else {
- d->prg_cpu[idx]->begin.control =
- cpu_to_le32(DMA_CTL_OUTPUT_MORE |
- DMA_CTL_IMMEDIATE | 0x10);
- }
- d->prg_cpu[idx]->end.control =
- cpu_to_le32(DMA_CTL_OUTPUT_LAST |
- DMA_CTL_IRQ |
- DMA_CTL_BRANCH |
- packet->data_size);
- /*
- * Check that the packet data buffer
- * does not cross a page boundary.
- *
- * XXX Fix this some day. eth1394 seems to trigger
- * it, but ignoring it doesn't seem to cause a
- * problem.
- */
-#if 0
- if (cross_bound((unsigned long)packet->data,
- packet->data_size)>0) {
- /* FIXME: do something about it */
- PRINT(KERN_ERR,
- "%s: packet data addr: %p size %Zd bytes "
- "cross page boundary", __func__,
- packet->data, packet->data_size);
- }
-#endif
- d->prg_cpu[idx]->end.address = cpu_to_le32(
- pci_map_single(ohci->dev, packet->data,
- packet->data_size,
- PCI_DMA_TODEVICE));
-
- d->prg_cpu[idx]->end.branchAddress = 0;
- d->prg_cpu[idx]->end.status = 0;
- if (d->branchAddrPtr)
- *(d->branchAddrPtr) =
- cpu_to_le32(d->prg_bus[idx] | 0x3);
- d->branchAddrPtr =
- &(d->prg_cpu[idx]->end.branchAddress);
- } else { /* quadlet transmit */
- if (packet->type == hpsb_raw)
- d->prg_cpu[idx]->begin.control =
- cpu_to_le32(DMA_CTL_OUTPUT_LAST |
- DMA_CTL_IMMEDIATE |
- DMA_CTL_IRQ |
- DMA_CTL_BRANCH |
- (packet->header_size + 4));
- else
- d->prg_cpu[idx]->begin.control =
- cpu_to_le32(DMA_CTL_OUTPUT_LAST |
- DMA_CTL_IMMEDIATE |
- DMA_CTL_IRQ |
- DMA_CTL_BRANCH |
- packet->header_size);
-
- if (d->branchAddrPtr)
- *(d->branchAddrPtr) =
- cpu_to_le32(d->prg_bus[idx] | 0x2);
- d->branchAddrPtr =
- &(d->prg_cpu[idx]->begin.branchAddress);
- }
-
- } else { /* iso packet */
- d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
- (packet->header[0] & 0xFFFF);
- d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000;
- header_le32_to_cpu(d->prg_cpu[idx]->data, packet->tcode);
-
- d->prg_cpu[idx]->begin.control =
- cpu_to_le32(DMA_CTL_OUTPUT_MORE |
- DMA_CTL_IMMEDIATE | 0x8);
- d->prg_cpu[idx]->end.control =
- cpu_to_le32(DMA_CTL_OUTPUT_LAST |
- DMA_CTL_UPDATE |
- DMA_CTL_IRQ |
- DMA_CTL_BRANCH |
- packet->data_size);
- d->prg_cpu[idx]->end.address = cpu_to_le32(
- pci_map_single(ohci->dev, packet->data,
- packet->data_size, PCI_DMA_TODEVICE));
-
- d->prg_cpu[idx]->end.branchAddress = 0;
- d->prg_cpu[idx]->end.status = 0;
- DBGMSG("Iso xmit context info: header[%08x %08x]\n"
- " begin=%08x %08x %08x %08x\n"
- " %08x %08x %08x %08x\n"
- " end =%08x %08x %08x %08x",
- d->prg_cpu[idx]->data[0], d->prg_cpu[idx]->data[1],
- d->prg_cpu[idx]->begin.control,
- d->prg_cpu[idx]->begin.address,
- d->prg_cpu[idx]->begin.branchAddress,
- d->prg_cpu[idx]->begin.status,
- d->prg_cpu[idx]->data[0],
- d->prg_cpu[idx]->data[1],
- d->prg_cpu[idx]->data[2],
- d->prg_cpu[idx]->data[3],
- d->prg_cpu[idx]->end.control,
- d->prg_cpu[idx]->end.address,
- d->prg_cpu[idx]->end.branchAddress,
- d->prg_cpu[idx]->end.status);
- if (d->branchAddrPtr)
- *(d->branchAddrPtr) = cpu_to_le32(d->prg_bus[idx] | 0x3);
- d->branchAddrPtr = &(d->prg_cpu[idx]->end.branchAddress);
- }
- d->free_prgs--;
-
- /* queue the packet in the appropriate context queue */
- list_add_tail(&packet->driver_list, &d->fifo_list);
- d->prg_ind = (d->prg_ind + 1) % d->num_desc;
-}
-
-/*
- * This function fills the FIFO with the (eventual) pending packets
- * and runs or wakes up the DMA prg if necessary.
- *
- * The function MUST be called with the d->lock held.
- */
-static void dma_trm_flush(struct ti_ohci *ohci, struct dma_trm_ctx *d)
-{
- struct hpsb_packet *packet, *ptmp;
- int idx = d->prg_ind;
- int z = 0;
-
- /* insert the packets into the dma fifo */
- list_for_each_entry_safe(packet, ptmp, &d->pending_list, driver_list) {
- if (!d->free_prgs)
- break;
-
- /* For the first packet only */
- if (!z)
- z = (packet->data_size) ? 3 : 2;
-
- /* Insert the packet */
- list_del_init(&packet->driver_list);
- insert_packet(ohci, d, packet);
- }
-
- /* Nothing must have been done, either no free_prgs or no packets */
- if (z == 0)
- return;
-
- /* Is the context running ? (should be unless it is
- the first packet to be sent in this context) */
- if (!(reg_read(ohci, d->ctrlSet) & 0x8000)) {
- u32 nodeId = reg_read(ohci, OHCI1394_NodeID);
-
- DBGMSG("Starting transmit DMA ctx=%d",d->ctx);
- reg_write(ohci, d->cmdPtr, d->prg_bus[idx] | z);
-
- /* Check that the node id is valid, and not 63 */
- if (!(nodeId & 0x80000000) || (nodeId & 0x3f) == 63)
- PRINT(KERN_ERR, "Running dma failed because Node ID is not valid");
- else
- reg_write(ohci, d->ctrlSet, 0x8000);
- } else {
- /* Wake up the dma context if necessary */
- if (!(reg_read(ohci, d->ctrlSet) & 0x400))
- DBGMSG("Waking transmit DMA ctx=%d",d->ctx);
-
- /* do this always, to avoid race condition */
- reg_write(ohci, d->ctrlSet, 0x1000);
- }
-
- return;
-}
-
-/* Transmission of an async or iso packet */
-static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
-{
- struct ti_ohci *ohci = host->hostdata;
- struct dma_trm_ctx *d;
- unsigned long flags;
-
- if (packet->data_size > ohci->max_packet_size) {
- PRINT(KERN_ERR,
- "Transmit packet size %Zd is too big",
- packet->data_size);
- return -EOVERFLOW;
- }
-
- if (packet->type == hpsb_raw)
- d = &ohci->at_req_context;
- else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA))
- d = &ohci->at_resp_context;
- else
- d = &ohci->at_req_context;
-
- spin_lock_irqsave(&d->lock,flags);
-
- list_add_tail(&packet->driver_list, &d->pending_list);
-
- dma_trm_flush(ohci, d);
-
- spin_unlock_irqrestore(&d->lock,flags);
-
- return 0;
-}
-
-static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
-{
- struct ti_ohci *ohci = host->hostdata;
- int retval = 0, phy_reg;
-
- switch (cmd) {
- case RESET_BUS:
- switch (arg) {
- case SHORT_RESET:
- phy_reg = get_phy_reg(ohci, 5);
- phy_reg |= 0x40;
- set_phy_reg(ohci, 5, phy_reg); /* set ISBR */
- break;
- case LONG_RESET:
- phy_reg = get_phy_reg(ohci, 1);
- phy_reg |= 0x40;
- set_phy_reg(ohci, 1, phy_reg); /* set IBR */
- break;
- case SHORT_RESET_NO_FORCE_ROOT:
- phy_reg = get_phy_reg(ohci, 1);
- if (phy_reg & 0x80) {
- phy_reg &= ~0x80;
- set_phy_reg(ohci, 1, phy_reg); /* clear RHB */
- }
-
- phy_reg = get_phy_reg(ohci, 5);
- phy_reg |= 0x40;
- set_phy_reg(ohci, 5, phy_reg); /* set ISBR */
- break;
- case LONG_RESET_NO_FORCE_ROOT:
- phy_reg = get_phy_reg(ohci, 1);
- phy_reg &= ~0x80;
- phy_reg |= 0x40;
- set_phy_reg(ohci, 1, phy_reg); /* clear RHB, set IBR */
- break;
- case SHORT_RESET_FORCE_ROOT:
- phy_reg = get_phy_reg(ohci, 1);
- if (!(phy_reg & 0x80)) {
- phy_reg |= 0x80;
- set_phy_reg(ohci, 1, phy_reg); /* set RHB */
- }
-
- phy_reg = get_phy_reg(ohci, 5);
- phy_reg |= 0x40;
- set_phy_reg(ohci, 5, phy_reg); /* set ISBR */
- break;
- case LONG_RESET_FORCE_ROOT:
- phy_reg = get_phy_reg(ohci, 1);
- phy_reg |= 0xc0;
- set_phy_reg(ohci, 1, phy_reg); /* set RHB and IBR */
- break;
- default:
- retval = -1;
- }
- break;
-
- case GET_CYCLE_COUNTER:
- retval = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
- break;
-
- case SET_CYCLE_COUNTER:
- reg_write(ohci, OHCI1394_IsochronousCycleTimer, arg);
- break;
-
- case SET_BUS_ID:
- PRINT(KERN_ERR, "devctl command SET_BUS_ID err");
- break;
-
- case ACT_CYCLE_MASTER:
- if (arg) {
- /* check if we are root and other nodes are present */
- u32 nodeId = reg_read(ohci, OHCI1394_NodeID);
- if ((nodeId & (1<<30)) && (nodeId & 0x3f)) {
- /*
- * enable cycleTimer, cycleMaster
- */
- DBGMSG("Cycle master enabled");
- reg_write(ohci, OHCI1394_LinkControlSet,
- OHCI1394_LinkControl_CycleTimerEnable |
- OHCI1394_LinkControl_CycleMaster);
- }
- } else {
- /* disable cycleTimer, cycleMaster, cycleSource */
- reg_write(ohci, OHCI1394_LinkControlClear,
- OHCI1394_LinkControl_CycleTimerEnable |
- OHCI1394_LinkControl_CycleMaster |
- OHCI1394_LinkControl_CycleSource);
- }
- break;
-
- case CANCEL_REQUESTS:
- DBGMSG("Cancel request received");
- dma_trm_reset(&ohci->at_req_context);
- dma_trm_reset(&ohci->at_resp_context);
- break;
-
- default:
- PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet",
- cmd);
- break;
- }
- return retval;
-}
-
-/***********************************
- * rawiso ISO reception *
- ***********************************/
-
-/*
- We use either buffer-fill or packet-per-buffer DMA mode. The DMA
- buffer is split into "blocks" (regions described by one DMA
- descriptor). Each block must be one page or less in size, and
- must not cross a page boundary.
-
- There is one little wrinkle with buffer-fill mode: a packet that
- starts in the final block may wrap around into the first block. But
- the user API expects all packets to be contiguous. Our solution is
- to keep the very last page of the DMA buffer in reserve - if a
- packet spans the gap, we copy its tail into this page.
-*/
-
-struct ohci_iso_recv {
- struct ti_ohci *ohci;
-
- struct ohci1394_iso_tasklet task;
- int task_active;
-
- enum { BUFFER_FILL_MODE = 0,
- PACKET_PER_BUFFER_MODE = 1 } dma_mode;
-
- /* memory and PCI mapping for the DMA descriptors */
- struct dma_prog_region prog;
- struct dma_cmd *block; /* = (struct dma_cmd*) prog.virt */
-
- /* how many DMA blocks fit in the buffer */
- unsigned int nblocks;
-
- /* stride of DMA blocks */
- unsigned int buf_stride;
-
- /* number of blocks to batch between interrupts */
- int block_irq_interval;
-
- /* block that DMA will finish next */
- int block_dma;
-
- /* (buffer-fill only) block that the reader will release next */
- int block_reader;
-
- /* (buffer-fill only) bytes of buffer the reader has released,
- less than one block */
- int released_bytes;
-
- /* (buffer-fill only) buffer offset at which the next packet will appear */
- int dma_offset;
-
- /* OHCI DMA context control registers */
- u32 ContextControlSet;
- u32 ContextControlClear;
- u32 CommandPtr;
- u32 ContextMatch;
-};
-
-static void ohci_iso_recv_task(unsigned long data);
-static void ohci_iso_recv_stop(struct hpsb_iso *iso);
-static void ohci_iso_recv_shutdown(struct hpsb_iso *iso);
-static int ohci_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync);
-static void ohci_iso_recv_program(struct hpsb_iso *iso);
-
-static int ohci_iso_recv_init(struct hpsb_iso *iso)
-{
- struct ti_ohci *ohci = iso->host->hostdata;
- struct ohci_iso_recv *recv;
- int ctx;
- int ret = -ENOMEM;
-
- recv = kmalloc(sizeof(*recv), GFP_KERNEL);
- if (!recv)
- return -ENOMEM;
-
- iso->hostdata = recv;
- recv->ohci = ohci;
- recv->task_active = 0;
- dma_prog_region_init(&recv->prog);
- recv->block = NULL;
-
- /* use buffer-fill mode, unless irq_interval is 1
- (note: multichannel requires buffer-fill) */
-
- if (((iso->irq_interval == 1 && iso->dma_mode == HPSB_ISO_DMA_OLD_ABI) ||
- iso->dma_mode == HPSB_ISO_DMA_PACKET_PER_BUFFER) && iso->channel != -1) {
- recv->dma_mode = PACKET_PER_BUFFER_MODE;
- } else {
- recv->dma_mode = BUFFER_FILL_MODE;
- }
-
- /* set nblocks, buf_stride, block_irq_interval */
-
- if (recv->dma_mode == BUFFER_FILL_MODE) {
- recv->buf_stride = PAGE_SIZE;
-
- /* one block per page of data in the DMA buffer, minus the final guard page */
- recv->nblocks = iso->buf_size/PAGE_SIZE - 1;
- if (recv->nblocks < 3) {
- DBGMSG("ohci_iso_recv_init: DMA buffer too small");
- goto err;
- }
-
- /* iso->irq_interval is in packets - translate that to blocks */
- if (iso->irq_interval == 1)
- recv->block_irq_interval = 1;
- else
- recv->block_irq_interval = iso->irq_interval *
- ((recv->nblocks+1)/iso->buf_packets);
- if (recv->block_irq_interval*4 > recv->nblocks)
- recv->block_irq_interval = recv->nblocks/4;
- if (recv->block_irq_interval < 1)
- recv->block_irq_interval = 1;
-
- } else {
- int max_packet_size;
-
- recv->nblocks = iso->buf_packets;
- recv->block_irq_interval = iso->irq_interval;
- if (recv->block_irq_interval * 4 > iso->buf_packets)
- recv->block_irq_interval = iso->buf_packets / 4;
- if (recv->block_irq_interval < 1)
- recv->block_irq_interval = 1;
-
- /* choose a buffer stride */
- /* must be a power of 2, and <= PAGE_SIZE */
-
- max_packet_size = iso->buf_size / iso->buf_packets;
-
- for (recv->buf_stride = 8; recv->buf_stride < max_packet_size;
- recv->buf_stride *= 2);
-
- if (recv->buf_stride*iso->buf_packets > iso->buf_size ||
- recv->buf_stride > PAGE_SIZE) {
- /* this shouldn't happen, but anyway... */
- DBGMSG("ohci_iso_recv_init: problem choosing a buffer stride");
- goto err;
- }
- }
-
- recv->block_reader = 0;
- recv->released_bytes = 0;
- recv->block_dma = 0;
- recv->dma_offset = 0;
-
- /* size of DMA program = one descriptor per block */
- if (dma_prog_region_alloc(&recv->prog,
- sizeof(struct dma_cmd) * recv->nblocks,
- recv->ohci->dev))
- goto err;
-
- recv->block = (struct dma_cmd*) recv->prog.kvirt;
-
- ohci1394_init_iso_tasklet(&recv->task,
- iso->channel == -1 ? OHCI_ISO_MULTICHANNEL_RECEIVE :
- OHCI_ISO_RECEIVE,
- ohci_iso_recv_task, (unsigned long) iso);
-
- if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) {
- ret = -EBUSY;
- goto err;
- }
-
- recv->task_active = 1;
-
- /* recv context registers are spaced 32 bytes apart */
- ctx = recv->task.context;
- recv->ContextControlSet = OHCI1394_IsoRcvContextControlSet + 32 * ctx;
- recv->ContextControlClear = OHCI1394_IsoRcvContextControlClear + 32 * ctx;
- recv->CommandPtr = OHCI1394_IsoRcvCommandPtr + 32 * ctx;
- recv->ContextMatch = OHCI1394_IsoRcvContextMatch + 32 * ctx;
-
- if (iso->channel == -1) {
- /* clear multi-channel selection mask */
- reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, 0xFFFFFFFF);
- reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, 0xFFFFFFFF);
- }
-
- /* write the DMA program */
- ohci_iso_recv_program(iso);
-
- DBGMSG("ohci_iso_recv_init: %s mode, DMA buffer is %lu pages"
- " (%u bytes), using %u blocks, buf_stride %u, block_irq_interval %d",
- recv->dma_mode == BUFFER_FILL_MODE ?
- "buffer-fill" : "packet-per-buffer",
- iso->buf_size/PAGE_SIZE, iso->buf_size,
- recv->nblocks, recv->buf_stride, recv->block_irq_interval);
-
- return 0;
-
-err:
- ohci_iso_recv_shutdown(iso);
- return ret;
-}
-
-static void ohci_iso_recv_stop(struct hpsb_iso *iso)
-{
- struct ohci_iso_recv *recv = iso->hostdata;
-
- /* disable interrupts */
- reg_write(recv->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << recv->task.context);
-
- /* halt DMA */
- ohci1394_stop_context(recv->ohci, recv->ContextControlClear, NULL);
-}
-
-static void ohci_iso_recv_shutdown(struct hpsb_iso *iso)
-{
- struct ohci_iso_recv *recv = iso->hostdata;
-
- if (recv->task_active) {
- ohci_iso_recv_stop(iso);
- ohci1394_unregister_iso_tasklet(recv->ohci, &recv->task);
- recv->task_active = 0;
- }
-
- dma_prog_region_free(&recv->prog);
- kfree(recv);
- iso->hostdata = NULL;
-}
-
-/* set up a "gapped" ring buffer DMA program */
-static void ohci_iso_recv_program(struct hpsb_iso *iso)
-{
- struct ohci_iso_recv *recv = iso->hostdata;
- int blk;
-
- /* address of 'branch' field in previous DMA descriptor */
- u32 *prev_branch = NULL;
-
- for (blk = 0; blk < recv->nblocks; blk++) {
- u32 control;
-
- /* the DMA descriptor */
- struct dma_cmd *cmd = &recv->block[blk];
-
- /* offset of the DMA descriptor relative to the DMA prog buffer */
- unsigned long prog_offset = blk * sizeof(struct dma_cmd);
-
- /* offset of this packet's data within the DMA buffer */
- unsigned long buf_offset = blk * recv->buf_stride;
-
- if (recv->dma_mode == BUFFER_FILL_MODE) {
- control = 2 << 28; /* INPUT_MORE */
- } else {
- control = 3 << 28; /* INPUT_LAST */
- }
-
- control |= 8 << 24; /* s = 1, update xferStatus and resCount */
-
- /* interrupt on last block, and at intervals */
- if (blk == recv->nblocks-1 || (blk % recv->block_irq_interval) == 0) {
- control |= 3 << 20; /* want interrupt */
- }
-
- control |= 3 << 18; /* enable branch to address */
- control |= recv->buf_stride;
-
- cmd->control = cpu_to_le32(control);
- cmd->address = cpu_to_le32(dma_region_offset_to_bus(&iso->data_buf, buf_offset));
- cmd->branchAddress = 0; /* filled in on next loop */
- cmd->status = cpu_to_le32(recv->buf_stride);
-
- /* link the previous descriptor to this one */
- if (prev_branch) {
- *prev_branch = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog, prog_offset) | 1);
- }
-
- prev_branch = &cmd->branchAddress;
- }
-
- /* the final descriptor's branch address and Z should be left at 0 */
-}
-
-/* listen or unlisten to a specific channel (multi-channel mode only) */
-static void ohci_iso_recv_change_channel(struct hpsb_iso *iso, unsigned char channel, int listen)
-{
- struct ohci_iso_recv *recv = iso->hostdata;
- int reg, i;
-
- if (channel < 32) {
- reg = listen ? OHCI1394_IRMultiChanMaskLoSet : OHCI1394_IRMultiChanMaskLoClear;
- i = channel;
- } else {
- reg = listen ? OHCI1394_IRMultiChanMaskHiSet : OHCI1394_IRMultiChanMaskHiClear;
- i = channel - 32;
- }
-
- reg_write(recv->ohci, reg, (1 << i));
-
- /* issue a dummy read to force all PCI writes to be posted immediately */
- mb();
- reg_read(recv->ohci, OHCI1394_IsochronousCycleTimer);
-}
-
-static void ohci_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
-{
- struct ohci_iso_recv *recv = iso->hostdata;
- int i;
-
- for (i = 0; i < 64; i++) {
- if (mask & (1ULL << i)) {
- if (i < 32)
- reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoSet, (1 << i));
- else
- reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiSet, (1 << (i-32)));
- } else {
- if (i < 32)
- reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, (1 << i));
- else
- reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, (1 << (i-32)));
- }
- }
-
- /* issue a dummy read to force all PCI writes to be posted immediately */
- mb();
- reg_read(recv->ohci, OHCI1394_IsochronousCycleTimer);
-}
-
-static int ohci_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
-{
- struct ohci_iso_recv *recv = iso->hostdata;
- struct ti_ohci *ohci = recv->ohci;
- u32 command, contextMatch;
-
- reg_write(recv->ohci, recv->ContextControlClear, 0xFFFFFFFF);
- wmb();
-
- /* always keep ISO headers */
- command = (1 << 30);
-
- if (recv->dma_mode == BUFFER_FILL_MODE)
- command |= (1 << 31);
-
- reg_write(recv->ohci, recv->ContextControlSet, command);
-
- /* match on specified tags */
- contextMatch = tag_mask << 28;
-
- if (iso->channel == -1) {
- /* enable multichannel reception */
- reg_write(recv->ohci, recv->ContextControlSet, (1 << 28));
- } else {
- /* listen on channel */
- contextMatch |= iso->channel;
- }
-
- if (cycle != -1) {
- u32 seconds;
-
- /* enable cycleMatch */
- reg_write(recv->ohci, recv->ContextControlSet, (1 << 29));
-
- /* set starting cycle */
- cycle &= 0x1FFF;
-
- /* 'cycle' is only mod 8000, but we also need two 'seconds' bits -
- just snarf them from the current time */
- seconds = reg_read(recv->ohci, OHCI1394_IsochronousCycleTimer) >> 25;
-
- /* advance one second to give some extra time for DMA to start */
- seconds += 1;
-
- cycle |= (seconds & 3) << 13;
-
- contextMatch |= cycle << 12;
- }
-
- if (sync != -1) {
- /* set sync flag on first DMA descriptor */
- struct dma_cmd *cmd = &recv->block[recv->block_dma];
- cmd->control |= cpu_to_le32(DMA_CTL_WAIT);
-
- /* match sync field */
- contextMatch |= (sync&0xf)<<8;
- }
-
- reg_write(recv->ohci, recv->ContextMatch, contextMatch);
-
- /* address of first descriptor block */
- command = dma_prog_region_offset_to_bus(&recv->prog,
- recv->block_dma * sizeof(struct dma_cmd));
- command |= 1; /* Z=1 */
-
- reg_write(recv->ohci, recv->CommandPtr, command);
-
- /* enable interrupts */
- reg_write(recv->ohci, OHCI1394_IsoRecvIntMaskSet, 1 << recv->task.context);
-
- wmb();
-
- /* run */
- reg_write(recv->ohci, recv->ContextControlSet, 0x8000);
-
- /* issue a dummy read of the cycle timer register to force
- all PCI writes to be posted immediately */
- mb();
- reg_read(recv->ohci, OHCI1394_IsochronousCycleTimer);
-
- /* check RUN */
- if (!(reg_read(recv->ohci, recv->ContextControlSet) & 0x8000)) {
- PRINT(KERN_ERR,
- "Error starting IR DMA (ContextControl 0x%08x)\n",
- reg_read(recv->ohci, recv->ContextControlSet));
- return -1;
- }
-
- return 0;
-}
-
-static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
-{
- /* re-use the DMA descriptor for the block */
- /* by linking the previous descriptor to it */
-
- int next_i = block;
- int prev_i = (next_i == 0) ? (recv->nblocks - 1) : (next_i - 1);
-
- struct dma_cmd *next = &recv->block[next_i];
- struct dma_cmd *prev = &recv->block[prev_i];
-
- /* ignore out-of-range requests */
- if ((block < 0) || (block > recv->nblocks))
- return;
-
- /* 'next' becomes the new end of the DMA chain,
- so disable branch and enable interrupt */
- next->branchAddress = 0;
- next->control |= cpu_to_le32(3 << 20);
- next->status = cpu_to_le32(recv->buf_stride);
-
- /* link prev to next */
- prev->branchAddress = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog,
- sizeof(struct dma_cmd) * next_i)
- | 1); /* Z=1 */
-
- /* disable interrupt on previous DMA descriptor, except at intervals */
- if ((prev_i % recv->block_irq_interval) == 0) {
- prev->control |= cpu_to_le32(3 << 20); /* enable interrupt */
- } else {
- prev->control &= cpu_to_le32(~(3<<20)); /* disable interrupt */
- }
- wmb();
-
- /* wake up DMA in case it fell asleep */
- reg_write(recv->ohci, recv->ContextControlSet, (1 << 12));
-}
-
-static void ohci_iso_recv_bufferfill_release(struct ohci_iso_recv *recv,
- struct hpsb_iso_packet_info *info)
-{
- /* release the memory where the packet was */
- recv->released_bytes += info->total_len;
-
- /* have we released enough memory for one block? */
- while (recv->released_bytes > recv->buf_stride) {
- ohci_iso_recv_release_block(recv, recv->block_reader);
- recv->block_reader = (recv->block_reader + 1) % recv->nblocks;
- recv->released_bytes -= recv->buf_stride;
- }
-}
-
-static inline void ohci_iso_recv_release(struct hpsb_iso *iso, struct hpsb_iso_packet_info *info)
-{
- struct ohci_iso_recv *recv = iso->hostdata;
- if (recv->dma_mode == BUFFER_FILL_MODE) {
- ohci_iso_recv_bufferfill_release(recv, info);
- } else {
- ohci_iso_recv_release_block(recv, info - iso->infos);
- }
-}
-
-/* parse all packets from blocks that have been fully received */
-static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso_recv *recv)
-{
- int wake = 0;
- int runaway = 0;
- struct ti_ohci *ohci = recv->ohci;
-
- while (1) {
- /* we expect the next parsable packet to begin at recv->dma_offset */
- /* note: packet layout is as shown in section 10.6.1.1 of the OHCI spec */
-
- unsigned int offset;
- unsigned short len, cycle, total_len;
- unsigned char channel, tag, sy;
-
- unsigned char *p = iso->data_buf.kvirt;
-
- unsigned int this_block = recv->dma_offset/recv->buf_stride;
-
- /* don't loop indefinitely */
- if (runaway++ > 100000) {
- atomic_inc(&iso->overflows);
- PRINT(KERN_ERR,
- "IR DMA error - Runaway during buffer parsing!\n");
- break;
- }
-
- /* stop parsing once we arrive at block_dma (i.e. don't get ahead of DMA) */
- if (this_block == recv->block_dma)
- break;
-
- wake = 1;
-
- /* parse data length, tag, channel, and sy */
-
- /* note: we keep our own local copies of 'len' and 'offset'
- so the user can't mess with them by poking in the mmap area */
-
- len = p[recv->dma_offset+2] | (p[recv->dma_offset+3] << 8);
-
- if (len > 4096) {
- PRINT(KERN_ERR,
- "IR DMA error - bogus 'len' value %u\n", len);
- }
-
- channel = p[recv->dma_offset+1] & 0x3F;
- tag = p[recv->dma_offset+1] >> 6;
- sy = p[recv->dma_offset+0] & 0xF;
-
- /* advance to data payload */
- recv->dma_offset += 4;
-
- /* check for wrap-around */
- if (recv->dma_offset >= recv->buf_stride*recv->nblocks) {
- recv->dma_offset -= recv->buf_stride*recv->nblocks;
- }
-
- /* dma_offset now points to the first byte of the data payload */
- offset = recv->dma_offset;
-
- /* advance to xferStatus/timeStamp */
- recv->dma_offset += len;
-
- total_len = len + 8; /* 8 bytes header+trailer in OHCI packet */
- /* payload is padded to 4 bytes */
- if (len % 4) {
- recv->dma_offset += 4 - (len%4);
- total_len += 4 - (len%4);
- }
-
- /* check for wrap-around */
- if (recv->dma_offset >= recv->buf_stride*recv->nblocks) {
- /* uh oh, the packet data wraps from the last
- to the first DMA block - make the packet
- contiguous by copying its "tail" into the
- guard page */
-
- int guard_off = recv->buf_stride*recv->nblocks;
- int tail_len = len - (guard_off - offset);
-
- if (tail_len > 0 && tail_len < recv->buf_stride) {
- memcpy(iso->data_buf.kvirt + guard_off,
- iso->data_buf.kvirt,
- tail_len);
- }
-
- recv->dma_offset -= recv->buf_stride*recv->nblocks;
- }
-
- /* parse timestamp */
- cycle = p[recv->dma_offset+0] | (p[recv->dma_offset+1]<<8);
- cycle &= 0x1FFF;
-
- /* advance to next packet */
- recv->dma_offset += 4;
-
- /* check for wrap-around */
- if (recv->dma_offset >= recv->buf_stride*recv->nblocks) {
- recv->dma_offset -= recv->buf_stride*recv->nblocks;
- }
-
- hpsb_iso_packet_received(iso, offset, len, total_len, cycle, channel, tag, sy);
- }
-
- if (wake)
- hpsb_iso_wake(iso);
-}
-
-static void ohci_iso_recv_bufferfill_task(struct hpsb_iso *iso, struct ohci_iso_recv *recv)
-{
- int loop;
- struct ti_ohci *ohci = recv->ohci;
-
- /* loop over all blocks */
- for (loop = 0; loop < recv->nblocks; loop++) {
-
- /* check block_dma to see if it's done */
- struct dma_cmd *im = &recv->block[recv->block_dma];
-
- /* check the DMA descriptor for new writes to xferStatus */
- u16 xferstatus = le32_to_cpu(im->status) >> 16;
-
- /* rescount is the number of bytes *remaining to be written* in the block */
- u16 rescount = le32_to_cpu(im->status) & 0xFFFF;
-
- unsigned char event = xferstatus & 0x1F;
-
- if (!event) {
- /* nothing has happened to this block yet */
- break;
- }
-
- if (event != 0x11) {
- atomic_inc(&iso->overflows);
- PRINT(KERN_ERR,
- "IR DMA error - OHCI error code 0x%02x\n", event);
- }
-
- if (rescount != 0) {
- /* the card is still writing to this block;
- we can't touch it until it's done */
- break;
- }
-
- /* OK, the block is finished... */
-
- /* sync our view of the block */
- dma_region_sync_for_cpu(&iso->data_buf, recv->block_dma*recv->buf_stride, recv->buf_stride);
-
- /* reset the DMA descriptor */
- im->status = recv->buf_stride;
-
- /* advance block_dma */
- recv->block_dma = (recv->block_dma + 1) % recv->nblocks;
-
- if ((recv->block_dma+1) % recv->nblocks == recv->block_reader) {
- atomic_inc(&iso->overflows);
- DBGMSG("ISO reception overflow - "
- "ran out of DMA blocks");
- }
- }
-
- /* parse any packets that have arrived */
- ohci_iso_recv_bufferfill_parse(iso, recv);
-}
-
-static void ohci_iso_recv_packetperbuf_task(struct hpsb_iso *iso, struct ohci_iso_recv *recv)
-{
- int count;
- int wake = 0;
- struct ti_ohci *ohci = recv->ohci;
-
- /* loop over the entire buffer */
- for (count = 0; count < recv->nblocks; count++) {
- u32 packet_len = 0;
-
- /* pointer to the DMA descriptor */
- struct dma_cmd *il = ((struct dma_cmd*) recv->prog.kvirt) + iso->pkt_dma;
-
- /* check the DMA descriptor for new writes to xferStatus */
- u16 xferstatus = le32_to_cpu(il->status) >> 16;
- u16 rescount = le32_to_cpu(il->status) & 0xFFFF;
-
- unsigned char event = xferstatus & 0x1F;
-
- if (!event) {
- /* this packet hasn't come in yet; we are done for now */
- goto out;
- }
-
- if (event == 0x11) {
- /* packet received successfully! */
-
- /* rescount is the number of bytes *remaining* in the packet buffer,
- after the packet was written */
- packet_len = recv->buf_stride - rescount;
-
- } else if (event == 0x02) {
- PRINT(KERN_ERR, "IR DMA error - packet too long for buffer\n");
- } else if (event) {
- PRINT(KERN_ERR, "IR DMA error - OHCI error code 0x%02x\n", event);
- }
-
- /* sync our view of the buffer */
- dma_region_sync_for_cpu(&iso->data_buf, iso->pkt_dma * recv->buf_stride, recv->buf_stride);
-
- /* record the per-packet info */
- {
- /* iso header is 8 bytes ahead of the data payload */
- unsigned char *hdr;
-
- unsigned int offset;
- unsigned short cycle;
- unsigned char channel, tag, sy;
-
- offset = iso->pkt_dma * recv->buf_stride;
- hdr = iso->data_buf.kvirt + offset;
-
- /* skip iso header */
- offset += 8;
- packet_len -= 8;
-
- cycle = (hdr[0] | (hdr[1] << 8)) & 0x1FFF;
- channel = hdr[5] & 0x3F;
- tag = hdr[5] >> 6;
- sy = hdr[4] & 0xF;
-
- hpsb_iso_packet_received(iso, offset, packet_len,
- recv->buf_stride, cycle, channel, tag, sy);
- }
-
- /* reset the DMA descriptor */
- il->status = recv->buf_stride;
-
- wake = 1;
- recv->block_dma = iso->pkt_dma;
- }
-
-out:
- if (wake)
- hpsb_iso_wake(iso);
-}
-
-static void ohci_iso_recv_task(unsigned long data)
-{
- struct hpsb_iso *iso = (struct hpsb_iso*) data;
- struct ohci_iso_recv *recv = iso->hostdata;
-
- if (recv->dma_mode == BUFFER_FILL_MODE)
- ohci_iso_recv_bufferfill_task(iso, recv);
- else
- ohci_iso_recv_packetperbuf_task(iso, recv);
-}
-
-/***********************************
- * rawiso ISO transmission *
- ***********************************/
-
-struct ohci_iso_xmit {
- struct ti_ohci *ohci;
- struct dma_prog_region prog;
- struct ohci1394_iso_tasklet task;
- int task_active;
- int last_cycle;
- atomic_t skips;
-
- u32 ContextControlSet;
- u32 ContextControlClear;
- u32 CommandPtr;
-};
-
-/* transmission DMA program:
- one OUTPUT_MORE_IMMEDIATE for the IT header
- one OUTPUT_LAST for the buffer data */
-
-struct iso_xmit_cmd {
- struct dma_cmd output_more_immediate;
- u8 iso_hdr[8];
- u32 unused[2];
- struct dma_cmd output_last;
-};
-
-static int ohci_iso_xmit_init(struct hpsb_iso *iso);
-static int ohci_iso_xmit_start(struct hpsb_iso *iso, int cycle);
-static void ohci_iso_xmit_shutdown(struct hpsb_iso *iso);
-static void ohci_iso_xmit_task(unsigned long data);
-
-static int ohci_iso_xmit_init(struct hpsb_iso *iso)
-{
- struct ohci_iso_xmit *xmit;
- unsigned int prog_size;
- int ctx;
- int ret = -ENOMEM;
-
- xmit = kmalloc(sizeof(*xmit), GFP_KERNEL);
- if (!xmit)
- return -ENOMEM;
-
- iso->hostdata = xmit;
- xmit->ohci = iso->host->hostdata;
- xmit->task_active = 0;
- xmit->last_cycle = -1;
- atomic_set(&iso->skips, 0);
-
- dma_prog_region_init(&xmit->prog);
-
- prog_size = sizeof(struct iso_xmit_cmd) * iso->buf_packets;
-
- if (dma_prog_region_alloc(&xmit->prog, prog_size, xmit->ohci->dev))
- goto err;
-
- ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT,
- ohci_iso_xmit_task, (unsigned long) iso);
-
- if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) {
- ret = -EBUSY;
- goto err;
- }
-
- xmit->task_active = 1;
-
- /* xmit context registers are spaced 16 bytes apart */
- ctx = xmit->task.context;
- xmit->ContextControlSet = OHCI1394_IsoXmitContextControlSet + 16 * ctx;
- xmit->ContextControlClear = OHCI1394_IsoXmitContextControlClear + 16 * ctx;
- xmit->CommandPtr = OHCI1394_IsoXmitCommandPtr + 16 * ctx;
-
- return 0;
-
-err:
- ohci_iso_xmit_shutdown(iso);
- return ret;
-}
-
-static void ohci_iso_xmit_stop(struct hpsb_iso *iso)
-{
- struct ohci_iso_xmit *xmit = iso->hostdata;
- struct ti_ohci *ohci = xmit->ohci;
-
- /* disable interrupts */
- reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskClear, 1 << xmit->task.context);
-
- /* halt DMA */
- if (ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL)) {
- /* XXX the DMA context will lock up if you try to send too much data! */
- PRINT(KERN_ERR,
- "you probably exceeded the OHCI card's bandwidth limit - "
- "reload the module and reduce xmit bandwidth");
- }
-}
-
-static void ohci_iso_xmit_shutdown(struct hpsb_iso *iso)
-{
- struct ohci_iso_xmit *xmit = iso->hostdata;
-
- if (xmit->task_active) {
- ohci_iso_xmit_stop(iso);
- ohci1394_unregister_iso_tasklet(xmit->ohci, &xmit->task);
- xmit->task_active = 0;
- }
-
- dma_prog_region_free(&xmit->prog);
- kfree(xmit);
- iso->hostdata = NULL;
-}
-
-static void ohci_iso_xmit_task(unsigned long data)
-{
- struct hpsb_iso *iso = (struct hpsb_iso*) data;
- struct ohci_iso_xmit *xmit = iso->hostdata;
- struct ti_ohci *ohci = xmit->ohci;
- int wake = 0;
- int count;
-
- /* check the whole buffer if necessary, starting at pkt_dma */
- for (count = 0; count < iso->buf_packets; count++) {
- int cycle;
-
- /* DMA descriptor */
- struct iso_xmit_cmd *cmd = dma_region_i(&xmit->prog, struct iso_xmit_cmd, iso->pkt_dma);
-
- /* check for new writes to xferStatus */
- u16 xferstatus = le32_to_cpu(cmd->output_last.status) >> 16;
- u8 event = xferstatus & 0x1F;
-
- if (!event) {
- /* packet hasn't been sent yet; we are done for now */
- break;
- }
-
- if (event != 0x11)
- PRINT(KERN_ERR,
- "IT DMA error - OHCI error code 0x%02x\n", event);
-
- /* at least one packet went out, so wake up the writer */
- wake = 1;
-
- /* parse cycle */
- cycle = le32_to_cpu(cmd->output_last.status) & 0x1FFF;
-
- if (xmit->last_cycle > -1) {
- int cycle_diff = cycle - xmit->last_cycle;
- int skip;
-
- /* unwrap */
- if (cycle_diff < 0) {
- cycle_diff += 8000;
- if (cycle_diff < 0)
- PRINT(KERN_ERR, "bogus cycle diff %d\n",
- cycle_diff);
- }
-
- skip = cycle_diff - 1;
- if (skip > 0) {
- DBGMSG("skipped %d cycles without packet loss", skip);
- atomic_add(skip, &iso->skips);
- }
- }
- xmit->last_cycle = cycle;
-
- /* tell the subsystem the packet has gone out */
- hpsb_iso_packet_sent(iso, cycle, event != 0x11);
-
- /* reset the DMA descriptor for next time */
- cmd->output_last.status = 0;
- }
-
- if (wake)
- hpsb_iso_wake(iso);
-}
-
-static int ohci_iso_xmit_queue(struct hpsb_iso *iso, struct hpsb_iso_packet_info *info)
-{
- struct ohci_iso_xmit *xmit = iso->hostdata;
- struct ti_ohci *ohci = xmit->ohci;
-
- int next_i, prev_i;
- struct iso_xmit_cmd *next, *prev;
-
- unsigned int offset;
- unsigned short len;
- unsigned char tag, sy;
-
- /* check that the packet doesn't cross a page boundary
- (we could allow this if we added OUTPUT_MORE descriptor support) */
- if (cross_bound(info->offset, info->len)) {
- PRINT(KERN_ERR,
- "rawiso xmit: packet %u crosses a page boundary",
- iso->first_packet);
- return -EINVAL;
- }
-
- offset = info->offset;
- len = info->len;
- tag = info->tag;
- sy = info->sy;
-
- /* sync up the card's view of the buffer */
- dma_region_sync_for_device(&iso->data_buf, offset, len);
-
- /* append first_packet to the DMA chain */
- /* by linking the previous descriptor to it */
- /* (next will become the new end of the DMA chain) */
-
- next_i = iso->first_packet;
- prev_i = (next_i == 0) ? (iso->buf_packets - 1) : (next_i - 1);
-
- next = dma_region_i(&xmit->prog, struct iso_xmit_cmd, next_i);
- prev = dma_region_i(&xmit->prog, struct iso_xmit_cmd, prev_i);
-
- /* set up the OUTPUT_MORE_IMMEDIATE descriptor */
- memset(next, 0, sizeof(struct iso_xmit_cmd));
- next->output_more_immediate.control = cpu_to_le32(0x02000008);
-
- /* ISO packet header is embedded in the OUTPUT_MORE_IMMEDIATE */
-
- /* tcode = 0xA, and sy */
- next->iso_hdr[0] = 0xA0 | (sy & 0xF);
-
- /* tag and channel number */
- next->iso_hdr[1] = (tag << 6) | (iso->channel & 0x3F);
-
- /* transmission speed */
- next->iso_hdr[2] = iso->speed & 0x7;
-
- /* payload size */
- next->iso_hdr[6] = len & 0xFF;
- next->iso_hdr[7] = len >> 8;
-
- /* set up the OUTPUT_LAST */
- next->output_last.control = cpu_to_le32(1 << 28);
- next->output_last.control |= cpu_to_le32(1 << 27); /* update timeStamp */
- next->output_last.control |= cpu_to_le32(3 << 20); /* want interrupt */
- next->output_last.control |= cpu_to_le32(3 << 18); /* enable branch */
- next->output_last.control |= cpu_to_le32(len);
-
- /* payload bus address */
- next->output_last.address = cpu_to_le32(dma_region_offset_to_bus(&iso->data_buf, offset));
-
- /* leave branchAddress at zero for now */
-
- /* re-write the previous DMA descriptor to chain to this one */
-
- /* set prev branch address to point to next (Z=3) */
- prev->output_last.branchAddress = cpu_to_le32(
- dma_prog_region_offset_to_bus(&xmit->prog, sizeof(struct iso_xmit_cmd) * next_i) | 3);
-
- /*
- * Link the skip address to this descriptor itself. This causes a
- * context to skip a cycle whenever lost cycles or FIFO overruns occur,
- * without dropping the data at that point the application should then
- * decide whether this is an error condition or not. Some protocols
- * can deal with this by dropping some rate-matching padding packets.
- */
- next->output_more_immediate.branchAddress =
- prev->output_last.branchAddress;
-
- /* disable interrupt, unless required by the IRQ interval */
- if (prev_i % iso->irq_interval) {
- prev->output_last.control &= cpu_to_le32(~(3 << 20)); /* no interrupt */
- } else {
- prev->output_last.control |= cpu_to_le32(3 << 20); /* enable interrupt */
- }
-
- wmb();
-
- /* wake DMA in case it is sleeping */
- reg_write(xmit->ohci, xmit->ContextControlSet, 1 << 12);
-
- /* issue a dummy read of the cycle timer to force all PCI
- writes to be posted immediately */
- mb();
- reg_read(xmit->ohci, OHCI1394_IsochronousCycleTimer);
-
- return 0;
-}
-
-static int ohci_iso_xmit_start(struct hpsb_iso *iso, int cycle)
-{
- struct ohci_iso_xmit *xmit = iso->hostdata;
- struct ti_ohci *ohci = xmit->ohci;
-
- /* clear out the control register */
- reg_write(xmit->ohci, xmit->ContextControlClear, 0xFFFFFFFF);
- wmb();
-
- /* address and length of first descriptor block (Z=3) */
- reg_write(xmit->ohci, xmit->CommandPtr,
- dma_prog_region_offset_to_bus(&xmit->prog, iso->pkt_dma * sizeof(struct iso_xmit_cmd)) | 3);
-
- /* cycle match */
- if (cycle != -1) {
- u32 start = cycle & 0x1FFF;
-
- /* 'cycle' is only mod 8000, but we also need two 'seconds' bits -
- just snarf them from the current time */
- u32 seconds = reg_read(xmit->ohci, OHCI1394_IsochronousCycleTimer) >> 25;
-
- /* advance one second to give some extra time for DMA to start */
- seconds += 1;
-
- start |= (seconds & 3) << 13;
-
- reg_write(xmit->ohci, xmit->ContextControlSet, 0x80000000 | (start << 16));
- }
-
- /* enable interrupts */
- reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskSet, 1 << xmit->task.context);
-
- /* run */
- reg_write(xmit->ohci, xmit->ContextControlSet, 0x8000);
- mb();
-
- /* wait 100 usec to give the card time to go active */
- udelay(100);
-
- /* check the RUN bit */
- if (!(reg_read(xmit->ohci, xmit->ContextControlSet) & 0x8000)) {
- PRINT(KERN_ERR, "Error starting IT DMA (ContextControl 0x%08x)\n",
- reg_read(xmit->ohci, xmit->ContextControlSet));
- return -1;
- }
-
- return 0;
-}
-
-static int ohci_isoctl(struct hpsb_iso *iso, enum isoctl_cmd cmd, unsigned long arg)
-{
-
- switch(cmd) {
- case XMIT_INIT:
- return ohci_iso_xmit_init(iso);
- case XMIT_START:
- return ohci_iso_xmit_start(iso, arg);
- case XMIT_STOP:
- ohci_iso_xmit_stop(iso);
- return 0;
- case XMIT_QUEUE:
- return ohci_iso_xmit_queue(iso, (struct hpsb_iso_packet_info*) arg);
- case XMIT_SHUTDOWN:
- ohci_iso_xmit_shutdown(iso);
- return 0;
-
- case RECV_INIT:
- return ohci_iso_recv_init(iso);
- case RECV_START: {
- int *args = (int*) arg;
- return ohci_iso_recv_start(iso, args[0], args[1], args[2]);
- }
- case RECV_STOP:
- ohci_iso_recv_stop(iso);
- return 0;
- case RECV_RELEASE:
- ohci_iso_recv_release(iso, (struct hpsb_iso_packet_info*) arg);
- return 0;
- case RECV_FLUSH:
- ohci_iso_recv_task((unsigned long) iso);
- return 0;
- case RECV_SHUTDOWN:
- ohci_iso_recv_shutdown(iso);
- return 0;
- case RECV_LISTEN_CHANNEL:
- ohci_iso_recv_change_channel(iso, arg, 1);
- return 0;
- case RECV_UNLISTEN_CHANNEL:
- ohci_iso_recv_change_channel(iso, arg, 0);
- return 0;
- case RECV_SET_CHANNEL_MASK:
- ohci_iso_recv_set_channel_mask(iso, *((u64*) arg));
- return 0;
-
- default:
- PRINT_G(KERN_ERR, "ohci_isoctl cmd %d not implemented yet",
- cmd);
- break;
- }
- return -EINVAL;
-}
-
-/***************************************
- * IEEE-1394 functionality section END *
- ***************************************/
-
-
-/********************************************************
- * Global stuff (interrupt handler, init/shutdown code) *
- ********************************************************/
-
-static void dma_trm_reset(struct dma_trm_ctx *d)
-{
- unsigned long flags;
- LIST_HEAD(packet_list);
- struct ti_ohci *ohci = d->ohci;
- struct hpsb_packet *packet, *ptmp;
-
- ohci1394_stop_context(ohci, d->ctrlClear, NULL);
-
- /* Lock the context, reset it and release it. Move the packets
- * that were pending in the context to packet_list and free
- * them after releasing the lock. */
-
- spin_lock_irqsave(&d->lock, flags);
-
- list_splice_init(&d->fifo_list, &packet_list);
- list_splice_init(&d->pending_list, &packet_list);
-
- d->branchAddrPtr = NULL;
- d->sent_ind = d->prg_ind;
- d->free_prgs = d->num_desc;
-
- spin_unlock_irqrestore(&d->lock, flags);
-
- if (list_empty(&packet_list))
- return;
-
- PRINT(KERN_INFO, "AT dma reset ctx=%d, aborting transmission", d->ctx);
-
- /* Now process subsystem callbacks for the packets from this
- * context. */
- list_for_each_entry_safe(packet, ptmp, &packet_list, driver_list) {
- list_del_init(&packet->driver_list);
- hpsb_packet_sent(ohci->host, packet, ACKX_ABORTED);
- }
-}
-
-static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci,
- quadlet_t rx_event,
- quadlet_t tx_event)
-{
- struct ohci1394_iso_tasklet *t;
- unsigned long mask;
- unsigned long flags;
-
- spin_lock_irqsave(&ohci->iso_tasklet_list_lock, flags);
-
- list_for_each_entry(t, &ohci->iso_tasklet_list, link) {
- mask = 1 << t->context;
-
- if (t->type == OHCI_ISO_TRANSMIT) {
- if (tx_event & mask)
- tasklet_schedule(&t->tasklet);
- } else {
- /* OHCI_ISO_RECEIVE or OHCI_ISO_MULTICHANNEL_RECEIVE */
- if (rx_event & mask)
- tasklet_schedule(&t->tasklet);
- }
- }
-
- spin_unlock_irqrestore(&ohci->iso_tasklet_list_lock, flags);
-}
-
-static irqreturn_t ohci_irq_handler(int irq, void *dev_id)
-{
- quadlet_t event, node_id;
- struct ti_ohci *ohci = (struct ti_ohci *)dev_id;
- struct hpsb_host *host = ohci->host;
- int phyid = -1, isroot = 0;
- unsigned long flags;
-
- /* Read and clear the interrupt event register. Don't clear
- * the busReset event, though. This is done when we get the
- * selfIDComplete interrupt. */
- spin_lock_irqsave(&ohci->event_lock, flags);
- event = reg_read(ohci, OHCI1394_IntEventClear);
- reg_write(ohci, OHCI1394_IntEventClear, event & ~OHCI1394_busReset);
- spin_unlock_irqrestore(&ohci->event_lock, flags);
-
- if (!event)
- return IRQ_NONE;
-
- /* If event is ~(u32)0 cardbus card was ejected. In this case
- * we just return, and clean up in the ohci1394_pci_remove
- * function. */
- if (event == ~(u32) 0) {
- DBGMSG("Device removed.");
- return IRQ_NONE;
- }
-
- DBGMSG("IntEvent: %08x", event);
-
- if (event & OHCI1394_unrecoverableError) {
- int ctx;
- PRINT(KERN_ERR, "Unrecoverable error!");
-
- if (reg_read(ohci, OHCI1394_AsReqTrContextControlSet) & 0x800)
- PRINT(KERN_ERR, "Async Req Tx Context died: "
- "ctrl[%08x] cmdptr[%08x]",
- reg_read(ohci, OHCI1394_AsReqTrContextControlSet),
- reg_read(ohci, OHCI1394_AsReqTrCommandPtr));
-
- if (reg_read(ohci, OHCI1394_AsRspTrContextControlSet) & 0x800)
- PRINT(KERN_ERR, "Async Rsp Tx Context died: "
- "ctrl[%08x] cmdptr[%08x]",
- reg_read(ohci, OHCI1394_AsRspTrContextControlSet),
- reg_read(ohci, OHCI1394_AsRspTrCommandPtr));
-
- if (reg_read(ohci, OHCI1394_AsReqRcvContextControlSet) & 0x800)
- PRINT(KERN_ERR, "Async Req Rcv Context died: "
- "ctrl[%08x] cmdptr[%08x]",
- reg_read(ohci, OHCI1394_AsReqRcvContextControlSet),
- reg_read(ohci, OHCI1394_AsReqRcvCommandPtr));
-
- if (reg_read(ohci, OHCI1394_AsRspRcvContextControlSet) & 0x800)
- PRINT(KERN_ERR, "Async Rsp Rcv Context died: "
- "ctrl[%08x] cmdptr[%08x]",
- reg_read(ohci, OHCI1394_AsRspRcvContextControlSet),
- reg_read(ohci, OHCI1394_AsRspRcvCommandPtr));
-
- for (ctx = 0; ctx < ohci->nb_iso_xmit_ctx; ctx++) {
- if (reg_read(ohci, OHCI1394_IsoXmitContextControlSet + (16 * ctx)) & 0x800)
- PRINT(KERN_ERR, "Iso Xmit %d Context died: "
- "ctrl[%08x] cmdptr[%08x]", ctx,
- reg_read(ohci, OHCI1394_IsoXmitContextControlSet + (16 * ctx)),
- reg_read(ohci, OHCI1394_IsoXmitCommandPtr + (16 * ctx)));
- }
-
- for (ctx = 0; ctx < ohci->nb_iso_rcv_ctx; ctx++) {
- if (reg_read(ohci, OHCI1394_IsoRcvContextControlSet + (32 * ctx)) & 0x800)
- PRINT(KERN_ERR, "Iso Recv %d Context died: "
- "ctrl[%08x] cmdptr[%08x] match[%08x]", ctx,
- reg_read(ohci, OHCI1394_IsoRcvContextControlSet + (32 * ctx)),
- reg_read(ohci, OHCI1394_IsoRcvCommandPtr + (32 * ctx)),
- reg_read(ohci, OHCI1394_IsoRcvContextMatch + (32 * ctx)));
- }
-
- event &= ~OHCI1394_unrecoverableError;
- }
- if (event & OHCI1394_postedWriteErr) {
- PRINT(KERN_ERR, "physical posted write error");
- /* no recovery strategy yet, had to involve protocol drivers */
- event &= ~OHCI1394_postedWriteErr;
- }
- if (event & OHCI1394_cycleTooLong) {
- if(printk_ratelimit())
- PRINT(KERN_WARNING, "isochronous cycle too long");
- else
- DBGMSG("OHCI1394_cycleTooLong");
- reg_write(ohci, OHCI1394_LinkControlSet,
- OHCI1394_LinkControl_CycleMaster);
- event &= ~OHCI1394_cycleTooLong;
- }
- if (event & OHCI1394_cycleInconsistent) {
- /* We subscribe to the cycleInconsistent event only to
- * clear the corresponding event bit... otherwise,
- * isochronous cycleMatch DMA won't work. */
- DBGMSG("OHCI1394_cycleInconsistent");
- event &= ~OHCI1394_cycleInconsistent;
- }
- if (event & OHCI1394_busReset) {
- /* The busReset event bit can't be cleared during the
- * selfID phase, so we disable busReset interrupts, to
- * avoid burying the cpu in interrupt requests. */
- spin_lock_irqsave(&ohci->event_lock, flags);
- reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
-
- if (ohci->check_busreset) {
- int loop_count = 0;
-
- udelay(10);
-
- while (reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
- reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
-
- spin_unlock_irqrestore(&ohci->event_lock, flags);
- udelay(10);
- spin_lock_irqsave(&ohci->event_lock, flags);
-
- /* The loop counter check is to prevent the driver
- * from remaining in this state forever. For the
- * initial bus reset, the loop continues for ever
- * and the system hangs, until some device is plugged-in
- * or out manually into a port! The forced reset seems
- * to solve this problem. This mainly effects nForce2. */
- if (loop_count > 10000) {
- ohci_devctl(host, RESET_BUS, LONG_RESET);
- DBGMSG("Detected bus-reset loop. Forced a bus reset!");
- loop_count = 0;
- }
-
- loop_count++;
- }
- }
- spin_unlock_irqrestore(&ohci->event_lock, flags);
- if (!host->in_bus_reset) {
- DBGMSG("irq_handler: Bus reset requested");
-
- /* Subsystem call */
- hpsb_bus_reset(ohci->host);
- }
- event &= ~OHCI1394_busReset;
- }
- if (event & OHCI1394_reqTxComplete) {
- struct dma_trm_ctx *d = &ohci->at_req_context;
- DBGMSG("Got reqTxComplete interrupt "
- "status=0x%08X", reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- ohci1394_stop_context(ohci, d->ctrlClear,
- "reqTxComplete");
- else
- dma_trm_tasklet((unsigned long)d);
- //tasklet_schedule(&d->task);
- event &= ~OHCI1394_reqTxComplete;
- }
- if (event & OHCI1394_respTxComplete) {
- struct dma_trm_ctx *d = &ohci->at_resp_context;
- DBGMSG("Got respTxComplete interrupt "
- "status=0x%08X", reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- ohci1394_stop_context(ohci, d->ctrlClear,
- "respTxComplete");
- else
- tasklet_schedule(&d->task);
- event &= ~OHCI1394_respTxComplete;
- }
- if (event & OHCI1394_RQPkt) {
- struct dma_rcv_ctx *d = &ohci->ar_req_context;
- DBGMSG("Got RQPkt interrupt status=0x%08X",
- reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- ohci1394_stop_context(ohci, d->ctrlClear, "RQPkt");
- else
- tasklet_schedule(&d->task);
- event &= ~OHCI1394_RQPkt;
- }
- if (event & OHCI1394_RSPkt) {
- struct dma_rcv_ctx *d = &ohci->ar_resp_context;
- DBGMSG("Got RSPkt interrupt status=0x%08X",
- reg_read(ohci, d->ctrlSet));
- if (reg_read(ohci, d->ctrlSet) & 0x800)
- ohci1394_stop_context(ohci, d->ctrlClear, "RSPkt");
- else
- tasklet_schedule(&d->task);
- event &= ~OHCI1394_RSPkt;
- }
- if (event & OHCI1394_isochRx) {
- quadlet_t rx_event;
-
- rx_event = reg_read(ohci, OHCI1394_IsoRecvIntEventSet);
- reg_write(ohci, OHCI1394_IsoRecvIntEventClear, rx_event);
- ohci_schedule_iso_tasklets(ohci, rx_event, 0);
- event &= ~OHCI1394_isochRx;
- }
- if (event & OHCI1394_isochTx) {
- quadlet_t tx_event;
-
- tx_event = reg_read(ohci, OHCI1394_IsoXmitIntEventSet);
- reg_write(ohci, OHCI1394_IsoXmitIntEventClear, tx_event);
- ohci_schedule_iso_tasklets(ohci, 0, tx_event);
- event &= ~OHCI1394_isochTx;
- }
- if (event & OHCI1394_selfIDComplete) {
- if (host->in_bus_reset) {
- node_id = reg_read(ohci, OHCI1394_NodeID);
-
- if (!(node_id & 0x80000000)) {
- PRINT(KERN_ERR,
- "SelfID received, but NodeID invalid "
- "(probably new bus reset occurred): %08X",
- node_id);
- goto selfid_not_valid;
- }
-
- phyid = node_id & 0x0000003f;
- isroot = (node_id & 0x40000000) != 0;
-
- DBGMSG("SelfID interrupt received "
- "(phyid %d, %s)", phyid,
- (isroot ? "root" : "not root"));
-
- handle_selfid(ohci, host, phyid, isroot);
-
- /* Clear the bus reset event and re-enable the
- * busReset interrupt. */
- spin_lock_irqsave(&ohci->event_lock, flags);
- reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
- reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
- spin_unlock_irqrestore(&ohci->event_lock, flags);
-
- /* Turn on phys dma reception.
- *
- * TODO: Enable some sort of filtering management.
- */
- if (phys_dma) {
- reg_write(ohci, OHCI1394_PhyReqFilterHiSet,
- 0xffffffff);
- reg_write(ohci, OHCI1394_PhyReqFilterLoSet,
- 0xffffffff);
- }
-
- DBGMSG("PhyReqFilter=%08x%08x",
- reg_read(ohci, OHCI1394_PhyReqFilterHiSet),
- reg_read(ohci, OHCI1394_PhyReqFilterLoSet));
-
- hpsb_selfid_complete(host, phyid, isroot);
- } else
- PRINT(KERN_ERR,
- "SelfID received outside of bus reset sequence");
-
-selfid_not_valid:
- event &= ~OHCI1394_selfIDComplete;
- }
-
- /* Make sure we handle everything, just in case we accidentally
- * enabled an interrupt that we didn't write a handler for. */
- if (event)
- PRINT(KERN_ERR, "Unhandled interrupt(s) 0x%08x",
- event);
-
- return IRQ_HANDLED;
-}
-
-/* Put the buffer back into the dma context */
-static void insert_dma_buffer(struct dma_rcv_ctx *d, int idx)
-{
- struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
- DBGMSG("Inserting dma buf ctx=%d idx=%d", d->ctx, idx);
-
- d->prg_cpu[idx]->status = cpu_to_le32(d->buf_size);
- d->prg_cpu[idx]->branchAddress &= le32_to_cpu(0xfffffff0);
- idx = (idx + d->num_desc - 1 ) % d->num_desc;
- d->prg_cpu[idx]->branchAddress |= le32_to_cpu(0x00000001);
-
- /* To avoid a race, ensure 1394 interface hardware sees the inserted
- * context program descriptors before it sees the wakeup bit set. */
- wmb();
-
- /* wake up the dma context if necessary */
- if (!(reg_read(ohci, d->ctrlSet) & 0x400)) {
- PRINT(KERN_INFO,
- "Waking dma ctx=%d ... processing is probably too slow",
- d->ctx);
- }
-
- /* do this always, to avoid race condition */
- reg_write(ohci, d->ctrlSet, 0x1000);
-}
-
-#define cond_le32_to_cpu(data, noswap) \
- (noswap ? data : le32_to_cpu(data))
-
-static const int TCODE_SIZE[16] = {20, 0, 16, -1, 16, 20, 20, 0,
- -1, 0, -1, 0, -1, -1, 16, -1};
-
-/*
- * Determine the length of a packet in the buffer
- * Optimization suggested by Pascal Drolet <pascal.drolet@informission.ca>
- */
-static inline int packet_length(struct dma_rcv_ctx *d, int idx,
- quadlet_t *buf_ptr, int offset,
- unsigned char tcode, int noswap)
-{
- int length = -1;
-
- if (d->type == DMA_CTX_ASYNC_REQ || d->type == DMA_CTX_ASYNC_RESP) {
- length = TCODE_SIZE[tcode];
- if (length == 0) {
- if (offset + 12 >= d->buf_size) {
- length = (cond_le32_to_cpu(d->buf_cpu[(idx + 1) % d->num_desc]
- [3 - ((d->buf_size - offset) >> 2)], noswap) >> 16);
- } else {
- length = (cond_le32_to_cpu(buf_ptr[3], noswap) >> 16);
- }
- length += 20;
- }
- } else if (d->type == DMA_CTX_ISO) {
- /* Assumption: buffer fill mode with header/trailer */
- length = (cond_le32_to_cpu(buf_ptr[0], noswap) >> 16) + 8;
- }
-
- if (length > 0 && length % 4)
- length += 4 - (length % 4);
-
- return length;
-}
-
-/* Tasklet that processes dma receive buffers */
-static void dma_rcv_tasklet (unsigned long data)
-{
- struct dma_rcv_ctx *d = (struct dma_rcv_ctx*)data;
- struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
- unsigned int split_left, idx, offset, rescount;
- unsigned char tcode;
- int length, bytes_left, ack;
- unsigned long flags;
- quadlet_t *buf_ptr;
- char *split_ptr;
- char msg[256];
-
- spin_lock_irqsave(&d->lock, flags);
-
- idx = d->buf_ind;
- offset = d->buf_offset;
- buf_ptr = d->buf_cpu[idx] + offset/4;
-
- rescount = le32_to_cpu(d->prg_cpu[idx]->status) & 0xffff;
- bytes_left = d->buf_size - rescount - offset;
-
- while (bytes_left > 0) {
- tcode = (cond_le32_to_cpu(buf_ptr[0], ohci->no_swap_incoming) >> 4) & 0xf;
-
- /* packet_length() will return < 4 for an error */
- length = packet_length(d, idx, buf_ptr, offset, tcode, ohci->no_swap_incoming);
-
- if (length < 4) { /* something is wrong */
- sprintf(msg,"Unexpected tcode 0x%x(0x%08x) in AR ctx=%d, length=%d",
- tcode, cond_le32_to_cpu(buf_ptr[0], ohci->no_swap_incoming),
- d->ctx, length);
- ohci1394_stop_context(ohci, d->ctrlClear, msg);
- spin_unlock_irqrestore(&d->lock, flags);
- return;
- }
-
- /* The first case is where we have a packet that crosses
- * over more than one descriptor. The next case is where
- * it's all in the first descriptor. */
- if ((offset + length) > d->buf_size) {
- DBGMSG("Split packet rcv'd");
- if (length > d->split_buf_size) {
- ohci1394_stop_context(ohci, d->ctrlClear,
- "Split packet size exceeded");
- d->buf_ind = idx;
- d->buf_offset = offset;
- spin_unlock_irqrestore(&d->lock, flags);
- return;
- }
-
- if (le32_to_cpu(d->prg_cpu[(idx+1)%d->num_desc]->status)
- == d->buf_size) {
- /* Other part of packet not written yet.
- * this should never happen I think
- * anyway we'll get it on the next call. */
- PRINT(KERN_INFO,
- "Got only half a packet!");
- d->buf_ind = idx;
- d->buf_offset = offset;
- spin_unlock_irqrestore(&d->lock, flags);
- return;
- }
-
- split_left = length;
- split_ptr = (char *)d->spb;
- memcpy(split_ptr,buf_ptr,d->buf_size-offset);
- split_left -= d->buf_size-offset;
- split_ptr += d->buf_size-offset;
- insert_dma_buffer(d, idx);
- idx = (idx+1) % d->num_desc;
- buf_ptr = d->buf_cpu[idx];
- offset=0;
-
- while (split_left >= d->buf_size) {
- memcpy(split_ptr,buf_ptr,d->buf_size);
- split_ptr += d->buf_size;
- split_left -= d->buf_size;
- insert_dma_buffer(d, idx);
- idx = (idx+1) % d->num_desc;
- buf_ptr = d->buf_cpu[idx];
- }
-
- if (split_left > 0) {
- memcpy(split_ptr, buf_ptr, split_left);
- offset = split_left;
- buf_ptr += offset/4;
- }
- } else {
- DBGMSG("Single packet rcv'd");
- memcpy(d->spb, buf_ptr, length);
- offset += length;
- buf_ptr += length/4;
- if (offset==d->buf_size) {
- insert_dma_buffer(d, idx);
- idx = (idx+1) % d->num_desc;
- buf_ptr = d->buf_cpu[idx];
- offset=0;
- }
- }
-
- /* We get one phy packet to the async descriptor for each
- * bus reset. We always ignore it. */
- if (tcode != OHCI1394_TCODE_PHY) {
- if (!ohci->no_swap_incoming)
- header_le32_to_cpu(d->spb, tcode);
- DBGMSG("Packet received from node"
- " %d ack=0x%02X spd=%d tcode=0x%X"
- " length=%d ctx=%d tlabel=%d",
- (d->spb[1]>>16)&0x3f,
- (cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f,
- (cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3,
- tcode, length, d->ctx,
- (d->spb[0]>>10)&0x3f);
-
- ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f)
- == 0x11) ? 1 : 0;
-
- hpsb_packet_received(ohci->host, d->spb,
- length-4, ack);
- }
-#ifdef OHCI1394_DEBUG
- else
- PRINT (KERN_DEBUG, "Got phy packet ctx=%d ... discarded",
- d->ctx);
-#endif
-
- rescount = le32_to_cpu(d->prg_cpu[idx]->status) & 0xffff;
-
- bytes_left = d->buf_size - rescount - offset;
-
- }
-
- d->buf_ind = idx;
- d->buf_offset = offset;
-
- spin_unlock_irqrestore(&d->lock, flags);
-}
-
-/* Bottom half that processes sent packets */
-static void dma_trm_tasklet (unsigned long data)
-{
- struct dma_trm_ctx *d = (struct dma_trm_ctx*)data;
- struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
- struct hpsb_packet *packet, *ptmp;
- unsigned long flags;
- u32 status, ack;
- size_t datasize;
-
- spin_lock_irqsave(&d->lock, flags);
-
- list_for_each_entry_safe(packet, ptmp, &d->fifo_list, driver_list) {
- datasize = packet->data_size;
- if (datasize && packet->type != hpsb_raw)
- status = le32_to_cpu(
- d->prg_cpu[d->sent_ind]->end.status) >> 16;
- else
- status = le32_to_cpu(
- d->prg_cpu[d->sent_ind]->begin.status) >> 16;
-
- if (status == 0)
- /* this packet hasn't been sent yet*/
- break;
-
-#ifdef OHCI1394_DEBUG
- if (datasize)
- if (((le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf) == 0xa)
- DBGMSG("Stream packet sent to channel %d tcode=0x%X "
- "ack=0x%X spd=%d dataLength=%d ctx=%d",
- (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>8)&0x3f,
- (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf,
- status&0x1f, (status>>5)&0x3,
- le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16,
- d->ctx);
- else
- DBGMSG("Packet sent to node %d tcode=0x%X tLabel="
- "%d ack=0x%X spd=%d dataLength=%d ctx=%d",
- (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16)&0x3f,
- (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf,
- (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>10)&0x3f,
- status&0x1f, (status>>5)&0x3,
- le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3])>>16,
- d->ctx);
- else
- DBGMSG("Packet sent to node %d tcode=0x%X tLabel="
- "%d ack=0x%X spd=%d data=0x%08X ctx=%d",
- (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])
- >>16)&0x3f,
- (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
- >>4)&0xf,
- (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])
- >>10)&0x3f,
- status&0x1f, (status>>5)&0x3,
- le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3]),
- d->ctx);
-#endif
-
- if (status & 0x10) {
- ack = status & 0xf;
- } else {
- switch (status & 0x1f) {
- case EVT_NO_STATUS: /* that should never happen */
- case EVT_RESERVED_A: /* that should never happen */
- case EVT_LONG_PACKET: /* that should never happen */
- PRINT(KERN_WARNING, "Received OHCI evt_* error 0x%x", status & 0x1f);
- ack = ACKX_SEND_ERROR;
- break;
- case EVT_MISSING_ACK:
- ack = ACKX_TIMEOUT;
- break;
- case EVT_UNDERRUN:
- ack = ACKX_SEND_ERROR;
- break;
- case EVT_OVERRUN: /* that should never happen */
- PRINT(KERN_WARNING, "Received OHCI evt_* error 0x%x", status & 0x1f);
- ack = ACKX_SEND_ERROR;
- break;
- case EVT_DESCRIPTOR_READ:
- case EVT_DATA_READ:
- case EVT_DATA_WRITE:
- ack = ACKX_SEND_ERROR;
- break;
- case EVT_BUS_RESET: /* that should never happen */
- PRINT(KERN_WARNING, "Received OHCI evt_* error 0x%x", status & 0x1f);
- ack = ACKX_SEND_ERROR;
- break;
- case EVT_TIMEOUT:
- ack = ACKX_TIMEOUT;
- break;
- case EVT_TCODE_ERR:
- ack = ACKX_SEND_ERROR;
- break;
- case EVT_RESERVED_B: /* that should never happen */
- case EVT_RESERVED_C: /* that should never happen */
- PRINT(KERN_WARNING, "Received OHCI evt_* error 0x%x", status & 0x1f);
- ack = ACKX_SEND_ERROR;
- break;
- case EVT_UNKNOWN:
- case EVT_FLUSHED:
- ack = ACKX_SEND_ERROR;
- break;
- default:
- PRINT(KERN_ERR, "Unhandled OHCI evt_* error 0x%x", status & 0x1f);
- ack = ACKX_SEND_ERROR;
- BUG();
- }
- }
-
- list_del_init(&packet->driver_list);
- hpsb_packet_sent(ohci->host, packet, ack);
-
- if (datasize)
- pci_unmap_single(ohci->dev,
- cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address),
- datasize, PCI_DMA_TODEVICE);
-
- d->sent_ind = (d->sent_ind+1)%d->num_desc;
- d->free_prgs++;
- }
-
- dma_trm_flush(ohci, d);
-
- spin_unlock_irqrestore(&d->lock, flags);
-}
-
-static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
-{
- int i;
- struct ti_ohci *ohci = d->ohci;
-
- if (ohci == NULL)
- return;
-
- DBGMSG("Freeing dma_rcv_ctx %d", d->ctx);
-
- if (d->buf_cpu) {
- for (i=0; i<d->num_desc; i++)
- if (d->buf_cpu[i] && d->buf_bus[i])
- pci_free_consistent(
- ohci->dev, d->buf_size,
- d->buf_cpu[i], d->buf_bus[i]);
- kfree(d->buf_cpu);
- kfree(d->buf_bus);
- }
- if (d->prg_cpu) {
- for (i=0; i<d->num_desc; i++)
- if (d->prg_cpu[i] && d->prg_bus[i])
- pci_pool_free(d->prg_pool, d->prg_cpu[i],
- d->prg_bus[i]);
- pci_pool_destroy(d->prg_pool);
- kfree(d->prg_cpu);
- kfree(d->prg_bus);
- }
- kfree(d->spb);
-
- /* Mark this context as freed. */
- d->ohci = NULL;
-}
-
-static int
-alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
- enum context_type type, int ctx, int num_desc,
- int buf_size, int split_buf_size, int context_base)
-{
- int i, len;
- static int num_allocs;
- static char pool_name[20];
-
- d->ohci = ohci;
- d->type = type;
- d->ctx = ctx;
-
- d->num_desc = num_desc;
- d->buf_size = buf_size;
- d->split_buf_size = split_buf_size;
-
- d->ctrlSet = 0;
- d->ctrlClear = 0;
- d->cmdPtr = 0;
-
- d->buf_cpu = kzalloc(d->num_desc * sizeof(*d->buf_cpu), GFP_ATOMIC);
- d->buf_bus = kzalloc(d->num_desc * sizeof(*d->buf_bus), GFP_ATOMIC);
-
- if (d->buf_cpu == NULL || d->buf_bus == NULL) {
- PRINT(KERN_ERR, "Failed to allocate %s", "DMA buffer");
- free_dma_rcv_ctx(d);
- return -ENOMEM;
- }
-
- d->prg_cpu = kzalloc(d->num_desc * sizeof(*d->prg_cpu), GFP_ATOMIC);
- d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_ATOMIC);
-
- if (d->prg_cpu == NULL || d->prg_bus == NULL) {
- PRINT(KERN_ERR, "Failed to allocate %s", "DMA prg");
- free_dma_rcv_ctx(d);
- return -ENOMEM;
- }
-
- d->spb = kmalloc(d->split_buf_size, GFP_ATOMIC);
-
- if (d->spb == NULL) {
- PRINT(KERN_ERR, "Failed to allocate %s", "split buffer");
- free_dma_rcv_ctx(d);
- return -ENOMEM;
- }
-
- len = sprintf(pool_name, "ohci1394_rcv_prg");
- sprintf(pool_name+len, "%d", num_allocs);
- d->prg_pool = pci_pool_create(pool_name, ohci->dev,
- sizeof(struct dma_cmd), 4, 0);
- if(d->prg_pool == NULL)
- {
- PRINT(KERN_ERR, "pci_pool_create failed for %s", pool_name);
- free_dma_rcv_ctx(d);
- return -ENOMEM;
- }
- num_allocs++;
-
- for (i=0; i<d->num_desc; i++) {
- d->buf_cpu[i] = pci_alloc_consistent(ohci->dev,
- d->buf_size,
- d->buf_bus+i);
-
- if (d->buf_cpu[i] != NULL) {
- memset(d->buf_cpu[i], 0, d->buf_size);
- } else {
- PRINT(KERN_ERR,
- "Failed to allocate %s", "DMA buffer");
- free_dma_rcv_ctx(d);
- return -ENOMEM;
- }
-
- d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i);
-
- if (d->prg_cpu[i] != NULL) {
- memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd));
- } else {
- PRINT(KERN_ERR,
- "Failed to allocate %s", "DMA prg");
- free_dma_rcv_ctx(d);
- return -ENOMEM;
- }
- }
-
- spin_lock_init(&d->lock);
-
- d->ctrlSet = context_base + OHCI1394_ContextControlSet;
- d->ctrlClear = context_base + OHCI1394_ContextControlClear;
- d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
-
- tasklet_init(&d->task, dma_rcv_tasklet, (unsigned long) d);
- return 0;
-}
-
-static void free_dma_trm_ctx(struct dma_trm_ctx *d)
-{
- int i;
- struct ti_ohci *ohci = d->ohci;
-
- if (ohci == NULL)
- return;
-
- DBGMSG("Freeing dma_trm_ctx %d", d->ctx);
-
- if (d->prg_cpu) {
- for (i=0; i<d->num_desc; i++)
- if (d->prg_cpu[i] && d->prg_bus[i])
- pci_pool_free(d->prg_pool, d->prg_cpu[i],
- d->prg_bus[i]);
- pci_pool_destroy(d->prg_pool);
- kfree(d->prg_cpu);
- kfree(d->prg_bus);
- }
-
- /* Mark this context as freed. */
- d->ohci = NULL;
-}
-
-static int
-alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
- enum context_type type, int ctx, int num_desc,
- int context_base)
-{
- int i, len;
- static char pool_name[20];
- static int num_allocs=0;
-
- d->ohci = ohci;
- d->type = type;
- d->ctx = ctx;
- d->num_desc = num_desc;
- d->ctrlSet = 0;
- d->ctrlClear = 0;
- d->cmdPtr = 0;
-
- d->prg_cpu = kzalloc(d->num_desc * sizeof(*d->prg_cpu), GFP_KERNEL);
- d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_KERNEL);
-
- if (d->prg_cpu == NULL || d->prg_bus == NULL) {
- PRINT(KERN_ERR, "Failed to allocate %s", "AT DMA prg");
- free_dma_trm_ctx(d);
- return -ENOMEM;
- }
-
- len = sprintf(pool_name, "ohci1394_trm_prg");
- sprintf(pool_name+len, "%d", num_allocs);
- d->prg_pool = pci_pool_create(pool_name, ohci->dev,
- sizeof(struct at_dma_prg), 4, 0);
- if (d->prg_pool == NULL) {
- PRINT(KERN_ERR, "pci_pool_create failed for %s", pool_name);
- free_dma_trm_ctx(d);
- return -ENOMEM;
- }
- num_allocs++;
-
- for (i = 0; i < d->num_desc; i++) {
- d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i);
-
- if (d->prg_cpu[i] != NULL) {
- memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg));
- } else {
- PRINT(KERN_ERR,
- "Failed to allocate %s", "AT DMA prg");
- free_dma_trm_ctx(d);
- return -ENOMEM;
- }
- }
-
- spin_lock_init(&d->lock);
-
- /* initialize tasklet */
- d->ctrlSet = context_base + OHCI1394_ContextControlSet;
- d->ctrlClear = context_base + OHCI1394_ContextControlClear;
- d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
- tasklet_init(&d->task, dma_trm_tasklet, (unsigned long)d);
- return 0;
-}
-
-static void ohci_set_hw_config_rom(struct hpsb_host *host, __be32 *config_rom)
-{
- struct ti_ohci *ohci = host->hostdata;
-
- reg_write(ohci, OHCI1394_ConfigROMhdr, be32_to_cpu(config_rom[0]));
- reg_write(ohci, OHCI1394_BusOptions, be32_to_cpu(config_rom[2]));
-
- memcpy(ohci->csr_config_rom_cpu, config_rom, OHCI_CONFIG_ROM_LEN);
-}
-
-
-static quadlet_t ohci_hw_csr_reg(struct hpsb_host *host, int reg,
- quadlet_t data, quadlet_t compare)
-{
- struct ti_ohci *ohci = host->hostdata;
- int i;
-
- reg_write(ohci, OHCI1394_CSRData, data);
- reg_write(ohci, OHCI1394_CSRCompareData, compare);
- reg_write(ohci, OHCI1394_CSRControl, reg & 0x3);
-
- for (i = 0; i < OHCI_LOOP_COUNT; i++) {
- if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000)
- break;
-
- mdelay(1);
- }
-
- return reg_read(ohci, OHCI1394_CSRData);
-}
-
-static struct hpsb_host_driver ohci1394_driver = {
- .owner = THIS_MODULE,
- .name = OHCI1394_DRIVER_NAME,
- .set_hw_config_rom = ohci_set_hw_config_rom,
- .transmit_packet = ohci_transmit,
- .devctl = ohci_devctl,
- .isoctl = ohci_isoctl,
- .hw_csr_reg = ohci_hw_csr_reg,
-};
-
-/***********************************
- * PCI Driver Interface functions *
- ***********************************/
-
-#ifdef CONFIG_PPC_PMAC
-static void ohc