rpms/kernel/devel kernel.spec, 1.485, 1.486 linux-2.6-firewire-git-pending.patch, 1.13, 1.14 linux-2.6-firewire-git-update.patch, 1.8, 1.9

Jarod Wilson (jwilson) fedora-extras-commits at redhat.com
Mon Mar 10 14:10:10 UTC 2008


Author: jwilson

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

Modified Files:
	kernel.spec linux-2.6-firewire-git-pending.patch 
	linux-2.6-firewire-git-update.patch 
Log Message:
* Mon Mar 10 2008 Jarod Wilson <jwilson at redhat.com>
- firewire: additional debug output if config ROM read fails



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.485
retrieving revision 1.486
diff -u -r1.485 -r1.486
--- kernel.spec	8 Mar 2008 20:20:23 -0000	1.485
+++ kernel.spec	10 Mar 2008 14:09:35 -0000	1.486
@@ -1752,6 +1752,9 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL} -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.conf %{with_xen} xen
 
 %changelog
+* Mon Mar 10 2008 Jarod Wilson <jwilson at redhat.com>
+- firewire: additional debug output if config ROM read fails
+
 * Sat Mar  8 2008 Chuck Ebbert <cebbert at redhat.com>
 - 2.6.25-rc4-git3
 

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.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- linux-2.6-firewire-git-pending.patch	7 Mar 2008 06:46:59 -0000	1.13
+++ linux-2.6-firewire-git-pending.patch	10 Mar 2008 14:09:35 -0000	1.14
@@ -3,693 +3,1028 @@
 # tree, which we think we're going to want...
 #
 
-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.
+
+Increase reconnect management orb timeout.
+
+Signed-off-by: Jarod Wilson <jwilson at redhat.com>
+
+---
+
+ drivers/firewire/fw-sbp2.c |   15 +++++++++++++--
+ 1 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
+index d6d62c6..da315cf 100644
+--- a/drivers/firewire/fw-sbp2.c
++++ b/drivers/firewire/fw-sbp2.c
+@@ -170,6 +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_MAX_RECONNECT_ORB_TIMEOUT	6000U	/* Timeout in ms */
+ #define SBP2_ORB_TIMEOUT		2000U	/* Timeout in ms */
+ #define SBP2_ORB_NULL			0x80000000
+ #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
+@@ -538,14 +539,24 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+ 	orb->request.status_fifo.low  =
+ 		cpu_to_be32(lu->address_handler.offset);
+ 
+-	if (function == SBP2_LOGIN_REQUEST) {
++	switch (function) {
++
++	case SBP2_LOGIN_REQUEST:
+ 		/* Ask for 2^2 == 4 seconds reconnect grace period */
+ 		orb->request.misc |= cpu_to_be32(
+ 			MANAGEMENT_ORB_RECONNECT(2) |
+ 			MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login));
+ 		timeout = lu->tgt->mgt_orb_timeout;
+-	} else {
++		break;
++
++	case SBP2_RECONNECT_REQUEST:
++		timeout = min(SBP2_MAX_RECONNECT_ORB_TIMEOUT,
++			      lu->tgt->mgt_orb_timeout);
++		break;
++
++	default:
+ 		timeout = SBP2_ORB_TIMEOUT;
++		break;
+ 	}
+ 
+ 	init_completion(&orb->done);
+
+
+
+Use bitwise and to get reg in handle_registers.
+
+Signed-off-by: Jarod Wilson <jwilson at redhat.com>
+
+---
+
+ drivers/firewire/fw-transaction.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
+index 56f7ee9..e550535 100644
+--- a/drivers/firewire/fw-transaction.c
++++ b/drivers/firewire/fw-transaction.c
+@@ -791,7 +791,7 @@ handle_registers(struct fw_card *card, struct fw_request *request,
+ 		 unsigned long long offset,
+ 		 void *payload, size_t length, void *callback_data)
+ {
+-	int reg = offset - CSR_REGISTER_BASE;
++	int reg = offset & ~CSR_REGISTER_BASE;
+ 	unsigned long long bus_time;
+ 	__be32 *data = payload;
+
+
+
+Trivial change to replace more meaningless (to the untrained eye) hex
+values with defined CSR constants.
+
+Signed-off-by: Jarod Wilson <jwilson at redhat.com>
+
+---
+
+ drivers/firewire/fw-device.c      |    2 +-
+ drivers/firewire/fw-transaction.c |    9 ++++++---
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
+index 19f2fc4..f559c63 100644
+--- a/drivers/firewire/fw-device.c
++++ b/drivers/firewire/fw-device.c
+@@ -410,7 +410,7 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data)
+ 
+ 	init_completion(&callback_data.done);
+ 
+-	offset = 0xfffff0000400ULL + index * 4;
++	offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
+ 	fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
+ 			device->node_id, generation, device->max_speed,
+ 			offset, NULL, 4, complete_transaction, &callback_data);
+diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
+index 99529e5..56f7ee9 100644
+--- a/drivers/firewire/fw-transaction.c
++++ b/drivers/firewire/fw-transaction.c
+@@ -396,7 +396,8 @@ const struct fw_address_region fw_high_memory_region =
+ const struct fw_address_region fw_private_region =
+ 	{ .start = 0xffffe0000000ULL, .end = 0xfffff0000000ULL,  };
+ const struct fw_address_region fw_csr_region =
+-	{ .start = 0xfffff0000000ULL, .end = 0xfffff0000800ULL,  };
++	{ .start = CSR_REGISTER_BASE,
++	  .end   = CSR_REGISTER_BASE | CSR_CONFIG_ROM_END,  };
+ const struct fw_address_region fw_unit_space_region =
+ 	{ .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, };
+ EXPORT_SYMBOL(fw_low_memory_region);
+@@ -741,7 +742,8 @@ fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
+ EXPORT_SYMBOL(fw_core_handle_response);
+ 
+ static const struct fw_address_region topology_map_region =
+-	{ .start = 0xfffff0001000ull, .end = 0xfffff0001400ull, };
++	{ .start = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP,
++	  .end   = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP_END, };
+ 
+ static void
+ handle_topology_map(struct fw_card *card, struct fw_request *request,
+@@ -779,7 +781,8 @@ static struct fw_address_handler topology_map = {
+ };
+ 
+ static const struct fw_address_region registers_region =
+-	{ .start = 0xfffff0000000ull, .end = 0xfffff0000400ull, };
++	{ .start = CSR_REGISTER_BASE,
++	  .end   = CSR_REGISTER_BASE | CSR_CONFIG_ROM, };
+ 
+ static void
+ handle_registers(struct fw_card *card, struct fw_request *request,
+From stefanr at s5r6.in-berlin.de Sat Mar  8 16:38:16 2008
+Return-Path: <linux1394-devel-bounces at lists.sourceforge.net>
+Received: from mail.boston.redhat.com ([unix socket])
+	 by mail.boston.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
+	 Sat, 08 Mar 2008 16:39:18 -0500
+X-Sieve: CMU Sieve 2.2
+Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
+	by mail.boston.redhat.com (8.13.1/8.13.1) with ESMTP id m28LdHte029996
+	for <jwilson at boston.redhat.com>; Sat, 8 Mar 2008 16:39:18 -0500
+Received: from mx3.redhat.com (mx3.redhat.com [172.16.48.32])
+	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m28LdHkg017884
+	for <jwilson at redhat.com>; Sat, 8 Mar 2008 16:39:17 -0500
+Received: from lists-outbound.sourceforge.net (lists-outbound.sourceforge.net [66.35.250.225])
+	by mx3.redhat.com (8.13.8/8.13.8) with ESMTP id m28LceZI022672
+	for <jwilson at redhat.com>; Sat, 8 Mar 2008 16:38:40 -0500
+Received: from sc8-sf-list1-new.sourceforge.net (sc8-sf-list1-new-b.sourceforge.net [10.3.1.93])
+	by sc8-sf-spam2.sourceforge.net (Postfix) with ESMTP
+	id 9659912301; Sat,  8 Mar 2008 13:38:34 -0800 (PST)
+Received: from sc8-sf-mx1-b.sourceforge.net ([10.3.1.91]
+	helo=mail.sourceforge.net)
+	by sc8-sf-list1-new.sourceforge.net with esmtp (Exim 4.43)
+	id 1JY6kT-00038D-Vk for linux1394-devel at lists.sourceforge.net;
+	Sat, 08 Mar 2008 13:38:34 -0800
+Received: from einhorn.in-berlin.de ([192.109.42.8] ident=root)
+	by mail.sourceforge.net with esmtps (TLSv1:AES256-SHA:256)
+	(Exim 4.44) id 1JY6kR-0003im-Eq
+	for linux1394-devel at lists.sourceforge.net;
+	Sat, 08 Mar 2008 13:38:33 -0800
+X-Envelope-From: stefanr at s5r6.in-berlin.de
+Received: from stein (k5.avc-online.de [83.221.230.29]) (authenticated bits=0)
+	by einhorn.in-berlin.de (8.13.6/8.13.6/Debian-1) with ESMTP id
+	m28LcMtv012469
+	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT);
+	Sat, 8 Mar 2008 22:38:28 +0100
+Date: Sat, 8 Mar 2008 22:38:16 +0100 (CET)
+From: Stefan Richter <stefanr at s5r6.in-berlin.de>
+Subject: [PATCH] firewire: warn on fatal condition in topology code
+To: linux1394-devel at lists.sourceforge.net
+Message-ID: <tkrat.958f8693fedf5cf6 at s5r6.in-berlin.de>
+MIME-Version: 1.0
+Content-Disposition: INLINE
+X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254
+X-Scanned-By: MIMEDefang 2.63 on 172.16.48.32
+X-Scanned-By: MIMEDefang_at_IN-Berlin_e.V. on 192.109.42.8
+X-Spam-Report: Spam Filtering performed by sourceforge.net.
+	See http://spamassassin.org/tag/ for more details.
+	Report problems to
+	http://sf.net/tracker/?func=add&group_id=1&atid=200001
+Cc: linux-kernel at vger.kernel.org
+X-BeenThere: linux1394-devel at lists.sourceforge.net
+X-Mailman-Version: 2.1.8
+Precedence: list
+List-Id: Linux IEEE 1394 development list
+	<linux1394-devel.lists.sourceforge.net>
+List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/linux1394-devel>, 
+	<mailto:linux1394-devel-request at lists.sourceforge.net?subject=unsubscribe>
+List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=linux1394-devel>
+List-Post: <mailto:linux1394-devel at lists.sourceforge.net>
+List-Help: <mailto:linux1394-devel-request at lists.sourceforge.net?subject=help>
+List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/linux1394-devel>, 
+	<mailto:linux1394-devel-request at lists.sourceforge.net?subject=subscribe>
+Content-Type: text/plain;
+  charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linux1394-devel-bounces at lists.sourceforge.net
+Errors-To: linux1394-devel-bounces at lists.sourceforge.net
+X-RedHat-Spam-Score: -0.809 
+X-Length: 5020
+X-UID: 3936
+
+If this ever happens to anybody, we want to have it in his log.
+
+Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
+---
+ drivers/firewire/fw-topology.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: linux/drivers/firewire/fw-topology.c
+===================================================================
+--- linux.orig/drivers/firewire/fw-topology.c
++++ linux/drivers/firewire/fw-topology.c
+@@ -21,6 +21,7 @@
+ #include <linux/module.h>
+ #include <linux/wait.h>
+ #include <linux/errno.h>
++#include <asm/bug.h>
+ #include <asm/system.h>
+ #include "fw-transaction.h"
+ #include "fw-topology.h"
+@@ -425,8 +426,8 @@ update_tree(struct fw_card *card, struct
+ 	node1 = fw_node(list1.next);
+ 
+ 	while (&node0->link != &list0) {
++		WARN_ON(node0->port_count != node1->port_count);
+ 
+-		/* assert(node0->port_count == node1->port_count); */
+ 		if (node0->link_on && !node1->link_on)
+ 			event = FW_NODE_LINK_OFF;
+ 		else if (!node0->link_on && node1->link_on)
+
+-- 
+Stefan Richter
+-=====-==--- --== -=---
+http://arcgraph.de/sr/
+
+
+-------------------------------------------------------------------------
+This SF.net email is sponsored by: Microsoft
+Defy all challenges. Microsoft(R) Visual Studio 2008.
+http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
+_______________________________________________
+mailing list linux1394-devel at lists.sourceforge.net
+https://lists.sourceforge.net/lists/listinfo/linux1394-devel
+
+From stefanr at s5r6.in-berlin.de Sat Mar  8 18:27:20 2008
+Return-Path: <linux1394-devel-bounces at lists.sourceforge.net>
+Received: from mail.boston.redhat.com ([unix socket])
+	 by mail.boston.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
+	 Sat, 08 Mar 2008 18:28:31 -0500
+X-Sieve: CMU Sieve 2.2
+Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
+	by mail.boston.redhat.com (8.13.1/8.13.1) with ESMTP id m28NSVSq011980
+	for <jwilson at boston.redhat.com>; Sat, 8 Mar 2008 18:28:31 -0500
+Received: from mx3.redhat.com (mx3.redhat.com [172.16.48.32])
+	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m28NSUb1015266
+	for <jwilson at redhat.com>; Sat, 8 Mar 2008 18:28:30 -0500
+Received: from lists-outbound.sourceforge.net (lists-outbound.sourceforge.net [66.35.250.225])
+	by mx3.redhat.com (8.13.8/8.13.8) with ESMTP id m28NRqYa019208
+	for <jwilson at redhat.com>; Sat, 8 Mar 2008 18:27:53 -0500
+Received: from sc8-sf-list1-new.sourceforge.net (sc8-sf-list1-new-b.sourceforge.net [10.3.1.93])
+	by sc8-sf-spam2.sourceforge.net (Postfix) with ESMTP
+	id 37FEFFA22; Sat,  8 Mar 2008 15:27:47 -0800 (PST)
+Received: from sc8-sf-mx2-b.sourceforge.net ([10.3.1.92]
+	helo=mail.sourceforge.net)
+	by sc8-sf-list1-new.sourceforge.net with esmtp (Exim 4.43)
+	id 1JY8S9-0008Pp-Fd for linux1394-devel at lists.sourceforge.net;
+	Sat, 08 Mar 2008 15:27:45 -0800
+Received: from einhorn.in-berlin.de ([192.109.42.8] ident=root)
+	by mail.sourceforge.net with esmtps (TLSv1:AES256-SHA:256)
+	(Exim 4.44) id 1JY8S5-000097-QA
+	for linux1394-devel at lists.sourceforge.net;
+	Sat, 08 Mar 2008 15:27:45 -0800
+X-Envelope-From: stefanr at s5r6.in-berlin.de
+Received: from stein (k5.avc-online.de [83.221.230.29]) (authenticated bits=0)
+	by einhorn.in-berlin.de (8.13.6/8.13.6/Debian-1) with ESMTP id
+	m28NRPtg010333
+	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT);
+	Sun, 9 Mar 2008 00:27:33 +0100
+Date: Sun, 9 Mar 2008 00:27:20 +0100 (CET)
+From: Stefan Richter <stefanr at s5r6.in-berlin.de>
+Subject: [PATCH] firewire: update Kconfig help text
+To: linux1394-devel at lists.sourceforge.net
+Message-ID: <tkrat.9286022a0d31093d at s5r6.in-berlin.de>
+MIME-Version: 1.0
+Content-Disposition: INLINE
+X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254
+X-Scanned-By: MIMEDefang 2.63 on 172.16.48.32
+X-Scanned-By: MIMEDefang_at_IN-Berlin_e.V. on 192.109.42.8
+X-Spam-Report: Spam Filtering performed by sourceforge.net.
+	See http://spamassassin.org/tag/ for more details.
+	Report problems to
+	http://sf.net/tracker/?func=add&group_id=1&atid=200001
+Cc: linux-kernel at vger.kernel.org
+X-BeenThere: linux1394-devel at lists.sourceforge.net
+X-Mailman-Version: 2.1.8
+Precedence: list
+List-Id: Linux IEEE 1394 development list
+	<linux1394-devel.lists.sourceforge.net>
+List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/linux1394-devel>, 
+	<mailto:linux1394-devel-request at lists.sourceforge.net?subject=unsubscribe>
+List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=linux1394-devel>
+List-Post: <mailto:linux1394-devel at lists.sourceforge.net>
+List-Help: <mailto:linux1394-devel-request at lists.sourceforge.net?subject=help>
+List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/linux1394-devel>, 
+	<mailto:linux1394-devel-request at lists.sourceforge.net?subject=subscribe>
+Content-Type: text/plain;
+  charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linux1394-devel-bounces at lists.sourceforge.net
+Errors-To: linux1394-devel-bounces at lists.sourceforge.net
+X-RedHat-Spam-Score: -0.813 
+X-Length: 6999
+X-UID: 3940
+
+Remove some less necessary information, point out that video1394 and
+dv1394 should be blacklisted along with ohci1394.
+
+Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
+---
+ drivers/firewire/Kconfig |   50 ++++++++++++++-------------------------
+ 1 file changed, 19 insertions(+), 31 deletions(-)
+
+Index: linux/drivers/firewire/Kconfig
+===================================================================
+--- linux.orig/drivers/firewire/Kconfig
++++ linux/drivers/firewire/Kconfig
+@@ -1,5 +1,3 @@
+-# -*- shell-script -*-
+-
+ comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
+ 	depends on EXPERIMENTAL=n
+ 
+@@ -21,27 +19,7 @@ config FIREWIRE
+           NOTE:
+ 
+ 	  You should only build ONE of the stacks, unless you REALLY know what
+-	  you are doing.  If you install both, you should configure them only as
+-	  modules rather than link them statically, and you should blacklist one
+-	  of the concurrent low-level drivers in /etc/modprobe.conf.  Add either
+-
+-	      blacklist firewire-ohci
+-	  or
+-	      blacklist ohci1394
+-
+-	  there depending on which driver you DON'T want to have auto-loaded.
+-	  You can optionally do the same with the other IEEE 1394/ FireWire
+-	  drivers.
+-
+-	  If you have an old modprobe which doesn't implement the blacklist
+-	  directive, use either
+-
+-	       install firewire-ohci /bin/true
+-	  or
+-	       install ohci1394 /bin/true
+-
+-	  and so on, depending on which modules you DON't want to have
+-	  auto-loaded.
++	  you are doing.
+ 
+ config FIREWIRE_OHCI
+ 	tristate "Support for OHCI FireWire host controllers"
+@@ -57,8 +35,24 @@ config FIREWIRE_OHCI
+ 
+           NOTE:
+ 
+-	  If you also build ohci1394 of the classic stack, blacklist either
+-	  ohci1394 or firewire-ohci to let hotplug load only the desired driver.
++	  You should only build ohci1394 or firewire-ohci, but not both.
++	  If you nevertheless want to install both, you should configure them
++	  only as modules and blacklist the driver(s) which you don't want to
++	  have auto-loaded.  Add either
++
++	      blacklist firewire-ohci
++	  or
++	      blacklist ohci1394
++	      blacklist video1394
++	      blacklist dv1394
++
++	  to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf
++	  depending on your distribution.  The latter two modules should be
++	  blacklisted together with ohci1394 because they depend on ohci1394.
++
++	  If you have an old modprobe which doesn't implement the blacklist
++	  directive, use "install modulename /bin/true" for the modules to be
++	  blacklisted.
+ 
+ config FIREWIRE_SBP2
+ 	tristate "Support for storage devices (SBP-2 protocol driver)"
+@@ -75,9 +69,3 @@ config FIREWIRE_SBP2
+ 
+ 	  You should also enable support for disks, CD-ROMs, etc. in the SCSI
+ 	  configuration section.
+-
+-          NOTE:
+-
+-	  If you also build sbp2 of the classic stack, blacklist either sbp2
+-	  or firewire-sbp2 to let hotplug load only the desired driver.
+-
+
+-- 
+Stefan Richter
+-=====-==--- --== -=--=
+http://arcgraph.de/sr/
+
+
+-------------------------------------------------------------------------
+This SF.net email is sponsored by: Microsoft
+Defy all challenges. Microsoft(R) Visual Studio 2008.
+http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
+_______________________________________________
+mailing list linux1394-devel at lists.sourceforge.net
+https://lists.sourceforge.net/lists/listinfo/linux1394-devel
+
+Adds a goofy routine to dump the configuration ROM as far as it could be
+read, if fw-core failed to get it all.
 
 Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
 ---
- drivers/firewire/fw-device.c |   41 +++++++++++++++++++++++------------
- 1 file changed, 27 insertions(+), 14 deletions(-)
+
+We may want to reduce it to printing
+  - any encountered Extended ROM keys,
+  - the number of quadlets that were successfully read
+    (in the last attempt, or in the most successfull attempt?),
+  - the return code of the last attempt
+before submitting to mainline.
+
+ drivers/firewire/fw-device.c |  126 ++++++++++++++++++++++-------------
+ drivers/firewire/fw-device.h |    1 
+ 2 files changed, 82 insertions(+), 45 deletions(-)
 
 Index: linux/drivers/firewire/fw-device.c
 ===================================================================
 --- 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
+@@ -18,6 +18,7 @@
+  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
++#include <linux/bitops.h>
+ #include <linux/module.h>
+ #include <linux/wait.h>
+ #include <linux/errno.h>
+@@ -422,8 +423,12 @@ read_rom(struct fw_device *device, int g
  	return callback_data.rcode;
  }
  
-+#define READ_BIB_ROM_SIZE	256
-+#define READ_BIB_STACK_SIZE	16
-+
+-#define READ_BIB_ROM_SIZE	256
+-#define READ_BIB_STACK_SIZE	16
++#define MAX_CONFIG_ROM_SIZE ((CSR_CONFIG_ROM_END - CSR_CONFIG_ROM) / 4)
++
++struct config_rom_image {
++	u32 rom[MAX_CONFIG_ROM_SIZE];
++	DECLARE_BITMAP(read, MAX_CONFIG_ROM_SIZE);
++};
+ 
  /*
   * Read the bus info block, perform a speed probe, and read all of the rest of
-  * the config ROM.  We do all this with a cached bus generation.  If the bus
-@@ -409,16 +412,23 @@ read_rom(struct fw_device *device, int g
+@@ -432,35 +437,36 @@ read_rom(struct fw_device *device, int g
+  * It's better to start all over in this case because the node from which we
+  * are reading the ROM may have changed the ROM during the reset.
   */
- static int read_bus_info_block(struct fw_device *device, int generation)
+-static int read_bus_info_block(struct fw_device *device, int generation)
++static int read_bus_info_block(struct fw_device *device, int generation,
++			       struct config_rom_image *rom_img)
  {
--	static u32 rom[256];
--	u32 stack[16], sp, key;
--	int i, end, length;
-+	u32 *rom, *stack;
-+	u32 sp, key;
-+	int i, end, length, ret = -1;
-+
-+	rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE +
-+		      sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL);
-+	if (rom == NULL)
-+		return -ENOMEM;
-+
-+	stack = &rom[READ_BIB_ROM_SIZE];
+-	u32 *rom, *stack, *old_rom, *new_rom;
++	u32 *rom, *old_rom, *new_rom;
++	u32 stack[16];
+ 	u32 sp, key;
+-	int i, end, length, ret = -1;
++	int i, end, length, ret;
+ 
+-	rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE +
+-		      sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL);
+-	if (rom == NULL)
++	if (rom_img == NULL)
+ 		return -ENOMEM;
+-
+-	stack = &rom[READ_BIB_ROM_SIZE];
++	rom = rom_img->rom;
  
  	device->max_speed = SCODE_100;
  
  	/* First read the bus info block. */
  	for (i = 0; i < 5; i++) {
- 		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
--			return -1;
-+			goto out;
+-		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
+-			goto out;
++		ret = read_rom(device, generation, i, &rom[i]);
++		if (ret != RCODE_COMPLETE)
++			return ret;
++		__set_bit(i, rom_img->read);
  		/*
  		 * As per IEEE1212 7.2, during power-up, devices can
  		 * reply with a 0 for the first quadlet of the config
-@@ -428,7 +438,7 @@ static int read_bus_info_block(struct fw
+-		 * rom to indicate that they are booting (for example,
++		 * ROM to indicate that they are booting (for example,
+ 		 * if the firmware is on the disk of a external
+ 		 * harddisk).  In that case we just fail, and the
  		 * retry mechanism will try again later.
  		 */
  		if (i == 0 && rom[i] == 0)
--			return -1;
-+			goto out;
+-			goto out;
++			return -EAGAIN;
  	}
  
  	device->max_speed = device->node->max_speed;
-@@ -478,26 +488,26 @@ static int read_bus_info_block(struct fw
+@@ -484,15 +490,17 @@ static int read_bus_info_block(struct fw
+ 			device->max_speed = device->card->link_speed;
+ 
+ 		while (device->max_speed > SCODE_100) {
+-			if (read_rom(device, generation, 0, &dummy) ==
+-			    RCODE_COMPLETE)
++			ret = read_rom(device, generation, 0, &dummy);
++			if (ret == RCODE_COMPLETE)
+ 				break;
++			if (ret == RCODE_GENERATION)
++				return ret;
+ 			device->max_speed--;
+ 		}
+ 	}
+ 
+ 	/*
+-	 * Now parse the config rom.  The config rom is a recursive
++	 * Now parse the config ROM.  The config ROM is a recursive
+ 	 * directory structure so we parse it using a stack of
+ 	 * references to the blocks that make up the structure.  We
+ 	 * push a reference to the root directory on the stack to
+@@ -504,44 +512,49 @@ static int read_bus_info_block(struct fw
+ 	while (sp > 0) {
+ 		/*
+ 		 * Pop the next block reference of the stack.  The
+-		 * lower 24 bits is the offset into the config rom,
++		 * lower 24 bits is the offset into the config ROM,
+ 		 * the upper 8 bits are the type of the reference the
+ 		 * block.
  		 */
  		key = stack[--sp];
  		i = key & 0xffffff;
--		if (i >= ARRAY_SIZE(rom))
-+		if (i >= READ_BIB_ROM_SIZE)
+-		if (i >= READ_BIB_ROM_SIZE)
++		if (i >= MAX_CONFIG_ROM_SIZE) {
  			/*
  			 * The reference points outside the standard
- 			 * config rom area, something's fishy.
+-			 * config rom area, something's fishy.
++			 * config ROM area.
  			 */
--			return -1;
-+			goto out;
- 
+-			goto out;
+-
++			if (key >> 24 == (CSR_EXTENDED_ROM | CSR_LEAF))
++				fw_error("Extended ROM not supported\n");
++			return -EINVAL;
++		}
  		/* Read header quadlet for the block to get the length. */
- 		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
--			return -1;
-+			goto out;
+-		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
+-			goto out;
++		ret = read_rom(device, generation, i, &rom[i]);
++		if (ret != RCODE_COMPLETE)
++			return ret;
++		__set_bit(i, rom_img->read);
  		end = i + (rom[i] >> 16) + 1;
  		i++;
--		if (end > ARRAY_SIZE(rom))
-+		if (end > READ_BIB_ROM_SIZE)
+-		if (end > READ_BIB_ROM_SIZE)
++		if (end > MAX_CONFIG_ROM_SIZE) {
  			/*
  			 * This block extends outside standard config
  			 * area (and the array we're reading it
  			 * into).  That's broken, so ignore this
  			 * device.
  			 */
--			return -1;
-+			goto out;
- 
+-			goto out;
+-
++			return -EINVAL;
++		}
  		/*
  		 * Now read in the block.  If this is a directory
-@@ -507,9 +517,9 @@ static int read_bus_info_block(struct fw
+ 		 * block, check the entries as we read them to see if
+ 		 * it references another block, and push it in that case.
+ 		 */
  		while (i < end) {
- 			if (read_rom(device, generation, i, &rom[i]) !=
- 			    RCODE_COMPLETE)
--				return -1;
-+				goto out;
+-			if (read_rom(device, generation, i, &rom[i]) !=
+-			    RCODE_COMPLETE)
+-				goto out;
++			ret = read_rom(device, generation, i, &rom[i]);
++			if (ret != RCODE_COMPLETE)
++				return ret;
++			__set_bit(i, rom_img->read);
  			if ((key >> 30) == 3 && (rom[i] >> 30) > 1 &&
--			    sp < ARRAY_SIZE(stack))
-+			    sp < READ_BIB_STACK_SIZE)
+-			    sp < READ_BIB_STACK_SIZE)
++			    sp < ARRAY_SIZE(stack))
  				stack[sp++] = i + rom[i];
  			i++;
  		}
-@@ -519,11 +529,14 @@ static int read_bus_info_block(struct fw
+@@ -552,7 +565,7 @@ static int read_bus_info_block(struct fw
+ 	old_rom = device->config_rom;
+ 	new_rom = kmemdup(rom, length * 4, GFP_KERNEL);
+ 	if (new_rom == NULL)
+-		goto out;
++		return -ENOMEM;
  
- 	device->config_rom = kmalloc(length * 4, GFP_KERNEL);
- 	if (device->config_rom == NULL)
--		return -1;
-+		goto out;
- 	memcpy(device->config_rom, rom, length * 4);
- 	device->config_rom_length = length;
-+	ret = 0;
-+ out:
-+	kfree(rom);
+ 	down_write(&fw_device_rwsem);
+ 	device->config_rom = new_rom;
+@@ -560,14 +573,25 @@ static int read_bus_info_block(struct fw
+ 	up_write(&fw_device_rwsem);
+ 
+ 	kfree(old_rom);
+-	ret = 0;
+ 	device->cmc = rom[2] & 1 << 30;
+- out:
+-	kfree(rom);
  
--	return 0;
-+	return ret;
+-	return ret;
++	return 0;
++}
++
++static void dump_config_rom(struct config_rom_image *rom_img)
++{
++	int i;
++
++	if (rom_img == NULL || !test_bit(0, rom_img->read))
++		return;
++
++	fw_notify("config ROM read so far:\n");
++	for_each_bit(i, rom_img->read, MAX_CONFIG_ROM_SIZE)
++		printk(KERN_NOTICE "%x: %08x\n",
++		       CSR_CONFIG_ROM + i * 4, rom_img->rom[i]);
  }
  
++
  static void fw_unit_release(struct device *dev)
-
--- 
-Stefan Richter
--=====-==--- --== ---=-
-http://arcgraph.de/sr/
-
-
-When a device changes its configuration ROM, it announces this with a
-bus reset.  firewire-core has to check which node initiated a bus reset
-and whether any unit directories went away or were added on this node.
-
-Tested with an IOI FWB-IDE01AB which has its link-on bit set if bus
-power is available but does not respond to ROM read requests if self
-power is off.  This implements
-  - recognition of the units if self power is switched on after fw-core
-    gave up the initial attempt to read the config ROM,
-  - shutdown of the units when self power is switched off.
-
-Also tested with a second PC running Linux/ieee1394.  When the eth1394
-driver is inserted and removed on that node, fw-core now notices the
-addition and removal of the IPv4 unit on the ieee1394 node.
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
----
-
-Applies after "firewire: replace static ROM cache by allocated cache".
-
- drivers/firewire/fw-cdev.c     |   18 ++--
- drivers/firewire/fw-device.c   |  147 ++++++++++++++++++++++++++++++---
- drivers/firewire/fw-topology.c |    3 
- drivers/firewire/fw-topology.h |   11 +-
- 4 files changed, 158 insertions(+), 21 deletions(-)
-
-Index: linux/drivers/firewire/fw-cdev.c
-===================================================================
---- linux.orig/drivers/firewire/fw-cdev.c
-+++ linux/drivers/firewire/fw-cdev.c
-@@ -32,6 +32,7 @@
- #include <linux/idr.h>
- #include <linux/compat.h>
- #include <linux/firewire-cdev.h>
-+#include <asm/semaphore.h>
- #include <asm/system.h>
- #include <asm/uaccess.h>
- #include "fw-transaction.h"
-@@ -269,20 +270,25 @@ static int ioctl_get_info(struct client 
  {
- 	struct fw_cdev_get_info *get_info = buffer;
- 	struct fw_cdev_event_bus_reset bus_reset;
-+	struct fw_device *device = client->device;
-+	unsigned long ret = 0;
- 
- 	client->version = get_info->version;
- 	get_info->version = FW_CDEV_VERSION;
- 
-+	down(&device->device.sem);
- 	if (get_info->rom != 0) {
- 		void __user *uptr = u64_to_uptr(get_info->rom);
- 		size_t want = get_info->rom_length;
--		size_t have = client->device->config_rom_length * 4;
-+		size_t have;
- 
--		if (copy_to_user(uptr, client->device->config_rom,
--				 min(want, have)))
--			return -EFAULT;
-+		have = device->config_rom_length * 4;
-+		ret = copy_to_user(uptr, device->config_rom, min(want, have));
- 	}
--	get_info->rom_length = client->device->config_rom_length * 4;
-+	get_info->rom_length = device->config_rom_length * 4;
-+	up(&device->device.sem);
-+	if (ret != 0)
-+		return -EFAULT;
- 
- 	client->bus_reset_closure = get_info->bus_reset_closure;
- 	if (get_info->bus_reset != 0) {
-@@ -293,7 +299,7 @@ static int ioctl_get_info(struct client 
- 			return -EFAULT;
+ 	struct fw_unit *unit = fw_unit(dev);
+@@ -697,27 +721,32 @@ static void fw_device_init(struct work_s
+ {
+ 	struct fw_device *device =
+ 		container_of(work, struct fw_device, work.work);
++	struct config_rom_image *rom_img;
+ 	int minor, err;
+ 
++	rom_img = kzalloc(sizeof(*rom_img), GFP_KERNEL);
++
+ 	/*
+ 	 * All failure paths here set node->data to NULL, so that we
+ 	 * don't try to do device_for_each_child() on a kfree()'d
+ 	 * device.
+ 	 */
+ 
+-	if (read_bus_info_block(device, device->generation) < 0) {
++	err = read_bus_info_block(device, device->generation, rom_img);
++	if (err) {
+ 		if (device->config_rom_retries < MAX_RETRIES &&
+ 		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
+ 			device->config_rom_retries++;
+ 			schedule_delayed_work(&device->work, RETRY_DELAY);
+ 		} else {
+-			fw_notify("giving up on config rom for node id %x\n",
+-				  device->node_id);
++			fw_notify("giving up on config ROM for node id %x "
++				  "(returned %d)\n", device->node_id, err);
++			dump_config_rom(rom_img);
+ 			if (device->node == device->card->root_node)
+ 				schedule_delayed_work(&device->card->work, 0);
+ 			fw_device_release(&device->device);
+ 		}
+-		return;
++		goto out;
  	}
  
--	get_info->card = client->device->card->index;
-+	get_info->card = device->card->index;
+ 	err = -ENOMEM;
+@@ -786,7 +815,7 @@ static void fw_device_init(struct work_s
+ 	if (device->node == device->card->root_node)
+ 		schedule_delayed_work(&device->card->work, 0);
  
- 	return 0;
- }
-Index: linux/drivers/firewire/fw-device.c
-===================================================================
---- linux.orig/drivers/firewire/fw-device.c
-+++ linux/drivers/firewire/fw-device.c
-@@ -26,6 +26,7 @@
- #include <linux/delay.h>
- #include <linux/idr.h>
- #include <linux/rwsem.h>
-+#include <linux/string.h>
- #include <asm/semaphore.h>
- #include <asm/system.h>
- #include <linux/ctype.h>
-@@ -160,9 +161,9 @@ static void fw_device_release(struct dev
- 	 * Take the card lock so we don't set this to NULL while a
- 	 * FW_NODE_UPDATED callback is being handled.
- 	 */
--	spin_lock_irqsave(&device->card->lock, flags);
-+	spin_lock_irqsave(&card->lock, flags);
- 	device->node->data = NULL;
--	spin_unlock_irqrestore(&device->card->lock, flags);
-+	spin_unlock_irqrestore(&card->lock, flags);
- 
- 	fw_node_put(device->node);
- 	kfree(device->config_rom);
-@@ -337,10 +338,14 @@ static ssize_t
- config_rom_show(struct device *dev, struct device_attribute *attr, char *buf)
- {
- 	struct fw_device *device = fw_device(dev);
-+	size_t length;
+-	return;
++	goto out;
  
--	memcpy(buf, device->config_rom, device->config_rom_length * 4);
-+	down(&dev->sem);
-+	length = device->config_rom_length * 4;
-+	memcpy(buf, device->config_rom, length);
-+	up(&dev->sem);
+  error_with_cdev:
+ 	down_write(&fw_device_rwsem);
+@@ -796,6 +825,8 @@ static void fw_device_init(struct work_s
+ 	fw_device_put(device);		/* fw_device_idr's reference */
  
--	return device->config_rom_length * 4;
-+	return length;
+ 	put_device(&device->device);	/* our reference */
++ out:
++	kfree(rom_img);
  }
  
- static ssize_t
-@@ -412,7 +417,7 @@ read_rom(struct fw_device *device, int g
-  */
- static int read_bus_info_block(struct fw_device *device, int generation)
- {
--	u32 *rom, *stack;
-+	u32 *rom, *stack, *old_rom, *new_rom;
- 	u32 sp, key;
- 	int i, end, length, ret = -1;
+ static int update_unit(struct device *dev, void *data)
+@@ -854,6 +885,7 @@ static void fw_device_refresh(struct wor
+ 		container_of(work, struct fw_device, work.work);
+ 	struct fw_card *card = device->card;
+ 	int node_id = device->node_id;
++	struct config_rom_image *rom_img = NULL;
+ 
+ 	switch (reread_bus_info_block(device, device->generation)) {
+ 	case REREAD_BIB_ERROR:
+@@ -890,13 +922,15 @@ static void fw_device_refresh(struct wor
+ 	 */
+ 	device_for_each_child(&device->device, NULL, shutdown_unit);
  
-@@ -527,11 +532,18 @@ static int read_bus_info_block(struct fw
- 			length = i;
- 	}
+-	if (read_bus_info_block(device, device->generation) < 0) {
++	rom_img = kzalloc(sizeof(*rom_img), GFP_KERNEL);
++
++	if (read_bus_info_block(device, device->generation, rom_img) != 0) {
+ 		if (device->config_rom_retries < MAX_RETRIES &&
+ 		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
+ 			device->config_rom_retries++;
+ 			schedule_delayed_work(&device->work, RETRY_DELAY);
  
--	device->config_rom = kmalloc(length * 4, GFP_KERNEL);
--	if (device->config_rom == NULL)
-+	old_rom = device->config_rom;
-+	new_rom = kmemdup(rom, length * 4, GFP_KERNEL);
-+	if (new_rom == NULL)
- 		goto out;
--	memcpy(device->config_rom, rom, length * 4);
-+
-+	/* serialize with readers via sysfs or ioctl */
-+	down(&device->device.sem);
-+	device->config_rom = new_rom;
- 	device->config_rom_length = length;
-+	up(&device->device.sem);
-+
-+	kfree(old_rom);
- 	ret = 0;
-  out:
- 	kfree(rom);
-@@ -724,7 +736,7 @@ static void fw_device_init(struct work_s
- 	if (atomic_cmpxchg(&device->state,
- 		    FW_DEVICE_INITIALIZING,
- 		    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
--		fw_device_shutdown(&device->work.work);
-+		fw_device_shutdown(work);
- 	} else {
- 		if (device->config_rom_retries)
- 			fw_notify("created device %s: GUID %08x%08x, S%d00, "
-@@ -738,6 +750,7 @@ static void fw_device_init(struct work_s
- 				  device->device.bus_id,
- 				  device->config_rom[3], device->config_rom[4],
- 				  1 << device->max_speed);
-+		device->config_rom_retries = 0;
+-			return;
++			goto out;
+ 		}
+ 		goto give_up;
  	}
+@@ -910,16 +944,18 @@ static void fw_device_refresh(struct wor
  
- 	/*
-@@ -784,6 +797,104 @@ static void fw_device_update(struct work
- 	device_for_each_child(&device->device, NULL, update_unit);
+ 	fw_notify("refreshed device %s\n", device->device.bus_id);
+ 	device->config_rom_retries = 0;
+-	goto out;
++	goto out_bm;
+ 
+  give_up:
+ 	fw_notify("giving up on refresh of device %s\n", device->device.bus_id);
+  gone:
+ 	atomic_set(&device->state, FW_DEVICE_SHUTDOWN);
+ 	fw_device_shutdown(work);
+- out:
++ out_bm:
+ 	if (node_id == card->root_node->node_id)
+ 		schedule_delayed_work(&card->work, 0);
++ out:
++	kfree(rom_img);
  }
  
-+enum {
-+	REREAD_BIB_ERROR,
-+	REREAD_BIB_GONE,
-+	REREAD_BIB_UNCHANGED,
-+	REREAD_BIB_CHANGED,
-+};
-+
-+/* Reread and compare bus info block and header of root directory */
-+static int reread_bus_info_block(struct fw_device *device, int generation)
-+{
-+	u32 q;
-+	int i;
-+
-+	for (i = 0; i < 6; i++) {
-+		if (read_rom(device, generation, i, &q) != RCODE_COMPLETE)
-+			return REREAD_BIB_ERROR;
-+
-+		if (i == 0 && q == 0)
-+			return REREAD_BIB_GONE;
-+
-+		if (i > device->config_rom_length || q != device->config_rom[i])
-+			return REREAD_BIB_CHANGED;
-+	}
-+
-+	return REREAD_BIB_UNCHANGED;
-+}
-+
-+static void fw_device_refresh(struct work_struct *work)
-+{
-+	struct fw_device *device =
-+		container_of(work, struct fw_device, work.work);
-+	struct fw_card *card = device->card;
-+	int node_id = device->node_id;
-+
-+	switch (reread_bus_info_block(device, device->generation)) {
-+	case REREAD_BIB_ERROR:
-+		if (device->config_rom_retries < MAX_RETRIES / 2 &&
-+		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
-+			device->config_rom_retries++;
-+			schedule_delayed_work(&device->work, RETRY_DELAY / 2);
-+
-+			return;
-+		}
-+		goto give_up;
-+
-+	case REREAD_BIB_GONE:
-+		goto gone;
-+
-+	case REREAD_BIB_UNCHANGED:
-+		if (atomic_cmpxchg(&device->state,
-+			    FW_DEVICE_INITIALIZING,
-+			    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
-+			goto gone;
-+
-+		fw_device_update(work);
-+		device->config_rom_retries = 0;
-+
-+		return;
-+	}
-+
-+	/*
-+	 * Something changed.  We keep things simple and don't investigate
-+	 * further.  We just destroy all previous units and create new ones.
-+	 */
-+	device_for_each_child(&device->device, NULL, shutdown_unit);
-+
-+	if (read_bus_info_block(device, device->generation) < 0) {
-+		if (device->config_rom_retries < MAX_RETRIES &&
-+		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
-+			device->config_rom_retries++;
-+			schedule_delayed_work(&device->work, RETRY_DELAY);
-+
-+			return;
-+		}
-+		goto give_up;
-+	}
-+
-+	create_units(device);
-+
-+	if (atomic_cmpxchg(&device->state,
-+		    FW_DEVICE_INITIALIZING,
-+		    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
-+		goto gone;
-+
-+	fw_notify("refreshed device %s\n", device->device.bus_id);
-+	device->config_rom_retries = 0;
-+	goto out;
-+
-+ give_up:
-+	fw_notify("giving up on refresh of device %s\n", device->device.bus_id);
-+ gone:
-+	atomic_set(&device->state, FW_DEVICE_SHUTDOWN);
-+	fw_device_shutdown(work);
-+ out:
-+	if (node_id == card->root_node->node_id)
-+		schedule_delayed_work(&card->work, 0);
-+}
-+
  void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
- {
- 	struct fw_device *device;
-@@ -793,7 +904,7 @@ void fw_node_event(struct fw_card *card,
- 	case FW_NODE_LINK_ON:
- 		if (!node->link_on)
- 			break;
--
-+ create:
- 		device = kzalloc(sizeof(*device), GFP_ATOMIC);
- 		if (device == NULL)
- 			break;
-@@ -832,6 +943,22 @@ void fw_node_event(struct fw_card *card,
- 		schedule_delayed_work(&device->work, INITIAL_DELAY);
- 		break;
- 
-+	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-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
+Index: linux/drivers/firewire/fw-device.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,
- };
+--- linux.orig/drivers/firewire/fw-device.h
++++ linux/drivers/firewire/fw-device.h
+@@ -142,6 +142,7 @@ static inline void fw_unit_put(struct fw
+ #define CSR_DEPENDENT_INFO	0x14
+ #define CSR_MODEL		0x17
+ #define CSR_INSTANCE		0x18
++#define CSR_EXTENDED_ROM	0x1b
+ #define CSR_DIRECTORY_ID	0x20
  
- struct fw_node {
+ struct fw_csr_iterator {
 
 -- 
 Stefan Richter
--=====-==--- --== ---==
+-=====-==--- --== -=---
 http://arcgraph.de/sr/
 
 
-Increase reconnect management orb timeout value.
+-------------------------------------------------------------------------
+This SF.net email is sponsored by: Microsoft
+Defy all challenges. Microsoft(R) Visual Studio 2008.
+http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
+_______________________________________________
+mailing list linux1394-devel at lists.sourceforge.net
+https://lists.sourceforge.net/lists/listinfo/linux1394-devel
+
+From stefanr at s5r6.in-berlin.de Sun Mar  9 16:49:34 2008
+Return-Path: <linux1394-devel-bounces at lists.sourceforge.net>
+Received: from mail.boston.redhat.com ([unix socket])
+	 by mail.boston.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
+	 Sun, 09 Mar 2008 16:50:37 -0400
+X-Sieve: CMU Sieve 2.2
+Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
+	by mail.boston.redhat.com (8.13.1/8.13.1) with ESMTP id m29KobM5006784
+	for <jwilson at boston.redhat.com>; Sun, 9 Mar 2008 16:50:37 -0400
+Received: from mx3.redhat.com (mx3.redhat.com [172.16.48.32])
+	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m29KoaO1023147
+	for <jwilson at redhat.com>; Sun, 9 Mar 2008 16:50:36 -0400
+Received: from lists-outbound.sourceforge.net (lists-outbound.sourceforge.net [66.35.250.225])
+	by mx3.redhat.com (8.13.8/8.13.8) with ESMTP id m29Ko2Zt022736
+	for <jwilson at redhat.com>; Sun, 9 Mar 2008 16:50:03 -0400
+Received: from sc8-sf-list1-new.sourceforge.net (sc8-sf-list1-new-b.sourceforge.net [10.3.1.93])
+	by sc8-sf-spam2.sourceforge.net (Postfix) with ESMTP
+	id AD813136FC; Sun,  9 Mar 2008 12:49:56 -0800 (PST)
+Received: from sc8-sf-mx1-b.sourceforge.net ([10.3.1.91]
+	helo=mail.sourceforge.net)
+	by sc8-sf-list1-new.sourceforge.net with esmtp (Exim 4.43)
+	id 1JYSSw-0004vO-IA for linux1394-devel at lists.sourceforge.net;
+	Sun, 09 Mar 2008 13:49:54 -0700
+Received: from einhorn.in-berlin.de ([192.109.42.8] ident=root)
+	by mail.sourceforge.net with esmtps (TLSv1:AES256-SHA:256)
+	(Exim 4.44) id 1JYSSu-0003DS-D4
+	for linux1394-devel at lists.sourceforge.net;
+	Sun, 09 Mar 2008 13:49:54 -0700
+X-Envelope-From: stefanr at s5r6.in-berlin.de
+Received: from stein (k5.avc-online.de [83.221.230.29]) (authenticated bits=0)
+	by einhorn.in-berlin.de (8.13.6/8.13.6/Debian-1) with ESMTP id
+	m29Kndg7021845
+	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT);
+	Sun, 9 Mar 2008 21:49:45 +0100
+Date: Sun, 9 Mar 2008 21:49:34 +0100 (CET)
+From: Stefan Richter <stefanr at s5r6.in-berlin.de>
+Subject: [PATCH] firewire: debug AT, AR, and selfID-complete events
+To: linux1394-devel at lists.sourceforge.net
+Message-ID: <tkrat.f96c4067f6a48f4a at s5r6.in-berlin.de>
+MIME-Version: 1.0
+Content-Disposition: INLINE
+X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254
+X-Scanned-By: MIMEDefang 2.63 on 172.16.48.32
+X-Scanned-By: MIMEDefang_at_IN-Berlin_e.V. on 192.109.42.8
+X-Spam-Report: Spam Filtering performed by sourceforge.net.
+	See http://spamassassin.org/tag/ for more details.
+	Report problems to
+	http://sf.net/tracker/?func=add&group_id=1&atid=200001
+Cc: linux-kernel at vger.kernel.org
+X-BeenThere: linux1394-devel at lists.sourceforge.net
+X-Mailman-Version: 2.1.8
+Precedence: list
+List-Id: Linux IEEE 1394 development list
+	<linux1394-devel.lists.sourceforge.net>
+List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/linux1394-devel>, 
+	<mailto:linux1394-devel-request at lists.sourceforge.net?subject=unsubscribe>
+List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=linux1394-devel>
+List-Post: <mailto:linux1394-devel at lists.sourceforge.net>
+List-Help: <mailto:linux1394-devel-request at lists.sourceforge.net?subject=help>
+List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/linux1394-devel>, 
+	<mailto:linux1394-devel-request at lists.sourceforge.net?subject=subscribe>
+Content-Type: text/plain;
+  charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Sender: linux1394-devel-bounces at lists.sourceforge.net
+Errors-To: linux1394-devel-bounces at lists.sourceforge.net
+X-RedHat-Spam-Score: -0.813 
+X-Length: 10709
+X-UID: 3944
+
+This adds debug printks for asynchronous transmission and reception and
+for self ID reception.  The debug code is per default deactivated by #if
+blocks.
 
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
+Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
 ---
 
- drivers/firewire/fw-sbp2.c |   15 +++++++++++++--
- 1 files changed, 13 insertions(+), 2 deletions(-)
+I am undecided whether this is OK for mainline, and whether the debug
+options should become a Kconfig option or runtime options.
 
-diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
-index d6d62c6..da315cf 100644
---- a/drivers/firewire/fw-sbp2.c
-+++ b/drivers/firewire/fw-sbp2.c
-@@ -170,6 +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_MAX_RECONNECT_ORB_TIMEOUT	6000U	/* Timeout in ms */
- #define SBP2_ORB_TIMEOUT		2000U	/* Timeout in ms */
- #define SBP2_ORB_NULL			0x80000000
- #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
-@@ -538,14 +539,24 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
- 	orb->request.status_fifo.low  =
- 		cpu_to_be32(lu->address_handler.offset);
- 
--	if (function == SBP2_LOGIN_REQUEST) {
-+	switch (function) {
-+
-+	case SBP2_LOGIN_REQUEST:
- 		/* Ask for 2^2 == 4 seconds reconnect grace period */
- 		orb->request.misc |= cpu_to_be32(
- 			MANAGEMENT_ORB_RECONNECT(2) |
- 			MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login));
- 		timeout = lu->tgt->mgt_orb_timeout;
--	} else {
-+		break;
-+
-+	case SBP2_RECONNECT_REQUEST:
-+		timeout = min(SBP2_MAX_RECONNECT_ORB_TIMEOUT,
-+			      lu->tgt->mgt_orb_timeout);
-+		break;
-+
-+	default:
- 		timeout = SBP2_ORB_TIMEOUT;
-+		break;
- 	}
- 
- 	init_completion(&orb->done);
-
-
-
-Per the SBP-2 specification, all SBP-2 target devices must have a BUSY_TIMEOUT
-register. Per the 1394-1995 specification, the retry_limt portion of the
-register should be set to 0x0 initially, and set on the target by a logged in
-initiator (i.e., a Linux host w/firewire controller(s)).
-
-Well, as it turns out, lots of devices these days have actually moved on to
-starting to implement SBP-3 compliance, which says that retry_limit should
-default to 0xf instead (yes, SBP-3 stomps directly on 1394-1995, oops).
-
-Prior to this change, the firewire driver stack didn't touch retry_limit, and
-any SBP-3 compliant device worked fine, while SBP-2 compliant ones were unable
-to retransmit when the host returned an ack_busy_X, which resulted in stalled
-out I/O, eventually causing the SCSI layer to give up and offline the device.
-
-The simple fix is for us to set retry_limit to 0xf in the register for all
-devices (which actually matches what the old ieee1394 stack did).
-
-Prior to this change, a hard disk behind an SBP-2 Prolific PL-3507 bridge chip
-would routinely encounter buffer I/O errors and wind up offlined by the SCSI
-layer. With this change, I've encountered zero I/O failures moving tens of GB
-of data around.
+It may be temporarily useful to the few driver developers.  Do we want
+end users to provide us with debug logs of this kind?  Then it should
+be one or two runtime options.
 
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
-
----
 
-Update: use CSR_BUSY_TIMEOUT from fw-transaction.h instead of needlessly
-        creating an SBP2_BUSY_TIMEOUT
+ drivers/firewire/fw-ohci.c |  113 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 113 insertions(+)
 
- drivers/firewire/fw-sbp2.c |   31 +++++++++++++++++++++++++++----
- 1 files changed, 27 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
-index d6d62c6..fbf5b7a 100644
---- a/drivers/firewire/fw-sbp2.c
-+++ b/drivers/firewire/fw-sbp2.c
-@@ -173,6 +173,7 @@ struct sbp2_target {
- #define SBP2_ORB_TIMEOUT		2000U	/* Timeout in ms */
- #define SBP2_ORB_NULL			0x80000000
- #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
-+#define SBP2_RETRY_LIMIT		0xf	/* 15 retries */
+Index: linux/drivers/firewire/fw-ohci.c
+===================================================================
+--- linux.orig/drivers/firewire/fw-ohci.c
++++ linux/drivers/firewire/fw-ohci.c
+@@ -40,6 +40,9 @@
+ #include "fw-ohci.h"
+ #include "fw-transaction.h"
  
- /* Unit directory keys */
- #define SBP2_CSR_UNIT_CHARACTERISTICS	0x3a
-@@ -800,6 +801,30 @@ static void sbp2_target_put(struct sbp2_target *tgt)
- 	kref_put(&tgt->kref, sbp2_release_target);
++#define FIREWIRE_OHCI_DEBUG_AT_AR	0
++#define FIREWIRE_OHCI_DEBUG_SELFIDS	0
++
+ #define DESCRIPTOR_OUTPUT_MORE		0
+ #define DESCRIPTOR_OUTPUT_LAST		(1 << 12)
+ #define DESCRIPTOR_INPUT_MORE		(2 << 12)
+@@ -316,6 +319,71 @@ static int ar_context_add_page(struct ar
+ 	return 0;
  }
  
-+static void
-+complete_set_busy_timeout(struct fw_card *card, int rcode,
-+			  void *payload, size_t length, void *done)
++#if FIREWIRE_OHCI_DEBUG_AT_AR
++static void debug_ar_at_event(char dir, int speed, u32 *header, int evt)
 +{
-+	complete(done);
++	static const char *evts[] = {
++		[0x00] = "evt_no_status",	[0x01] = "-reserved-",
++		[0x02] = "evt_long_packet",	[0x03] = "evt_missing_ack",
++		[0x04] = "evt_underrun",	[0x05] = "evt_overrun",
++		[0x06] = "evt_descriptor_read",	[0x07] = "evt_data_read",
++		[0x08] = "evt_data_write",	[0x09] = "evt_bus_reset",
++		[0x0a] = "evt_timeout",		[0x0b] = "evt_tcode_err",
++		[0x0c] = "-reserved-",		[0x0d] = "-reserved-",
++		[0x0e] = "evt_unknown",		[0x0f] = "evt_flushed",
++		[0x10] = "-reserved-",		[0x11] = "ack_complete",
++		[0x12] = "ack_pending ",	[0x13] = "-reserved-",
++		[0x14] = "ack_busy_X",		[0x15] = "ack_busy_A",
++		[0x16] = "ack_busy_B",		[0x17] = "-reserved-",
++		[0x18] = "-reserved-",		[0x19] = "-reserved-",
++		[0x1a] = "-reserved-",		[0x1b] = "ack_tardy",
++		[0x1c] = "-reserved-",		[0x1d] = "ack_data_error",
++		[0x1e] = "ack_type_error",	[0x1f] = "-reserved-",
++	};
++	static const char *tcodes[] = {
++		[0x0] = "quadlet write request", [0x1] = "block write request",
++		[0x2] = "write response",	 [0x3] = "-reserved-",
++		[0x4] = "quadlet read request",	 [0x5] = "block read request",
++		[0x6] = "quadlet read response", [0x7] = "block read response",
++		[0x8] = "cycle start",		 [0x9] = "lock request",
++		[0xa] = "async stream packet",	 [0xb] = "lock response",
++		[0xc] = "-reserved-",		 [0xd] = "-reserved-",
++		[0xe] = "link internal",	 [0xf] = "reserved",
++	};
++	static const char *phys[] = {
++		[0x0] = "phy config packet",	 [0x1] = "link-on packet",
++		[0x2] = "self-id packet",	 [0x3] = "-reserved-",
++	};
++	int tcode = header[0] >> 4 & 0xf;
++
++	evt &= 0x1f;
++	if (header[0] == ~header[1])
++		printk(KERN_DEBUG "A%c evt %02x: %s, %s, %08x\n",
++		       dir, evt, evts[evt], phys[header[0] >> 30 & 0x3],
++		       header[0]);
++	else if (tcode == 0xe)
++		printk(KERN_DEBUG "A%c evt %02x: %s, %s\n",
++		       dir, evt, evts[evt], tcodes[tcode]);
++	else if (tcode == 0x0 || tcode == 0x1 ||
++		 tcode == 0x4 || tcode == 0x5 || tcode == 0x9)
++		printk(KERN_DEBUG "A%c evt %02x: tcode %x spd %x tl %02x "
++		       "src %04x dest %04x: "
++		       "%s, %s, %04x%08x\n",
++		       dir, evt, tcode, speed, header[0] >> 10 & 0x3f,
++		       header[1] >> 16, header[0] >> 16,
++		       evts[evt], tcodes[tcode], header[1] & 0xffff, header[2]);
++	else
++		printk(KERN_DEBUG "A%c evt %02x: tcode %x spd %x tl %02x "
++		       "src %04x dest %04x: "
++		       "%s, %s\n",
++		       dir, evt, tcode, speed, header[0] >> 10 & 0x3f,
++		       header[1] >> 16, header[0] >> 16,
++		       evts[evt], tcodes[tcode]);
 +}
++#else
++#define debug_ar_at_event(dir, speed, header, evt)
++#endif /* FIREWIRE_OHCI_DEBUG_AT_AR */
++
+ #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
+ #define cond_le32_to_cpu(v) \
+ 	(ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v))
+@@ -376,6 +444,8 @@ static __le32 *handle_ar_packet(struct a
+ 	p.timestamp  = status & 0xffff;
+ 	p.generation = ohci->request_generation;
+ 
++	debug_ar_at_event('R', p.speed, p.header, status >> 16 & 0x1f);
 +
-+static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
+ 	/*
+ 	 * The OHCI bus reset handler synthesizes a phy packet with
+ 	 * the new generation number when a bus reset happens (see
+@@ -824,6 +894,8 @@ static int handle_at_packet(struct conte
+ 	evt = le16_to_cpu(last->transfer_status) & 0x1f;
+ 	packet->timestamp = le16_to_cpu(last->res_count);
+ 
++	debug_ar_at_event('T', packet->speed, packet->header, evt);
++
+ 	switch (evt) {
+ 	case OHCI1394_evt_timeout:
+ 		/* Async response transmit timed out. */
+@@ -1005,6 +1077,45 @@ at_context_transmit(struct context *ctx,
+ 
+ }
+ 
++#if FIREWIRE_OHCI_DEBUG_SELFIDS
++static char _p(u32 *s, int shift)
 +{
-+	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
-+	DECLARE_COMPLETION_ONSTACK(done);
-+	struct fw_transaction t;
-+	static u32 busy_timeout;
-+
-+	/* FIXME: we should try to set dual-phase cycle_limit too */
-+	busy_timeout = cpu_to_be32(SBP2_RETRY_LIMIT);
-+
-+	fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
-+			lu->tgt->node_id, lu->generation, device->max_speed,
-+			CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout,
-+			sizeof(busy_timeout), complete_set_busy_timeout, &done);
-+	wait_for_completion(&done);
++	static const char port_connected[] = { '.', '-', 'p', 'c', };
++
++	return port_connected[*s >> shift & 3];
 +}
 +
- static void sbp2_reconnect(struct work_struct *work);
- 
- static void sbp2_login(struct work_struct *work)
-@@ -851,10 +876,8 @@ static void sbp2_login(struct work_struct *work)
- 	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. */
--	sbp2_set_busy_timeout(scsi_id);
--#endif
-+	/* set appropriate retry limit(s) in BUSY_TIMEOUT register */
-+	sbp2_set_busy_timeout(lu);
++static void debug_selfid_complete_event(int self_id_count, u32 *s)
++{
++	static const char *speed[] = {
++		[0] = "S100", [1] = "S200", [2] = "S400",    [3] = "beta",
++	};
++	static const char *power[] = {
++		[0] = "+0W",  [1] = "+15W", [2] = "+30W",    [3] = "+45W",
++		[4] = "-3W",  [5] = " ?W",  [6] = "-3..-6W", [7] = "-3..-10W",
++	};
++
++	for (; self_id_count--; ++s)
++		if ((*s & 1 << 23) == 0)
++			printk(KERN_DEBUG "selfID 0: %08x, phy %d [%c%c%c] "
++			       "%s gc=%d %s %s%s%s%s\n",
++			       *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2),
++			       speed[*s >> 14 & 3], *s >> 16 & 63,
++			       power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "",
++			       *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : "",
++			       *s & 1 ? "..." : "");
++		else
++			printk(KERN_DEBUG "selfID n: %08x, phy %d "
++			       "[%c%c%c%c%c%c%c%c]%s\n",
++			       *s, *s >> 24 & 63,
++			       _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10),
++			       _p(s,  8), _p(s,  6), _p(s,  4), _p(s,  2),
++			       *s & 1 ? "..." : "");
++}
++#else
++#define debug_selfid_complete_event(self_id_count, s)
++#endif /* FIREWIRE_OHCI_DEBUG_SELFIDS */
++
+ static void bus_reset_tasklet(unsigned long data)
+ {
+ 	struct fw_ohci *ohci = (struct fw_ohci *)data;
+@@ -1115,6 +1226,8 @@ static void bus_reset_tasklet(unsigned l
+ 		dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
+ 				  free_rom, free_rom_bus);
  
- 	PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
- 	sbp2_agent_reset(lu);
-
----
-
-Try to write dual-phase retry protocol limits to BUSY_TIMEOUT register.
-- The dual-phase retry protocol is optional to implement, and if not 
-  supported, writes to the dual-phase portion of the register will be
-  ignored. We try to write the original 1394-1995 default here.
-- In the case of devices that are also SBP-3-compliant, all writes are 
-  ignored, as the register is read-only, but contains single-phase retry of
-  15, which is what we're trying to set for all SBP-2 device anyway, so this
-  write attempt is safe and yields more consistent behavior for all devices.
-
-See section 8.3.2.3.5 of the 1394-1995 spec, section 6.2 of the SBP-2 spec,
-and section 6.4 of the SBP-3 spec for further details.
++	debug_selfid_complete_event(self_id_count, ohci->self_id_buffer);
++
+ 	fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation,
+ 				 self_id_count, ohci->self_id_buffer);
+ }
 
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
----
+-- 
+Stefan Richter
+-=====-==--- --== -=--=
+http://arcgraph.de/sr/
 
-Update: refresh for updated patch 1/2 using CSR_BUSY_TIMEOUT
 
- drivers/firewire/fw-sbp2.c |   22 +++++++++++++++++++---
- 1 files changed, 19 insertions(+), 3 deletions(-)
+-------------------------------------------------------------------------
+This SF.net email is sponsored by: Microsoft
+Defy all challenges. Microsoft(R) Visual Studio 2008.
+http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
+_______________________________________________
+mailing list linux1394-devel at lists.sourceforge.net
+https://lists.sourceforge.net/lists/listinfo/linux1394-devel
 
-diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
-index fbf5b7a..763f653 100644
---- a/drivers/firewire/fw-sbp2.c
-+++ b/drivers/firewire/fw-sbp2.c
-@@ -173,7 +173,8 @@ struct sbp2_target {
- #define SBP2_ORB_TIMEOUT		2000U	/* Timeout in ms */
- #define SBP2_ORB_NULL			0x80000000
- #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
--#define SBP2_RETRY_LIMIT		0xf	/* 15 retries */
-+#define SBP2_RETRY_LIMIT		0xf		/* 15 retries */
-+#define SBP2_CYCLE_LIMIT		(0xc8 << 12)	/* 200 125us cycles */
- 
- /* Unit directory keys */
- #define SBP2_CSR_UNIT_CHARACTERISTICS	0x3a
-@@ -808,6 +809,22 @@ complete_set_busy_timeout(struct fw_card *card, int rcode,
- 	complete(done);
- }
- 
-+/*
-+ * Write retransmit retry values into the BUSY_TIMEOUT register.
-+ * - The single-phase retry protocol is supported by all SBP-2 devices, but the
-+ *   default retry_limit value is 0 (i.e. never retry transmission). We write a
-+ *   saner value after logging into the device.
-+ * - The dual-phase retry protocol is optional to implement, and if not
-+ *   supported, writes to the dual-phase portion of the register will be
-+ *   ignored. We try to write the original 1394-1995 default here.
-+ * - In the case of devices that are also SBP-3-compliant, all writes are
-+ *   ignored, as the register is read-only, but contains single-phase retry of
-+ *   15, which is what we're trying to set for all SBP-2 device anyway, so this
-+ *   write attempt is safe and yields more consistent behavior for all devices.
-+ *
-+ * See section 8.3.2.3.5 of the 1394-1995 spec, section 6.2 of the SBP-2 spec,
-+ * and section 6.4 of the SBP-3 spec for further details.
-+ */
- static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
- {
- 	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
-@@ -815,8 +832,7 @@ static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
- 	struct fw_transaction t;
- 	static u32 busy_timeout;
- 
--	/* FIXME: we should try to set dual-phase cycle_limit too */
--	busy_timeout = cpu_to_be32(SBP2_RETRY_LIMIT);
-+	busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
- 
- 	fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
- 			lu->tgt->node_id, lu->generation, device->max_speed,

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.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- linux-2.6-firewire-git-update.patch	3 Mar 2008 21:12:45 -0000	1.8
+++ linux-2.6-firewire-git-update.patch	10 Mar 2008 14:09:35 -0000	1.9
@@ -1,21 +1,26 @@
-git diff in linux1394-git tree vs. 2.6.25-rc3-git4, 03/03/2008
-
- 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 ++++++++++++------------------
+ Documentation/debugging-via-ohci1394.txt |   13 +-
+ drivers/firewire/fw-card.c               |   40 +-----
+ drivers/firewire/fw-cdev.c               |   13 ++-
+ drivers/firewire/fw-device.c             |  261 ++++++++++++++++++++++++------
+ drivers/firewire/fw-device.h             |   38 ++++--
+ drivers/firewire/fw-ohci.c               |  114 ++++++++++---
+ drivers/firewire/fw-sbp2.c               |  175 +++++++++++---------
+ drivers/firewire/fw-topology.c           |    3 +
+ drivers/firewire/fw-topology.h           |   11 +-
  drivers/firewire/fw-transaction.c        |    2 +-
- drivers/firewire/fw-transaction.h        |   10 +--
+ drivers/firewire/fw-transaction.h        |   10 +-
  drivers/ieee1394/csr.c                   |    6 +-
  drivers/ieee1394/dv1394.c                |    3 +-
+ drivers/ieee1394/highlevel.c             |    6 +-
+ drivers/ieee1394/ieee1394_core.c         |    2 +-
  drivers/ieee1394/nodemgr.c               |    6 +-
- drivers/ieee1394/ohci1394.c              |  109 ++++++++++++---------------
+ drivers/ieee1394/ohci1394.c              |  111 ++++++-------
+ drivers/ieee1394/pcilynx.c               |   12 +-
  drivers/ieee1394/raw1394.c               |    1 -
- drivers/ieee1394/sbp2.c                  |    7 +-
+ drivers/ieee1394/sbp2.c                  |   11 +-
  drivers/ieee1394/video1394.c             |    3 +-
- lib/Kconfig.debug                        |   10 +++
- 15 files changed, 233 insertions(+), 236 deletions(-)
+ lib/Kconfig.debug                        |   10 ++
+ 22 files changed, 538 insertions(+), 313 deletions(-)
 
 diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
 index c360d4e..371ba27 100644
@@ -42,9 +47,18 @@
  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
 diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
-index a034627..140b34d 100644
+index a034627..7e4012d 100644
 --- a/drivers/firewire/fw-card.c
 +++ b/drivers/firewire/fw-card.c
+@@ -331,7 +331,7 @@ fw_card_bm_work(struct work_struct *work)
+ 		 */
+ 		spin_unlock_irqrestore(&card->lock, flags);
+ 		goto out;
+-	} else if (root_device->config_rom[2] & BIB_CMC) {
++	} else if (root_device->cmc) {
+ 		/*
+ 		 * FIXME: I suppose we should set the cmstr bit in the
+ 		 * STATE_CLEAR register of this node, as described in
 @@ -398,7 +398,6 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
  {
  	static atomic_t index = ATOMIC_INIT(-1);
@@ -107,11 +121,560 @@
  int
  fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
  {
+diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
+index 46bc197..4a54192 100644
+--- a/drivers/firewire/fw-cdev.c
++++ b/drivers/firewire/fw-cdev.c
+@@ -269,21 +269,28 @@ static int ioctl_get_info(struct client *client, void *buffer)
+ {
+ 	struct fw_cdev_get_info *get_info = buffer;
+ 	struct fw_cdev_event_bus_reset bus_reset;
++	unsigned long ret = 0;
+ 
+ 	client->version = get_info->version;
+ 	get_info->version = FW_CDEV_VERSION;
+ 
++	down_read(&fw_device_rwsem);
++
+ 	if (get_info->rom != 0) {
+ 		void __user *uptr = u64_to_uptr(get_info->rom);
+ 		size_t want = get_info->rom_length;
+ 		size_t have = client->device->config_rom_length * 4;
+ 
+-		if (copy_to_user(uptr, client->device->config_rom,
+-				 min(want, have)))
+-			return -EFAULT;
++		ret = copy_to_user(uptr, client->device->config_rom,
++				   min(want, have));
+ 	}
+ 	get_info->rom_length = client->device->config_rom_length * 4;
+ 
++	up_read(&fw_device_rwsem);
++
++	if (ret != 0)
++		return -EFAULT;
++
+ 	client->bus_reset_closure = get_info->bus_reset_closure;
+ 	if (get_info->bus_reset != 0) {
+ 		void __user *uptr = u64_to_uptr(get_info->bus_reset);
+diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
+index 870125a..19f2fc4 100644
+--- a/drivers/firewire/fw-device.c
++++ b/drivers/firewire/fw-device.c
+@@ -25,7 +25,7 @@
+ #include <linux/device.h>
+ #include <linux/delay.h>
+ #include <linux/idr.h>
+-#include <linux/rwsem.h>
++#include <linux/string.h>
+ #include <asm/semaphore.h>
+ #include <asm/system.h>
+ #include <linux/ctype.h>
+@@ -160,9 +160,9 @@ static void fw_device_release(struct device *dev)
+ 	 * Take the card lock so we don't set this to NULL while a
+ 	 * FW_NODE_UPDATED callback is being handled.
+ 	 */
+-	spin_lock_irqsave(&device->card->lock, flags);
++	spin_lock_irqsave(&card->lock, flags);
+ 	device->node->data = NULL;
+-	spin_unlock_irqrestore(&device->card->lock, flags);
++	spin_unlock_irqrestore(&card->lock, flags);
+ 
+ 	fw_node_put(device->node);
+ 	kfree(device->config_rom);
+@@ -195,7 +195,9 @@ show_immediate(struct device *dev, struct device_attribute *dattr, char *buf)
+ 		container_of(dattr, struct config_rom_attribute, attr);
+ 	struct fw_csr_iterator ci;
+ 	u32 *dir;
+-	int key, value;
++	int key, value, ret = -ENOENT;
++
++	down_read(&fw_device_rwsem);
+ 
+ 	if (is_fw_unit(dev))
+ 		dir = fw_unit(dev)->directory;
+@@ -204,11 +206,15 @@ show_immediate(struct device *dev, struct device_attribute *dattr, char *buf)
+ 
+ 	fw_csr_iterator_init(&ci, dir);
+ 	while (fw_csr_iterator_next(&ci, &key, &value))
+-		if (attr->key == key)
+-			return snprintf(buf, buf ? PAGE_SIZE : 0,
+-					"0x%06x\n", value);
++		if (attr->key == key) {
++			ret = snprintf(buf, buf ? PAGE_SIZE : 0,
++				       "0x%06x\n", value);
++			break;
++		}
++
++	up_read(&fw_device_rwsem);
+ 
+-	return -ENOENT;
++	return ret;
+ }
+ 
+ #define IMMEDIATE_ATTR(name, key)				\
+@@ -221,9 +227,11 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
+ 		container_of(dattr, struct config_rom_attribute, attr);
+ 	struct fw_csr_iterator ci;
+ 	u32 *dir, *block = NULL, *p, *end;
+-	int length, key, value, last_key = 0;
++	int length, key, value, last_key = 0, ret = -ENOENT;
+ 	char *b;
+ 
++	down_read(&fw_device_rwsem);
++
+ 	if (is_fw_unit(dev))
+ 		dir = fw_unit(dev)->directory;
+ 	else
+@@ -238,18 +246,20 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
+ 	}
+ 
+ 	if (block == NULL)
+-		return -ENOENT;
++		goto out;
+ 
+ 	length = min(block[0] >> 16, 256U);
+ 	if (length < 3)
+-		return -ENOENT;
++		goto out;
+ 
+ 	if (block[1] != 0 || block[2] != 0)
+ 		/* Unknown encoding. */
+-		return -ENOENT;
++		goto out;
+ 
+-	if (buf == NULL)
+-		return length * 4;
++	if (buf == NULL) {
++		ret = length * 4;
++		goto out;
++	}
+ 
+ 	b = buf;
+ 	end = &block[length + 1];
+@@ -259,8 +269,11 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
+ 	/* Strip trailing whitespace and add newline. */
+ 	while (b--, (isspace(*b) || *b == '\0') && b > buf);
+ 	strcpy(b + 1, "\n");
++	ret = b + 2 - buf;
++ out:
++	up_read(&fw_device_rwsem);
+ 
+-	return b + 2 - buf;
++	return ret;
+ }
+ 
+ #define TEXT_LEAF_ATTR(name, key)				\
+@@ -337,19 +350,28 @@ static ssize_t
+ config_rom_show(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+ 	struct fw_device *device = fw_device(dev);
++	size_t length;
+ 
+-	memcpy(buf, device->config_rom, device->config_rom_length * 4);
++	down_read(&fw_device_rwsem);
++	length = device->config_rom_length * 4;
++	memcpy(buf, device->config_rom, length);
++	up_read(&fw_device_rwsem);
+ 
+-	return device->config_rom_length * 4;
++	return length;
+ }
+ 
+ static ssize_t
+ guid_show(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+ 	struct fw_device *device = fw_device(dev);
++	int ret;
++
++	down_read(&fw_device_rwsem);
++	ret = snprintf(buf, PAGE_SIZE, "0x%08x%08x\n",
++		       device->config_rom[3], device->config_rom[4]);
++	up_read(&fw_device_rwsem);
+ 
+-	return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n",
+-			device->config_rom[3], device->config_rom[4]);
++	return ret;
+ }
+ 
+ static struct device_attribute fw_device_attributes[] = {
+@@ -400,6 +422,9 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data)
+ 	return callback_data.rcode;
+ }
+ 
++#define READ_BIB_ROM_SIZE	256
++#define READ_BIB_STACK_SIZE	16
++
+ /*
+  * Read the bus info block, perform a speed probe, and read all of the rest of
+  * the config ROM.  We do all this with a cached bus generation.  If the bus
+@@ -409,16 +434,23 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data)
+  */
+ static int read_bus_info_block(struct fw_device *device, int generation)
+ {
+-	static u32 rom[256];
+-	u32 stack[16], sp, key;
+-	int i, end, length;
++	u32 *rom, *stack, *old_rom, *new_rom;
++	u32 sp, key;
++	int i, end, length, ret = -1;
++
++	rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE +
++		      sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL);
++	if (rom == NULL)
++		return -ENOMEM;
++
++	stack = &rom[READ_BIB_ROM_SIZE];
+ 
+ 	device->max_speed = SCODE_100;
+ 
+ 	/* First read the bus info block. */
+ 	for (i = 0; i < 5; i++) {
+ 		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
+-			return -1;
++			goto out;
+ 		/*
+ 		 * As per IEEE1212 7.2, during power-up, devices can
+ 		 * reply with a 0 for the first quadlet of the config
+@@ -428,7 +460,7 @@ static int read_bus_info_block(struct fw_device *device, int generation)
+ 		 * retry mechanism will try again later.
+ 		 */
+ 		if (i == 0 && rom[i] == 0)
+-			return -1;
++			goto out;
+ 	}
+ 
+ 	device->max_speed = device->node->max_speed;
+@@ -478,26 +510,26 @@ static int read_bus_info_block(struct fw_device *device, int generation)
+ 		 */
+ 		key = stack[--sp];
+ 		i = key & 0xffffff;
+-		if (i >= ARRAY_SIZE(rom))
++		if (i >= READ_BIB_ROM_SIZE)
+ 			/*
+ 			 * The reference points outside the standard
+ 			 * config rom area, something's fishy.
+ 			 */
+-			return -1;
++			goto out;
+ 
+ 		/* Read header quadlet for the block to get the length. */
+ 		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
+-			return -1;
++			goto out;
+ 		end = i + (rom[i] >> 16) + 1;
+ 		i++;
+-		if (end > ARRAY_SIZE(rom))
++		if (end > READ_BIB_ROM_SIZE)
+ 			/*
+ 			 * This block extends outside standard config
+ 			 * area (and the array we're reading it
+ 			 * into).  That's broken, so ignore this
+ 			 * device.
+ 			 */
+-			return -1;
++			goto out;
+ 
+ 		/*
+ 		 * Now read in the block.  If this is a directory
+@@ -507,9 +539,9 @@ static int read_bus_info_block(struct fw_device *device, int generation)
+ 		while (i < end) {
+ 			if (read_rom(device, generation, i, &rom[i]) !=
+ 			    RCODE_COMPLETE)
+-				return -1;
++				goto out;
+ 			if ((key >> 30) == 3 && (rom[i] >> 30) > 1 &&
+-			    sp < ARRAY_SIZE(stack))
++			    sp < READ_BIB_STACK_SIZE)
+ 				stack[sp++] = i + rom[i];
+ 			i++;
+ 		}
+@@ -517,13 +549,23 @@ static int read_bus_info_block(struct fw_device *device, int generation)
+ 			length = i;
+ 	}
+ 
+-	device->config_rom = kmalloc(length * 4, GFP_KERNEL);
+-	if (device->config_rom == NULL)
+-		return -1;
+-	memcpy(device->config_rom, rom, length * 4);
++	old_rom = device->config_rom;
++	new_rom = kmemdup(rom, length * 4, GFP_KERNEL);
++	if (new_rom == NULL)
++		goto out;
++
++	down_write(&fw_device_rwsem);
++	device->config_rom = new_rom;
+ 	device->config_rom_length = length;
++	up_write(&fw_device_rwsem);
+ 
+-	return 0;
++	kfree(old_rom);
++	ret = 0;
++	device->cmc = rom[2] & 1 << 30;
++ out:
++	kfree(rom);
++
++	return ret;
+ }
+ 
+ static void fw_unit_release(struct device *dev)
+@@ -592,7 +634,14 @@ static int shutdown_unit(struct device *device, void *data)
+ 	return 0;
+ }
+ 
+-static DECLARE_RWSEM(idr_rwsem);
++/*
++ * fw_device_rwsem acts as dual purpose mutex:
++ *   - serializes accesses to fw_device_idr,
++ *   - serializes accesses to fw_device.config_rom/.config_rom_length and
++ *     fw_unit.directory, unless those accesses happen at safe occasions
++ */
++DECLARE_RWSEM(fw_device_rwsem);
++
+ static DEFINE_IDR(fw_device_idr);
+ int fw_cdev_major;
+ 
+@@ -600,11 +649,11 @@ struct fw_device *fw_device_get_by_devt(dev_t devt)
+ {
+ 	struct fw_device *device;
+ 
+-	down_read(&idr_rwsem);
++	down_read(&fw_device_rwsem);
+ 	device = idr_find(&fw_device_idr, MINOR(devt));
+ 	if (device)
+ 		fw_device_get(device);
+-	up_read(&idr_rwsem);
++	up_read(&fw_device_rwsem);
+ 
+ 	return device;
+ }
+@@ -619,9 +668,9 @@ static void fw_device_shutdown(struct work_struct *work)
+ 	device_for_each_child(&device->device, NULL, shutdown_unit);
+ 	device_unregister(&device->device);
+ 
+-	down_write(&idr_rwsem);
++	down_write(&fw_device_rwsem);
+ 	idr_remove(&fw_device_idr, minor);
+-	up_write(&idr_rwsem);
++	up_write(&fw_device_rwsem);
+ 	fw_device_put(device);
+ }
+ 
+@@ -674,10 +723,10 @@ static void fw_device_init(struct work_struct *work)
+ 	err = -ENOMEM;
+ 
+ 	fw_device_get(device);
+-	down_write(&idr_rwsem);
++	down_write(&fw_device_rwsem);
+ 	if (idr_pre_get(&fw_device_idr, GFP_KERNEL))
+ 		err = idr_get_new(&fw_device_idr, device, &minor);
+-	up_write(&idr_rwsem);
++	up_write(&fw_device_rwsem);
+ 
+ 	if (err < 0)
+ 		goto error;
+@@ -711,7 +760,7 @@ static void fw_device_init(struct work_struct *work)
+ 	if (atomic_cmpxchg(&device->state,
+ 		    FW_DEVICE_INITIALIZING,
+ 		    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
+-		fw_device_shutdown(&device->work.work);
++		fw_device_shutdown(work);
+ 	} else {
+ 		if (device->config_rom_retries)
+ 			fw_notify("created device %s: GUID %08x%08x, S%d00, "
+@@ -725,6 +774,7 @@ static void fw_device_init(struct work_struct *work)
+ 				  device->device.bus_id,
+ 				  device->config_rom[3], device->config_rom[4],
+ 				  1 << device->max_speed);
++		device->config_rom_retries = 0;
+ 	}
+ 
+ 	/*
+@@ -739,9 +789,9 @@ static void fw_device_init(struct work_struct *work)
+ 	return;
+ 
+  error_with_cdev:
+-	down_write(&idr_rwsem);
++	down_write(&fw_device_rwsem);
+ 	idr_remove(&fw_device_idr, minor);
+-	up_write(&idr_rwsem);
++	up_write(&fw_device_rwsem);
+  error:
+ 	fw_device_put(device);		/* fw_device_idr's reference */
+ 
+@@ -771,6 +821,107 @@ static void fw_device_update(struct work_struct *work)
+ 	device_for_each_child(&device->device, NULL, update_unit);
+ }
+ 
++enum {
++	REREAD_BIB_ERROR,
++	REREAD_BIB_GONE,
++	REREAD_BIB_UNCHANGED,
++	REREAD_BIB_CHANGED,
++};
++
++/* Reread and compare bus info block and header of root directory */
++static int reread_bus_info_block(struct fw_device *device, int generation)
++{
++	u32 q;
++	int i;
++
++	for (i = 0; i < 6; i++) {
++		if (read_rom(device, generation, i, &q) != RCODE_COMPLETE)
++			return REREAD_BIB_ERROR;
++
++		if (i == 0 && q == 0)
++			return REREAD_BIB_GONE;
++
++		if (i > device->config_rom_length || q != device->config_rom[i])
++			return REREAD_BIB_CHANGED;
++	}
++
++	return REREAD_BIB_UNCHANGED;
++}
++
++static void fw_device_refresh(struct work_struct *work)
++{
++	struct fw_device *device =
++		container_of(work, struct fw_device, work.work);
++	struct fw_card *card = device->card;
++	int node_id = device->node_id;
++
++	switch (reread_bus_info_block(device, device->generation)) {
++	case REREAD_BIB_ERROR:
++		if (device->config_rom_retries < MAX_RETRIES / 2 &&
++		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
++			device->config_rom_retries++;
++			schedule_delayed_work(&device->work, RETRY_DELAY / 2);
++
++			return;
++		}
++		goto give_up;
++
++	case REREAD_BIB_GONE:
++		goto gone;
++
++	case REREAD_BIB_UNCHANGED:
++		if (atomic_cmpxchg(&device->state,
++			    FW_DEVICE_INITIALIZING,
++			    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
++			goto gone;
++
++		fw_device_update(work);
++		device->config_rom_retries = 0;
++
++		return;
++
++	case REREAD_BIB_CHANGED:
++		break;
++	}
++
++	/*
++	 * Something changed.  We keep things simple and don't investigate
++	 * further.  We just destroy all previous units and create new ones.
++	 */
++	device_for_each_child(&device->device, NULL, shutdown_unit);
++
++	if (read_bus_info_block(device, device->generation) < 0) {
++		if (device->config_rom_retries < MAX_RETRIES &&
++		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
++			device->config_rom_retries++;
++			schedule_delayed_work(&device->work, RETRY_DELAY);
++
++			return;
++		}
++		goto give_up;
++	}
++
++	create_units(device);
++
++	if (atomic_cmpxchg(&device->state,
++		    FW_DEVICE_INITIALIZING,
++		    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
++		goto gone;
++
++	fw_notify("refreshed device %s\n", device->device.bus_id);
++	device->config_rom_retries = 0;
++	goto out;
++
++ give_up:
++	fw_notify("giving up on refresh of device %s\n", device->device.bus_id);
++ gone:
++	atomic_set(&device->state, FW_DEVICE_SHUTDOWN);
++	fw_device_shutdown(work);
++ out:
++	if (node_id == card->root_node->node_id)
++		schedule_delayed_work(&card->work, 0);
++}
++
+ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
+ {
+ 	struct fw_device *device;
+@@ -780,7 +931,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
+ 	case FW_NODE_LINK_ON:
+ 		if (!node->link_on)
+ 			break;
+-
++ create:
+ 		device = kzalloc(sizeof(*device), GFP_ATOMIC);
+ 		if (device == NULL)
+ 			break;
+@@ -819,6 +970,22 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
+ 		schedule_delayed_work(&device->work, INITIAL_DELAY);
+ 		break;
+ 
++	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;
 diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
-index 78ecd39..0d771fd 100644
+index 78ecd39..5f131f5 100644
 --- a/drivers/firewire/fw-device.h
 +++ b/drivers/firewire/fw-device.h
-@@ -64,28 +64,24 @@ struct fw_device {
+@@ -21,6 +21,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/cdev.h>
++#include <linux/rwsem.h>
+ #include <asm/atomic.h>
+ 
+ enum fw_device_state {
+@@ -46,6 +47,11 @@ struct fw_attribute_group {
+  * fw_device.node_id is guaranteed to be current too.
+  *
+  * The same applies to fw_device.card->node_id vs. fw_device.generation.
++ *
++ * fw_device.config_rom and fw_device.config_rom_length may be accessed during
++ * the lifetime of any fw_unit belonging to the fw_device, before device_del()
++ * was called on the last fw_unit.  Alternatively, they may be accessed while
++ * holding fw_device_rwsem.
+  */
+ struct fw_device {
+ 	atomic_t state;
+@@ -53,6 +59,7 @@ struct fw_device {
+ 	int node_id;
+ 	int generation;
+ 	unsigned max_speed;
++	bool cmc;
+ 	struct fw_card *card;
+ 	struct device device;
+ 	struct list_head link;
+@@ -64,28 +71,24 @@ struct fw_device {
  	struct fw_attribute_group attribute_group;
  };
  
@@ -144,7 +707,19 @@
  {
  	put_device(&device->device);
  }
-@@ -104,12 +100,23 @@ struct fw_unit {
+@@ -96,20 +99,35 @@ int fw_device_enable_phys_dma(struct fw_device *device);
+ void fw_device_cdev_update(struct fw_device *device);
+ void fw_device_cdev_remove(struct fw_device *device);
+ 
++extern struct rw_semaphore fw_device_rwsem;
+ extern int fw_cdev_major;
+ 
++/*
++ * fw_unit.directory must not be accessed after device_del(&fw_unit.device).
++ */
+ struct fw_unit {
+ 	struct device device;
+ 	u32 *directory;
  	struct fw_attribute_group attribute_group;
  };
  
@@ -468,20 +1043,30 @@
  		fw_error("pci_enable_device failed\n");
  		return err;
 diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
-index 03069a4..d6d62c6 100644
+index 03069a4..366981b 100644
 --- a/drivers/firewire/fw-sbp2.c
 +++ b/drivers/firewire/fw-sbp2.c
-@@ -174,9 +174,6 @@ struct sbp2_target {
+@@ -153,6 +153,7 @@ struct sbp2_target {
+ 	struct list_head lu_list;
+ 
+ 	u64 management_agent_address;
++	u64 guid;
+ 	int directory_id;
+ 	int node_id;
+ 	int address_high;
+@@ -173,9 +174,8 @@ struct sbp2_target {
+ #define SBP2_ORB_TIMEOUT		2000U	/* Timeout in ms */
  #define SBP2_ORB_NULL			0x80000000
  #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
- 
+-
 -#define SBP2_DIRECTION_TO_MEDIA		0x0
 -#define SBP2_DIRECTION_FROM_MEDIA	0x1
--
++#define SBP2_RETRY_LIMIT		0xf		/* 15 retries */
++#define SBP2_CYCLE_LIMIT		(0xc8 << 12)	/* 200 125us cycles */
+ 
  /* Unit directory keys */
  #define SBP2_CSR_UNIT_CHARACTERISTICS	0x3a
- #define SBP2_CSR_FIRMWARE_REVISION	0x3c
-@@ -223,8 +220,8 @@ struct sbp2_status {
+@@ -223,8 +223,8 @@ struct sbp2_status {
  };
  
  struct sbp2_pointer {
@@ -492,7 +1077,7 @@
  };
  
  struct sbp2_orb {
-@@ -252,8 +249,8 @@ struct sbp2_management_orb {
+@@ -252,8 +252,8 @@ struct sbp2_management_orb {
  	struct {
  		struct sbp2_pointer password;
  		struct sbp2_pointer response;
@@ -503,7 +1088,7 @@
  		struct sbp2_pointer status_fifo;
  	} request;
  	__be32 response[4];
-@@ -262,20 +259,17 @@ struct sbp2_management_orb {
+@@ -262,20 +262,17 @@ struct sbp2_management_orb {
  	struct sbp2_status status;
  };
  
@@ -527,7 +1112,7 @@
  #define COMMAND_ORB_REQUEST_FORMAT(v)	((v) << 29)
  #define COMMAND_ORB_NOTIFY		((1) << 31)
  
-@@ -284,7 +278,7 @@ struct sbp2_command_orb {
+@@ -284,7 +281,7 @@ struct sbp2_command_orb {
  	struct {
  		struct sbp2_pointer next;
  		struct sbp2_pointer data_descriptor;
@@ -536,7 +1121,7 @@
  		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,
+@@ -453,8 +450,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
  	unsigned long flags;
  
  	orb->pointer.high = 0;
@@ -546,7 +1131,7 @@
  
  	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,
+@@ -530,31 +526,31 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
  	if (dma_mapping_error(orb->response_bus))
  		goto fail_mapping_response;
  
@@ -590,7 +1175,7 @@
  	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,
+@@ -599,8 +595,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
  			 sizeof(orb->response), DMA_FROM_DEVICE);
   fail_mapping_response:
  	if (response)
@@ -600,7 +1185,7 @@
  	kref_put(&orb->base.kref, free_orb);
  
  	return retval;
-@@ -695,10 +687,8 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
+@@ -695,10 +690,8 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
  	if (!tgt->dont_block && !lu->blocked &&
  	    lu->generation != card->generation) {
  		lu->blocked = true;
@@ -612,7 +1197,7 @@
  	}
  	spin_unlock_irqrestore(&card->lock, flags);
  }
-@@ -725,10 +715,8 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
+@@ -725,10 +718,8 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
  	}
  	spin_unlock_irqrestore(&card->lock, flags);
  
@@ -624,7 +1209,7 @@
  }
  
  /*
-@@ -790,7 +778,7 @@ static void sbp2_release_target(struct kref *kref)
+@@ -790,7 +781,7 @@ static void sbp2_release_target(struct kref *kref)
  	scsi_remove_host(shost);
  	fw_notify("released %s\n", tgt->bus_id);
  
@@ -633,7 +1218,53 @@
  	scsi_host_put(shost);
  	fw_device_put(device);
  }
-@@ -855,11 +843,10 @@ static void sbp2_login(struct work_struct *work)
+@@ -812,6 +803,45 @@ static void sbp2_target_put(struct sbp2_target *tgt)
+ 	kref_put(&tgt->kref, sbp2_release_target);
+ }
+ 
++static void
++complete_set_busy_timeout(struct fw_card *card, int rcode,
++			  void *payload, size_t length, void *done)
++{
++	complete(done);
++}
++
++/*
++ * Write retransmit retry values into the BUSY_TIMEOUT register.
++ * - The single-phase retry protocol is supported by all SBP-2 devices, but the
++ *   default retry_limit value is 0 (i.e. never retry transmission). We write a
++ *   saner value after logging into the device.
++ * - The dual-phase retry protocol is optional to implement, and if not
++ *   supported, writes to the dual-phase portion of the register will be
++ *   ignored. We try to write the original 1394-1995 default here.
++ * - In the case of devices that are also SBP-3-compliant, all writes are
++ *   ignored, as the register is read-only, but contains single-phase retry of
++ *   15, which is what we're trying to set for all SBP-2 device anyway, so this
++ *   write attempt is safe and yields more consistent behavior for all devices.
++ *
++ * See section 8.3.2.3.5 of the 1394-1995 spec, section 6.2 of the SBP-2 spec,
++ * and section 6.4 of the SBP-3 spec for further details.
++ */
++static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
++{
++	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
++	DECLARE_COMPLETION_ONSTACK(done);
++	struct fw_transaction t;
++	static u32 busy_timeout;
++
++	busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
++
++	fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
++			lu->tgt->node_id, lu->generation, device->max_speed,
++			CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout,
++			sizeof(busy_timeout), complete_set_busy_timeout, &done);
++	wait_for_completion(&done);
++}
++
+ static void sbp2_reconnect(struct work_struct *work);
+ 
+ static void sbp2_login(struct work_struct *work)
+@@ -855,19 +885,16 @@ static void sbp2_login(struct work_struct *work)
  	tgt->address_high = local_node_id << 16;
  	sbp2_set_generation(lu, generation);
  
@@ -648,7 +1279,25 @@
  
  	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)
+ 
+-#if 0
+-	/* FIXME: The linux1394 sbp2 does this last step. */
+-	sbp2_set_busy_timeout(scsi_id);
+-#endif
++	/* set appropriate retry limit(s) in BUSY_TIMEOUT register */
++	sbp2_set_busy_timeout(lu);
+ 
+ 	PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
+ 	sbp2_agent_reset(lu);
+@@ -1083,6 +1110,7 @@ static int sbp2_probe(struct device *dev)
+ 	kref_init(&tgt->kref);
+ 	INIT_LIST_HEAD(&tgt->lu_list);
+ 	tgt->bus_id = unit->device.bus_id;
++	tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4];
+ 
+ 	if (fw_device_enable_phys_dma(device) < 0)
+ 		goto fail_shost_put;
+@@ -1091,6 +1119,7 @@ static int sbp2_probe(struct device *dev)
  		goto fail_shost_put;
  
  	fw_device_get(device);
@@ -656,7 +1305,7 @@
  
  	/* 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)
+@@ -1106,8 +1135,6 @@ static int sbp2_probe(struct device *dev)
  
  	sbp2_init_workarounds(tgt, model, firmware_revision);
  
@@ -665,7 +1314,7 @@
  	/* 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,
+@@ -1339,9 +1366,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) {
@@ -681,7 +1330,7 @@
  		return 0;
  	}
  
-@@ -1362,16 +1351,14 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+@@ -1362,16 +1392,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);
@@ -700,7 +1349,7 @@
  	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,
+@@ -1385,11 +1413,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.
  	 */
@@ -716,7 +1365,7 @@
  
  	return 0;
  
-@@ -1435,8 +1421,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+@@ -1435,8 +1462,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
  	orb->done = done;
  	orb->cmd  = cmd;
  
@@ -726,7 +1375,7 @@
  	/*
  	 * 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)
+@@ -1445,25 +1471,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);
@@ -755,7 +1404,7 @@
  	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)
+@@ -1491,11 +1509,8 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
  
  	sdev->allow_restart = 1;
  
@@ -769,6 +1418,68 @@
  
  	if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36)
  		sdev->inquiry_len = 36;
+@@ -1553,16 +1568,14 @@ sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
+ {
+ 	struct scsi_device *sdev = to_scsi_device(dev);
+ 	struct sbp2_logical_unit *lu;
+-	struct fw_device *device;
+ 
+ 	if (!sdev)
+ 		return 0;
+ 
+ 	lu = sdev->hostdata;
+-	device = fw_device(lu->tgt->unit->device.parent);
+ 
+-	return sprintf(buf, "%08x%08x:%06x:%04x\n",
+-			device->config_rom[3], device->config_rom[4],
++	return sprintf(buf, "%016llx:%06x:%04x\n",
++			(unsigned long long)lu->tgt->guid,
+ 			lu->tgt->directory_id, lu->lun);
+ }
+ 
+diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
+index e47bb04..25e8725 100644
+--- a/drivers/firewire/fw-topology.c
++++ b/drivers/firewire/fw-topology.c
+@@ -107,6 +107,7 @@ static struct fw_node *fw_node_create(u32 sid, int port_count, int color)
+ 	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 fw_node *root)
+ 			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;
+ 
+diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h
+index cedc1ec..addb9f8 100644
+--- a/drivers/firewire/fw-topology.h
++++ b/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,
+ };
+ 
+ struct fw_node {
 diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
 index 7fcc59d..99529e5 100644
 --- a/drivers/firewire/fw-transaction.c
@@ -858,6 +1569,50 @@
  };
  
  
+diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c
+index b642546..fa2bfec 100644
+--- a/drivers/ieee1394/highlevel.c
++++ b/drivers/ieee1394/highlevel.c
+@@ -339,7 +339,7 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
+ 	if ((alignment & 3) || (alignment > 0x800000000000ULL) ||
+ 	    (hweight64(alignment) != 1)) {
+ 		HPSB_ERR("%s called with invalid alignment: 0x%048llx",
+-			 __FUNCTION__, (unsigned long long)alignment);
++			 __func__, (unsigned long long)alignment);
+ 		return retval;
+ 	}
+ 
+@@ -354,7 +354,7 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
+ 	if (((start|end) & ~align_mask) || (start >= end) ||
+ 	    (end > CSR1212_ALL_SPACE_END)) {
+ 		HPSB_ERR("%s called with invalid addresses "
+-			 "(start = %012Lx  end = %012Lx)", __FUNCTION__,
++			 "(start = %012Lx  end = %012Lx)", __func__,
+ 			 (unsigned long long)start,(unsigned long long)end);
+ 		return retval;
+ 	}
+@@ -422,7 +422,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
+ 
+ 	if (((start|end) & 3) || (start >= end) ||
+ 	    (end > CSR1212_ALL_SPACE_END)) {
+-		HPSB_ERR("%s called with invalid addresses", __FUNCTION__);
++		HPSB_ERR("%s called with invalid addresses", __func__);
+ 		return 0;
+ 	}
+ 
+diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
+index 36c747b..942bf1f 100644
+--- a/drivers/ieee1394/ieee1394_core.c
++++ b/drivers/ieee1394/ieee1394_core.c
+@@ -242,7 +242,7 @@ int hpsb_bus_reset(struct hpsb_host *host)
+ {
+ 	if (host->in_bus_reset) {
+ 		HPSB_NOTICE("%s called while bus reset already in progress",
+-			    __FUNCTION__);
++			    __func__);
+ 		return 1;
+ 	}
+ 
 diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
 index 511e432..70afa37 100644
 --- a/drivers/ieee1394/nodemgr.c
@@ -876,9 +1631,18 @@
  		    id->vendor_id != ud->vendor_id)
  			continue;
 diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
-index 969de2a..29b8910 100644
+index 969de2a..0808bae 100644
 --- a/drivers/ieee1394/ohci1394.c
 +++ b/drivers/ieee1394/ohci1394.c
+@@ -708,7 +708,7 @@ static void insert_packet(struct ti_ohci *ohci,
+                                 /* FIXME: do something about it */
+                                 PRINT(KERN_ERR,
+                                       "%s: packet data addr: %p size %Zd bytes "
+-                                      "cross page boundary", __FUNCTION__,
++				      "cross page boundary", __func__,
+                                       packet->data, packet->data_size);
+                         }
+ #endif
 @@ -2993,15 +2993,9 @@ do {						\
  	return err;				\
  } while (0)
@@ -1080,6 +1844,62 @@
  	if (err) {
  		PRINT(KERN_ERR, "pci_enable_device failed with %d", err);
  		return err;
+diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
+index 8af01ab..9c35e0d 100644
+--- a/drivers/ieee1394/pcilynx.c
++++ b/drivers/ieee1394/pcilynx.c
+@@ -226,7 +226,7 @@ static int get_phy_reg(struct ti_lynx *lynx, int addr)
+         if (addr > 15) {
+                 PRINT(KERN_ERR, lynx->id,
+                       "%s: PHY register address %d out of range",
+-		      __FUNCTION__, addr);
++		      __func__, addr);
+                 return -1;
+         }
+ 
+@@ -238,7 +238,7 @@ static int get_phy_reg(struct ti_lynx *lynx, int addr)
+ 
+                 if (i > 10000) {
+                         PRINT(KERN_ERR, lynx->id, "%s: runaway loop, aborting",
+-			      __FUNCTION__);
++			      __func__);
+                         retval = -1;
+                         break;
+                 }
+@@ -261,13 +261,13 @@ static int set_phy_reg(struct ti_lynx *lynx, int addr, int val)
+ 
+         if (addr > 15) {
+                 PRINT(KERN_ERR, lynx->id,
+-                      "%s: PHY register address %d out of range", __FUNCTION__, addr);
++		      "%s: PHY register address %d out of range", __func__, addr);
+                 return -1;
+         }
+ 
+         if (val > 0xff) {
+                 PRINT(KERN_ERR, lynx->id,
+-                      "%s: PHY register value %d out of range", __FUNCTION__, val);
++		      "%s: PHY register value %d out of range", __func__, val);
+                 return -1;
+         }
+ 
+@@ -287,7 +287,7 @@ static int sel_phy_reg_page(struct ti_lynx *lynx, int page)
+ 
+         if (page > 7) {
+                 PRINT(KERN_ERR, lynx->id,
+-                      "%s: PHY page %d out of range", __FUNCTION__, page);
++		      "%s: PHY page %d out of range", __func__, page);
+                 return -1;
+         }
+ 
+@@ -309,7 +309,7 @@ static int sel_phy_reg_port(struct ti_lynx *lynx, int port)
+ 
+         if (port > 15) {
+                 PRINT(KERN_ERR, lynx->id,
+-                      "%s: PHY port %d out of range", __FUNCTION__, port);
++		      "%s: PHY port %d out of range", __func__, port);
+                 return -1;
+         }
+ 
 diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
 index 37e7e10..3634785 100644
 --- a/drivers/ieee1394/raw1394.c
@@ -1093,9 +1913,27 @@
  
  /******************************************************************************/
 diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
-index 9e2b196..29e6663 100644
+index 9e2b196..d5b9281 100644
 --- a/drivers/ieee1394/sbp2.c
 +++ b/drivers/ieee1394/sbp2.c
+@@ -610,7 +610,7 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
+ 		cmd->Current_SCpnt = Current_SCpnt;
+ 		list_add_tail(&cmd->list, &lu->cmd_orb_inuse);
+ 	} else
+-		SBP2_ERR("%s: no orbs available", __FUNCTION__);
++		SBP2_ERR("%s: no orbs available", __func__);
+ 	spin_unlock_irqrestore(&lu->cmd_orb_lock, flags);
+ 	return cmd;
+ }
+@@ -1289,7 +1289,7 @@ static int sbp2_set_busy_timeout(struct sbp2_lu *lu)
+ 
+ 	data = cpu_to_be32(SBP2_BUSY_TIMEOUT_VALUE);
+ 	if (hpsb_node_write(lu->ne, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4))
+-		SBP2_ERR("%s error", __FUNCTION__);
++		SBP2_ERR("%s error", __func__);
+ 	return 0;
+ }
+ 
 @@ -1980,11 +1980,8 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
  	lu->sdev = sdev;
  	sdev->allow_restart = 1;




More information about the fedora-extras-commits mailing list