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