rpms/kernel/devel kernel.spec, 1.469, 1.470 linux-2.6-firewire-git-pending.patch, 1.10, 1.11 linux-2.6-firewire-git-update.patch, 1.7, 1.8

Jarod Wilson (jwilson) fedora-extras-commits at redhat.com
Mon Mar 3 21:13:29 UTC 2008


Author: jwilson

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv18680

Modified Files:
	kernel.spec linux-2.6-firewire-git-pending.patch 
	linux-2.6-firewire-git-update.patch 
Log Message:
* Mon Mar 03 2008 Jarod Wilson <jwilson at redhat.com>
- Rebase firewire to latest linux1394-2.6.git tree
- firewire-sbp2: permit drives to suspend (#243210)
- firewire: restore bus power on resume on older PowerPC Macs



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.469
retrieving revision 1.470
diff -u -r1.469 -r1.470
--- kernel.spec	3 Mar 2008 16:05:03 -0000	1.469
+++ kernel.spec	3 Mar 2008 21:12:45 -0000	1.470
@@ -1144,11 +1144,11 @@
 #ApplyPatch linux-2.6-ext4-stable-queue.patch
 
 # linux1394 git patches
-#ApplyPatch linux-2.6-firewire-git-update.patch
-#C=$(wc -l $RPM_SOURCE_DIR/linux-2.6-firewire-git-pending.patch | awk '{print $1}')
-#if [ "$C" -gt 10 ]; then
-#ApplyPatch linux-2.6-firewire-git-pending.patch
-#fi
+ApplyPatch linux-2.6-firewire-git-update.patch
+C=$(wc -l $RPM_SOURCE_DIR/linux-2.6-firewire-git-pending.patch | awk '{print $1}')
+if [ "$C" -gt 10 ]; then
+ApplyPatch linux-2.6-firewire-git-pending.patch
+fi
 
 # usb video
 ApplyPatch linux-2.6-uvcvideo.patch
@@ -1744,6 +1744,11 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL} -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.conf %{with_xen} xen
 
 %changelog
+* Mon Mar 03 2008 Jarod Wilson <jwilson at redhat.com>
+- Rebase firewire to latest linux1394-2.6.git tree
+- firewire-sbp2: permit drives to suspend (#243210)
+- firewire: restore bus power on resume on older PowerPC Macs
+
 * Mon Mar 03 2008 Kyle McMartin <kmcmartin at redhat.com>
 - Add virtio_blk patch from Jeremy Katz
 

linux-2.6-firewire-git-pending.patch:

View full diff with command:
/usr/bin/cvs -f diff  -kk -u -N -r 1.10 -r 1.11 linux-2.6-firewire-git-pending.patch
Index: linux-2.6-firewire-git-pending.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-firewire-git-pending.patch,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- linux-2.6-firewire-git-pending.patch	2 Mar 2008 05:54:10 -0000	1.10
+++ linux-2.6-firewire-git-pending.patch	3 Mar 2008 21:12:45 -0000	1.11
@@ -3,1722 +3,485 @@
 # tree, which we think we're going to want...
 #
 
-The generation of incoming requests was filled in in wrong byte order on
-machines with big endian CPU.
+read_bus_info_block() is repeatedly called by workqueue jobs.
+These will step on each others toes eventually if there are multiple
+workqueue threads, and we end up with corrupt config ROM images.
 
 Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
-Cc: sparclinux at vger.kernel.org
-Cc: linuxppc-dev at ozlabs.org
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
 ---
+ drivers/firewire/fw-device.c |   41 +++++++++++++++++++++++------------
+ 1 file changed, 27 insertions(+), 14 deletions(-)
 
-This patch is a shot in the dark, based on a warning when building with
-C=1 CHECKFLAGS="-D__CHECK_ENDIAN__".  Is it really a fix, or was the
-previous code accidentally correct?
-
-This needs to be tested on different big endian PCs, if possible with
-the Apple Uninorth FireWire controller and other types of controllers.
-One test which involves ohci->request_generation is simply with an SBP-2
-device (harddisk, CD-ROM...).  Does SBP-2 login etc. work?
-
-If possible, also test whether the device remains accessible after
-forcing a bus reset, e.g. by "echo br short > firecontrol".  You need
-the easy to build utility firecontrol and a libraw1394 with "juju"
-backend.  See wiki.linux1394.org for directions.
-
-
- drivers/firewire/fw-ohci.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: linux/drivers/firewire/fw-ohci.c
-===================================================================
---- linux.orig/drivers/firewire/fw-ohci.c
-+++ linux/drivers/firewire/fw-ohci.c
-@@ -375,7 +375,7 @@ static __le32 *handle_ar_packet(struct a
- 	 */
- 
- 	if (p.ack + 16 == 0x09)
--		ohci->request_generation = (buffer[2] >> 16) & 0xff;
-+		ohci->request_generation = (p.header[2] >> 16) & 0xff;
- 	else if (ctx == &ohci->ar_request_ctx)
- 		fw_core_handle_request(&ohci->card, &p);
- 	else
-
--- 
-Stefan Richter
--=====-==--- --=- =-===
-http://arcgraph.de/sr/
-
-
-Kills warnings from 'make C=1 CHECKFLAGS="-D__CHECK_ENDIAN__" modules':
-
-drivers/firewire/fw-transaction.c:771:10: warning: incorrect type in assignment (different base types)
-drivers/firewire/fw-transaction.c:771:10:    expected unsigned int [unsigned] [usertype] <noident>
-drivers/firewire/fw-transaction.c:771:10:    got restricted unsigned int [usertype] <noident>
-drivers/firewire/fw-transaction.h:93:10: warning: incorrect type in assignment (different base types)
-drivers/firewire/fw-transaction.h:93:10:    expected unsigned int [unsigned] [usertype] <noident>
-drivers/firewire/fw-transaction.h:93:10:    got restricted unsigned int [usertype] <noident>
-drivers/firewire/fw-ohci.c:1490:8: warning: restricted degrades to integer
-drivers/firewire/fw-ohci.c:1490:35: warning: restricted degrades to integer
-drivers/firewire/fw-ohci.c:1516:5: warning: cast to restricted type
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
-Cc: sparclinux at vger.kernel.org
-Cc: linuxppc-dev at ozlabs.org
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
----
- drivers/firewire/fw-ohci.c        |    4 ++--
- drivers/firewire/fw-transaction.c |    2 +-
- drivers/firewire/fw-transaction.h |    6 +++---
- 3 files changed, 6 insertions(+), 6 deletions(-)
-
-Index: linux/drivers/firewire/fw-ohci.c
-===================================================================
---- linux.orig/drivers/firewire/fw-ohci.c
-+++ linux/drivers/firewire/fw-ohci.c
-@@ -1487,7 +1487,7 @@ static int handle_ir_dualbuffer_packet(s
- 	void *p, *end;
- 	int i;
- 
--	if (db->first_res_count > 0 && db->second_res_count > 0) {
-+	if (db->first_res_count != 0 && db->second_res_count != 0) {
- 		if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
- 			/* This descriptor isn't done yet, stop iteration. */
- 			return 0;
-@@ -1513,7 +1513,7 @@ static int handle_ir_dualbuffer_packet(s
- 		memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
- 		i += ctx->base.header_size;
- 		ctx->excess_bytes +=
--			(le32_to_cpu(*(u32 *)(p + 4)) >> 16) & 0xffff;
-+			(le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
- 		p += ctx->base.header_size + 4;
- 	}
- 	ctx->header_length = i;
-Index: linux/drivers/firewire/fw-transaction.c
-===================================================================
---- linux.orig/drivers/firewire/fw-transaction.c
-+++ linux/drivers/firewire/fw-transaction.c
-@@ -751,7 +751,7 @@ handle_topology_map(struct fw_card *card
- 		    void *payload, size_t length, void *callback_data)
- {
- 	int i, start, end;
--	u32 *map;
-+	__be32 *map;
- 
- 	if (!TCODE_IS_READ_REQUEST(tcode)) {
- 		fw_send_response(card, request, RCODE_TYPE_ERROR);
-Index: linux/drivers/firewire/fw-transaction.h
-===================================================================
---- linux.orig/drivers/firewire/fw-transaction.h
-+++ linux/drivers/firewire/fw-transaction.h
-@@ -85,12 +85,12 @@
- static inline void
- fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
- {
--	u32 *dst = _dst;
--	u32 *src = _src;
-+	u32    *dst = _dst;
-+	__be32 *src = _src;
- 	int i;
- 
- 	for (i = 0; i < size / 4; i++)
--		dst[i] = cpu_to_be32(src[i]);
-+		dst[i] = be32_to_cpu(src[i]);
- }
- 
- static inline void
-
--- 
-Stefan Richter
--=====-==--- --=- =-===
-http://arcgraph.de/sr/
-
-
-Patch "firewire: fw-sbp2: fix NULL pointer deref. in scsi_remove_device"
-had the unintended effect that firewire-sbp2 could not be unloaded
-anymore until all SBP-2 devices were unplugged.
-
-We now fix the NULL pointer bug by reacquiring a reference to the sdev
-instead of holding a reference to the sdev (and to the module) all the
-time.
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
----
-
-This applies on top of current linux-2.6.git master as well as on top of
-linux1394-2.6.git master.
-
-
- drivers/firewire/fw-sbp2.c |   46 +++++++++++++++++++++----------------
- 1 file changed, 27 insertions(+), 19 deletions(-)
-
-Index: linux/drivers/firewire/fw-sbp2.c
+Index: linux/drivers/firewire/fw-device.c
 ===================================================================
---- linux.orig/drivers/firewire/fw-sbp2.c
-+++ linux/drivers/firewire/fw-sbp2.c
-@@ -122,7 +122,6 @@ static const char sbp2_driver_name[] = "
- struct sbp2_logical_unit {
- 	struct sbp2_target *tgt;
- 	struct list_head link;
--	struct scsi_device *sdev;
- 	struct fw_address_handler address_handler;
- 	struct list_head orb_list;
- 
-@@ -139,6 +138,7 @@ struct sbp2_logical_unit {
- 	int generation;
- 	int retries;
- 	struct delayed_work work;
-+	bool has_sdev;
- 	bool blocked;
- };
- 
-@@ -751,20 +751,33 @@ static void sbp2_unblock(struct sbp2_tar
- 	scsi_unblock_requests(shost);
+--- linux.orig/drivers/firewire/fw-device.c
++++ linux/drivers/firewire/fw-device.c
+@@ -400,6 +400,9 @@ read_rom(struct fw_device *device, int g
+ 	return callback_data.rcode;
  }
  
-+static int sbp2_lun2int(u16 lun)
-+{
-+	struct scsi_lun eight_bytes_lun;
-+
-+	memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
[...1727 lines suppressed...]
-Shut up two "may be used uninitialised in this function" warnings due to
-PPC32's implementation of dma_alloc_coherent().
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
----
-
-Wasn't there a macro somewhere for this?
-
-Also, could this be better done in PPC32's dma_alloc_coherent()?
-At least this kind of workaround here doesn't add anything to the
-compiled result.
-
- drivers/firewire/fw-ohci.c |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-Index: linux-2.6.25-rc3/drivers/firewire/fw-ohci.c
-===================================================================
---- linux-2.6.25-rc3.orig/drivers/firewire/fw-ohci.c
-+++ linux-2.6.25-rc3/drivers/firewire/fw-ohci.c
-@@ -544,7 +544,7 @@ static int
- context_add_buffer(struct context *ctx)
- {
- 	struct descriptor_buffer *desc;
--	dma_addr_t bus_addr;
-+	dma_addr_t uninitialized_var(bus_addr);
- 	int offset;
  
- 	/*
-@@ -1334,7 +1334,7 @@ ohci_set_config_rom(struct fw_card *card
- 	unsigned long flags;
- 	int retval = -EBUSY;
- 	__be32 *next_config_rom;
--	dma_addr_t next_config_rom_bus;
-+	dma_addr_t uninitialized_var(next_config_rom_bus);
- 
- 	ohci = fw_ohci(card);
- 
-
--- 
-Stefan Richter
--=====-==--- --== ----=
-http://arcgraph.de/sr/
-
-
-This way firewire-ohci can be used for remote debugging like ohci1394.
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
----
- Documentation/debugging-via-ohci1394.txt |   13 ++++++++-----
- drivers/firewire/fw-ohci.c               |    9 +++++++++
- lib/Kconfig.debug                        |   10 ++++++++++
- 3 files changed, 27 insertions(+), 5 deletions(-)
-
-Index: linux/Documentation/debugging-via-ohci1394.txt
-===================================================================
---- linux.orig/Documentation/debugging-via-ohci1394.txt
-+++ linux/Documentation/debugging-via-ohci1394.txt
-@@ -41,11 +41,14 @@ to a working state and enables physical 
- This can be turned off by ohci1394's module parameter phys_dma=0.
- 
- The alternative firewire-ohci driver in drivers/firewire uses filtered physical
--DMA, hence is not yet suitable for remote debugging.
--
--Because ohci1394 depends on the PCI enumeration to be completed, an
--initialization routine which runs pretty early (long before console_init()
--which makes the printk buffer appear on the console can be called) was written.
-+DMA by default, which is more secure but not suitable for remote debugging.
-+Compile the driver with CONFIG_FIREWIRE_OHCI_REMOTE_DMA to get unfiltered
-+physical DMA.
-+
-+Because ohci1394 and firewire-ohci depend on the PCI enumeration to be
-+completed, an initialization routine which runs pretty early has been
-+implemented for x86.  This routine runs long before console_init() can be
-+called, i.e. before the printk buffer appears on the console.
- 
- To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu:
- Provide code for enabling DMA over FireWire early on boot) and pass the
-Index: linux/drivers/firewire/fw-ohci.c
++	case FW_NODE_INITIATED_RESET:
++		device = node->data;
++		if (device == NULL)
++			goto create;
++
++		device->node_id = node->node_id;
++		smp_wmb();  /* update node_id before generation */
++		device->generation = card->generation;
++		if (atomic_cmpxchg(&device->state,
++			    FW_DEVICE_RUNNING,
++			    FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) {
++			PREPARE_DELAYED_WORK(&device->work, fw_device_refresh);
++			schedule_delayed_work(&device->work, INITIAL_DELAY);
++		}
++		break;
++
+ 	case FW_NODE_UPDATED:
+ 		if (!node->link_on || node->data == NULL)
+ 			break;
+Index: linux/drivers/firewire/fw-topology.c
 ===================================================================
---- linux.orig/drivers/firewire/fw-ohci.c
-+++ linux/drivers/firewire/fw-ohci.c
-@@ -1091,6 +1091,11 @@ static void bus_reset_tasklet(unsigned l
- 		reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header);
- 	}
- 
-+#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
-+	reg_write(ohci, OHCI1394_PhyReqFilterHiSet, ~0);
-+	reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0);
-+#endif
-+
- 	spin_unlock_irqrestore(&ohci->lock, flags);
- 
- 	if (free_rom)
-@@ -1429,6 +1434,9 @@ static int ohci_cancel_packet(struct fw_
- static int
- ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
- {
-+#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
-+	return 0;
-+#else
- 	struct fw_ohci *ohci = fw_ohci(card);
- 	unsigned long flags;
- 	int n, retval = 0;
-@@ -1460,6 +1468,7 @@ ohci_enable_phys_dma(struct fw_card *car
-  out:
- 	spin_unlock_irqrestore(&ohci->lock, flags);
- 	return retval;
-+#endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */
- }
+--- linux.orig/drivers/firewire/fw-topology.c
++++ linux/drivers/firewire/fw-topology.c
+@@ -107,6 +107,7 @@ static struct fw_node *fw_node_create(u3
+ 	node->node_id = LOCAL_BUS | SELF_ID_PHY_ID(sid);
+ 	node->link_on = SELF_ID_LINK_ON(sid);
+ 	node->phy_speed = SELF_ID_PHY_SPEED(sid);
++	node->initiated_reset = SELF_ID_PHY_INITIATOR(sid);
+ 	node->port_count = port_count;
+ 
+ 	atomic_set(&node->ref_count, 1);
+@@ -430,6 +431,8 @@ update_tree(struct fw_card *card, struct
+ 			event = FW_NODE_LINK_OFF;
+ 		else if (!node0->link_on && node1->link_on)
+ 			event = FW_NODE_LINK_ON;
++		else if (node1->initiated_reset && node1->link_on)
++			event = FW_NODE_INITIATED_RESET;
+ 		else
+ 			event = FW_NODE_UPDATED;
+ 
+Index: linux/drivers/firewire/fw-topology.h
+===================================================================
+--- linux.orig/drivers/firewire/fw-topology.h
++++ linux/drivers/firewire/fw-topology.h
+@@ -20,11 +20,12 @@
+ #define __fw_topology_h
+ 
+ enum {
+-	FW_NODE_CREATED =   0x00,
+-	FW_NODE_UPDATED =   0x01,
+-	FW_NODE_DESTROYED = 0x02,
+-	FW_NODE_LINK_ON =   0x03,
+-	FW_NODE_LINK_OFF =  0x04,
++	FW_NODE_CREATED,
++	FW_NODE_UPDATED,
++	FW_NODE_DESTROYED,
++	FW_NODE_LINK_ON,
++	FW_NODE_LINK_OFF,
++	FW_NODE_INITIATED_RESET,
+ };
  
- static u64
-Index: linux/lib/Kconfig.debug
-===================================================================
---- linux.orig/lib/Kconfig.debug
-+++ linux/lib/Kconfig.debug
-@@ -592,6 +592,16 @@ config LATENCYTOP
- 	  Enable this option if you want to use the LatencyTOP tool
- 	  to find out which userspace is blocking on what kernel operations.
- 
-+config FIREWIRE_OHCI_REMOTE_DMA
-+	bool "Remote debugging via firewire-ohci"
-+	depends on FIREWIRE_OHCI
-+	help
-+	  This option lets you use the FireWire bus for remote debugging.
-+	  It enables unfiltered remote DMA in the firewire-ohci driver.
-+	  See Documentation/debugging-via-ohci1394.txt for more information.
-+
-+	  If unsure, say N.
-+
- config PROVIDE_OHCI1394_DMA_INIT
- 	bool "Provide code for enabling DMA over FireWire early on boot"
- 	depends on PCI && X86
+ struct fw_node {
 
 -- 
 Stefan Richter
--=====-==--- --=- ===--
+-=====-==--- --== ---==
 http://arcgraph.de/sr/
 
 

linux-2.6-firewire-git-update.patch:

Index: linux-2.6-firewire-git-update.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-firewire-git-update.patch,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- linux-2.6-firewire-git-update.patch	21 Feb 2008 04:40:21 -0000	1.7
+++ linux-2.6-firewire-git-update.patch	3 Mar 2008 21:12:45 -0000	1.8
@@ -1,905 +1,1102 @@
-git diff in linux1394-git tree vs. 2.6.25-rc1, 02/20/2008
+git diff in linux1394-git tree vs. 2.6.25-rc3-git4, 03/03/2008
 
- Documentation/debugging-via-ohci1394.txt |   17 +-
- drivers/firewire/fw-cdev.c               |    8 +-
- drivers/firewire/fw-device.c             |   48 +++--
- drivers/firewire/fw-device.h             |    2 +-
- drivers/firewire/fw-sbp2.c               |  358 +++++++++++++++++++++++-------
- drivers/ieee1394/sbp2.c                  |   22 ++-
- drivers/ieee1394/sbp2.h                  |    2 +
- 7 files changed, 345 insertions(+), 112 deletions(-)
-
----
+ Documentation/debugging-via-ohci1394.txt |   13 ++-
+ drivers/firewire/fw-card.c               |   38 ----------
+ drivers/firewire/fw-device.h             |   27 ++++---
+ drivers/firewire/fw-ohci.c               |  114 +++++++++++++++++++++-------
+ drivers/firewire/fw-sbp2.c               |  120 ++++++++++++------------------
+ drivers/firewire/fw-transaction.c        |    2 +-
+ drivers/firewire/fw-transaction.h        |   10 +--
+ drivers/ieee1394/csr.c                   |    6 +-
+ drivers/ieee1394/dv1394.c                |    3 +-
+ drivers/ieee1394/nodemgr.c               |    6 +-
+ drivers/ieee1394/ohci1394.c              |  109 ++++++++++++---------------
+ drivers/ieee1394/raw1394.c               |    1 -
+ drivers/ieee1394/sbp2.c                  |    7 +-
+ drivers/ieee1394/video1394.c             |    3 +-
+ lib/Kconfig.debug                        |   10 +++
+ 15 files changed, 233 insertions(+), 236 deletions(-)
 
 diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
-index de4804e..c360d4e 100644
+index c360d4e..371ba27 100644
 --- a/Documentation/debugging-via-ohci1394.txt
 +++ b/Documentation/debugging-via-ohci1394.txt
-@@ -36,14 +36,15 @@ available (notebooks) or too slow for extensive debug information (like ACPI).
- Drivers
- -------
- 
--The OHCI-1394 drivers in drivers/firewire and drivers/ieee1394 initialize
--the OHCI-1394 controllers to a working state and can be used to enable
--physical DMA. By default you only have to load the driver, and physical
--DMA access will be granted to all remote nodes, but it can be turned off
--when using the ohci1394 driver.
--
--Because these drivers depend on the PCI enumeration to be completed, an
--initialization routine which can runs pretty early (long before console_init(),
-+The ohci1394 driver in drivers/ieee1394 initializes the OHCI-1394 controllers
-+to a working state and enables physical DMA by default for all remote nodes.
-+This can be turned off by ohci1394's module parameter phys_dma=0.
-+
-+The alternative firewire-ohci driver in drivers/firewire uses filtered physical
-+DMA, hence is not yet suitable for remote debugging.
-+
-+Because ohci1394 depends on the PCI enumeration to be completed, an
-+initialization routine which runs pretty early (long before console_init()
- which makes the printk buffer appear on the console can be called) was written.
+@@ -41,11 +41,14 @@ to a working state and enables physical DMA by default for all remote nodes.
+ This can be turned off by ohci1394's module parameter phys_dma=0.
+ 
+ The alternative firewire-ohci driver in drivers/firewire uses filtered physical
+-DMA, hence is not yet suitable for remote debugging.
+-
+-Because ohci1394 depends on the PCI enumeration to be completed, an
+-initialization routine which runs pretty early (long before console_init()
+-which makes the printk buffer appear on the console can be called) was written.
++DMA by default, which is more secure but not suitable for remote debugging.
++Compile the driver with CONFIG_FIREWIRE_OHCI_REMOTE_DMA to get unfiltered
++physical DMA.
++
++Because ohci1394 and firewire-ohci depend on the PCI enumeration to be
++completed, an initialization routine which runs pretty early has been
++implemented for x86.  This routine runs long before console_init() can be
++called, i.e. before the printk buffer appears on the console.
  
  To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu:
-diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
-index 7e73cba..44ccee2 100644
---- a/drivers/firewire/fw-cdev.c
-+++ b/drivers/firewire/fw-cdev.c
-@@ -109,15 +109,17 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
- 	struct client *client;
- 	unsigned long flags;
+ Provide code for enabling DMA over FireWire early on boot) and pass the
+diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
+index a034627..140b34d 100644
+--- a/drivers/firewire/fw-card.c
++++ b/drivers/firewire/fw-card.c
+@@ -398,7 +398,6 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
+ {
+ 	static atomic_t index = ATOMIC_INIT(-1);
  
--	device = fw_device_from_devt(inode->i_rdev);
-+	device = fw_device_get_by_devt(inode->i_rdev);
- 	if (device == NULL)
- 		return -ENODEV;
- 
- 	client = kzalloc(sizeof(*client), GFP_KERNEL);
--	if (client == NULL)
-+	if (client == NULL) {
-+		fw_device_put(device);
- 		return -ENOMEM;
-+	}
+-	kref_init(&card->kref);
+ 	atomic_set(&card->device_count, 0);
+ 	card->index = atomic_inc_return(&index);
+ 	card->driver = driver;
+@@ -429,12 +428,6 @@ fw_card_add(struct fw_card *card,
+ 	card->link_speed = link_speed;
+ 	card->guid = guid;
+ 
+-	/*
+-	 * The subsystem grabs a reference when the card is added and
+-	 * drops it when the driver calls fw_core_remove_card.
+-	 */
+-	fw_card_get(card);
+-
+ 	mutex_lock(&card_mutex);
+ 	config_rom = generate_config_rom(card, &length);
+ 	list_add_tail(&card->link, &card_list);
+@@ -540,40 +533,9 @@ fw_core_remove_card(struct fw_card *card)
+ 	cancel_delayed_work_sync(&card->work);
+ 	fw_flush_transactions(card);
+ 	del_timer_sync(&card->flush_timer);
+-
+-	fw_card_put(card);
+ }
+ EXPORT_SYMBOL(fw_core_remove_card);
+ 
+-struct fw_card *
+-fw_card_get(struct fw_card *card)
+-{
+-	kref_get(&card->kref);
+-
+-	return card;
+-}
+-EXPORT_SYMBOL(fw_card_get);
+-
+-static void
+-release_card(struct kref *kref)
+-{
+-	struct fw_card *card = container_of(kref, struct fw_card, kref);
+-
+-	kfree(card);
+-}
+-
+-/*
+- * An assumption for fw_card_put() is that the card driver allocates
+- * the fw_card struct with kalloc and that it has been shut down
+- * before the last ref is dropped.
+- */
+-void
+-fw_card_put(struct fw_card *card)
+-{
+-	kref_put(&card->kref, release_card);
+-}
+-EXPORT_SYMBOL(fw_card_put);
+-
+ int
+ fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
+ {
+diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
+index 78ecd39..0d771fd 100644
+--- a/drivers/firewire/fw-device.h
++++ b/drivers/firewire/fw-device.h
+@@ -64,28 +64,24 @@ struct fw_device {
+ 	struct fw_attribute_group attribute_group;
+ };
  
--	client->device = fw_device_get(device);
-+	client->device = device;
- 	INIT_LIST_HEAD(&client->event_list);
- 	INIT_LIST_HEAD(&client->resource_list);
- 	spin_lock_init(&client->lock);
-diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
-index de9066e..2ab13e0 100644
---- a/drivers/firewire/fw-device.c
-+++ b/drivers/firewire/fw-device.c
-@@ -358,12 +358,9 @@ static ssize_t
- guid_show(struct device *dev, struct device_attribute *attr, char *buf)
- {
- 	struct fw_device *device = fw_device(dev);
--	u64 guid;
- 
--	guid = ((u64)device->config_rom[3] << 32) | device->config_rom[4];
--
--	return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
--			(unsigned long long)guid);
-+	return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n",
-+			device->config_rom[3], device->config_rom[4]);
- }
- 
- static struct device_attribute fw_device_attributes[] = {
-@@ -610,12 +607,14 @@ static DECLARE_RWSEM(idr_rwsem);
- static DEFINE_IDR(fw_device_idr);
- int fw_cdev_major;
+-static inline struct fw_device *
+-fw_device(struct device *dev)
++static inline struct fw_device *fw_device(struct device *dev)
+ {
+ 	return container_of(dev, struct fw_device, device);
+ }
  
--struct fw_device *fw_device_from_devt(dev_t devt)
-+struct fw_device *fw_device_get_by_devt(dev_t devt)
+-static inline int
+-fw_device_is_shutdown(struct fw_device *device)
++static inline int fw_device_is_shutdown(struct fw_device *device)
  {
- 	struct fw_device *device;
+ 	return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN;
+ }
  
- 	down_read(&idr_rwsem);
- 	device = idr_find(&fw_device_idr, MINOR(devt));
-+	if (device)
-+		fw_device_get(device);
- 	up_read(&idr_rwsem);
+-static inline struct fw_device *
+-fw_device_get(struct fw_device *device)
++static inline struct fw_device *fw_device_get(struct fw_device *device)
+ {
+ 	get_device(&device->device);
  
  	return device;
-@@ -627,13 +626,14 @@ static void fw_device_shutdown(struct work_struct *work)
- 		container_of(work, struct fw_device, work.work);
- 	int minor = MINOR(device->device.devt);
+ }
  
--	down_write(&idr_rwsem);
--	idr_remove(&fw_device_idr, minor);
--	up_write(&idr_rwsem);
--
- 	fw_device_cdev_remove(device);
- 	device_for_each_child(&device->device, NULL, shutdown_unit);
- 	device_unregister(&device->device);
-+
-+	down_write(&idr_rwsem);
-+	idr_remove(&fw_device_idr, minor);
-+	up_write(&idr_rwsem);
-+	fw_device_put(device);
+-static inline void
+-fw_device_put(struct fw_device *device)
++static inline void fw_device_put(struct fw_device *device)
+ {
+ 	put_device(&device->device);
  }
+@@ -104,12 +100,23 @@ struct fw_unit {
+ 	struct fw_attribute_group attribute_group;
+ };
  
- static struct device_type fw_device_type = {
-@@ -682,10 +682,13 @@ static void fw_device_init(struct work_struct *work)
- 	}
+-static inline struct fw_unit *
+-fw_unit(struct device *dev)
++static inline struct fw_unit *fw_unit(struct device *dev)
+ {
+ 	return container_of(dev, struct fw_unit, device);
+ }
  
- 	err = -ENOMEM;
++static inline struct fw_unit *fw_unit_get(struct fw_unit *unit)
++{
++	get_device(&unit->device);
 +
-+	fw_device_get(device);
- 	down_write(&idr_rwsem);
- 	if (idr_pre_get(&fw_device_idr, GFP_KERNEL))
- 		err = idr_get_new(&fw_device_idr, device, &minor);
- 	up_write(&idr_rwsem);
++	return unit;
++}
 +
- 	if (err < 0)
- 		goto error;
++static inline void fw_unit_put(struct fw_unit *unit)
++{
++	put_device(&unit->device);
++}
++
+ #define CSR_OFFSET	0x40
+ #define CSR_LEAF	0x80
+ #define CSR_DIRECTORY	0xc0
+diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
+index 7ebad3c..28ea78c 100644
+--- a/drivers/firewire/fw-ohci.c
++++ b/drivers/firewire/fw-ohci.c
+@@ -33,6 +33,10 @@
+ #include <asm/page.h>
+ #include <asm/system.h>
+ 
++#ifdef CONFIG_PPC_PMAC
++#include <asm/pmac_feature.h>
++#endif
++
+ #include "fw-ohci.h"
+ #include "fw-transaction.h"
  
-@@ -717,13 +720,22 @@ static void fw_device_init(struct work_struct *work)
+@@ -175,6 +179,7 @@ struct fw_ohci {
+ 	int generation;
+ 	int request_generation;
+ 	u32 bus_seconds;
++	bool old_uninorth;
+ 
+ 	/*
+ 	 * Spinlock for accessing fw_ohci data.  Never call out of
+@@ -311,15 +316,22 @@ static int ar_context_add_page(struct ar_context *ctx)
+ 	return 0;
+ }
+ 
++#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
++#define cond_le32_to_cpu(v) \
++	(ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v))
++#else
++#define cond_le32_to_cpu(v) le32_to_cpu(v)
++#endif
++
+ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+ {
+ 	struct fw_ohci *ohci = ctx->ohci;
+ 	struct fw_packet p;
+ 	u32 status, length, tcode;
+ 
+-	p.header[0] = le32_to_cpu(buffer[0]);
+-	p.header[1] = le32_to_cpu(buffer[1]);
+-	p.header[2] = le32_to_cpu(buffer[2]);
++	p.header[0] = cond_le32_to_cpu(buffer[0]);
++	p.header[1] = cond_le32_to_cpu(buffer[1]);
++	p.header[2] = cond_le32_to_cpu(buffer[2]);
+ 
+ 	tcode = (p.header[0] >> 4) & 0x0f;
+ 	switch (tcode) {
+@@ -331,7 +343,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+ 		break;
+ 
+ 	case TCODE_READ_BLOCK_REQUEST :
+-		p.header[3] = le32_to_cpu(buffer[3]);
++		p.header[3] = cond_le32_to_cpu(buffer[3]);
+ 		p.header_length = 16;
+ 		p.payload_length = 0;
+ 		break;
+@@ -340,7 +352,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+ 	case TCODE_READ_BLOCK_RESPONSE:
+ 	case TCODE_LOCK_REQUEST:
+ 	case TCODE_LOCK_RESPONSE:
+-		p.header[3] = le32_to_cpu(buffer[3]);
++		p.header[3] = cond_le32_to_cpu(buffer[3]);
+ 		p.header_length = 16;
+ 		p.payload_length = p.header[3] >> 16;
+ 		break;
+@@ -357,7 +369,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+ 
+ 	/* FIXME: What to do about evt_* errors? */
+ 	length = (p.header_length + p.payload_length + 3) / 4;
+-	status = le32_to_cpu(buffer[length]);
++	status = cond_le32_to_cpu(buffer[length]);
+ 
+ 	p.ack        = ((status >> 16) & 0x1f) - 16;
+ 	p.speed      = (status >> 21) & 0x7;
+@@ -375,7 +387,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
  	 */
- 	if (atomic_cmpxchg(&device->state,
- 		    FW_DEVICE_INITIALIZING,
--		    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
-+		    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
- 		fw_device_shutdown(&device->work.work);
--	else
--		fw_notify("created new fw device %s "
--			  "(%d config rom retries, S%d00)\n",
--			  device->device.bus_id, device->config_rom_retries,
--			  1 << device->max_speed);
-+	} else {
-+		if (device->config_rom_retries)
-+			fw_notify("created device %s: GUID %08x%08x, S%d00, "
-+				  "%d config ROM retries\n",
-+				  device->device.bus_id,
-+				  device->config_rom[3], device->config_rom[4],
-+				  1 << device->max_speed,
-+				  device->config_rom_retries);
-+		else
-+			fw_notify("created device %s: GUID %08x%08x, S%d00\n",
-+				  device->device.bus_id,
-+				  device->config_rom[3], device->config_rom[4],
-+				  1 << device->max_speed);
-+	}
+ 
+ 	if (p.ack + 16 == 0x09)
+-		ohci->request_generation = (buffer[2] >> 16) & 0xff;
++		ohci->request_generation = (p.header[2] >> 16) & 0xff;
+ 	else if (ctx == &ohci->ar_request_ctx)
+ 		fw_core_handle_request(&ohci->card, &p);
+ 	else
+@@ -532,7 +544,7 @@ static int
+ context_add_buffer(struct context *ctx)
+ {
+ 	struct descriptor_buffer *desc;
+-	dma_addr_t bus_addr;
++	dma_addr_t uninitialized_var(bus_addr);
+ 	int offset;
  
  	/*
- 	 * Reschedule the IRM work if we just finished reading the
-@@ -741,7 +753,9 @@ static void fw_device_init(struct work_struct *work)
- 	idr_remove(&fw_device_idr, minor);
- 	up_write(&idr_rwsem);
-  error:
--	put_device(&device->device);
-+	fw_device_put(device);		/* fw_device_idr's reference */
+@@ -1022,13 +1034,14 @@ static void bus_reset_tasklet(unsigned long data)
+ 	 */
+ 
+ 	self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
+-	generation = (le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
++	generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
+ 	rmb();
+ 
+ 	for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
+ 		if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
+ 			fw_error("inconsistent self IDs\n");
+-		ohci->self_id_buffer[j] = le32_to_cpu(ohci->self_id_cpu[i]);
++		ohci->self_id_buffer[j] =
++				cond_le32_to_cpu(ohci->self_id_cpu[i]);
+ 	}
+ 	rmb();
+ 
+@@ -1091,6 +1104,11 @@ static void bus_reset_tasklet(unsigned long data)
+ 		reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header);
+ 	}
+ 
++#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
++	reg_write(ohci, OHCI1394_PhyReqFilterHiSet, ~0);
++	reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0);
++#endif
 +
-+	put_device(&device->device);	/* our reference */
+ 	spin_unlock_irqrestore(&ohci->lock, flags);
+ 
+ 	if (free_rom)
+@@ -1316,7 +1334,7 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
+ 	unsigned long flags;
+ 	int retval = -EBUSY;
+ 	__be32 *next_config_rom;
+-	dma_addr_t next_config_rom_bus;
++	dma_addr_t uninitialized_var(next_config_rom_bus);
+ 
+ 	ohci = fw_ohci(card);
+ 
+@@ -1429,6 +1447,9 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
+ static int
+ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
+ {
++#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
++	return 0;
++#else
+ 	struct fw_ohci *ohci = fw_ohci(card);
+ 	unsigned long flags;
+ 	int n, retval = 0;
+@@ -1460,6 +1481,7 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
+  out:
+ 	spin_unlock_irqrestore(&ohci->lock, flags);
+ 	return retval;
++#endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */
  }
  
- static int update_unit(struct device *dev, void *data)
-diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
-index 0854fe2..43808c0 100644
---- a/drivers/firewire/fw-device.h
-+++ b/drivers/firewire/fw-device.h
-@@ -77,13 +77,13 @@ fw_device_is_shutdown(struct fw_device *device)
+ static u64
+@@ -1487,7 +1509,7 @@ static int handle_ir_dualbuffer_packet(struct context *context,
+ 	void *p, *end;
+ 	int i;
+ 
+-	if (db->first_res_count > 0 && db->second_res_count > 0) {
++	if (db->first_res_count != 0 && db->second_res_count != 0) {
+ 		if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
+ 			/* This descriptor isn't done yet, stop iteration. */
+ 			return 0;
+@@ -1513,7 +1535,7 @@ static int handle_ir_dualbuffer_packet(struct context *context,
+ 		memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
+ 		i += ctx->base.header_size;
+ 		ctx->excess_bytes +=
+-			(le32_to_cpu(*(u32 *)(p + 4)) >> 16) & 0xffff;
++			(le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
+ 		p += ctx->base.header_size + 4;
+ 	}
+ 	ctx->header_length = i;
+@@ -2039,6 +2061,35 @@ static const struct fw_card_driver ohci_driver = {
+ 	.stop_iso		= ohci_stop_iso,
+ };
+ 
++#ifdef CONFIG_PPC_PMAC
++static void ohci_pmac_on(struct pci_dev *dev)
++{
++	if (machine_is(powermac)) {
++		struct device_node *ofn = pci_device_to_OF_node(dev);
++
++		if (ofn) {
++			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 1);
++			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
++		}
++	}
++}
++
++static void ohci_pmac_off(struct pci_dev *dev)
++{
++	if (machine_is(powermac)) {
++		struct device_node *ofn = pci_device_to_OF_node(dev);
++
++		if (ofn) {
++			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
++			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
++		}
++	}
++}
++#else
++#define ohci_pmac_on(dev)
++#define ohci_pmac_off(dev)
++#endif /* CONFIG_PPC_PMAC */
++
+ static int __devinit
+ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+ {
+@@ -2048,6 +2099,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+ 	int err;
+ 	size_t size;
+ 
++	ohci_pmac_on(dev);
++
+ 	ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
+ 	if (ohci == NULL) {
+ 		fw_error("Could not malloc fw_ohci data.\n");
+@@ -2059,13 +2112,17 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+ 	err = pci_enable_device(dev);
+ 	if (err) {
+ 		fw_error("Failed to enable OHCI hardware.\n");
+-		goto fail_put_card;
++		goto fail_free;
+ 	}
+ 
+ 	pci_set_master(dev);
+ 	pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0);
+ 	pci_set_drvdata(dev, ohci);
+ 
++#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
++	ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE &&
++			     dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW;
++#endif
+ 	spin_lock_init(&ohci->lock);
+ 
+ 	tasklet_init(&ohci->bus_reset_tasklet,
+@@ -2151,8 +2208,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+ 	pci_release_region(dev, 0);
+  fail_disable:
+ 	pci_disable_device(dev);
+- fail_put_card:
+-	fw_card_put(&ohci->card);
++ fail_free:
++	kfree(&ohci->card);
+ 
+ 	return err;
  }
+@@ -2180,39 +2237,42 @@ static void pci_remove(struct pci_dev *dev)
+ 	pci_iounmap(dev, ohci->registers);
+ 	pci_release_region(dev, 0);
+ 	pci_disable_device(dev);
+-	fw_card_put(&ohci->card);
++	ohci_pmac_off(dev);
++	kfree(&ohci->card);
  
- struct fw_device *fw_device_get(struct fw_device *device);
-+struct fw_device *fw_device_get_by_devt(dev_t devt);
- void fw_device_put(struct fw_device *device);
- int fw_device_enable_phys_dma(struct fw_device *device);
+ 	fw_notify("Removed fw-ohci device.\n");
+ }
  
- void fw_device_cdev_update(struct fw_device *device);
- void fw_device_cdev_remove(struct fw_device *device);
+ #ifdef CONFIG_PM
+-static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
++static int pci_suspend(struct pci_dev *dev, pm_message_t state)
+ {
+-	struct fw_ohci *ohci = pci_get_drvdata(pdev);
++	struct fw_ohci *ohci = pci_get_drvdata(dev);
+ 	int err;
+ 
+ 	software_reset(ohci);
+-	free_irq(pdev->irq, ohci);
+-	err = pci_save_state(pdev);
++	free_irq(dev->irq, ohci);
++	err = pci_save_state(dev);
+ 	if (err) {
+ 		fw_error("pci_save_state failed\n");
+ 		return err;
+ 	}
+-	err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
++	err = pci_set_power_state(dev, pci_choose_state(dev, state));
+ 	if (err)
+ 		fw_error("pci_set_power_state failed with %d\n", err);
++	ohci_pmac_off(dev);
  
--struct fw_device *fw_device_from_devt(dev_t devt);
- extern int fw_cdev_major;
+ 	return 0;
+ }
  
- struct fw_unit {
+-static int pci_resume(struct pci_dev *pdev)
++static int pci_resume(struct pci_dev *dev)
+ {
+-	struct fw_ohci *ohci = pci_get_drvdata(pdev);
++	struct fw_ohci *ohci = pci_get_drvdata(dev);
+ 	int err;
+ 
+-	pci_set_power_state(pdev, PCI_D0);
+-	pci_restore_state(pdev);
+-	err = pci_enable_device(pdev);
++	ohci_pmac_on(dev);
++	pci_set_power_state(dev, PCI_D0);
++	pci_restore_state(dev);
++	err = pci_enable_device(dev);
+ 	if (err) {
+ 		fw_error("pci_enable_device failed\n");
+ 		return err;
 diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
-index 19ece9b..5259491 100644
+index 03069a4..d6d62c6 100644
 --- a/drivers/firewire/fw-sbp2.c
 +++ b/drivers/firewire/fw-sbp2.c
-@@ -28,14 +28,15 @@
-  * and many others.
-  */
- 
-+#include <linux/blkdev.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
- #include <linux/kernel.h>
-+#include <linux/mod_devicetable.h>
- #include <linux/module.h>
- #include <linux/moduleparam.h>
--#include <linux/mod_devicetable.h>
--#include <linux/device.h>
- #include <linux/scatterlist.h>
--#include <linux/dma-mapping.h>
--#include <linux/blkdev.h>
- #include <linux/string.h>
- #include <linux/stringify.h>
- #include <linux/timer.h>
-@@ -47,9 +48,9 @@
- #include <scsi/scsi_device.h>
- #include <scsi/scsi_host.h>
- 
--#include "fw-transaction.h"
--#include "fw-topology.h"
- #include "fw-device.h"
-+#include "fw-topology.h"
-+#include "fw-transaction.h"
+@@ -174,9 +174,6 @@ struct sbp2_target {
+ #define SBP2_ORB_NULL			0x80000000
+ #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
  
- /*
-  * So far only bridges from Oxford Semiconductor are known to support
-@@ -82,6 +83,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
-  *   Avoids access beyond actual disk limits on devices with an off-by-one bug.
-  *   Don't use this with devices which don't have this bug.
-  *
-+ * - delay inquiry
-+ *   Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
-+ *
-  * - override internal blacklist
-  *   Instead of adding to the built-in blacklist, use only the workarounds
-  *   specified in the module load parameter.
-@@ -91,6 +95,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
- #define SBP2_WORKAROUND_INQUIRY_36	0x2
- #define SBP2_WORKAROUND_MODE_SENSE_8	0x4
- #define SBP2_WORKAROUND_FIX_CAPACITY	0x8
-+#define SBP2_WORKAROUND_DELAY_INQUIRY	0x10
-+#define SBP2_INQUIRY_DELAY		12
- #define SBP2_WORKAROUND_OVERRIDE	0x100
- 
- static int sbp2_param_workarounds;
-@@ -100,6 +106,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
- 	", 36 byte inquiry = "    __stringify(SBP2_WORKAROUND_INQUIRY_36)
- 	", skip mode page 8 = "   __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
- 	", fix capacity = "       __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
-+	", delay inquiry = "      __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
- 	", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
- 	", or a combination)");
+-#define SBP2_DIRECTION_TO_MEDIA		0x0
+-#define SBP2_DIRECTION_FROM_MEDIA	0x1
+-
+ /* Unit directory keys */
+ #define SBP2_CSR_UNIT_CHARACTERISTICS	0x3a
+ #define SBP2_CSR_FIRMWARE_REVISION	0x3c
+@@ -223,8 +220,8 @@ struct sbp2_status {
+ };
  
-@@ -132,6 +139,7 @@ struct sbp2_logical_unit {
- 	int generation;
- 	int retries;
- 	struct delayed_work work;
-+	bool blocked;
+ struct sbp2_pointer {
+-	u32 high;
+-	u32 low;
++	__be32 high;
++	__be32 low;
  };
  
- /*
-@@ -141,16 +149,18 @@ struct sbp2_logical_unit {
- struct sbp2_target {
- 	struct kref kref;
- 	struct fw_unit *unit;
-+	const char *bus_id;
-+	struct list_head lu_list;
+ struct sbp2_orb {
+@@ -252,8 +249,8 @@ struct sbp2_management_orb {
+ 	struct {
+ 		struct sbp2_pointer password;
+ 		struct sbp2_pointer response;
+-		u32 misc;
+-		u32 length;
++		__be32 misc;
++		__be32 length;
+ 		struct sbp2_pointer status_fifo;
+ 	} request;
+ 	__be32 response[4];
+@@ -262,20 +259,17 @@ struct sbp2_management_orb {
+ 	struct sbp2_status status;
+ };
  
- 	u64 management_agent_address;
- 	int directory_id;
- 	int node_id;
- 	int address_high;
+-#define LOGIN_RESPONSE_GET_LOGIN_ID(v)	((v).misc & 0xffff)
+-#define LOGIN_RESPONSE_GET_LENGTH(v)	(((v).misc >> 16) & 0xffff)
 -
--	unsigned workarounds;
--	struct list_head lu_list;
--
-+	unsigned int workarounds;
- 	unsigned int mgt_orb_timeout;
-+
-+	int dont_block;	/* counter for each logical unit */
-+	int blocked;	/* ditto */
+ struct sbp2_login_response {
+-	u32 misc;
++	__be32 misc;
+ 	struct sbp2_pointer command_block_agent;
+-	u32 reconnect_hold;
++	__be32 reconnect_hold;
  };
+ #define COMMAND_ORB_DATA_SIZE(v)	((v))
+ #define COMMAND_ORB_PAGE_SIZE(v)	((v) << 16)
+ #define COMMAND_ORB_PAGE_TABLE_PRESENT	((1) << 19)
+ #define COMMAND_ORB_MAX_PAYLOAD(v)	((v) << 20)
+ #define COMMAND_ORB_SPEED(v)		((v) << 24)
+-#define COMMAND_ORB_DIRECTION(v)	((v) << 27)
++#define COMMAND_ORB_DIRECTION		((1) << 27)
+ #define COMMAND_ORB_REQUEST_FORMAT(v)	((v) << 29)
+ #define COMMAND_ORB_NOTIFY		((1) << 31)
+ 
+@@ -284,7 +278,7 @@ struct sbp2_command_orb {
+ 	struct {
+ 		struct sbp2_pointer next;
+ 		struct sbp2_pointer data_descriptor;
+-		u32 misc;
++		__be32 misc;
+ 		u8 command_block[12];
+ 	} request;
+ 	struct scsi_cmnd *cmd;
+@@ -453,8 +447,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
+ 	unsigned long flags;
+ 
+ 	orb->pointer.high = 0;
+-	orb->pointer.low = orb->request_bus;
+-	fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof(orb->pointer));
++	orb->pointer.low = cpu_to_be32(orb->request_bus);
+ 
+ 	spin_lock_irqsave(&device->card->lock, flags);
+ 	list_add_tail(&orb->link, &lu->orb_list);
+@@ -530,31 +523,31 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+ 	if (dma_mapping_error(orb->response_bus))
+ 		goto fail_mapping_response;
+ 
+-	orb->request.response.high    = 0;
+-	orb->request.response.low     = orb->response_bus;
++	orb->request.response.high = 0;
++	orb->request.response.low  = cpu_to_be32(orb->response_bus);
+ 
+-	orb->request.misc =
++	orb->request.misc = cpu_to_be32(
+ 		MANAGEMENT_ORB_NOTIFY |
+ 		MANAGEMENT_ORB_FUNCTION(function) |
+-		MANAGEMENT_ORB_LUN(lun_or_login_id);
+-	orb->request.length =
+-		MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response));
++		MANAGEMENT_ORB_LUN(lun_or_login_id));
++	orb->request.length = cpu_to_be32(
++		MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response)));
+ 
+-	orb->request.status_fifo.high = lu->address_handler.offset >> 32;
+-	orb->request.status_fifo.low  = lu->address_handler.offset;
++	orb->request.status_fifo.high =
++		cpu_to_be32(lu->address_handler.offset >> 32);
++	orb->request.status_fifo.low  =
++		cpu_to_be32(lu->address_handler.offset);
+ 
+ 	if (function == SBP2_LOGIN_REQUEST) {
+ 		/* Ask for 2^2 == 4 seconds reconnect grace period */
+-		orb->request.misc |=
++		orb->request.misc |= cpu_to_be32(
+ 			MANAGEMENT_ORB_RECONNECT(2) |
+-			MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login);
++			MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login));
+ 		timeout = lu->tgt->mgt_orb_timeout;
+ 	} else {
+ 		timeout = SBP2_ORB_TIMEOUT;
+ 	}
+ 
+-	fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
+-
+ 	init_completion(&orb->done);
+ 	orb->base.callback = complete_management_orb;
+ 
+@@ -599,8 +592,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+ 			 sizeof(orb->response), DMA_FROM_DEVICE);
+  fail_mapping_response:
+ 	if (response)
+-		fw_memcpy_from_be32(response,
+-				    orb->response, sizeof(orb->response));
++		memcpy(response, orb->response, sizeof(orb->response));
+ 	kref_put(&orb->base.kref, free_orb);
+ 
+ 	return retval;
+@@ -695,10 +687,8 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
+ 	if (!tgt->dont_block && !lu->blocked &&
+ 	    lu->generation != card->generation) {
+ 		lu->blocked = true;
+-		if (++tgt->blocked == 1) {
++		if (++tgt->blocked == 1)
+ 			scsi_block_requests(shost);
+-			fw_notify("blocked %s\n", lu->tgt->bus_id);
+-		}
+ 	}
+ 	spin_unlock_irqrestore(&card->lock, flags);
+ }
+@@ -725,10 +715,8 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
+ 	}
+ 	spin_unlock_irqrestore(&card->lock, flags);
+ 
+-	if (unblock) {
++	if (unblock)
+ 		scsi_unblock_requests(shost);
+-		fw_notify("unblocked %s\n", lu->tgt->bus_id);
+-	}
+ }
  
  /*
-@@ -160,7 +170,7 @@ struct sbp2_target {
-  */
- #define SBP2_MIN_LOGIN_ORB_TIMEOUT	5000U	/* Timeout in ms */
- #define SBP2_MAX_LOGIN_ORB_TIMEOUT	40000U	/* Timeout in ms */
--#define SBP2_ORB_TIMEOUT		2000	/* Timeout in ms */
-+#define SBP2_ORB_TIMEOUT		2000U	/* Timeout in ms */
- #define SBP2_ORB_NULL			0x80000000
- #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
+@@ -790,7 +778,7 @@ static void sbp2_release_target(struct kref *kref)
+ 	scsi_remove_host(shost);
+ 	fw_notify("released %s\n", tgt->bus_id);
  
-@@ -297,7 +307,7 @@ struct sbp2_command_orb {
- static const struct {
- 	u32 firmware_revision;
- 	u32 model;
--	unsigned workarounds;
-+	unsigned int workarounds;
- } sbp2_workarounds_table[] = {
- 	/* DViCO Momobay CX-1 with TSB42AA9 bridge */ {
- 		.firmware_revision	= 0x002800,
-@@ -305,6 +315,11 @@ static const struct {
- 		.workarounds		= SBP2_WORKAROUND_INQUIRY_36 |
- 					  SBP2_WORKAROUND_MODE_SENSE_8,
- 	},
-+	/* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
-+		.firmware_revision	= 0x002800,
-+		.model			= 0x000000,
-+		.workarounds		= SBP2_WORKAROUND_DELAY_INQUIRY,
-+	},
- 	/* Initio bridges, actually only needed for some older ones */ {
- 		.firmware_revision	= 0x000200,
- 		.model			= ~0,
-@@ -501,6 +516,9 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
- 	unsigned int timeout;
- 	int retval = -ENOMEM;
+-	put_device(&tgt->unit->device);
++	fw_unit_put(tgt->unit);
+ 	scsi_host_put(shost);
+ 	fw_device_put(device);
+ }
+@@ -855,11 +843,10 @@ static void sbp2_login(struct work_struct *work)
+ 	tgt->address_high = local_node_id << 16;
+ 	sbp2_set_generation(lu, generation);
  
-+	if (function == SBP2_LOGOUT_REQUEST && fw_device_is_shutdown(device))
-+		return 0;
-+
- 	orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
- 	if (orb == NULL)
- 		return -ENOMEM;
-@@ -553,20 +571,20 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
- 
- 	retval = -EIO;
- 	if (sbp2_cancel_orbs(lu) == 0) {
--		fw_error("orb reply timed out, rcode=0x%02x\n",
--			 orb->base.rcode);
-+		fw_error("%s: orb reply timed out, rcode=0x%02x\n",
-+			 lu->tgt->bus_id, orb->base.rcode);
- 		goto out;
+-	/* Get command block agent offset and login id. */
+ 	lu->command_block_agent_address =
+-		((u64) (response.command_block_agent.high & 0xffff) << 32) |
+-		response.command_block_agent.low;
+-	lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
++		((u64)(be32_to_cpu(response.command_block_agent.high) & 0xffff)
++		      << 32) | be32_to_cpu(response.command_block_agent.low);
++	lu->login_id = be32_to_cpu(response.misc) & 0xffff;
+ 
+ 	fw_notify("%s: logged in to LUN %04x (%d retries)\n",
+ 		  tgt->bus_id, lu->lun, lu->retries);
+@@ -1091,6 +1078,7 @@ static int sbp2_probe(struct device *dev)
+ 		goto fail_shost_put;
+ 
+ 	fw_device_get(device);
++	fw_unit_get(unit);
+ 
+ 	/* Initialize to values that won't match anything in our table. */
+ 	firmware_revision = 0xff000000;
+@@ -1106,8 +1094,6 @@ static int sbp2_probe(struct device *dev)
+ 
+ 	sbp2_init_workarounds(tgt, model, firmware_revision);
+ 
+-	get_device(&unit->device);
+-
+ 	/* Do the login in a workqueue so we can easily reschedule retries. */
+ 	list_for_each_entry(lu, &tgt->lu_list, link)
+ 		sbp2_queue_work(lu, 0);
+@@ -1339,9 +1325,12 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+ 	 * tables.
+ 	 */
+ 	if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
+-		orb->request.data_descriptor.high = lu->tgt->address_high;
+-		orb->request.data_descriptor.low  = sg_dma_address(sg);
+-		orb->request.misc |= COMMAND_ORB_DATA_SIZE(sg_dma_len(sg));
++		orb->request.data_descriptor.high =
++			cpu_to_be32(lu->tgt->address_high);
++		orb->request.data_descriptor.low  =
++			cpu_to_be32(sg_dma_address(sg));
++		orb->request.misc |=
++			cpu_to_be32(COMMAND_ORB_DATA_SIZE(sg_dma_len(sg)));
+ 		return 0;
  	}
  
- 	if (orb->base.rcode != RCODE_COMPLETE) {
--		fw_error("management write failed, rcode 0x%02x\n",
--			 orb->base.rcode);
-+		fw_error("%s: management write failed, rcode 0x%02x\n",
-+			 lu->tgt->bus_id, orb->base.rcode);
- 		goto out;
+@@ -1362,16 +1351,14 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+ 				goto fail_page_table;
+ 			}
+ 			l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH);
+-			orb->page_table[j].low = sg_addr;
+-			orb->page_table[j].high = (l << 16);
++			orb->page_table[j].low = cpu_to_be32(sg_addr);
++			orb->page_table[j].high = cpu_to_be32(l << 16);
+ 			sg_addr += l;
+ 			sg_len -= l;
+ 			j++;
+ 		}
  	}
  
- 	if (STATUS_GET_RESPONSE(orb->status) != 0 ||
- 	    STATUS_GET_SBP_STATUS(orb->status) != 0) {
--		fw_error("error status: %d:%d\n",
-+		fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id,
- 			 STATUS_GET_RESPONSE(orb->status),
- 			 STATUS_GET_SBP_STATUS(orb->status));
+-	fw_memcpy_to_be32(orb->page_table, orb->page_table,
+-			  sizeof(orb->page_table[0]) * j);
+ 	orb->page_table_bus =
+ 		dma_map_single(device->card->device, orb->page_table,
+ 			       sizeof(orb->page_table), DMA_TO_DEVICE);
+@@ -1385,11 +1372,10 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+ 	 * initiator (i.e. us), but data_descriptor can refer to data
+ 	 * on other nodes so we need to put our ID in descriptor.high.
+ 	 */
+-	orb->request.data_descriptor.high = lu->tgt->address_high;
+-	orb->request.data_descriptor.low  = orb->page_table_bus;
+-	orb->request.misc |=
+-		COMMAND_ORB_PAGE_TABLE_PRESENT |
+-		COMMAND_ORB_DATA_SIZE(j);
++	orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high);
++	orb->request.data_descriptor.low  = cpu_to_be32(orb->page_table_bus);
++	orb->request.misc |= cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT |
++					 COMMAND_ORB_DATA_SIZE(j));
+ 
+ 	return 0;
+ 
+@@ -1435,8 +1421,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+ 	orb->done = done;
+ 	orb->cmd  = cmd;
+ 
+-	orb->request.next.high   = SBP2_ORB_NULL;
+-	orb->request.next.low    = 0x0;
++	orb->request.next.high   = cpu_to_be32(SBP2_ORB_NULL);
+ 	/*
+ 	 * At speed 100 we can do 512 bytes per packet, at speed 200,
+ 	 * 1024 bytes per packet etc.  The SBP-2 max_payload field
+@@ -1445,25 +1430,17 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+ 	 */
+ 	max_payload = min(device->max_speed + 7,
+ 			  device->card->max_receive - 1);
+-	orb->request.misc =
++	orb->request.misc = cpu_to_be32(
+ 		COMMAND_ORB_MAX_PAYLOAD(max_payload) |
+ 		COMMAND_ORB_SPEED(device->max_speed) |
+-		COMMAND_ORB_NOTIFY;
++		COMMAND_ORB_NOTIFY);
+ 
+ 	if (cmd->sc_data_direction == DMA_FROM_DEVICE)
+-		orb->request.misc |=
+-			COMMAND_ORB_DIRECTION(SBP2_DIRECTION_FROM_MEDIA);
+-	else if (cmd->sc_data_direction == DMA_TO_DEVICE)
+-		orb->request.misc |=
+-			COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
++		orb->request.misc |= cpu_to_be32(COMMAND_ORB_DIRECTION);
+ 
+ 	if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
  		goto out;
-@@ -590,29 +608,147 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
  
- static void
- complete_agent_reset_write(struct fw_card *card, int rcode,
--			   void *payload, size_t length, void *data)
-+			   void *payload, size_t length, void *done)
-+{
-+	complete(done);
-+}
-+
-+static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
+-	fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
+-
+-	memset(orb->request.command_block,
+-	       0, sizeof(orb->request.command_block));
+ 	memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
+ 
+ 	orb->base.callback = complete_command_orb;
+@@ -1491,11 +1468,8 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
+ 
+ 	sdev->allow_restart = 1;
+ 
+-	/*
+-	 * Update the dma alignment (minimum alignment requirements for
+-	 * start and end of DMA transfers) to be a sector
+-	 */
+-	blk_queue_update_dma_alignment(sdev->request_queue, 511);
++	/* SBP-2 requires quadlet alignment of the data buffers. */
++	blk_queue_update_dma_alignment(sdev->request_queue, 4 - 1);
+ 
+ 	if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36)
+ 		sdev->inquiry_len = 36;
+diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
+index 7fcc59d..99529e5 100644
+--- a/drivers/firewire/fw-transaction.c
++++ b/drivers/firewire/fw-transaction.c
+@@ -751,7 +751,7 @@ handle_topology_map(struct fw_card *card, struct fw_request *request,
+ 		    void *payload, size_t length, void *callback_data)
  {
--	struct fw_transaction *t = data;
-+	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
-+	DECLARE_COMPLETION_ONSTACK(done);
-+	struct fw_transaction t;
-+	static u32 z;
-+
-+	fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
-+			lu->tgt->node_id, lu->generation, device->max_speed,
-+			lu->command_block_agent_address + SBP2_AGENT_RESET,
-+			&z, sizeof(z), complete_agent_reset_write, &done);
-+	wait_for_completion(&done);
-+}
+ 	int i, start, end;
+-	u32 *map;
++	__be32 *map;
+ 
+ 	if (!TCODE_IS_READ_REQUEST(tcode)) {
+ 		fw_send_response(card, request, RCODE_TYPE_ERROR);
+diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
+index 09cb728..1a22a23 100644
+--- a/drivers/firewire/fw-transaction.h
++++ b/drivers/firewire/fw-transaction.h
+@@ -86,12 +86,12 @@
+ static inline void
+ fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
+ {
+-	u32 *dst = _dst;
+-	u32 *src = _src;
++	u32    *dst = _dst;
++	__be32 *src = _src;
+ 	int i;
  
--	kfree(t);
-+static void
-+complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
-+				   void *payload, size_t length, void *data)
-+{
-+	kfree(data);
+ 	for (i = 0; i < size / 4; i++)
+-		dst[i] = cpu_to_be32(src[i]);
++		dst[i] = be32_to_cpu(src[i]);
  }
  
--static int sbp2_agent_reset(struct sbp2_logical_unit *lu)
-+static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
- {
- 	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- 	struct fw_transaction *t;
--	static u32 zero;
-+	static u32 z;
- 
--	t = kzalloc(sizeof(*t), GFP_ATOMIC);
-+	t = kmalloc(sizeof(*t), GFP_ATOMIC);
- 	if (t == NULL)
--		return -ENOMEM;
-+		return;
- 
- 	fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
- 			lu->tgt->node_id, lu->generation, device->max_speed,
- 			lu->command_block_agent_address + SBP2_AGENT_RESET,
--			&zero, sizeof(zero), complete_agent_reset_write, t);
-+			&z, sizeof(z), complete_agent_reset_write_no_wait, t);
-+}
+ static inline void
+@@ -221,7 +221,6 @@ struct fw_card {
+ 	const struct fw_card_driver *driver;
+ 	struct device *device;
+ 	atomic_t device_count;
+-	struct kref kref;
  
--	return 0;
-+static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
-+{
-+	struct fw_card *card = fw_device(lu->tgt->unit->device.parent)->card;
-+	unsigned long flags;
-+
-+	/* serialize with comparisons of lu->generation and card->generation */
-+	spin_lock_irqsave(&card->lock, flags);
-+	lu->generation = generation;
-+	spin_unlock_irqrestore(&card->lock, flags);
-+}
-+
-+static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
-+{
-+	/*
-+	 * We may access dont_block without taking card->lock here:
-+	 * All callers of sbp2_allow_block() and all callers of sbp2_unblock()
-+	 * are currently serialized against each other.
-+	 * And a wrong result in sbp2_conditionally_block()'s access of
-+	 * dont_block is rather harmless, it simply misses its first chance.
-+	 */
-+	--lu->tgt->dont_block;
-+}
+ 	int node_id;
+ 	int generation;
+@@ -263,9 +262,6 @@ struct fw_card {
+ 	int bm_generation;
+ };
+ 
+-struct fw_card *fw_card_get(struct fw_card *card);
+-void fw_card_put(struct fw_card *card);
+-
+ /*
+  * The iso packet format allows for an immediate header/payload part
+  * stored in 'header' immediately after the packet info plus an
+diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
+index 52ac83e..c90be40 100644
+--- a/drivers/ieee1394/csr.c
++++ b/drivers/ieee1394/csr.c
+@@ -133,8 +133,7 @@ static void host_reset(struct hpsb_host *host)
+                 host->csr.state &= ~0x100;
+         }
+ 
+-        host->csr.topology_map[1] =
+-                cpu_to_be32(be32_to_cpu(host->csr.topology_map[1]) + 1);
++	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] =
+@@ -142,8 +141,7 @@ static void host_reset(struct hpsb_host *host)
+                             | csr_crc16(host->csr.topology_map + 1,
+                                         host->selfid_count + 2));
+ 
+-        host->csr.speed_map[1] =
+-                cpu_to_be32(be32_to_cpu(host->csr.speed_map[1]) + 1);
++	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));
+diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
+index 6572211..8c72f36 100644
+--- a/drivers/ieee1394/dv1394.c
++++ b/drivers/ieee1394/dv1394.c
+@@ -2179,8 +2179,7 @@ static struct ieee1394_device_id dv1394_id_table[] = {
+ MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
+ 
+ static struct hpsb_protocol_driver dv1394_driver = {
+-	.name		= "dv1394",
+-	.id_table	= dv1394_id_table,
++	.name = "dv1394",
+ };
+ 
+ 
+diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
+index 511e432..70afa37 100644
+--- a/drivers/ieee1394/nodemgr.c
++++ b/drivers/ieee1394/nodemgr.c
+@@ -701,7 +701,11 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
+ 		return 0;
+ 
+ 	driver = container_of(drv, struct hpsb_protocol_driver, driver);
+-	for (id = driver->id_table; id->match_flags != 0; id++) {
++	id = driver->id_table;
++	if (!id)
++		return 0;
 +
-+/*
-+ * Blocks lu->tgt if all of the following conditions are met:
-+ *   - Login, INQUIRY, and high-level SCSI setup of all of the target's
-+ *     logical units have been finished (indicated by dont_block == 0).
-+ *   - lu->generation is stale.
-+ *
-+ * Note, scsi_block_requests() must be called while holding card->lock,
-+ * otherwise it might foil sbp2_[conditionally_]unblock()'s attempt to
-+ * unblock the target.
-+ */
-+static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
++	for (; id->match_flags != 0; id++) {
+ 		if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
+ 		    id->vendor_id != ud->vendor_id)
+ 			continue;
+diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
+index 969de2a..29b8910 100644
+--- a/drivers/ieee1394/ohci1394.c
++++ b/drivers/ieee1394/ohci1394.c
+@@ -2993,15 +2993,9 @@ do {						\
+ 	return err;				\
+ } while (0)
+ 
+-static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
+-					const struct pci_device_id *ent)
+-{
+-	struct hpsb_host *host;
+-	struct ti_ohci *ohci;	/* shortcut to currently handled device */
+-	resource_size_t ohci_base;
+-
+ #ifdef CONFIG_PPC_PMAC
+-	/* Necessary on some machines if ohci1394 was loaded/ unloaded before */
++static void ohci1394_pmac_on(struct pci_dev *dev)
 +{
-+	struct sbp2_target *tgt = lu->tgt;
-+	struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
-+	struct Scsi_Host *shost =
-+		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&card->lock, flags);
-+	if (!tgt->dont_block && !lu->blocked &&
-+	    lu->generation != card->generation) {
-+		lu->blocked = true;
-+		if (++tgt->blocked == 1) {
-+			scsi_block_requests(shost);
-+			fw_notify("blocked %s\n", lu->tgt->bus_id);
-+		}
-+	}
-+	spin_unlock_irqrestore(&card->lock, flags);
+ 	if (machine_is(powermac)) {
+ 		struct device_node *ofn = pci_device_to_OF_node(dev);
+ 
+@@ -3010,8 +3004,32 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
+ 			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
+ 		}
+ 	}
 +}
 +
-+/*
-+ * Unblocks lu->tgt as soon as all its logical units can be unblocked.
-+ * Note, it is harmless to run scsi_unblock_requests() outside the
-+ * card->lock protected section.  On the other hand, running it inside
-+ * the section might clash with shost->host_lock.
-+ */
-+static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
++static void ohci1394_pmac_off(struct pci_dev *dev)
 +{
-+	struct sbp2_target *tgt = lu->tgt;
-+	struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
-+	struct Scsi_Host *shost =
-+		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-+	unsigned long flags;
-+	bool unblock = false;
-+
-+	spin_lock_irqsave(&card->lock, flags);
-+	if (lu->blocked && lu->generation == card->generation) {
-+		lu->blocked = false;
-+		unblock = --tgt->blocked == 0;
-+	}
-+	spin_unlock_irqrestore(&card->lock, flags);
++	if (machine_is(powermac)) {
++		struct device_node *ofn = pci_device_to_OF_node(dev);
 +
-+	if (unblock) {
-+		scsi_unblock_requests(shost);
-+		fw_notify("unblocked %s\n", lu->tgt->bus_id);
++		if (ofn) {
++			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
++			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
++		}
 +	}
 +}
-+
-+/*
-+ * Prevents future blocking of tgt and unblocks it.
-+ * Note, it is harmless to run scsi_unblock_requests() outside the
-+ * card->lock protected section.  On the other hand, running it inside
-+ * the section might clash with shost->host_lock.
-+ */
-+static void sbp2_unblock(struct sbp2_target *tgt)
-+{
-+	struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
-+	struct Scsi_Host *shost =
-+		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&card->lock, flags);
-+	++tgt->dont_block;
-+	spin_unlock_irqrestore(&card->lock, flags);
-+
-+	scsi_unblock_requests(shost);
- }
- 
- static void sbp2_release_target(struct kref *kref)
-@@ -621,23 +757,24 @@ static void sbp2_release_target(struct kref *kref)
- 	struct sbp2_logical_unit *lu, *next;
- 	struct Scsi_Host *shost =
- 		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
--	struct fw_device *device = fw_device(tgt->unit->device.parent);
-+
-+	/* prevent deadlocks */
-+	sbp2_unblock(tgt);
- 
- 	list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
--		if (lu->sdev)
-+		if (lu->sdev) {
- 			scsi_remove_device(lu->sdev);
--
--		if (!fw_device_is_shutdown(device))
--			sbp2_send_management_orb(lu, tgt->node_id,
--					lu->generation, SBP2_LOGOUT_REQUEST,
--					lu->login_id, NULL);
-+			scsi_device_put(lu->sdev);
-+		}
-+		sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
-+				SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
++#else
++#define ohci1394_pmac_on(dev)
++#define ohci1394_pmac_off(dev)
+ #endif /* CONFIG_PPC_PMAC */
  
- 		fw_core_remove_address_handler(&lu->address_handler);
- 		list_del(&lu->link);
- 		kfree(lu);
- 	}
- 	scsi_remove_host(shost);
--	fw_notify("released %s\n", tgt->unit->device.bus_id);
-+	fw_notify("released %s\n", tgt->bus_id);
++static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
++					const struct pci_device_id *ent)
++{
++	struct hpsb_host *host;
++	struct ti_ohci *ohci;	/* shortcut to currently handled device */
++	resource_size_t ohci_base;
++
++	ohci1394_pmac_on(dev);
+         if (pci_enable_device(dev))
+ 		FAIL(-ENXIO, "Failed to enable OHCI hardware");
+         pci_set_master(dev);
+@@ -3203,16 +3221,16 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
+ #undef FAIL
+ }
  
- 	put_device(&tgt->unit->device);
- 	scsi_host_put(shost);
-@@ -666,33 +803,43 @@ static void sbp2_login(struct work_struct *work)
+-static void ohci1394_pci_remove(struct pci_dev *pdev)
++static void ohci1394_pci_remove(struct pci_dev *dev)
  {
- 	struct sbp2_logical_unit *lu =
- 		container_of(work, struct sbp2_logical_unit, work.work);
--	struct Scsi_Host *shost =
--		container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]);
-+	struct sbp2_target *tgt = lu->tgt;
-+	struct fw_device *device = fw_device(tgt->unit->device.parent);
-+	struct Scsi_Host *shost;
- 	struct scsi_device *sdev;
- 	struct scsi_lun eight_bytes_lun;
--	struct fw_unit *unit = lu->tgt->unit;
--	struct fw_device *device = fw_device(unit->device.parent);
- 	struct sbp2_login_response response;
- 	int generation, node_id, local_node_id;
- 
-+	if (fw_device_is_shutdown(device))
-+		goto out;
-+
- 	generation    = device->generation;
- 	smp_rmb();    /* node_id must not be older than generation */
- 	node_id       = device->node_id;
- 	local_node_id = device->card->node_id;
- 
-+	/* If this is a re-login attempt, log out, or we might be rejected. */
-+	if (lu->sdev)
-+		sbp2_send_management_orb(lu, device->node_id, generation,
-+				SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
-+
- 	if (sbp2_send_management_orb(lu, node_id, generation,
- 				SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
--		if (lu->retries++ < 5)
-+		if (lu->retries++ < 5) {
- 			sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
--		else
--			fw_error("failed to login to %s LUN %04x\n",
--				 unit->device.bus_id, lu->lun);
-+		} else {
-+			fw_error("%s: failed to login to LUN %04x\n",
-+				 tgt->bus_id, lu->lun);
-+			/* Let any waiting I/O fail from now on. */
-+			sbp2_unblock(lu->tgt);
-+		}
- 		goto out;
+ 	struct ti_ohci *ohci;
+-	struct device *dev;
++	struct device *device;
+ 
+-	ohci = pci_get_drvdata(pdev);
++	ohci = pci_get_drvdata(dev);
+ 	if (!ohci)
+ 		return;
+ 
+-	dev = get_device(&ohci->host->device);
++	device = get_device(&ohci->host->device);
+ 
+ 	switch (ohci->init_state) {
+ 	case OHCI_INIT_DONE:
+@@ -3246,7 +3264,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
+ 		/* Soft reset before we start - this disables
+ 		 * interrupts and clears linkEnable and LPS. */
+ 		ohci_soft_reset(ohci);
+-		free_irq(ohci->dev->irq, ohci);
++		free_irq(dev->irq, ohci);
+ 
+ 	case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE:
+ 		/* The ohci_soft_reset() stops all DMA contexts, so we
+@@ -3257,12 +3275,12 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
+ 		free_dma_trm_ctx(&ohci->at_resp_context);
+ 
+ 	case OHCI_INIT_HAVE_SELFID_BUFFER:
+-		pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE,
++		pci_free_consistent(dev, OHCI1394_SI_DMA_BUF_SIZE,
+ 				    ohci->selfid_buf_cpu,
+ 				    ohci->selfid_buf_bus);
+ 
+ 	case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER:
+-		pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
++		pci_free_consistent(dev, OHCI_CONFIG_ROM_LEN,
+ 				    ohci->csr_config_rom_cpu,
+ 				    ohci->csr_config_rom_bus);
+ 
+@@ -3270,35 +3288,24 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
+ 		iounmap(ohci->registers);
+ 
+ 	case OHCI_INIT_HAVE_MEM_REGION:
+-		release_mem_region(pci_resource_start(ohci->dev, 0),
++		release_mem_region(pci_resource_start(dev, 0),
+ 				   OHCI1394_REGISTER_SIZE);
+ 
+-#ifdef CONFIG_PPC_PMAC
+-	/* On UniNorth, power down the cable and turn off the chip clock
+-	 * to save power on laptops */
+-	if (machine_is(powermac)) {
+-		struct device_node* ofn = pci_device_to_OF_node(ohci->dev);
+-
+-		if (ofn) {
+-			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
+-			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
+-		}
+-	}
+-#endif /* CONFIG_PPC_PMAC */
++		ohci1394_pmac_off(dev);
+ 
+ 	case OHCI_INIT_ALLOC_HOST:
+-		pci_set_drvdata(ohci->dev, NULL);
++		pci_set_drvdata(dev, NULL);
  	}
  
--	lu->generation        = generation;
--	lu->tgt->node_id      = node_id;
--	lu->tgt->address_high = local_node_id << 16;
-+	tgt->node_id	  = node_id;
-+	tgt->address_high = local_node_id << 16;
-+	sbp2_set_generation(lu, generation);
- 
- 	/* Get command block agent offset and login id. */
- 	lu->command_block_agent_address =
-@@ -700,8 +847,8 @@ static void sbp2_login(struct work_struct *work)
- 		response.command_block_agent.low;
- 	lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
- 
--	fw_notify("logged in to %s LUN %04x (%d retries)\n",
--		  unit->device.bus_id, lu->lun, lu->retries);
-+	fw_notify("%s: logged in to LUN %04x (%d retries)\n",
-+		  tgt->bus_id, lu->lun, lu->retries);
- 
- #if 0
- 	/* FIXME: The linux1394 sbp2 does this last step. */
-@@ -711,26 +858,62 @@ static void sbp2_login(struct work_struct *work)
- 	PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
- 	sbp2_agent_reset(lu);
- 
-+	/* This was a re-login. */
-+	if (lu->sdev) {
-+		sbp2_cancel_orbs(lu);
-+		sbp2_conditionally_unblock(lu);
-+		goto out;
-+	}
-+
-+	if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
-+		ssleep(SBP2_INQUIRY_DELAY);
-+
- 	memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
- 	eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
- 	eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
-+	shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
- 
- 	sdev = __scsi_add_device(shost, 0, 0,
- 				 scsilun_to_int(&eight_bytes_lun), lu);
--	if (IS_ERR(sdev)) {
--		sbp2_send_management_orb(lu, node_id, generation,
--				SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
--		/*
--		 * Set this back to sbp2_login so we fall back and
--		 * retry login on bus reset.
--		 */
--		PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
--	} else {
--		lu->sdev = sdev;
-+	/*
-+	 * FIXME:  We are unable to perform reconnects while in sbp2_login().
-+	 * Therefore __scsi_add_device() will get into trouble if a bus reset
-+	 * happens in parallel.  It will either fail or leave us with an
-+	 * unusable sdev.  As a workaround we check for this and retry the
-+	 * whole login and SCSI probing.
-+	 */
-+
-+	/* Reported error during __scsi_add_device() */
-+	if (IS_ERR(sdev))
-+		goto out_logout_login;
-+
-+	/* Unreported error during __scsi_add_device() */
-+	smp_rmb(); /* get current card generation */
-+	if (generation != device->card->generation) {
-+		scsi_remove_device(sdev);
- 		scsi_device_put(sdev);
-+		goto out_logout_login;
- 	}
-+
-+	/* No error during __scsi_add_device() */
-+	lu->sdev = sdev;
-+	sbp2_allow_block(lu);
-+	goto out;
-+
-+ out_logout_login:
-+	smp_rmb(); /* generation may have changed */
-+	generation = device->generation;
-+	smp_rmb(); /* node_id must not be older than generation */
-+
-+	sbp2_send_management_orb(lu, device->node_id, generation,
-+				 SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
-+	/*
-+	 * If a bus reset happened, sbp2_update will have requeued
-+	 * lu->work already.  Reset the work from reconnect to login.
-+	 */
-+	PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
-  out:
--	sbp2_target_put(lu->tgt);
-+	sbp2_target_put(tgt);
+-	if (dev)
+-		put_device(dev);
++	if (device)
++		put_device(device);
  }
  
- static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
-@@ -755,6 +938,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
- 	lu->sdev = NULL;
- 	lu->lun  = lun_entry & 0xffff;
- 	lu->retries = 0;
-+	lu->blocked = false;
-+	++tgt->dont_block;
- 	INIT_LIST_HEAD(&lu->orb_list);
- 	INIT_DELAYED_WORK(&lu->work, sbp2_login);
- 
-@@ -813,7 +998,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
- 			if (timeout > tgt->mgt_orb_timeout)
- 				fw_notify("%s: config rom contains %ds "
- 					  "management ORB timeout, limiting "
--					  "to %ds\n", tgt->unit->device.bus_id,
-+					  "to %ds\n", tgt->bus_id,
- 					  timeout / 1000,
- 					  tgt->mgt_orb_timeout / 1000);
- 			break;
-@@ -836,12 +1021,12 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
- 				  u32 firmware_revision)
- {
- 	int i;
--	unsigned w = sbp2_param_workarounds;
-+	unsigned int w = sbp2_param_workarounds;
- 
- 	if (w)
- 		fw_notify("Please notify linux1394-devel at lists.sourceforge.net "
- 			  "if you need the workarounds parameter for %s\n",
--			  tgt->unit->device.bus_id);
-+			  tgt->bus_id);
- 
- 	if (w & SBP2_WORKAROUND_OVERRIDE)
- 		goto out;
-@@ -863,8 +1048,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
- 	if (w)
- 		fw_notify("Workarounds for %s: 0x%x "
- 			  "(firmware_revision 0x%06x, model_id 0x%06x)\n",
--			  tgt->unit->device.bus_id,
--			  w, firmware_revision, model);
-+			  tgt->bus_id, w, firmware_revision, model);
- 	tgt->workarounds = w;
- }
- 
-@@ -888,6 +1072,7 @@ static int sbp2_probe(struct device *dev)
- 	tgt->unit = unit;
- 	kref_init(&tgt->kref);
- 	INIT_LIST_HEAD(&tgt->lu_list);
-+	tgt->bus_id = unit->device.bus_id;
- 
- 	if (fw_device_enable_phys_dma(device) < 0)
- 		goto fail_shost_put;
-@@ -938,10 +1123,13 @@ static void sbp2_reconnect(struct work_struct *work)
+ #ifdef CONFIG_PM
+-static int ohci1394_pci_suspend(struct pci_dev *pdev, pm_message_t state)
++static int ohci1394_pci_suspend(struct pci_dev *dev, pm_message_t state)
  {
- 	struct sbp2_logical_unit *lu =
- 		container_of(work, struct sbp2_logical_unit, work.work);
--	struct fw_unit *unit = lu->tgt->unit;
--	struct fw_device *device = fw_device(unit->device.parent);
-+	struct sbp2_target *tgt = lu->tgt;
-+	struct fw_device *device = fw_device(tgt->unit->device.parent);
- 	int generation, node_id, local_node_id;
- 
-+	if (fw_device_is_shutdown(device))
-+		goto out;
-+
- 	generation    = device->generation;
- 	smp_rmb();    /* node_id must not be older than generation */
- 	node_id       = device->node_id;
-@@ -950,10 +1138,17 @@ static void sbp2_reconnect(struct work_struct *work)
- 	if (sbp2_send_management_orb(lu, node_id, generation,
- 				     SBP2_RECONNECT_REQUEST,
- 				     lu->login_id, NULL) < 0) {
--		if (lu->retries++ >= 5) {
--			fw_error("failed to reconnect to %s\n",
--				 unit->device.bus_id);
--			/* Fall back and try to log in again. */
-+		/*
-+		 * If reconnect was impossible even though we are in the
-+		 * current generation, fall back and try to log in again.
-+		 *
-+		 * We could check for "Function rejected" status, but
-+		 * looking at the bus generation as simpler and more general.
-+		 */
-+		smp_rmb(); /* get current card generation */
-+		if (generation == device->card->generation ||
-+		    lu->retries++ >= 5) {
-+			fw_error("%s: failed to reconnect\n", tgt->bus_id);
- 			lu->retries = 0;
- 			PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
- 		}
-@@ -961,17 +1156,18 @@ static void sbp2_reconnect(struct work_struct *work)
- 		goto out;
+ 	int err;
+-	struct ti_ohci *ohci = pci_get_drvdata(pdev);
++	struct ti_ohci *ohci = pci_get_drvdata(dev);
+ 
+ 	if (!ohci) {
+ 		printk(KERN_ERR "%s: tried to suspend nonexisting host\n",
+@@ -3326,32 +3333,23 @@ static int ohci1394_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+ 	ohci_devctl(ohci->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT);
+ 	ohci_soft_reset(ohci);
+ 
+-	err = pci_save_state(pdev);
++	err = pci_save_state(dev);
+ 	if (err) {
+ 		PRINT(KERN_ERR, "pci_save_state failed with %d", err);
+ 		return err;
  	}
+-	err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
++	err = pci_set_power_state(dev, pci_choose_state(dev, state));
+ 	if (err)
+ 		DBGMSG("pci_set_power_state failed with %d", err);
+-
+-/* PowerMac suspend code comes last */
+-#ifdef CONFIG_PPC_PMAC
+-	if (machine_is(powermac)) {
+-		struct device_node *ofn = pci_device_to_OF_node(pdev);
+-
+-		if (ofn)
+-			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
+-	}
+-#endif /* CONFIG_PPC_PMAC */
++	ohci1394_pmac_off(dev);
  
--	lu->generation        = generation;
--	lu->tgt->node_id      = node_id;
--	lu->tgt->address_high = local_node_id << 16;
-+	tgt->node_id      = node_id;
-+	tgt->address_high = local_node_id << 16;
-+	sbp2_set_generation(lu, generation);
- 
--	fw_notify("reconnected to %s LUN %04x (%d retries)\n",
--		  unit->device.bus_id, lu->lun, lu->retries);
-+	fw_notify("%s: reconnected to LUN %04x (%d retries)\n",
-+		  tgt->bus_id, lu->lun, lu->retries);
- 
- 	sbp2_agent_reset(lu);
- 	sbp2_cancel_orbs(lu);
-+	sbp2_conditionally_unblock(lu);
-  out:
--	sbp2_target_put(lu->tgt);
-+	sbp2_target_put(tgt);
+ 	return 0;
  }
  
- static void sbp2_update(struct fw_unit *unit)
-@@ -986,6 +1182,7 @@ static void sbp2_update(struct fw_unit *unit)
- 	 * Iteration over tgt->lu_list is therefore safe here.
- 	 */
- 	list_for_each_entry(lu, &tgt->lu_list, link) {
-+		sbp2_conditionally_block(lu);
- 		lu->retries = 0;
- 		sbp2_queue_work(lu, 0);
- 	}
-@@ -1063,7 +1260,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
- 
- 	if (status != NULL) {
- 		if (STATUS_GET_DEAD(*status))
--			sbp2_agent_reset(orb->lu);
-+			sbp2_agent_reset_no_wait(orb->lu);
- 
- 		switch (STATUS_GET_RESPONSE(*status)) {
- 		case SBP2_STATUS_REQUEST_COMPLETE:
-@@ -1089,6 +1286,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
- 		 * or when sending the write (less likely).
- 		 */
- 		result = DID_BUS_BUSY << 16;
-+		sbp2_conditionally_block(orb->lu);
- 	}
- 
- 	dma_unmap_single(device->card->device, orb->base.request_bus,
-@@ -1197,7 +1395,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
- 	struct sbp2_logical_unit *lu = cmd->device->hostdata;
- 	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- 	struct sbp2_command_orb *orb;
--	unsigned max_payload;
-+	unsigned int max_payload;
- 	int retval = SCSI_MLQUEUE_HOST_BUSY;
- 
- 	/*
-@@ -1275,6 +1473,10 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
+-static int ohci1394_pci_resume(struct pci_dev *pdev)
++static int ohci1394_pci_resume(struct pci_dev *dev)
  {
- 	struct sbp2_logical_unit *lu = sdev->hostdata;
- 
-+	/* (Re-)Adding logical units via the SCSI stack is not supported. */
-+	if (!lu)
-+		return -ENOSYS;
-+
- 	sdev->allow_restart = 1;
- 
- 	/*
-@@ -1319,7 +1521,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
- {
- 	struct sbp2_logical_unit *lu = cmd->device->hostdata;
+ 	int err;
+-	struct ti_ohci *ohci = pci_get_drvdata(pdev);
++	struct ti_ohci *ohci = pci_get_drvdata(dev);
+ 
+ 	if (!ohci) {
+ 		printk(KERN_ERR "%s: tried to resume nonexisting host\n",
+@@ -3360,19 +3358,10 @@ static int ohci1394_pci_resume(struct pci_dev *pdev)
+ 	}
+ 	DBGMSG("resume called");
  
--	fw_notify("sbp2_scsi_abort\n");
-+	fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id);
- 	sbp2_agent_reset(lu);
- 	sbp2_cancel_orbs(lu);
+-/* PowerMac resume code comes first */
+-#ifdef CONFIG_PPC_PMAC
+-	if (machine_is(powermac)) {
+-		struct device_node *ofn = pci_device_to_OF_node(pdev);
+-
+-		if (ofn)
+-			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
+-	}
+-#endif /* CONFIG_PPC_PMAC */
+-
+-	pci_set_power_state(pdev, PCI_D0);
+-	pci_restore_state(pdev);
+-	err = pci_enable_device(pdev);
++	ohci1394_pmac_on(dev);
++	pci_set_power_state(dev, PCI_D0);
++	pci_restore_state(dev);
++	err = pci_enable_device(dev);
+ 	if (err) {
+ 		PRINT(KERN_ERR, "pci_enable_device failed with %d", err);
+ 		return err;
+diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
+index 37e7e10..3634785 100644
+--- a/drivers/ieee1394/raw1394.c
++++ b/drivers/ieee1394/raw1394.c
+@@ -2959,7 +2959,6 @@ MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
+ 
+ static struct hpsb_protocol_driver raw1394_driver = {
+ 	.name = "raw1394",
+-	.id_table = raw1394_id_table,
+ };
  
+ /******************************************************************************/
 diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
-index 28e155a..29e6663 100644
+index 9e2b196..29e6663 100644
 --- a/drivers/ieee1394/sbp2.c
 +++ b/drivers/ieee1394/sbp2.c
-@@ -183,6 +183,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
-  *   Avoids access beyond actual disk limits on devices with an off-by-one bug.
-  *   Don't use this with devices which don't have this bug.
-  *
-+ * - delay inquiry
-+ *   Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
-+ *
-  * - override internal blacklist
-  *   Instead of adding to the built-in blacklist, use only the workarounds
-  *   specified in the module load parameter.
-@@ -195,6 +198,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
- 	", 36 byte inquiry = "    __stringify(SBP2_WORKAROUND_INQUIRY_36)
- 	", skip mode page 8 = "   __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
- 	", fix capacity = "       __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
-+	", delay inquiry = "      __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
- 	", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
- 	", or a combination)");
- 
-@@ -357,6 +361,11 @@ static const struct {
- 		.workarounds		= SBP2_WORKAROUND_INQUIRY_36 |
- 					  SBP2_WORKAROUND_MODE_SENSE_8,
- 	},
-+	/* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
-+		.firmware_revision	= 0x002800,
-+		.model_id		= 0x000000,
-+		.workarounds		= SBP2_WORKAROUND_DELAY_INQUIRY,
-+	},
- 	/* Initio bridges, actually only needed for some older ones */ {
- 		.firmware_revision	= 0x000200,
- 		.model_id		= SBP2_ROM_VALUE_WILDCARD,
-@@ -914,6 +923,9 @@ static int sbp2_start_device(struct sbp2_lu *lu)
- 	sbp2_agent_reset(lu, 1);
- 	sbp2_max_speed_and_size(lu);
- 
-+	if (lu->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
-+		ssleep(SBP2_INQUIRY_DELAY);
-+
- 	error = scsi_add_device(lu->shost, 0, lu->ud->id, 0);
- 	if (error) {
- 		SBP2_ERR("scsi_add_device failed");
-@@ -1962,14 +1974,14 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
- {
- 	struct sbp2_lu *lu = (struct sbp2_lu *)sdev->host->hostdata[0];
- 
-+	if (sdev->lun != 0 || sdev->id != lu->ud->id || sdev->channel != 0)
-+		return -ENODEV;
-+
+@@ -1980,11 +1980,8 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
  	lu->sdev = sdev;
  	sdev->allow_restart = 1;
  
@@ -913,16 +1110,38 @@
  
  	if (lu->workarounds & SBP2_WORKAROUND_INQUIRY_36)
  		sdev->inquiry_len = 36;
-diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
-index d2ecb0d..80d8e09 100644
---- a/drivers/ieee1394/sbp2.h
-+++ b/drivers/ieee1394/sbp2.h
-@@ -343,6 +343,8 @@ enum sbp2lu_state_types {
- #define SBP2_WORKAROUND_INQUIRY_36	0x2
- #define SBP2_WORKAROUND_MODE_SENSE_8	0x4
- #define SBP2_WORKAROUND_FIX_CAPACITY	0x8
-+#define SBP2_WORKAROUND_DELAY_INQUIRY	0x10
-+#define SBP2_INQUIRY_DELAY		12
- #define SBP2_WORKAROUND_OVERRIDE	0x100
+diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
+index bd28adf..cc240b2 100644
+--- a/drivers/ieee1394/video1394.c
++++ b/drivers/ieee1394/video1394.c
+@@ -1315,8 +1315,7 @@ static struct ieee1394_device_id video1394_id_table[] = {
+ MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
+ 
+ static struct hpsb_protocol_driver video1394_driver = {
+-	.name		= VIDEO1394_DRIVER_NAME,
+-	.id_table	= video1394_id_table,
++	.name = VIDEO1394_DRIVER_NAME,
+ };
+ 
  
- #endif /* SBP2_H */
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 0796c1a..4e370e1 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -592,6 +592,16 @@ config LATENCYTOP
+ 	  Enable this option if you want to use the LatencyTOP tool
+ 	  to find out which userspace is blocking on what kernel operations.
+ 
++config FIREWIRE_OHCI_REMOTE_DMA
++	bool "Remote debugging via firewire-ohci"
++	depends on FIREWIRE_OHCI
++	help
++	  This option lets you use the FireWire bus for remote debugging.
++	  It enables unfiltered remote DMA in the firewire-ohci driver.
++	  See Documentation/debugging-via-ohci1394.txt for more information.
++
++	  If unsure, say N.
++
+ config PROVIDE_OHCI1394_DMA_INIT
+ 	bool "Provide code for enabling DMA over FireWire early on boot"
+ 	depends on PCI && X86




More information about the fedora-extras-commits mailing list