rpms/kernel/devel kernel.spec, 1.609, 1.610 linux-2.6-firewire-git-pending.patch, 1.28, 1.29 linux-2.6-firewire-git-update.patch, 1.12, 1.13

Jarod Wilson (jwilson) fedora-extras-commits at redhat.com
Sun Apr 13 02:57:41 UTC 2008


Author: jwilson

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

Modified Files:
	kernel.spec linux-2.6-firewire-git-pending.patch 
	linux-2.6-firewire-git-update.patch 
Log Message:
* Sat Apr 12 2008 Jarod Wilson <jwilson at redhat.com>
- Resync with latest FireWire git tree
- Add work-around patch for wrong generation in bus reset packets
  with TI controllers (#243081). Might also help #370931...



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.609
retrieving revision 1.610
diff -u -r1.609 -r1.610
--- kernel.spec	13 Apr 2008 00:08:40 -0000	1.609
+++ kernel.spec	13 Apr 2008 02:57:01 -0000	1.610
@@ -1755,6 +1755,11 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL}.xen -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.xen.conf %{with_xen} xen
 
 %changelog
+* Sat Apr 12 2008 Jarod Wilson <jwilson at redhat.com>
+- Resync with latest FireWire git tree
+- Add work-around patch for wrong generation in bus reset packets
+  with TI controllers (#243081). Might also help #370931...
+
 * Sat Apr 12 2008 Dave Jones <davej at redhat.com>
 - Silence some noisy printks caused by BIOS bugs.
 

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.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- linux-2.6-firewire-git-pending.patch	8 Apr 2008 21:24:06 -0000	1.28
+++ linux-2.6-firewire-git-pending.patch	13 Apr 2008 02:57:01 -0000	1.29
@@ -3,326 +3,104 @@
 # tree, which we think we're going to want...
 #
 
-
-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	10000U	/* 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);
-
--- 
-Jarod Wilson
-jwilson at redhat.com
-
-
-While trying to debug this piece of crap JMicron PCI-e controller in my
-possession, one thought was that perhaps I was encountering register access
-failures. I'm not, but logging them would be good, so we can see if they
-are a real problem we should be taking into account anywhere in the code.
-
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
-
----
-
- drivers/firewire/fw-ohci.c |   12 +++++++++---
- drivers/firewire/fw-ohci.h |    1 +
- 2 files changed, 10 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
-index 3d4ef3f..26befb7 100644
---- a/drivers/firewire/fw-ohci.c
-+++ b/drivers/firewire/fw-ohci.c
-@@ -257,7 +257,7 @@ static void log_irqs(u32 evt)
- 	if (likely(!(param_debug & OHCI_PARAM_DEBUG_IRQS)))
- 		return;
- 
--	printk(KERN_DEBUG KBUILD_MODNAME ": IRQ %08x%s%s%s%s%s%s%s%s%s%s%s\n",
-+	printk(KERN_DEBUG KBUILD_MODNAME ": IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s\n",
- 	       evt,
- 	       evt & OHCI1394_selfIDComplete	? " selfID"		: "",
- 	       evt & OHCI1394_RQPkt		? " AR_req"		: "",
-@@ -269,11 +269,13 @@ static void log_irqs(u32 evt)
- 	       evt & OHCI1394_postedWriteErr	? " postedWriteErr"	: "",
- 	       evt & OHCI1394_cycleTooLong	? " cycleTooLong"	: "",
- 	       evt & OHCI1394_cycle64Seconds	? " cycle64Seconds"	: "",
-+	       evt & OHCI1394_regAccessFail	? " regAccessFail"	: "",
- 	       evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
- 		       OHCI1394_RSPkt | OHCI1394_reqTxComplete |
- 		       OHCI1394_respTxComplete | OHCI1394_isochRx |
- 		       OHCI1394_isochTx | OHCI1394_postedWriteErr |
--		       OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds)
-+		       OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
-+		       OHCI1394_regAccessFail)
- 						? " ?"			: "");
- }
- 
-@@ -1351,6 +1353,9 @@ static irqreturn_t irq_handler(int irq, void *data)
- 		iso_event &= ~(1 << i);
- 	}
- 
-+	if (unlikely(event & OHCI1394_regAccessFail))
-+		fw_error("Register access failure\n");
-+
- 	if (unlikely(event & OHCI1394_postedWriteErr))
- 		fw_error("PCI posted write error\n");
- 
-@@ -1448,7 +1453,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
- 		  OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
- 		  OHCI1394_isochRx | OHCI1394_isochTx |
- 		  OHCI1394_postedWriteErr | OHCI1394_cycleTooLong |
--		  OHCI1394_cycle64Seconds | OHCI1394_masterIntEnable);
-+		  OHCI1394_cycle64Seconds | OHCI1394_regAccessFail |
-+		  OHCI1394_masterIntEnable);
- 
- 	/* Activate link_on bit and contender bit in our self ID packets.*/
- 	if (ohci_update_phy_reg(card, 4, 0,
-diff --git a/drivers/firewire/fw-ohci.h b/drivers/firewire/fw-ohci.h
-index 5754c6e..a2fbb62 100644
---- a/drivers/firewire/fw-ohci.h
-+++ b/drivers/firewire/fw-ohci.h
-@@ -125,6 +125,7 @@
- #define OHCI1394_lockRespErr		0x00000200
- #define OHCI1394_selfIDComplete		0x00010000
- #define OHCI1394_busReset		0x00020000
-+#define OHCI1394_regAccessFail		0x00040000
- #define OHCI1394_phy			0x00080000
- #define OHCI1394_cycleSynch		0x00100000
- #define OHCI1394_cycle64Seconds		0x00200000
-
--- 
-Jarod Wilson
-jwilson at redhat.com
-
-
-firewire: fw-ohci: don't append to AT context when not active
-
-Date: Mon, 7 Apr 2008 22:32:33 +0200 (CEST)
+Date: Sat, 12 Apr 2008 22:31:25 +0200 (CEST)
 From: Stefan Richter <stefanr at s5r6.in-berlin.de>
-Subject: [PATCH update 2] firewire: fw-ohci: don't append to AT context when
- its not active
-To: Jarod Wilson <jwilson at redhat.com>
-cc: linux1394-devel at lists.sourceforge.net,
- linux-kernel at vger.kernel.org,
- =?iso-8859-1?Q?Kristian_H=F8gsberg?= <krh at redhat.com>
-
-From: Jarod Wilson <jwilson at redhat.com>
-
-I finally tracked down the issues with this JMicron PCI-e card in my
-possession to a failure to comply with section 7.2.3.2 of the OHCI 1.1
-specification (thanks to Kristian for the pointer to illustrate that it
-is indeed a flaw in this card, not the driver). The controller should
-simply flush the packets we've appended to its AT queue if a bus reset
-occurs before they've been transmitted and we'll try again, but
-something goes wrong and the controller winds up hung.
-
-However, we can avoid the problem by simply checking if the
-IntEvent.busReset register had been set before we try appending to the
-AT context. When busReset is set, the AT context is completely halted
-until busReset is cleared, so there's no point in appending AT packets
-until the register is cleared. So at_context_queue_packet() now checks
-for busReset being set, and bails with an RCODE_GENERATION packet ack,
-which results in us trying to append the packet again after recognizing
-the fact there has been a bus reset, and clearing busReset.
-
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
-
-Split out busReset event logging to do it safer as a separate patch.
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
----
- drivers/firewire/fw-ohci.c |   15 +++++++++++++--
- 1 file changed, 13 insertions(+), 2 deletions(-)
-
-Index: linux/drivers/firewire/fw-ohci.c
-===================================================================
---- linux.orig/drivers/firewire/fw-ohci.c
-+++ linux/drivers/firewire/fw-ohci.c
-@@ -950,8 +950,19 @@ at_context_queue_packet(struct context *
- 				     DESCRIPTOR_IRQ_ALWAYS |
- 				     DESCRIPTOR_BRANCH_ALWAYS);
- 
--	/* FIXME: Document how the locking works. */
--	if (ohci->generation != packet->generation) {
-+	/*
-+	 * If the controller and packet generations don't match, we need to
-+	 * bail out and try again.  If IntEvent.busReset is set, the AT context
-+	 * is halted, so appending to the context and trying to run it is
-+	 * futile.  Most controllers do the right thing and just flush the AT
-+	 * queue (per section 7.2.3.2 of the OHCI 1.1 specification), but
-+	 * some controllers (like a JMicron JMB381 PCI-e) misbehave and wind
-+	 * up stalling out.  So we just bail out in software and try again
-+	 * later, and everyone is happy.
-+	 * FIXME: Document how the locking works.
-+	 */
-+	if (ohci->generation != packet->generation ||
-+	    reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
- 		if (packet->payload_length > 0)
- 			dma_unmap_single(ohci->card.device, payload_bus,
- 					 packet->payload_length, DMA_TO_DEVICE);
-
--- 
-Stefan Richter
--=====-==--- -=-- --===
-http://arcgraph.de/sr/
-
-
-Date: Mon, 7 Apr 2008 22:33:35 +0200 (CEST)
-From: Stefan Richter <stefanr at s5r6.in-berlin.de>
-Subject: [PATCH] firewire: fw-ohci: conditionally log busReset interrupts
-To: Jarod Wilson <jwilson at redhat.com>
-cc: linux1394-devel at lists.sourceforge.net,
- linux-kernel at vger.kernel.org,
- =?iso-8859-1?Q?Kristian_H=F8gsberg?= <krh at redhat.com>
-
-Add a debug option to watch bus reset interrupt events.  Half of this
-patch is taken from Jarod Wilson's first version of the JMicron fix.
-
-BusReset interrupts are only generated if the respective module
-parameter flag was set before the controller is being initialized.  We
-keep this event masked otherwise to reduce IRQ load in normal operation
-and to avoid potential problems with buggy chips.
-
-Note, this is unlike the other IRQ events whose logging can be enabled
-any time after chip initialization.  This and the influence on what
-interrupts the chip generates is why I added an extra flag for it.
-
-Also, reorder the debug parameter flags according to their perceived
-usefulness.
+Subject: [PATCH update] firewire: fw-ohci: work around generation bug in TI
+	controllers (fix AV/C and more)
+To: linux1394-devel at lists.sourceforge.net
+Cc: linux-kernel at vger.kernel.org
+
+Unlike the ohci1394 driver, fw-ohci uses the selfIDGeneration field of
+bus reset packets to determine the generation of incoming requests as
+per OHCI 1.1 clause 8.4.2.3.  This is more precise --- provided that the
+controller inserts the correct generation.  Texas Instruments chips
+often don't.
+
+This prevented the transmission of response packets, which for example
+broke AV/C transactions as used when communicating with miniDV cameras
+and any other AV/C devices.
+
+There is apparently no way to detect and adjust incorrect generations.
+Therefore we ignore the generation of bus reset packets from TI chips
+and use the generation of the self ID buffer instead.  Alas this is
+received at a slightly wrong time.  In rare cases, this could cause us
+to not respond to legitimate requests or to respond to expired requests.
+(The latter is less likely because the bus reset packet AR event is
+typically handled before the self ID complete event.)
+
+Bug reported by Mladen Kuntner, who was extraordinarily patient while
+dealing with the driver maintainers.
+https://bugzilla.redhat.com/show_bug.cgi?id=243081
 
 Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
 Signed-off-by: Jarod Wilson <jwilson at redhat.com>
 ---
 
-This could be merged into "firewire: debug interrupt events" before
-mainline commit.
+update: use a quirk flag for simpler code
 
- drivers/firewire/fw-ohci.c |   28 ++++++++++++++++++++--------
- 1 file changed, 20 insertions(+), 8 deletions(-)
+ drivers/firewire/fw-ohci.c |   21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
 
 Index: linux/drivers/firewire/fw-ohci.c
 ===================================================================
 --- linux.orig/drivers/firewire/fw-ohci.c
 +++ linux/drivers/firewire/fw-ohci.c
-@@ -240,24 +240,32 @@ static char ohci_driver_name[] = KBUILD_
- 
- #ifdef CONFIG_FIREWIRE_OHCI_DEBUG
- 
--#define OHCI_PARAM_DEBUG_IRQS		1
-+#define OHCI_PARAM_DEBUG_AT_AR		1
- #define OHCI_PARAM_DEBUG_SELFIDS	2
--#define OHCI_PARAM_DEBUG_AT_AR		4
-+#define OHCI_PARAM_DEBUG_IRQS		4
-+#define OHCI_PARAM_DEBUG_BUSRESETS	8 /* only effective before chip init */
+@@ -181,6 +181,7 @@ struct fw_ohci {
+ 	int request_generation;	/* for timestamping incoming requests */
+ 	u32 bus_seconds;
+ 	bool old_uninorth;
++	bool bus_reset_packet_quirk;
+ 
+ 	/*
+ 	 * Spinlock for accessing fw_ohci data.  Never call out of
+@@ -571,14 +572,19 @@ static __le32 *handle_ar_packet(struct a
+ 	 * generation.  We only need this for requests; for responses
+ 	 * we use the unique tlabel for finding the matching
+ 	 * request.
++	 *
++	 * Alas some chips sometimes emit bus reset packets with a
++	 * wrong generation.  We set the correct generation for these
++	 * at a slightly incorrect time (in bus_reset_tasklet).
+ 	 */
+-
+-	if (evt == OHCI1394_evt_bus_reset)
+-		ohci->request_generation = (p.header[2] >> 16) & 0xff;
+-	else if (ctx == &ohci->ar_request_ctx)
++	if (evt == OHCI1394_evt_bus_reset) {
++		if (!ohci->bus_reset_packet_quirk)
++			ohci->request_generation = (p.header[2] >> 16) & 0xff;
++	} else if (ctx == &ohci->ar_request_ctx) {
+ 		fw_core_handle_request(&ohci->card, &p);
+-	else
++	} else {
+ 		fw_core_handle_response(&ohci->card, &p);
++	}
  
- static int param_debug;
- module_param_named(debug, param_debug, int, 0644);
- MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
--	", IRQs = "		__stringify(OHCI_PARAM_DEBUG_IRQS)
--	", self-IDs = "		__stringify(OHCI_PARAM_DEBUG_SELFIDS)
- 	", AT/AR events = "	__stringify(OHCI_PARAM_DEBUG_AT_AR)
-+	", self-IDs = "		__stringify(OHCI_PARAM_DEBUG_SELFIDS)
-+	", IRQs = "		__stringify(OHCI_PARAM_DEBUG_IRQS)
-+	", busReset events = "	__stringify(OHCI_PARAM_DEBUG_BUSRESETS)
- 	", or a combination, or all = -1)");
- 
- static void log_irqs(u32 evt)
- {
--	if (likely(!(param_debug & OHCI_PARAM_DEBUG_IRQS)))
-+	if (likely(!(param_debug &
-+			(OHCI_PARAM_DEBUG_IRQS | OHCI_PARAM_DEBUG_BUSRESETS))))
-+		return;
-+
-+	if (!(param_debug & OHCI_PARAM_DEBUG_IRQS) &&
-+	    !(evt & OHCI1394_busReset))
- 		return;
- 
--	printk(KERN_DEBUG KBUILD_MODNAME ": IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s\n",
-+	printk(KERN_DEBUG KBUILD_MODNAME ": IRQ "
-+	       "%08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- 	       evt,
- 	       evt & OHCI1394_selfIDComplete	? " selfID"		: "",
- 	       evt & OHCI1394_RQPkt		? " AR_req"		: "",
-@@ -270,12 +278,13 @@ static void log_irqs(u32 evt)
- 	       evt & OHCI1394_cycleTooLong	? " cycleTooLong"	: "",
- 	       evt & OHCI1394_cycle64Seconds	? " cycle64Seconds"	: "",
- 	       evt & OHCI1394_regAccessFail	? " regAccessFail"	: "",
-+	       evt & OHCI1394_busReset		? " busReset"		: "",
- 	       evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
- 		       OHCI1394_RSPkt | OHCI1394_reqTxComplete |
- 		       OHCI1394_respTxComplete | OHCI1394_isochRx |
- 		       OHCI1394_isochTx | OHCI1394_postedWriteErr |
- 		       OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
--		       OHCI1394_regAccessFail)
-+		       OHCI1394_regAccessFail | OHCI1394_busReset)
- 						? " ?"			: "");
+ 	return buffer + length + 1;
  }
+@@ -1285,6 +1291,9 @@ static void bus_reset_tasklet(unsigned l
+ 	context_stop(&ohci->at_response_ctx);
+ 	reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
  
-@@ -1328,7 +1337,8 @@ static irqreturn_t irq_handler(int irq, 
- 	if (!event || !~event)
- 		return IRQ_NONE;
- 
--	reg_write(ohci, OHCI1394_IntEventClear, event);
-+	/* busReset must not be cleared yet, see OHCI 1.1 clause 7.2.3.2 */
-+	reg_write(ohci, OHCI1394_IntEventClear, event & ~OHCI1394_busReset);
- 	log_irqs(event);
- 
- 	if (event & OHCI1394_selfIDComplete)
-@@ -1467,6 +1477,8 @@ static int ohci_enable(struct fw_card *c
- 		  OHCI1394_postedWriteErr | OHCI1394_cycleTooLong |
- 		  OHCI1394_cycle64Seconds | OHCI1394_regAccessFail |
- 		  OHCI1394_masterIntEnable);
-+	if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
-+		reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
++	if (ohci->bus_reset_packet_quirk)
++		ohci->request_generation = generation;
++
+ 	/*
+ 	 * This next bit is unrelated to the AT context stuff but we
+ 	 * have to do it under the spinlock also.  If a new config rom
+@@ -2360,6 +2369,8 @@ pci_probe(struct pci_dev *dev, const str
+ 	ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE &&
+ 			     dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW;
+ #endif
++	ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI;
++
+ 	spin_lock_init(&ohci->lock);
  
- 	/* Activate link_on bit and contender bit in our self ID packets.*/
- 	if (ohci_update_phy_reg(card, 4, 0,
+ 	tasklet_init(&ohci->bus_reset_tasklet,
 
 -- 
 Stefan Richter
--=====-==--- -=-- --===
+-=====-==--- -=-- -==--
 http://arcgraph.de/sr/
 
 

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

Index: linux-2.6-firewire-git-update.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-firewire-git-update.patch,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- linux-2.6-firewire-git-update.patch	2 Apr 2008 14:49:30 -0000	1.12
+++ linux-2.6-firewire-git-update.patch	13 Apr 2008 02:57:01 -0000	1.13
@@ -1,56 +1,30 @@
-git diff in linux1394-2.6.git vs. v2.6.25-rc8, April 02, 2008
+git diff in linux1394-2.6.git vs. v2.6.25-rc9, April 12, 2008
 
- Documentation/debugging-via-ohci1394.txt |   13 +-
- drivers/firewire/Kconfig                 |    5 +
- drivers/firewire/fw-card.c               |   52 +----
- drivers/firewire/fw-cdev.c               |   13 +-
- drivers/firewire/fw-device.c             |  263 +++++++++++++++++++-----
- drivers/firewire/fw-device.h             |   38 +++-
- drivers/firewire/fw-iso.c                |    5 -
- drivers/firewire/fw-ohci.c               |  338 ++++++++++++++++++++++++------
- drivers/firewire/fw-ohci.h               |    1 +
- drivers/firewire/fw-sbp2.c               |  150 ++++++-------
- drivers/firewire/fw-topology.c           |   22 ++-
- drivers/firewire/fw-topology.h           |   11 +-
- drivers/firewire/fw-transaction.c        |   75 ++++----
- drivers/firewire/fw-transaction.h        |   17 +-
- drivers/ieee1394/csr.c                   |    6 +-
- drivers/ieee1394/dv1394.c                |    4 +-
- drivers/ieee1394/highlevel.c             |    6 +-
- drivers/ieee1394/ieee1394_core.c         |    2 +-
- drivers/ieee1394/nodemgr.c               |    6 +-
- drivers/ieee1394/ohci1394.c              |  229 ++++++++++----------
- drivers/ieee1394/pcilynx.c               |   15 +-
- drivers/ieee1394/raw1394.c               |    2 -
- drivers/ieee1394/sbp2.c                  |   11 +-
- drivers/ieee1394/video1394.c             |    4 +-
- lib/Kconfig.debug                        |   10 +
- 25 files changed, 835 insertions(+), 463 deletions(-)
+ drivers/firewire/Kconfig          |    5 +
+ drivers/firewire/fw-card.c        |   52 +-----
+ drivers/firewire/fw-cdev.c        |   13 +-
+ drivers/firewire/fw-device.c      |  263 +++++++++++++++++++++-----
+ drivers/firewire/fw-device.h      |   38 +++-
+ drivers/firewire/fw-iso.c         |    5 -
+ drivers/firewire/fw-ohci.c        |  383 ++++++++++++++++++++++++++++++-------
+ drivers/firewire/fw-ohci.h        |    2 +
+ drivers/firewire/fw-sbp2.c        |  150 +++++++--------
+ drivers/firewire/fw-topology.c    |   22 ++-
+ drivers/firewire/fw-topology.h    |   11 +-
+ drivers/firewire/fw-transaction.c |   75 ++++----
+ drivers/firewire/fw-transaction.h |   17 +-
+ drivers/ieee1394/csr.c            |    6 +-
+ drivers/ieee1394/dv1394.c         |    4 +-
+ drivers/ieee1394/highlevel.c      |    6 +-
+ drivers/ieee1394/ieee1394_core.c  |    2 +-
+ drivers/ieee1394/nodemgr.c        |    6 +-
+ drivers/ieee1394/ohci1394.c       |  229 +++++++++++-----------
+ drivers/ieee1394/pcilynx.c        |   15 +-
+ drivers/ieee1394/raw1394.c        |    2 -
+ drivers/ieee1394/sbp2.c           |   11 +-
+ drivers/ieee1394/video1394.c      |    4 +-
+ 23 files changed, 859 insertions(+), 462 deletions(-)
 
-diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
-index c360d4e..371ba27 100644
---- a/Documentation/debugging-via-ohci1394.txt
-+++ b/Documentation/debugging-via-ohci1394.txt
-@@ -41,11 +41,14 @@ to a working state and enables physical DMA by default for all remote nodes.
- This can be turned off by ohci1394's module parameter phys_dma=0.
- 
- The alternative firewire-ohci driver in drivers/firewire uses filtered physical
--DMA, hence is not yet suitable for remote debugging.
--
--Because ohci1394 depends on the PCI enumeration to be completed, an
--initialization routine which runs pretty early (long before console_init()
--which makes the printk buffer appear on the console can be called) was written.
-+DMA by default, which is more secure but not suitable for remote debugging.
-+Compile the driver with CONFIG_FIREWIRE_OHCI_REMOTE_DMA to get unfiltered
-+physical DMA.
-+
-+Because ohci1394 and firewire-ohci depend on the PCI enumeration to be
-+completed, an initialization routine which runs pretty early has been
-+implemented for x86.  This routine runs long before console_init() can be
-+called, i.e. before the printk buffer appears on the console.
- 
- To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu:
- Provide code for enabling DMA over FireWire early on boot) and pass the
 diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
 index 25bdc2d..fb4d391 100644
 --- a/drivers/firewire/Kconfig
@@ -867,7 +841,7 @@
  }
 -EXPORT_SYMBOL(fw_iso_context_stop);
 diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
-index ca6d51e..3d4ef3f 100644
+index ca6d51e..67a8797 100644
 --- a/drivers/firewire/fw-ohci.c
 +++ b/drivers/firewire/fw-ohci.c
 @@ -27,6 +27,7 @@
@@ -887,30 +861,38 @@
  	u32 bus_seconds;
  	bool old_uninorth;
  
-@@ -237,6 +238,179 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
+@@ -237,6 +238,196 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
  
  static char ohci_driver_name[] = KBUILD_MODNAME;
  
 +#ifdef CONFIG_FIREWIRE_OHCI_DEBUG
 +
-+#define OHCI_PARAM_DEBUG_IRQS		1
++#define OHCI_PARAM_DEBUG_AT_AR		1
 +#define OHCI_PARAM_DEBUG_SELFIDS	2
-+#define OHCI_PARAM_DEBUG_AT_AR		4
++#define OHCI_PARAM_DEBUG_IRQS		4
++#define OHCI_PARAM_DEBUG_BUSRESETS	8 /* only effective before chip init */
 +
 +static int param_debug;
 +module_param_named(debug, param_debug, int, 0644);
 +MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
-+	", IRQs = "		__stringify(OHCI_PARAM_DEBUG_IRQS)
-+	", self-IDs = "		__stringify(OHCI_PARAM_DEBUG_SELFIDS)
 +	", AT/AR events = "	__stringify(OHCI_PARAM_DEBUG_AT_AR)
++	", self-IDs = "		__stringify(OHCI_PARAM_DEBUG_SELFIDS)
++	", IRQs = "		__stringify(OHCI_PARAM_DEBUG_IRQS)
++	", busReset events = "	__stringify(OHCI_PARAM_DEBUG_BUSRESETS)
 +	", or a combination, or all = -1)");
 +
 +static void log_irqs(u32 evt)
 +{
-+	if (likely(!(param_debug & OHCI_PARAM_DEBUG_IRQS)))
++	if (likely(!(param_debug &
++			(OHCI_PARAM_DEBUG_IRQS | OHCI_PARAM_DEBUG_BUSRESETS))))
 +		return;
 +
-+	printk(KERN_DEBUG KBUILD_MODNAME ": IRQ %08x%s%s%s%s%s%s%s%s%s%s%s\n",
++	if (!(param_debug & OHCI_PARAM_DEBUG_IRQS) &&
++	    !(evt & OHCI1394_busReset))
++		return;
++
++	printk(KERN_DEBUG KBUILD_MODNAME ": IRQ "
++	       "%08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
 +	       evt,
 +	       evt & OHCI1394_selfIDComplete	? " selfID"		: "",
 +	       evt & OHCI1394_RQPkt		? " AR_req"		: "",
@@ -922,11 +904,14 @@
 +	       evt & OHCI1394_postedWriteErr	? " postedWriteErr"	: "",
 +	       evt & OHCI1394_cycleTooLong	? " cycleTooLong"	: "",
 +	       evt & OHCI1394_cycle64Seconds	? " cycle64Seconds"	: "",
++	       evt & OHCI1394_regAccessFail	? " regAccessFail"	: "",
++	       evt & OHCI1394_busReset		? " busReset"		: "",
 +	       evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
 +		       OHCI1394_RSPkt | OHCI1394_reqTxComplete |
 +		       OHCI1394_respTxComplete | OHCI1394_isochRx |
 +		       OHCI1394_isochTx | OHCI1394_postedWriteErr |
-+		       OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds)
++		       OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
++		       OHCI1394_regAccessFail | OHCI1394_busReset)
 +						? " ?"			: "");
 +}
 +
@@ -944,13 +929,13 @@
 +	return port[*s >> shift & 3];
 +}
 +
-+static void log_selfids(int generation, int self_id_count, u32 *s)
++static void log_selfids(int node_id, int generation, int self_id_count, u32 *s)
 +{
 +	if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS)))
 +		return;
 +
-+	printk(KERN_DEBUG KBUILD_MODNAME ": %d selfIDs, generation %d\n",
-+	       self_id_count, generation);
++	printk(KERN_DEBUG KBUILD_MODNAME ": %d selfIDs, generation %d, "
++	       "local node ID %04x\n", self_id_count, generation, node_id);
 +
 +	for (; self_id_count--; ++s)
 +		if ((*s & 1 << 23) == 0)
@@ -1013,6 +998,12 @@
 +	if (unlikely(evt >= ARRAY_SIZE(evts)))
 +			evt = 0x1f;
 +
++	if (evt == OHCI1394_evt_bus_reset) {
++		printk(KERN_DEBUG "A%c evt_bus_reset, generation %d\n",
++		       dir, (header[2] >> 16) & 0xff);
++		return;
++	}
++
 +	if (header[0] == ~header[1]) {
 +		printk(KERN_DEBUG "A%c %s, %s, %08x\n",
 +		       dir, evts[evt], phys[header[0] >> 30 & 0x3],
@@ -1059,7 +1050,7 @@
 +#else
 +
 +#define log_irqs(evt)
-+#define log_selfids(generation, self_id_count, sid)
++#define log_selfids(node_id, generation, self_id_count, sid)
 +#define log_ar_at_event(dir, speed, header, evt)
 +
 +#endif /* CONFIG_FIREWIRE_OHCI_DEBUG */
@@ -1067,7 +1058,7 @@
  static inline void reg_write(const struct fw_ohci *ohci, int offset, u32 data)
  {
  	writel(data, ohci->registers + offset);
-@@ -320,6 +494,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+@@ -320,6 +511,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
  	struct fw_ohci *ohci = ctx->ohci;
  	struct fw_packet p;
  	u32 status, length, tcode;
@@ -1075,7 +1066,7 @@
  
  	p.header[0] = cond_le32_to_cpu(buffer[0]);
  	p.header[1] = cond_le32_to_cpu(buffer[1]);
-@@ -362,12 +537,15 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+@@ -362,12 +554,15 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
  	/* FIXME: What to do about evt_* errors? */
  	length = (p.header_length + p.payload_length + 3) / 4;
  	status = cond_le32_to_cpu(buffer[length]);
@@ -1092,7 +1083,7 @@
  	/*
  	 * The OHCI bus reset handler synthesizes a phy packet with
  	 * the new generation number when a bus reset happens (see
-@@ -378,7 +556,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+@@ -378,7 +573,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
  	 * request.
  	 */
  
@@ -1101,7 +1092,29 @@
  		ohci->request_generation = (p.header[2] >> 16) & 0xff;
  	else if (ctx == &ohci->ar_request_ctx)
  		fw_core_handle_request(&ohci->card, &p);
-@@ -817,6 +995,8 @@ static int handle_at_packet(struct context *context,
+@@ -770,8 +965,19 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
+ 				     DESCRIPTOR_IRQ_ALWAYS |
+ 				     DESCRIPTOR_BRANCH_ALWAYS);
+ 
+-	/* FIXME: Document how the locking works. */
+-	if (ohci->generation != packet->generation) {
++	/*
++	 * If the controller and packet generations don't match, we need to
++	 * bail out and try again.  If IntEvent.busReset is set, the AT context
++	 * is halted, so appending to the context and trying to run it is
++	 * futile.  Most controllers do the right thing and just flush the AT
++	 * queue (per section 7.2.3.2 of the OHCI 1.1 specification), but
++	 * some controllers (like a JMicron JMB381 PCI-e) misbehave and wind
++	 * up stalling out.  So we just bail out in software and try again
++	 * later, and everyone is happy.
++	 * FIXME: Document how the locking works.
++	 */
++	if (ohci->generation != packet->generation ||
++	    reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
+ 		if (packet->payload_length > 0)
+ 			dma_unmap_single(ohci->card.device, payload_bus,
+ 					 packet->payload_length, DMA_TO_DEVICE);
+@@ -817,6 +1023,8 @@ static int handle_at_packet(struct context *context,
  	evt = le16_to_cpu(last->transfer_status) & 0x1f;
  	packet->timestamp = le16_to_cpu(last->res_count);
  
@@ -1110,7 +1123,7 @@
  	switch (evt) {
  	case OHCI1394_evt_timeout:
  		/* Async response transmit timed out. */
-@@ -1019,20 +1199,30 @@ static void bus_reset_tasklet(unsigned long data)
+@@ -1019,20 +1227,30 @@ static void bus_reset_tasklet(unsigned long data)
  	ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
  			       OHCI1394_NodeID_nodeNumber);
  
@@ -1145,7 +1158,7 @@
  		ohci->self_id_buffer[j] =
  				cond_le32_to_cpu(ohci->self_id_cpu[i]);
  	}
-@@ -1097,12 +1287,19 @@ static void bus_reset_tasklet(unsigned long data)
+@@ -1097,12 +1315,20 @@ static void bus_reset_tasklet(unsigned long data)
  		reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header);
  	}
  
@@ -1160,20 +1173,35 @@
  		dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
  				  free_rom, free_rom_bus);
  
-+	log_selfids(generation, self_id_count, ohci->self_id_buffer);
++	log_selfids(ohci->node_id, generation,
++		    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);
  }
-@@ -1119,6 +1316,7 @@ static irqreturn_t irq_handler(int irq, void *data)
+@@ -1118,7 +1344,9 @@ static irqreturn_t irq_handler(int irq, void *data)
+ 	if (!event || !~event)
  		return IRQ_NONE;
  
- 	reg_write(ohci, OHCI1394_IntEventClear, event);
+-	reg_write(ohci, OHCI1394_IntEventClear, event);
++	/* busReset must not be cleared yet, see OHCI 1.1 clause 7.2.3.2 */
++	reg_write(ohci, OHCI1394_IntEventClear, event & ~OHCI1394_busReset);
 +	log_irqs(event);
  
  	if (event & OHCI1394_selfIDComplete)
  		tasklet_schedule(&ohci->bus_reset_tasklet);
-@@ -1192,6 +1390,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
+@@ -1153,6 +1381,10 @@ static irqreturn_t irq_handler(int irq, void *data)
+ 		iso_event &= ~(1 << i);
+ 	}
+ 
++	if (unlikely(event & OHCI1394_regAccessFail))
++		fw_error("Register access failure - "
++			 "please notify linux1394-devel at lists.sf.net\n");
++
+ 	if (unlikely(event & OHCI1394_postedWriteErr))
+ 		fw_error("PCI posted write error\n");
+ 
+@@ -1192,6 +1424,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
  {
  	struct fw_ohci *ohci = fw_ohci(card);
  	struct pci_dev *dev = to_pci_dev(card->device);
@@ -1182,7 +1210,7 @@
  
  	if (software_reset(ohci)) {
  		fw_error("Failed to reset ohci card.\n");
-@@ -1203,13 +1403,24 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
+@@ -1203,13 +1437,24 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
  	 * most of the registers.  In fact, on some cards (ALI M5251),
  	 * accessing registers in the SClk domain without LPS enabled
  	 * will lock up the machine.  Wait 50msec to make sure we have
@@ -1209,7 +1237,19 @@
  
  	reg_write(ohci, OHCI1394_HCControlClear,
  		  OHCI1394_HCControl_noByteSwapData);
-@@ -1421,6 +1632,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
+@@ -1237,7 +1482,10 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
+ 		  OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
+ 		  OHCI1394_isochRx | OHCI1394_isochTx |
+ 		  OHCI1394_postedWriteErr | OHCI1394_cycleTooLong |
+-		  OHCI1394_cycle64Seconds | OHCI1394_masterIntEnable);
++		  OHCI1394_cycle64Seconds | OHCI1394_regAccessFail |
++		  OHCI1394_masterIntEnable);
++	if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
++		reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
+ 
+ 	/* Activate link_on bit and contender bit in our self ID packets.*/
+ 	if (ohci_update_phy_reg(card, 4, 0,
+@@ -1421,6 +1669,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
  	if (packet->ack != 0)
  		goto out;
  
@@ -1217,7 +1257,7 @@
  	driver_data->packet = NULL;
  	packet->ack = RCODE_CANCELLED;
  	packet->callback(packet, &ohci->card, packet->ack);
-@@ -1435,6 +1647,9 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
+@@ -1435,6 +1684,9 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
  static int
  ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
  {
@@ -1227,7 +1267,7 @@
  	struct fw_ohci *ohci = fw_ohci(card);
  	unsigned long flags;
  	int n, retval = 0;
-@@ -1466,6 +1681,7 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
+@@ -1466,6 +1718,7 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
   out:
  	spin_unlock_irqrestore(&ohci->lock, flags);
  	return retval;
@@ -1235,7 +1275,7 @@
  }
  
  static u64
-@@ -2045,17 +2261,9 @@ static const struct fw_card_driver ohci_driver = {
+@@ -2045,17 +2298,9 @@ static const struct fw_card_driver ohci_driver = {
  	.stop_iso		= ohci_stop_iso,
  };
  
@@ -1255,7 +1295,7 @@
  	if (machine_is(powermac)) {
  		struct device_node *ofn = pci_device_to_OF_node(dev);
  
-@@ -2064,8 +2272,33 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+@@ -2064,8 +2309,33 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
  		}
  	}
@@ -1289,7 +1329,7 @@
  	ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
  	if (ohci == NULL) {
  		fw_error("Could not malloc fw_ohci data.\n");
-@@ -2074,10 +2307,12 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+@@ -2074,10 +2344,12 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  
  	fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev);
  
@@ -1303,7 +1343,7 @@
  	}
  
  	pci_set_master(dev);
-@@ -2173,8 +2408,9 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+@@ -2173,8 +2445,9 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  	pci_release_region(dev, 0);
   fail_disable:
  	pci_disable_device(dev);
@@ -1315,7 +1355,7 @@
  
  	return err;
  }
-@@ -2202,72 +2438,42 @@ static void pci_remove(struct pci_dev *dev)
+@@ -2202,72 +2475,42 @@ static void pci_remove(struct pci_dev *dev)
  	pci_iounmap(dev, ohci->registers);
  	pci_release_region(dev, 0);
  	pci_disable_device(dev);
@@ -1403,7 +1443,7 @@
  		fw_error("pci_enable_device failed\n");
  		return err;
 diff --git a/drivers/firewire/fw-ohci.h b/drivers/firewire/fw-ohci.h
-index dec4f04..5754c6e 100644
+index dec4f04..a2fbb62 100644
 --- a/drivers/firewire/fw-ohci.h
 +++ b/drivers/firewire/fw-ohci.h
 @@ -30,6 +30,7 @@
@@ -1414,6 +1454,14 @@
  #define OHCI1394_IRMultiChanMaskHiSet         0x070
  #define OHCI1394_IRMultiChanMaskHiClear       0x074
  #define OHCI1394_IRMultiChanMaskLoSet         0x078
+@@ -124,6 +125,7 @@
+ #define OHCI1394_lockRespErr		0x00000200
+ #define OHCI1394_selfIDComplete		0x00010000
+ #define OHCI1394_busReset		0x00020000
++#define OHCI1394_regAccessFail		0x00040000
+ #define OHCI1394_phy			0x00080000
+ #define OHCI1394_cycleSynch		0x00100000
+ #define OHCI1394_cycle64Seconds		0x00200000
 diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
 index 62b4e47..2a99937 100644
 --- a/drivers/firewire/fw-sbp2.c
@@ -2750,24 +2798,3 @@
  	ret = cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16);
  	if (ret) {
  		PRINT_G(KERN_ERR, "video1394: unable to get minor device block");
-diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
-index 0796c1a..4e370e1 100644
---- a/lib/Kconfig.debug
-+++ b/lib/Kconfig.debug
-@@ -592,6 +592,16 @@ config LATENCYTOP
- 	  Enable this option if you want to use the LatencyTOP tool
- 	  to find out which userspace is blocking on what kernel operations.
- 
-+config FIREWIRE_OHCI_REMOTE_DMA
-+	bool "Remote debugging via firewire-ohci"
-+	depends on FIREWIRE_OHCI
-+	help
-+	  This option lets you use the FireWire bus for remote debugging.
-+	  It enables unfiltered remote DMA in the firewire-ohci driver.
-+	  See Documentation/debugging-via-ohci1394.txt for more information.
-+
-+	  If unsure, say N.
-+
- config PROVIDE_OHCI1394_DMA_INIT
- 	bool "Provide code for enabling DMA over FireWire early on boot"
- 	depends on PCI && X86




More information about the fedora-extras-commits mailing list