linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [git pull] FireWire updates
@ 2009-07-04 20:49 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2009-07-04 20:49 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following IEEE 1394/ FireWire subsystem updates.
These are recent but straight-forward fixes.

Stefan Richter (3):
      firewire: core: do not DMA-map stack addresses
      firewire: sbp2: add support for disks >2 TB (and 16 bytes long CDBs)
      ieee1394: sbp2: add support for disks >2 TB (and 16 bytes long CDBs)

 drivers/firewire/core-card.c |   14 +++++++-------
 drivers/firewire/core-cdev.c |    4 +++-
 drivers/firewire/core-iso.c  |   24 +++++++++++++-----------
 drivers/firewire/core.h      |    3 ++-
 drivers/firewire/sbp2.c      |   10 +++++++++-
 drivers/ieee1394/sbp2.c      |    1 +
 drivers/ieee1394/sbp2.h      |    8 +++++++-
 include/linux/firewire.h     |    1 +
 8 files changed, 43 insertions(+), 22 deletions(-)


commit ebbb16bffa646f853899ef3fdc0ac7abab888703
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Tue Jun 30 20:28:31 2009 +0200

    ieee1394: sbp2: add support for disks >2 TB (and 16 bytes long CDBs)
    
    Increase the command ORB data structure to transport up to 16 bytes long
    CDBs (instead of 12 bytes), and tell the SCSI mid layer about it.  This
    is notably necessary for READ CAPACITY(16) and friends, i.e. support of
    large disks.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index a51ab23..f599f49 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -880,6 +880,7 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud)
 	}
 
 	shost->hostdata[0] = (unsigned long)lu;
+	shost->max_cmd_len = SBP2_MAX_CDB_SIZE;
 
 	if (!scsi_add_host(shost, &ud->device)) {
 		lu->shost = shost;
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index c5036f1..64a3a66 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -25,6 +25,12 @@
 #define SBP2_DEVICE_NAME		"sbp2"
 
 /*
+ * There is no transport protocol limit to the CDB length,  but we implement
+ * a fixed length only.  16 bytes is enough for disks larger than 2 TB.
+ */
+#define SBP2_MAX_CDB_SIZE		16
+
+/*
  * SBP-2 specific definitions
  */
 
@@ -51,7 +57,7 @@ struct sbp2_command_orb {
 	u32 data_descriptor_hi;
 	u32 data_descriptor_lo;
 	u32 misc;
-	u8 cdb[12];
+	u8 cdb[SBP2_MAX_CDB_SIZE];
 } __attribute__((packed));
 
 #define SBP2_LOGIN_REQUEST		0x0

commit af2719415a5ceae06f2a6d33e78b555e64697fc8
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Tue Jun 30 20:27:59 2009 +0200

    firewire: sbp2: add support for disks >2 TB (and 16 bytes long CDBs)
    
    Increase the command ORB data structure to transport up to 16 bytes long
    CDBs (instead of 12 bytes), and tell the SCSI mid layer about it.  This
    is notably necessary for READ CAPACITY(16) and friends, i.e. support of
    large disks.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 2353643..d27cb05 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -201,6 +201,12 @@ static struct fw_device *target_device(struct sbp2_target *tgt)
 #define SBP2_CYCLE_LIMIT		(0xc8 << 12)	/* 200 125us cycles */
 
 /*
+ * There is no transport protocol limit to the CDB length,  but we implement
+ * a fixed length only.  16 bytes is enough for disks larger than 2 TB.
+ */
+#define SBP2_MAX_CDB_SIZE		16
+
+/*
  * The default maximum s/g segment size of a FireWire controller is
  * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
  * be quadlet-aligned, we set the length limit to 0xffff & ~3.
@@ -312,7 +318,7 @@ struct sbp2_command_orb {
 		struct sbp2_pointer next;
 		struct sbp2_pointer data_descriptor;
 		__be32 misc;
-		u8 command_block[12];
+		u8 command_block[SBP2_MAX_CDB_SIZE];
 	} request;
 	struct scsi_cmnd *cmd;
 	scsi_done_fn_t done;
@@ -1146,6 +1152,8 @@ static int sbp2_probe(struct device *dev)
 	if (fw_device_enable_phys_dma(device) < 0)
 		goto fail_shost_put;
 
+	shost->max_cmd_len = SBP2_MAX_CDB_SIZE;
+
 	if (scsi_add_host(shost, &unit->device) < 0)
 		goto fail_shost_put;
 

commit 6fdc03709433ccc2005f0f593ae9d9dd04f7b485
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sat Jun 20 13:23:59 2009 +0200

    firewire: core: do not DMA-map stack addresses
    
    The DMA mapping API cannot map on-stack addresses, as explained in
    Documentation/DMA-mapping.txt.  Convert the two cases of on-stack packet
    payload buffers in firewire-core (payload of lock requests in the bus
    manager work and in iso resource management) to slab-allocated memory.
    
    There are a number on-stack buffers for quadlet write or quadlet read
    requests in firewire-core and firewire-sbp2.  These are harmless; they
    are copied to/ from card driver internal DMA buffers since quadlet
    payloads are inlined with packet headers.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index 543fcca..f74edae 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -196,8 +196,8 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation)
 {
 	int channel, bandwidth = 0;
 
-	fw_iso_resource_manage(card, generation, 1ULL << 31,
-			       &channel, &bandwidth, true);
+	fw_iso_resource_manage(card, generation, 1ULL << 31, &channel,
+			       &bandwidth, true, card->bm_transaction_data);
 	if (channel == 31) {
 		card->broadcast_channel_allocated = true;
 		device_for_each_child(card->device, (void *)(long)generation,
@@ -230,7 +230,6 @@ static void fw_card_bm_work(struct work_struct *work)
 	bool do_reset = false;
 	bool root_device_is_running;
 	bool root_device_is_cmc;
-	__be32 lock_data[2];
 
 	spin_lock_irqsave(&card->lock, flags);
 
@@ -273,22 +272,23 @@ static void fw_card_bm_work(struct work_struct *work)
 			goto pick_me;
 		}
 
-		lock_data[0] = cpu_to_be32(0x3f);
-		lock_data[1] = cpu_to_be32(local_id);
+		card->bm_transaction_data[0] = cpu_to_be32(0x3f);
+		card->bm_transaction_data[1] = cpu_to_be32(local_id);
 
 		spin_unlock_irqrestore(&card->lock, flags);
 
 		rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
 				irm_id, generation, SCODE_100,
 				CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
-				lock_data, sizeof(lock_data));
+				card->bm_transaction_data,
+				sizeof(card->bm_transaction_data));
 
 		if (rcode == RCODE_GENERATION)
 			/* Another bus reset, BM work has been rescheduled. */
 			goto out;
 
 		if (rcode == RCODE_COMPLETE &&
-		    lock_data[0] != cpu_to_be32(0x3f)) {
+		    card->bm_transaction_data[0] != cpu_to_be32(0x3f)) {
 
 			/* Somebody else is BM.  Only act as IRM. */
 			if (local_id == irm_id)
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index d1d30c6..ced186d 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -125,6 +125,7 @@ struct iso_resource {
 	int generation;
 	u64 channels;
 	s32 bandwidth;
+	__be32 transaction_data[2];
 	struct iso_resource_event *e_alloc, *e_dealloc;
 };
 
@@ -1049,7 +1050,8 @@ static void iso_resource_work(struct work_struct *work)
 			r->channels, &channel, &bandwidth,
 			todo == ISO_RES_ALLOC ||
 			todo == ISO_RES_REALLOC ||
-			todo == ISO_RES_ALLOC_ONCE);
+			todo == ISO_RES_ALLOC_ONCE,
+			r->transaction_data);
 	/*
 	 * Is this generation outdated already?  As long as this resource sticks
 	 * in the idr, it will be scheduled again for a newer generation or at
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index 166f19c..110e731 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -177,9 +177,8 @@ EXPORT_SYMBOL(fw_iso_context_stop);
  */
 
 static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
-			    int bandwidth, bool allocate)
+			    int bandwidth, bool allocate, __be32 data[2])
 {
-	__be32 data[2];
 	int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
 
 	/*
@@ -215,9 +214,9 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
 }
 
 static int manage_channel(struct fw_card *card, int irm_id, int generation,
-			  u32 channels_mask, u64 offset, bool allocate)
+		u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
 {
-	__be32 data[2], c, all, old;
+	__be32 c, all, old;
 	int i, retry = 5;
 
 	old = all = allocate ? cpu_to_be32(~0) : 0;
@@ -260,7 +259,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
 }
 
 static void deallocate_channel(struct fw_card *card, int irm_id,
-			       int generation, int channel)
+			       int generation, int channel, __be32 buffer[2])
 {
 	u32 mask;
 	u64 offset;
@@ -269,7 +268,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id,
 	offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
 				CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
 
-	manage_channel(card, irm_id, generation, mask, offset, false);
+	manage_channel(card, irm_id, generation, mask, offset, false, buffer);
 }
 
 /**
@@ -298,7 +297,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id,
  */
 void fw_iso_resource_manage(struct fw_card *card, int generation,
 			    u64 channels_mask, int *channel, int *bandwidth,
-			    bool allocate)
+			    bool allocate, __be32 buffer[2])
 {
 	u32 channels_hi = channels_mask;	/* channels 31...0 */
 	u32 channels_lo = channels_mask >> 32;	/* channels 63...32 */
@@ -310,10 +309,12 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
 
 	if (channels_hi)
 		c = manage_channel(card, irm_id, generation, channels_hi,
-		    CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, allocate);
+				CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI,
+				allocate, buffer);
 	if (channels_lo && c < 0) {
 		c = manage_channel(card, irm_id, generation, channels_lo,
-		    CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, allocate);
+				CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO,
+				allocate, buffer);
 		if (c >= 0)
 			c += 32;
 	}
@@ -325,12 +326,13 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
 	if (*bandwidth == 0)
 		return;
 
-	ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
+	ret = manage_bandwidth(card, irm_id, generation, *bandwidth,
+			       allocate, buffer);
 	if (ret < 0)
 		*bandwidth = 0;
 
 	if (allocate && ret < 0 && c >= 0) {
-		deallocate_channel(card, irm_id, generation, c);
+		deallocate_channel(card, irm_id, generation, c, buffer);
 		*channel = ret;
 	}
 }
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index c3cfc64..6052816 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -120,7 +120,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event);
 
 int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
 void fw_iso_resource_manage(struct fw_card *card, int generation,
-		u64 channels_mask, int *channel, int *bandwidth, bool allocate);
+			    u64 channels_mask, int *channel, int *bandwidth,
+			    bool allocate, __be32 buffer[2]);
 
 
 /* -topology */
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 9823946..192d1e4 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -127,6 +127,7 @@ struct fw_card {
 	struct delayed_work work;
 	int bm_retries;
 	int bm_generation;
+	__be32 bm_transaction_data[2];
 
 	bool broadcast_channel_allocated;
 	u32 broadcast_channel;

Thanks,
-- 
Stefan Richter
-=====-==--= -=== --=--
http://arcgraph.de/sr/


^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [git pull] FireWire updates
@ 2009-10-14 21:26 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2009-10-14 21:26 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive a documentation update and a driver fix.

Justin P. Mattock (1):
      ieee1394: update URLs in debugging-via-ohci1394.txt

Stefan Richter (2):
      ieee1394: add documentation entry to MAINTAINERS
      firewire: sbp2: provide fallback if mgt_ORB_timeout is missing

 Documentation/debugging-via-ohci1394.txt |    8 ++--
 MAINTAINERS                              |    1 +
 drivers/firewire/sbp2.c                  |   39 ++++++++++-----------
 3 files changed, 24 insertions(+), 24 deletions(-)

Thanks.


commit eaf76e0d027a917a013ad8a88a94132d0feab622
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Thu Oct 8 00:39:31 2009 +0200

    firewire: sbp2: provide fallback if mgt_ORB_timeout is missing
    
    The Unit_Characteristics entry of an SBP-2 unit directory is not
    mandatory as far as I can tell.  If it is missing, we would probably
    fail to log in into the target because firewire-sbp2 would not wait for
    status after it sent the login request.
    
    The fix moves the cleanup of tgt->mgt_orb_timeout into a place where it
    is executed exactly once before login, rather than 0..n times depending
    on the target's config ROM.  With targets with one or more
    Unit_Characteristics entries, the result is the same as before.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 50f0176..98dbbda 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -188,14 +188,7 @@ static struct fw_device *target_device(struct sbp2_target *tgt)
 /* Impossible login_id, to detect logout attempt before successful login */
 #define INVALID_LOGIN_ID 0x10000
 
-/*
- * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
- * provided in the config rom. Most devices do provide a value, which
- * we'll use for login management orbs, but with some sane limits.
- */
-#define SBP2_MIN_LOGIN_ORB_TIMEOUT	5000U	/* Timeout in ms */
-#define SBP2_MAX_LOGIN_ORB_TIMEOUT	40000U	/* Timeout in ms */
-#define SBP2_ORB_TIMEOUT		2000U	/* Timeout in ms */
+#define SBP2_ORB_TIMEOUT		2000U		/* Timeout in ms */
 #define SBP2_ORB_NULL			0x80000000
 #define SBP2_RETRY_LIMIT		0xf		/* 15 retries */
 #define SBP2_CYCLE_LIMIT		(0xc8 << 12)	/* 200 125us cycles */
@@ -1034,7 +1027,6 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
 {
 	struct fw_csr_iterator ci;
 	int key, value;
-	unsigned int timeout;
 
 	fw_csr_iterator_init(&ci, directory);
 	while (fw_csr_iterator_next(&ci, &key, &value)) {
@@ -1059,17 +1051,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
 
 		case SBP2_CSR_UNIT_CHARACTERISTICS:
 			/* the timeout value is stored in 500ms units */
-			timeout = ((unsigned int) value >> 8 & 0xff) * 500;
-			timeout = max(timeout, SBP2_MIN_LOGIN_ORB_TIMEOUT);
-			tgt->mgt_orb_timeout =
-				  min(timeout, SBP2_MAX_LOGIN_ORB_TIMEOUT);
-
-			if (timeout > tgt->mgt_orb_timeout)
-				fw_notify("%s: config rom contains %ds "
-					  "management ORB timeout, limiting "
-					  "to %ds\n", tgt->bus_id,
-					  timeout / 1000,
-					  tgt->mgt_orb_timeout / 1000);
+			tgt->mgt_orb_timeout = (value >> 8 & 0xff) * 500;
 			break;
 
 		case SBP2_CSR_LOGICAL_UNIT_NUMBER:
@@ -1087,6 +1069,22 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
 	return 0;
 }
 
+/*
+ * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
+ * provided in the config rom. Most devices do provide a value, which
+ * we'll use for login management orbs, but with some sane limits.
+ */
+static void sbp2_clamp_management_orb_timeout(struct sbp2_target *tgt)
+{
+	unsigned int timeout = tgt->mgt_orb_timeout;
+
+	if (timeout > 40000)
+		fw_notify("%s: %ds mgt_ORB_timeout limited to 40s\n",
+			  tgt->bus_id, timeout / 1000);
+
+	tgt->mgt_orb_timeout = clamp_val(timeout, 5000, 40000);
+}
+
 static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
 				  u32 firmware_revision)
 {
@@ -1171,6 +1169,7 @@ static int sbp2_probe(struct device *dev)
 			       &firmware_revision) < 0)
 		goto fail_tgt_put;
 
+	sbp2_clamp_management_orb_timeout(tgt);
 	sbp2_init_workarounds(tgt, model, firmware_revision);
 
 	/*

commit 544df55d6c1590bc21c86119b89a1689b1eb5e75
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sat Oct 3 10:17:29 2009 +0200

    ieee1394: add documentation entry to MAINTAINERS
    
    Add the file pattern of drivers/ieee1394/init_ohci1394_dma.c's
    documentation to the maintainers database.  init_ohci1394_dma.c is not
    really part of the IEEE 1394 subsystem, but this maintainers contact
    seems to be better than none at all.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/MAINTAINERS b/MAINTAINERS
index 8dca9d8..6a387f6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2519,6 +2519,7 @@ L:	linux1394-devel@lists.sourceforge.net
 W:	http://www.linux1394.org/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
 S:	Maintained
+F:	Documentation/debugging-via-ohci1394.txt
 F:	drivers/ieee1394/
 
 IEEE 1394 RAW I/O DRIVER

commit 211a641770c2ae191c9589fee69a8fb67f67fffd
Author: Justin P. Mattock <justinmattock@gmail.com>
Date:   Tue Sep 29 15:13:58 2009 -0700

    ieee1394: update URLs in debugging-via-ohci1394.txt
    
    Update URLs of the userspace tools to use ohci1394_dma=early for
    debugging.
    
    Seems the address ftp://ftp.suse.de/private/bk/firewire/tools/* is not
    very helpful.  After a quick search, seems this was talked about:
    http://www.mail-archive.com/kgdb-bugreport@lists.sourceforge.net/msg02761.html
    (can't find the original thread).
    
    Signed-off-by: Justin P. Mattock <justinmattock@gmail.com>
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
index 59a91e5..611f5a5 100644
--- a/Documentation/debugging-via-ohci1394.txt
+++ b/Documentation/debugging-via-ohci1394.txt
@@ -64,14 +64,14 @@ be used to view the printk buffer of a remote machine, even with live update.
 
 Bernhard Kaindl enhanced firescope to support accessing 64-bit machines
 from 32-bit firescope and vice versa:
-- ftp://ftp.suse.de/private/bk/firewire/tools/firescope-0.2.2.tar.bz2
+- http://halobates.de/firewire/firescope-0.2.2.tar.bz2
 
 and he implemented fast system dump (alpha version - read README.txt):
-- ftp://ftp.suse.de/private/bk/firewire/tools/firedump-0.1.tar.bz2
+- http://halobates.de/firewire/firedump-0.1.tar.bz2
 
 There is also a gdb proxy for firewire which allows to use gdb to access
 data which can be referenced from symbols found by gdb in vmlinux:
-- ftp://ftp.suse.de/private/bk/firewire/tools/fireproxy-0.33.tar.bz2
+- http://halobates.de/firewire/fireproxy-0.33.tar.bz2
 
 The latest version of this gdb proxy (fireproxy-0.34) can communicate (not
 yet stable) with kgdb over an memory-based communication module (kgdbom).
@@ -178,7 +178,7 @@ Step-by-step instructions for using firescope with early OHCI initialization:
 
 Notes
 -----
-Documentation and specifications: ftp://ftp.suse.de/private/bk/firewire/docs
+Documentation and specifications: http://halobates.de/firewire/
 
 FireWire is a trademark of Apple Inc. - for more information please refer to:
 http://en.wikipedia.org/wiki/FireWire

-- 
Stefan Richter
-=====-==--= =-=- -===-
http://arcgraph.de/sr/


^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [git pull] FireWire updates
@ 2009-02-06 14:58 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2009-02-06 14:58 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following IEEE 1394/ FireWire subsystem updates.

Petr Vandrovec (1):
      firewire: core: Remove card from list of cards when enable fails

Stefan Richter (1):
      ieee1394: dv1394: move deprecation message from module init to file open

 drivers/firewire/fw-card.c |    9 ++++++++-
 drivers/ieee1394/dv1394.c  |    8 ++++----
 2 files changed, 12 insertions(+), 5 deletions(-)


diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 7be2cf3..a5dd7a6 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -412,6 +412,7 @@ fw_card_add(struct fw_card *card,
 {
 	u32 *config_rom;
 	size_t length;
+	int err;
 
 	card->max_receive = max_receive;
 	card->link_speed = link_speed;
@@ -422,7 +423,13 @@ fw_card_add(struct fw_card *card,
 	list_add_tail(&card->link, &card_list);
 	mutex_unlock(&card_mutex);
 
-	return card->driver->enable(card, config_rom, length);
+	err = card->driver->enable(card, config_rom, length);
+	if (err < 0) {
+		mutex_lock(&card_mutex);
+		list_del(&card->link);
+		mutex_unlock(&card_mutex);
+	}
+	return err;
 }
 EXPORT_SYMBOL(fw_card_add);
 
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index a329e6b..3838bc4 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1823,6 +1823,10 @@ static int dv1394_open(struct inode *inode, struct file *file)
 
 #endif
 
+	printk(KERN_INFO "%s: NOTE, the dv1394 interface is unsupported "
+	       "and will not be available in the new firewire driver stack. "
+	       "Try libraw1394 based programs instead.\n", current->comm);
+
 	return 0;
 }
 
@@ -2567,10 +2571,6 @@ static int __init dv1394_init_module(void)
 {
 	int ret;
 
-	printk(KERN_WARNING
-	       "NOTE: The dv1394 driver is unsupported and may be removed in a "
-	       "future Linux release. Use raw1394 instead.\n");
-
 	cdev_init(&dv1394_cdev, &dv1394_fops);
 	dv1394_cdev.owner = THIS_MODULE;
 	ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16);


Thanks,
-- 
Stefan Richter
-=====-==--= --=- --==-
http://arcgraph.de/sr/


^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [git pull] FireWire updates
@ 2009-01-29 20:52 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2009-01-29 20:52 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following IEEE 1394/ FireWire subsystem updates.
This is a bundle of fixes of old problems, especially:

The new driver stack:
  - firewire-core did dangerous and incorrect bus topology comparisons
    if there were more bus reset events than self ID complete events.
  - firewire-core was too quick to report a device as unplugged to upper
    layers.

Both driver stacks:
  - Asynchronous IO with some camcorders was unsuccessful especially in
    newer kernels.  Fixed by configuring the controller for more request
    retries.

Old driver stack:
  - There was an unnecessary limitation to 800 Mb/s in the core driver
    even though the rest of the stack was already fundamentally capable
    to deal with 3200 Mb/s hardware.

...and more, as the shortlog tells.

Stefan Richter (16):
      firewire: insist on successive self ID complete events
      firewire: unnecessary BM delay after generation rollover
      firewire: keep highlevel drivers attached during brief connection loss
      firewire: ohci: change "context_stop: still active" log message
      firewire: ohci: increase AT req. retries, fix ack_busy_X from Panasonic camcorders and others
      ieee1394: ohci1394: increase AT req. retries, fix ack_busy_X from Panasonic camcorders and others
      firewire: core: optimize card shutdown
      ieee1394: support for speeds greater than S800
      ieee1394: sbp2: update a help string
      ieee1394: sbp2: fix payload limit at S1600 and S3200
      ieee1394: sbp2: don't assume zero model_id or firmware_revision if there is none
      firewire: sbp2: fix payload limit at S1600 and S3200
      firewire: sbp2: define some magic numbers as macros
      firewire: sbp2: fix DMA mapping leak on the failure path
      firewire: sbp2: add workarounds for 2nd and 3rd generation iPods
      ieee1394: sbp2: add workarounds for 2nd and 3rd generation iPods

 drivers/firewire/fw-card.c        |    4 +-
 drivers/firewire/fw-device.c      |  123 +++++++++++++++++++++++-----
 drivers/firewire/fw-device.h      |    1 +
 drivers/firewire/fw-ohci.c        |    6 +-
 drivers/firewire/fw-sbp2.c        |   89 ++++++++++++---------
 drivers/firewire/fw-topology.c    |   12 +++
 drivers/firewire/fw-transaction.h |    9 ++
 drivers/ieee1394/ieee1394.h       |    4 +-
 drivers/ieee1394/ieee1394_core.c  |   16 ++--
 drivers/ieee1394/ohci1394.h       |    2 +-
 drivers/ieee1394/sbp2.c           |   54 ++++++++-----
 11 files changed, 221 insertions(+), 99 deletions(-)


diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 6bd91a1..7be2cf3 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -232,7 +232,7 @@ fw_card_bm_work(struct work_struct *work)
 	root_id = root_node->node_id;
 	grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
 
-	if (card->bm_generation + 1 == generation ||
+	if (is_next_generation(generation, card->bm_generation) ||
 	    (card->bm_generation != generation && grace)) {
 		/*
 		 * This first step is to figure out who is IRM and
@@ -512,7 +512,7 @@ fw_core_remove_card(struct fw_card *card)
 	fw_core_initiate_bus_reset(card, 1);
 
 	mutex_lock(&card_mutex);
-	list_del(&card->link);
+	list_del_init(&card->link);
 	mutex_unlock(&card_mutex);
 
 	/* Set up the dummy driver. */
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 2af5a8d..bf53acb 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -25,6 +25,7 @@
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/idr.h>
+#include <linux/jiffies.h>
 #include <linux/string.h>
 #include <linux/rwsem.h>
 #include <linux/semaphore.h>
@@ -634,12 +635,39 @@ struct fw_device *fw_device_get_by_devt(dev_t devt)
 	return device;
 }
 
+/*
+ * These defines control the retry behavior for reading the config
+ * rom.  It shouldn't be necessary to tweak these; if the device
+ * doesn't respond to a config rom read within 10 seconds, it's not
+ * going to respond at all.  As for the initial delay, a lot of
+ * devices will be able to respond within half a second after bus
+ * reset.  On the other hand, it's not really worth being more
+ * aggressive than that, since it scales pretty well; if 10 devices
+ * are plugged in, they're all getting read within one second.
+ */
+
+#define MAX_RETRIES	10
+#define RETRY_DELAY	(3 * HZ)
+#define INITIAL_DELAY	(HZ / 2)
+#define SHUTDOWN_DELAY	(2 * HZ)
+
 static void fw_device_shutdown(struct work_struct *work)
 {
 	struct fw_device *device =
 		container_of(work, struct fw_device, work.work);
 	int minor = MINOR(device->device.devt);
 
+	if (time_is_after_jiffies(device->card->reset_jiffies + SHUTDOWN_DELAY)
+	    && !list_empty(&device->card->link)) {
+		schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
+		return;
+	}
+
+	if (atomic_cmpxchg(&device->state,
+			   FW_DEVICE_GONE,
+			   FW_DEVICE_SHUTDOWN) != FW_DEVICE_GONE)
+		return;
+
 	fw_device_cdev_remove(device);
 	device_for_each_child(&device->device, NULL, shutdown_unit);
 	device_unregister(&device->device);
@@ -647,6 +675,7 @@ static void fw_device_shutdown(struct work_struct *work)
 	down_write(&fw_device_rwsem);
 	idr_remove(&fw_device_idr, minor);
 	up_write(&fw_device_rwsem);
+
 	fw_device_put(device);
 }
 
@@ -654,25 +683,63 @@ static struct device_type fw_device_type = {
 	.release	= fw_device_release,
 };
 
+static void fw_device_update(struct work_struct *work);
+
 /*
- * These defines control the retry behavior for reading the config
- * rom.  It shouldn't be necessary to tweak these; if the device
- * doesn't respond to a config rom read within 10 seconds, it's not
- * going to respond at all.  As for the initial delay, a lot of
- * devices will be able to respond within half a second after bus
- * reset.  On the other hand, it's not really worth being more
- * aggressive than that, since it scales pretty well; if 10 devices
- * are plugged in, they're all getting read within one second.
+ * If a device was pending for deletion because its node went away but its
+ * bus info block and root directory header matches that of a newly discovered
+ * device, revive the existing fw_device.
+ * The newly allocated fw_device becomes obsolete instead.
  */
+static int lookup_existing_device(struct device *dev, void *data)
+{
+	struct fw_device *old = fw_device(dev);
+	struct fw_device *new = data;
+	struct fw_card *card = new->card;
+	int match = 0;
+
+	down_read(&fw_device_rwsem); /* serialize config_rom access */
+	spin_lock_irq(&card->lock);  /* serialize node access */
+
+	if (memcmp(old->config_rom, new->config_rom, 6 * 4) == 0 &&
+	    atomic_cmpxchg(&old->state,
+			   FW_DEVICE_GONE,
+			   FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
+		struct fw_node *current_node = new->node;
+		struct fw_node *obsolete_node = old->node;
+
+		new->node = obsolete_node;
+		new->node->data = new;
+		old->node = current_node;
+		old->node->data = old;
+
+		old->max_speed = new->max_speed;
+		old->node_id = current_node->node_id;
+		smp_wmb();  /* update node_id before generation */
+		old->generation = card->generation;
+		old->config_rom_retries = 0;
+		fw_notify("rediscovered device %s\n", dev_name(dev));
 
-#define MAX_RETRIES	10
-#define RETRY_DELAY	(3 * HZ)
-#define INITIAL_DELAY	(HZ / 2)
+		PREPARE_DELAYED_WORK(&old->work, fw_device_update);
+		schedule_delayed_work(&old->work, 0);
+
+		if (current_node == card->root_node)
+			fw_schedule_bm_work(card, 0);
+
+		match = 1;
+	}
+
+	spin_unlock_irq(&card->lock);
+	up_read(&fw_device_rwsem);
+
+	return match;
+}
 
 static void fw_device_init(struct work_struct *work)
 {
 	struct fw_device *device =
 		container_of(work, struct fw_device, work.work);
+	struct device *revived_dev;
 	int minor, err;
 
 	/*
@@ -696,6 +763,15 @@ static void fw_device_init(struct work_struct *work)
 		return;
 	}
 
+	revived_dev = device_find_child(device->card->device,
+					device, lookup_existing_device);
+	if (revived_dev) {
+		put_device(revived_dev);
+		fw_device_release(&device->device);
+
+		return;
+	}
+
 	device_initialize(&device->device);
 
 	fw_device_get(device);
@@ -734,9 +810,10 @@ static void fw_device_init(struct work_struct *work)
 	 * fw_node_event().
 	 */
 	if (atomic_cmpxchg(&device->state,
-		    FW_DEVICE_INITIALIZING,
-		    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
-		fw_device_shutdown(work);
+			   FW_DEVICE_INITIALIZING,
+			   FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
+		PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
+		schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
 	} else {
 		if (device->config_rom_retries)
 			fw_notify("created device %s: GUID %08x%08x, S%d00, "
@@ -847,8 +924,8 @@ static void fw_device_refresh(struct work_struct *work)
 
 	case REREAD_BIB_UNCHANGED:
 		if (atomic_cmpxchg(&device->state,
-			    FW_DEVICE_INITIALIZING,
-			    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
+				   FW_DEVICE_INITIALIZING,
+				   FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
 			goto gone;
 
 		fw_device_update(work);
@@ -879,8 +956,8 @@ static void fw_device_refresh(struct work_struct *work)
 	create_units(device);
 
 	if (atomic_cmpxchg(&device->state,
-		    FW_DEVICE_INITIALIZING,
-		    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
+			   FW_DEVICE_INITIALIZING,
+			   FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
 		goto gone;
 
 	fw_notify("refreshed device %s\n", dev_name(&device->device));
@@ -890,8 +967,9 @@ static void fw_device_refresh(struct work_struct *work)
  give_up:
 	fw_notify("giving up on refresh of device %s\n", dev_name(&device->device));
  gone:
-	atomic_set(&device->state, FW_DEVICE_SHUTDOWN);
-	fw_device_shutdown(work);
+	atomic_set(&device->state, FW_DEVICE_GONE);
+	PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
+	schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
  out:
 	if (node_id == card->root_node->node_id)
 		fw_schedule_bm_work(card, 0);
@@ -995,9 +1073,10 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
 		 */
 		device = node->data;
 		if (atomic_xchg(&device->state,
-				FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) {
+				FW_DEVICE_GONE) == FW_DEVICE_RUNNING) {
 			PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
-			schedule_delayed_work(&device->work, 0);
+			schedule_delayed_work(&device->work,
+				list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);
 		}
 		break;
 	}
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index df51732..8ef6ec2 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -28,6 +28,7 @@
 enum fw_device_state {
 	FW_DEVICE_INITIALIZING,
 	FW_DEVICE_RUNNING,
+	FW_DEVICE_GONE,
 	FW_DEVICE_SHUTDOWN,
 };
 
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index ab9c01e..6d19828 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -226,7 +226,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
 #define CONTEXT_DEAD	0x0800
 #define CONTEXT_ACTIVE	0x0400
 
-#define OHCI1394_MAX_AT_REQ_RETRIES	0x2
+#define OHCI1394_MAX_AT_REQ_RETRIES	0xf
 #define OHCI1394_MAX_AT_RESP_RETRIES	0x2
 #define OHCI1394_MAX_PHYS_RESP_RETRIES	0x8
 
@@ -896,11 +896,11 @@ static void context_stop(struct context *ctx)
 	for (i = 0; i < 10; i++) {
 		reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs));
 		if ((reg & CONTEXT_ACTIVE) == 0)
-			break;
+			return;
 
-		fw_notify("context_stop: still active (0x%08x)\n", reg);
 		mdelay(1);
 	}
+	fw_error("Error: DMA context still active (0x%08x)\n", reg);
 }
 
 struct driver_data {
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index e88d506..c71c441 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -168,6 +168,7 @@ struct sbp2_target {
 	int address_high;
 	unsigned int workarounds;
 	unsigned int mgt_orb_timeout;
+	unsigned int max_payload;
 
 	int dont_block;	/* counter for each logical unit */
 	int blocked;	/* ditto */
@@ -310,14 +311,16 @@ struct sbp2_command_orb {
 	dma_addr_t page_table_bus;
 };
 
+#define SBP2_ROM_VALUE_WILDCARD ~0         /* match all */
+#define SBP2_ROM_VALUE_MISSING  0xff000000 /* not present in the unit dir. */
+
 /*
  * List of devices with known bugs.
  *
  * The firmware_revision field, masked with 0xffff00, is the best
  * indicator for the type of bridge chip of a device.  It yields a few
  * false positives but this did not break correctly behaving devices
- * so far.  We use ~0 as a wildcard, since the 24 bit values we get
- * from the config rom can never match that.
+ * so far.
  */
 static const struct {
 	u32 firmware_revision;
@@ -339,33 +342,35 @@ static const struct {
 	},
 	/* Initio bridges, actually only needed for some older ones */ {
 		.firmware_revision	= 0x000200,
-		.model			= ~0,
+		.model			= SBP2_ROM_VALUE_WILDCARD,
 		.workarounds		= SBP2_WORKAROUND_INQUIRY_36,
 	},
 	/* PL-3507 bridge with Prolific firmware */ {
 		.firmware_revision	= 0x012800,
-		.model			= ~0,
+		.model			= SBP2_ROM_VALUE_WILDCARD,
 		.workarounds		= SBP2_WORKAROUND_POWER_CONDITION,
 	},
 	/* Symbios bridge */ {
 		.firmware_revision	= 0xa0b800,
-		.model			= ~0,
+		.model			= SBP2_ROM_VALUE_WILDCARD,
 		.workarounds		= SBP2_WORKAROUND_128K_MAX_TRANS,
 	},
 	/* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
 		.firmware_revision	= 0x002600,
-		.model			= ~0,
+		.model			= SBP2_ROM_VALUE_WILDCARD,
 		.workarounds		= SBP2_WORKAROUND_128K_MAX_TRANS,
 	},
-
 	/*
-	 * There are iPods (2nd gen, 3rd gen) with model_id == 0, but
-	 * these iPods do not feature the read_capacity bug according
-	 * to one report.  Read_capacity behaviour as well as model_id
-	 * could change due to Apple-supplied firmware updates though.
+	 * iPod 2nd generation: needs 128k max transfer size workaround
+	 * iPod 3rd generation: needs fix capacity workaround
 	 */
-
-	/* iPod 4th generation. */ {
+	{
+		.firmware_revision	= 0x0a2700,
+		.model			= 0x000000,
+		.workarounds		= SBP2_WORKAROUND_128K_MAX_TRANS |
+					  SBP2_WORKAROUND_FIX_CAPACITY,
+	},
+	/* iPod 4th generation */ {
 		.firmware_revision	= 0x0a2700,
 		.model			= 0x000021,
 		.workarounds		= SBP2_WORKAROUND_FIX_CAPACITY,
@@ -1092,7 +1097,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
 			continue;
 
 		if (sbp2_workarounds_table[i].model != model &&
-		    sbp2_workarounds_table[i].model != ~0)
+		    sbp2_workarounds_table[i].model != SBP2_ROM_VALUE_WILDCARD)
 			continue;
 
 		w |= sbp2_workarounds_table[i].workarounds;
@@ -1142,20 +1147,28 @@ static int sbp2_probe(struct device *dev)
 	fw_device_get(device);
 	fw_unit_get(unit);
 
-	/* Initialize to values that won't match anything in our table. */
-	firmware_revision = 0xff000000;
-	model = 0xff000000;
-
 	/* implicit directory ID */
 	tgt->directory_id = ((unit->directory - device->config_rom) * 4
 			     + CSR_CONFIG_ROM) & 0xffffff;
 
+	firmware_revision = SBP2_ROM_VALUE_MISSING;
+	model		  = SBP2_ROM_VALUE_MISSING;
+
 	if (sbp2_scan_unit_dir(tgt, unit->directory, &model,
 			       &firmware_revision) < 0)
 		goto fail_tgt_put;
 
 	sbp2_init_workarounds(tgt, model, firmware_revision);
 
+	/*
+	 * At S100 we can do 512 bytes per packet, at S200 1024 bytes,
+	 * and so on up to 4096 bytes.  The SBP-2 max_payload field
+	 * specifies the max payload size as 2 ^ (max_payload + 2), so
+	 * if we set this to max_speed + 7, we get the right value.
+	 */
+	tgt->max_payload = min(device->max_speed + 7, 10U);
+	tgt->max_payload = min(tgt->max_payload, device->card->max_receive - 1);
+
 	/* 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, DIV_ROUND_UP(HZ, 5));
@@ -1273,6 +1286,19 @@ static struct fw_driver sbp2_driver = {
 	.id_table = sbp2_id_table,
 };
 
+static void sbp2_unmap_scatterlist(struct device *card_device,
+				   struct sbp2_command_orb *orb)
+{
+	if (scsi_sg_count(orb->cmd))
+		dma_unmap_sg(card_device, scsi_sglist(orb->cmd),
+			     scsi_sg_count(orb->cmd),
+			     orb->cmd->sc_data_direction);
+
+	if (orb->request.misc & cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT))
+		dma_unmap_single(card_device, orb->page_table_bus,
+				 sizeof(orb->page_table), DMA_TO_DEVICE);
+}
+
 static unsigned int
 sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
 {
@@ -1352,15 +1378,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
 
 	dma_unmap_single(device->card->device, orb->base.request_bus,
 			 sizeof(orb->request), DMA_TO_DEVICE);
-
-	if (scsi_sg_count(orb->cmd) > 0)
-		dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
-			     scsi_sg_count(orb->cmd),
-			     orb->cmd->sc_data_direction);
-
-	if (orb->page_table_bus != 0)
-		dma_unmap_single(device->card->device, orb->page_table_bus,
-				 sizeof(orb->page_table), DMA_TO_DEVICE);
+	sbp2_unmap_scatterlist(device->card->device, orb);
 
 	orb->cmd->result = result;
 	orb->done(orb->cmd);
@@ -1434,7 +1452,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 	struct sbp2_logical_unit *lu = cmd->device->hostdata;
 	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
 	struct sbp2_command_orb *orb;
-	unsigned int max_payload;
 	int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
 
 	/*
@@ -1462,17 +1479,9 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 	orb->done = done;
 	orb->cmd  = cmd;
 
-	orb->request.next.high   = cpu_to_be32(SBP2_ORB_NULL);
-	/*
-	 * At speed 100 we can do 512 bytes per packet, at speed 200,
-	 * 1024 bytes per packet etc.  The SBP-2 max_payload field
-	 * specifies the max payload size as 2 ^ (max_payload + 2), so
-	 * if we set this to max_speed + 7, we get the right value.
-	 */
-	max_payload = min(device->max_speed + 7,
-			  device->card->max_receive - 1);
+	orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL);
 	orb->request.misc = cpu_to_be32(
-		COMMAND_ORB_MAX_PAYLOAD(max_payload) |
+		COMMAND_ORB_MAX_PAYLOAD(lu->tgt->max_payload) |
 		COMMAND_ORB_SPEED(device->max_speed) |
 		COMMAND_ORB_NOTIFY);
 
@@ -1491,8 +1500,10 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 	orb->base.request_bus =
 		dma_map_single(device->card->device, &orb->request,
 			       sizeof(orb->request), DMA_TO_DEVICE);
-	if (dma_mapping_error(device->card->device, orb->base.request_bus))
+	if (dma_mapping_error(device->card->device, orb->base.request_bus)) {
+		sbp2_unmap_scatterlist(device->card->device, orb);
 		goto out;
+	}
 
 	sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation,
 		      lu->command_block_agent_address + SBP2_ORB_POINTER);
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index c9be6e6..8dd6703 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -518,6 +518,18 @@ fw_core_handle_bus_reset(struct fw_card *card,
 	struct fw_node *local_node;
 	unsigned long flags;
 
+	/*
+	 * If the selfID buffer is not the immediate successor of the
+	 * previously processed one, we cannot reliably compare the
+	 * old and new topologies.
+	 */
+	if (!is_next_generation(generation, card->generation) &&
+	    card->local_node != NULL) {
+		fw_notify("skipped bus generations, destroying all nodes\n");
+		fw_destroy_nodes(card);
+		card->bm_retries = 0;
+	}
+
 	spin_lock_irqsave(&card->lock, flags);
 
 	card->node_id = node_id;
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index c9ab12a..1d78e9c 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -276,6 +276,15 @@ static inline void fw_card_put(struct fw_card *card)
 extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);
 
 /*
+ * Check whether new_generation is the immediate successor of old_generation.
+ * Take counter roll-over at 255 (as per to OHCI) into account.
+ */
+static inline bool is_next_generation(int new_generation, int old_generation)
+{
+	return (new_generation & 0xff) == ((old_generation + 1) & 0xff);
+}
+
+/*
  * The iso packet format allows for an immediate header/payload part
  * stored in 'header' immediately after the packet info plus an
  * indirect payload part that is pointer to by the 'payload' field.
diff --git a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h
index e0ae0d3..af320e2 100644
--- a/drivers/ieee1394/ieee1394.h
+++ b/drivers/ieee1394/ieee1394.h
@@ -54,9 +54,7 @@
 #define IEEE1394_SPEED_800	0x03
 #define IEEE1394_SPEED_1600	0x04
 #define IEEE1394_SPEED_3200	0x05
-
-/* The current highest tested speed supported by the subsystem */
-#define IEEE1394_SPEED_MAX	IEEE1394_SPEED_800
+#define IEEE1394_SPEED_MAX	IEEE1394_SPEED_3200
 
 /* Maps speed values above to a string representation */
 extern const char *hpsb_speedto_str[];
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index dcdb71a..2beb8d9 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -338,6 +338,7 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
 	u8 cldcnt[nodecount];
 	u8 *map = host->speed_map;
 	u8 *speedcap = host->speed;
+	u8 local_link_speed = host->csr.lnk_spd;
 	struct selfid *sid;
 	struct ext_selfid *esid;
 	int i, j, n;
@@ -373,8 +374,8 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
 			if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++;
 
 			speedcap[n] = sid->speed;
-			if (speedcap[n] > host->csr.lnk_spd)
-				speedcap[n] = host->csr.lnk_spd;
+			if (speedcap[n] > local_link_speed)
+				speedcap[n] = local_link_speed;
 			n--;
 		}
 	}
@@ -407,12 +408,11 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
 		}
 	}
 
-#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX
-	/* assume maximum speed for 1394b PHYs, nodemgr will correct it */
-	for (n = 0; n < nodecount; n++)
-		if (speedcap[n] == SELFID_SPEED_UNKNOWN)
-			speedcap[n] = IEEE1394_SPEED_MAX;
-#endif
+	/* assume a maximum speed for 1394b PHYs, nodemgr will correct it */
+	if (local_link_speed > SELFID_SPEED_UNKNOWN)
+		for (i = 0; i < nodecount; i++)
+			if (speedcap[i] == SELFID_SPEED_UNKNOWN)
+				speedcap[i] = local_link_speed;
 }
 
 
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h
index 4320bf0..7fb8ab9 100644
--- a/drivers/ieee1394/ohci1394.h
+++ b/drivers/ieee1394/ohci1394.h
@@ -26,7 +26,7 @@
 
 #define OHCI1394_DRIVER_NAME      "ohci1394"
 
-#define OHCI1394_MAX_AT_REQ_RETRIES	0x2
+#define OHCI1394_MAX_AT_REQ_RETRIES	0xf
 #define OHCI1394_MAX_AT_RESP_RETRIES	0x2
 #define OHCI1394_MAX_PHYS_RESP_RETRIES	0x8
 #define OHCI1394_MAX_SELF_ID_ERRORS	16
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index ab1034c..f3fd865 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -115,8 +115,8 @@
  */
 static int sbp2_max_speed = IEEE1394_SPEED_MAX;
 module_param_named(max_speed, sbp2_max_speed, int, 0644);
-MODULE_PARM_DESC(max_speed, "Force max speed "
-		 "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)");
+MODULE_PARM_DESC(max_speed, "Limit data transfer speed (5 <= 3200, "
+		 "4 <= 1600, 3 <= 800, 2 <= 400, 1 <= 200, 0 = 100 Mb/s)");
 
 /*
  * Set serialize_io to 0 or N to use dynamically appended lists of command ORBs.
@@ -256,7 +256,7 @@ static int sbp2_set_busy_timeout(struct sbp2_lu *);
 static int sbp2_max_speed_and_size(struct sbp2_lu *);
 
 
-static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
+static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xa, 0xa, 0xa };
 
 static DEFINE_RWLOCK(sbp2_hi_logical_units_lock);
 
@@ -347,8 +347,8 @@ static struct scsi_host_template sbp2_shost_template = {
 	.sdev_attrs		 = sbp2_sysfs_sdev_attrs,
 };
 
-/* for match-all entries in sbp2_workarounds_table */
-#define SBP2_ROM_VALUE_WILDCARD 0x1000000
+#define SBP2_ROM_VALUE_WILDCARD ~0         /* match all */
+#define SBP2_ROM_VALUE_MISSING  0xff000000 /* not present in the unit dir. */
 
 /*
  * List of devices with known bugs.
@@ -359,60 +359,70 @@ static struct scsi_host_template sbp2_shost_template = {
  */
 static const struct {
 	u32 firmware_revision;
-	u32 model_id;
+	u32 model;
 	unsigned workarounds;
 } sbp2_workarounds_table[] = {
 	/* DViCO Momobay CX-1 with TSB42AA9 bridge */ {
 		.firmware_revision	= 0x002800,
-		.model_id		= 0x001010,
+		.model			= 0x001010,
 		.workarounds		= SBP2_WORKAROUND_INQUIRY_36 |
 					  SBP2_WORKAROUND_MODE_SENSE_8 |
 					  SBP2_WORKAROUND_POWER_CONDITION,
 	},
 	/* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
 		.firmware_revision	= 0x002800,
-		.model_id		= 0x000000,
+		.model			= 0x000000,
 		.workarounds		= SBP2_WORKAROUND_DELAY_INQUIRY |
 					  SBP2_WORKAROUND_POWER_CONDITION,
 	},
 	/* Initio bridges, actually only needed for some older ones */ {
 		.firmware_revision	= 0x000200,
-		.model_id		= SBP2_ROM_VALUE_WILDCARD,
+		.model			= SBP2_ROM_VALUE_WILDCARD,
 		.workarounds		= SBP2_WORKAROUND_INQUIRY_36,
 	},
 	/* PL-3507 bridge with Prolific firmware */ {
 		.firmware_revision	= 0x012800,
-		.model_id		= SBP2_ROM_VALUE_WILDCARD,
+		.model			= SBP2_ROM_VALUE_WILDCARD,
 		.workarounds		= SBP2_WORKAROUND_POWER_CONDITION,
 	},
 	/* Symbios bridge */ {
 		.firmware_revision	= 0xa0b800,
-		.model_id		= SBP2_ROM_VALUE_WILDCARD,
+		.model			= SBP2_ROM_VALUE_WILDCARD,
 		.workarounds		= SBP2_WORKAROUND_128K_MAX_TRANS,
 	},
 	/* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
 		.firmware_revision	= 0x002600,
-		.model_id		= SBP2_ROM_VALUE_WILDCARD,
+		.model			= SBP2_ROM_VALUE_WILDCARD,
 		.workarounds		= SBP2_WORKAROUND_128K_MAX_TRANS,
 	},
+	/*
+	 * iPod 2nd generation: needs 128k max transfer size workaround
+	 * iPod 3rd generation: needs fix capacity workaround
+	 */
+	{
+		.firmware_revision	= 0x0a2700,
+		.model			= 0x000000,
+		.workarounds		= SBP2_WORKAROUND_128K_MAX_TRANS |
+					  SBP2_WORKAROUND_FIX_CAPACITY,
+	},
 	/* iPod 4th generation */ {
 		.firmware_revision	= 0x0a2700,
-		.model_id		= 0x000021,
+		.model			= 0x000021,
 		.workarounds		= SBP2_WORKAROUND_FIX_CAPACITY,
 	},
 	/* iPod mini */ {
 		.firmware_revision	= 0x0a2700,
-		.model_id		= 0x000022,
+		.model			= 0x000022,
 		.workarounds		= SBP2_WORKAROUND_FIX_CAPACITY,
 	},
 	/* iPod mini */ {
 		.firmware_revision	= 0x0a2700,
-		.model_id		= 0x000023,
+		.model			= 0x000023,
 		.workarounds		= SBP2_WORKAROUND_FIX_CAPACITY,
 	},
 	/* iPod Photo */ {
 		.firmware_revision	= 0x0a2700,
-		.model_id		= 0x00007e,
+		.model			= 0x00007e,
 		.workarounds		= SBP2_WORKAROUND_FIX_CAPACITY,
 	}
 };
@@ -1341,13 +1351,15 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
 	struct csr1212_keyval *kv;
 	struct csr1212_dentry *dentry;
 	u64 management_agent_addr;
-	u32 unit_characteristics, firmware_revision;
+	u32 unit_characteristics, firmware_revision, model;
 	unsigned workarounds;
 	int i;
 
 	management_agent_addr = 0;
 	unit_characteristics = 0;
-	firmware_revision = 0;
+	firmware_revision = SBP2_ROM_VALUE_MISSING;
+	model = ud->flags & UNIT_DIRECTORY_MODEL_ID ?
+				ud->model_id : SBP2_ROM_VALUE_MISSING;
 
 	csr1212_for_each_dir_entry(ud->ne->csr, kv, ud->ud_kv, dentry) {
 		switch (kv->key.id) {
@@ -1388,9 +1400,9 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
 			    sbp2_workarounds_table[i].firmware_revision !=
 			    (firmware_revision & 0xffff00))
 				continue;
-			if (sbp2_workarounds_table[i].model_id !=
+			if (sbp2_workarounds_table[i].model !=
 			    SBP2_ROM_VALUE_WILDCARD &&
-			    sbp2_workarounds_table[i].model_id != ud->model_id)
+			    sbp2_workarounds_table[i].model != model)
 				continue;
 			workarounds |= sbp2_workarounds_table[i].workarounds;
 			break;
@@ -1403,7 +1415,7 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
 			  NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid),
 			  workarounds, firmware_revision,
 			  ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id,
-			  ud->model_id);
+			  model);
 
 	/* We would need one SCSI host template for each target to adjust
 	 * max_sectors on the fly, therefore warn only. */


Thanks,
-- 
Stefan Richter
-=====-==--= ---= ===-=
http://arcgraph.de/sr/


^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [git pull] FireWire updates
@ 2008-10-27 16:25 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2008-10-27 16:25 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following FireWire subsystem updates.  They fix long-
standing bugs, among them a quite visible panic.  It's very new stuff
but stress-tested.

Jay Fenlason (4):
      firewire: Survive more than 256 bus resets
      firewire: fix struct fw_node memory leak
      firewire: fw-ohci: don't leak dma memory on module removal
      firewire: fw-sbp2: fix races

Stefan Richter (2):
      firewire: fw-ohci: initialization failure path fixes
      firewire: fw-sbp2: delay first login to avoid retries

 drivers/firewire/fw-ohci.c        |   50 +++++++++++++++++++++++-----
 drivers/firewire/fw-sbp2.c        |   38 +++++++++++++++------
 drivers/firewire/fw-topology.c    |    6 ++-
 drivers/firewire/fw-transaction.h |    2 +-
 4 files changed, 73 insertions(+), 23 deletions(-)


commit cd1f70fdb4823c97328a1f151f328eb36fafd579
Author: Jay Fenlason <fenlason@redhat.com>
Date:   Fri Oct 24 15:26:20 2008 -0400

    firewire: fw-sbp2: fix races
    
    1: There is a small race between queue_delayed_work() and its
       corresponding kref_get().  Do the kref_get first, and _put it again
       if the queue_delayed_work() failed, so there is no chance of the
       kref going to zero while the work is scheduled.
    2: An SBP2_LOGOUT_REQUEST could be sent out with a login_id full of
       garbage.  Initialize it to an invalid value so we can tell if we
       ever got a valid login_id.
    3: The node ID and generation may have changed but the new values may
       not yet have been recorded in lu and tgt when the final logout is
       attempted.  Use the latest values from the device in
       sbp2_release_target().
    
    Signed-off-by: Jay Fenlason <fenlason@redhat.com>
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 17bf0e1..d334cac 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -173,6 +173,9 @@ struct sbp2_target {
 	int blocked;	/* ditto */
 };
 
+/* Impossible login_id, to detect logout attempt before successful login */
+#define INVALID_LOGIN_ID 0x10000
+
 /*
  * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
  * provided in the config rom. Most devices do provide a value, which
@@ -788,9 +791,20 @@ static void sbp2_release_target(struct kref *kref)
 			scsi_remove_device(sdev);
 			scsi_device_put(sdev);
 		}
-		sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
-				SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
-
+		if (lu->login_id != INVALID_LOGIN_ID) {
+			int generation, node_id;
+			/*
+			 * tgt->node_id may be obsolete here if we failed
+			 * during initial login or after a bus reset where
+			 * the topology changed.
+			 */
+			generation = device->generation;
+			smp_rmb(); /* node_id vs. generation */
+			node_id    = device->node_id;
+			sbp2_send_management_orb(lu, node_id, generation,
+						 SBP2_LOGOUT_REQUEST,
+						 lu->login_id, NULL);
+		}
 		fw_core_remove_address_handler(&lu->address_handler);
 		list_del(&lu->link);
 		kfree(lu);
@@ -805,19 +819,20 @@ static void sbp2_release_target(struct kref *kref)
 
 static struct workqueue_struct *sbp2_wq;
 
+static void sbp2_target_put(struct sbp2_target *tgt)
+{
+	kref_put(&tgt->kref, sbp2_release_target);
+}
+
 /*
  * Always get the target's kref when scheduling work on one its units.
  * Each workqueue job is responsible to call sbp2_target_put() upon return.
  */
 static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
 {
-	if (queue_delayed_work(sbp2_wq, &lu->work, delay))
-		kref_get(&lu->tgt->kref);
-}
-
-static void sbp2_target_put(struct sbp2_target *tgt)
-{
-	kref_put(&tgt->kref, sbp2_release_target);
+	kref_get(&lu->tgt->kref);
+	if (!queue_delayed_work(sbp2_wq, &lu->work, delay))
+		sbp2_target_put(lu->tgt);
 }
 
 /*
@@ -978,6 +993,7 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
 
 	lu->tgt      = tgt;
 	lu->lun      = lun_entry & 0xffff;
+	lu->login_id = INVALID_LOGIN_ID;
 	lu->retries  = 0;
 	lu->has_sdev = false;
 	lu->blocked  = false;

commit 0dcfeb7e3c8695c5aa3677dda8efb9bef2e7e64d
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Wed Oct 22 00:28:36 2008 +0200

    firewire: fw-sbp2: delay first login to avoid retries
    
    This optimizes firewire-sbp2's device probe for the case that the local
    node and the SBP-2 node were discovered at the same time.  In this case,
    fw-core's bus management work and fw-sbp2's login and SCSI probe work
    are scheduled in parallel (in the globally shared workqueue and in
    fw-sbp2's workqueue, respectively).  The bus reset from fw-core may then
    disturb and extremely delay the login and SCSI probe because the latter
    fails with several command timeouts and retries and has to be retried
    from scratch.
    
    We avoid this particular situation of sbp2_login() and fw_card_bm_work()
    running in parallel by delaying the first sbp2_login() a little bit.
    
    This is meant to be a short-term fix for
    https://bugzilla.redhat.com/show_bug.cgi?id=466679.  In the long run,
    the SCSI probe, i.e. fw-sbp2's call of __scsi_add_device(), should be
    parallelized with sbp2_reconnect().
    
    Problem reported and fix tested and confirmed by Alex Kanavin.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index ef0b9b4..17bf0e1 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -1147,7 +1147,7 @@ static int sbp2_probe(struct device *dev)
 
 	/* 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);
+		sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
 	return 0;
 
  fail_tgt_put:

commit 7007a0765e33bf89182e069e35ec6009fa54f610
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sun Oct 26 09:50:31 2008 +0100

    firewire: fw-ohci: initialization failure path fixes
    
    Fix leaks when pci_probe fails.  Simplify error log strings.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 5a5685f..8e16bfb 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -2365,8 +2365,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 
 	ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
 	if (ohci == NULL) {
-		fw_error("Could not malloc fw_ohci data.\n");
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto fail;
 	}
 
 	fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev);
@@ -2375,7 +2375,7 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 
 	err = pci_enable_device(dev);
 	if (err) {
-		fw_error("Failed to enable OHCI hardware.\n");
+		fw_error("Failed to enable OHCI hardware\n");
 		goto fail_free;
 	}
 
@@ -2443,9 +2443,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 	ohci->ir_context_list = kzalloc(size, GFP_KERNEL);
 
 	if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) {
-		fw_error("Out of memory for it/ir contexts.\n");
 		err = -ENOMEM;
-		goto fail_registers;
+		goto fail_contexts;
 	}
 
 	/* self-id dma buffer allocation */
@@ -2454,9 +2453,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 					       &ohci->self_id_bus,
 					       GFP_KERNEL);
 	if (ohci->self_id_cpu == NULL) {
-		fw_error("Out of memory for self ID buffer.\n");
 		err = -ENOMEM;
-		goto fail_registers;
+		goto fail_contexts;
 	}
 
 	bus_options = reg_read(ohci, OHCI1394_BusOptions);
@@ -2476,9 +2474,13 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  fail_self_id:
 	dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE,
 			  ohci->self_id_cpu, ohci->self_id_bus);
- fail_registers:
-	kfree(ohci->it_context_list);
+ fail_contexts:
 	kfree(ohci->ir_context_list);
+	kfree(ohci->it_context_list);
+	context_release(&ohci->at_response_ctx);
+	context_release(&ohci->at_request_ctx);
+	ar_context_release(&ohci->ar_response_ctx);
+	ar_context_release(&ohci->ar_request_ctx);
 	pci_iounmap(dev, ohci->registers);
  fail_iomem:
 	pci_release_region(dev, 0);
@@ -2487,6 +2489,9 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  fail_free:
 	kfree(&ohci->card);
 	ohci_pmac_off(dev);
+ fail:
+	if (err == -ENOMEM)
+		fw_error("Out of memory\n");
 
 	return err;
 }

commit a55709ba9d27053471f9fca8ee76b41ecefc14cd
Author: Jay Fenlason <fenlason@redhat.com>
Date:   Wed Oct 22 15:59:42 2008 -0400

    firewire: fw-ohci: don't leak dma memory on module removal
    
    The transmit and receive context dma memory was not being freed on
    module removal.  Neither was the config rom memory.  Fix that.
    
    The ab->next assignment is pure paranoia.
    
    Signed-off-by: Jay Fenlason <fenlason@redhat.com>
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 251416f..5a5685f 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -476,6 +476,7 @@ static int ar_context_add_page(struct ar_context *ctx)
 	if (ab == NULL)
 		return -ENOMEM;
 
+	ab->next = NULL;
 	memset(&ab->descriptor, 0, sizeof(ab->descriptor));
 	ab->descriptor.control        = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
 						    DESCRIPTOR_STATUS |
@@ -496,6 +497,21 @@ static int ar_context_add_page(struct ar_context *ctx)
 	return 0;
 }
 
+static void ar_context_release(struct ar_context *ctx)
+{
+	struct ar_buffer *ab, *ab_next;
+	size_t offset;
+	dma_addr_t ab_bus;
+
+	for (ab = ctx->current_buffer; ab; ab = ab_next) {
+		ab_next = ab->next;
+		offset = offsetof(struct ar_buffer, data);
+		ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
+		dma_free_coherent(ctx->ohci->card.device, PAGE_SIZE,
+				  ab, ab_bus);
+	}
+}
+
 #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
 #define cond_le32_to_cpu(v) \
 	(ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v))
@@ -2491,8 +2507,19 @@ static void pci_remove(struct pci_dev *dev)
 
 	software_reset(ohci);
 	free_irq(dev->irq, ohci);
+
+	if (ohci->next_config_rom && ohci->next_config_rom != ohci->config_rom)
+		dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
+				  ohci->next_config_rom, ohci->next_config_rom_bus);
+	if (ohci->config_rom)
+		dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
+				  ohci->config_rom, ohci->config_rom_bus);
 	dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE,
 			  ohci->self_id_cpu, ohci->self_id_bus);
+	ar_context_release(&ohci->ar_request_ctx);
+	ar_context_release(&ohci->ar_response_ctx);
+	context_release(&ohci->at_request_ctx);
+	context_release(&ohci->at_response_ctx);
 	kfree(ohci->it_context_list);
 	kfree(ohci->ir_context_list);
 	pci_iounmap(dev, ohci->registers);

commit 77e557191701afa55ae7320d42ad6458a2ad292e
Author: Jay Fenlason <fenlason@redhat.com>
Date:   Thu Oct 16 18:00:15 2008 -0400

    firewire: fix struct fw_node memory leak
    
    With the bus_resets patch applied, it is easy to see this memory leak
    by repeatedly resetting the firewire bus while running slabtop in
    another window.  Just watch kmalloc-32 grow and grow...
    
    Signed-off-by: Jay Fenlason <fenlason@redhat.com>
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index c1b8107..5e20471 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -413,7 +413,7 @@ static void
 update_tree(struct fw_card *card, struct fw_node *root)
 {
 	struct list_head list0, list1;
-	struct fw_node *node0, *node1;
+	struct fw_node *node0, *node1, *next1;
 	int i, event;
 
 	INIT_LIST_HEAD(&list0);
@@ -485,7 +485,9 @@ update_tree(struct fw_card *card, struct fw_node *root)
 		}
 
 		node0 = fw_node(node0->link.next);
-		node1 = fw_node(node1->link.next);
+		next1 = fw_node(node1->link.next);
+		fw_node_put(node1);
+		node1 = next1;
 	}
 }
 

commit 4f9740d4f5a17fa6a1b097fa3ccdfb7246660307
Author: Jay Fenlason <fenlason@redhat.com>
Date:   Thu Oct 16 15:51:59 2008 -0400

    firewire: Survive more than 256 bus resets
    
    The "color" is used during the topology building after a bus reset,
    hovever in "struct fw_node"s it is stored in a u8, but in struct fw_card
    it is stored in an int.  When the value wraps in one struct, but not
    the other, disaster strikes.
    
    Signed-off-by: Jay Fenlason <fenlason@redhat.com>
    
    Fixes http://bugzilla.kernel.org/show_bug.cgi?id=10922.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index 027f58c..aed7dbb 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -248,7 +248,7 @@ struct fw_card {
 	struct fw_node *local_node;
 	struct fw_node *root_node;
 	struct fw_node *irm_node;
-	int color;
+	u8 color; /* must be u8 to match the definition in struct fw_node */
 	int gap_count;
 	bool beta_repeaters_present;
 


Thanks,
-- 
Stefan Richter
-=====-==--- =-=- ==-==
http://arcgraph.de/sr/


^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [git pull] FireWire updates
@ 2008-07-25 18:31 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2008-07-25 18:31 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive a few FireWire subsystem fixes.

JiSheng Zhang (1):
      firewire: queue the right number of data

Stefan Richter (7):
      firewire: fix race of bus reset with request transmission
      firewire: fully initialize fw_transaction before marking it pending
      firewire: small fw_fill_request cleanup
      firewire: warn on unfinished transactions during card removal
      firewire: fw-ohci: TSB43AB22/A dualbuffer workaround
      firewire: avoid memleak after phy config transmit failure
      firewire: state userland requirements in Kconfig help

 drivers/firewire/Kconfig          |    9 +++-
 drivers/firewire/fw-card.c        |    2 +-
 drivers/firewire/fw-cdev.c        |    6 +-
 drivers/firewire/fw-ohci.c        |   37 +++++++++-----
 drivers/firewire/fw-topology.c    |    2 -
 drivers/firewire/fw-transaction.c |   79 +++++++++++------------------
 include/linux/pci_ids.h           |    1 +
 7 files changed, 66 insertions(+), 70 deletions(-)

Thanks,
-- 
Stefan Richter
-=====-==--- -=== ==--=
http://arcgraph.de/sr/


^ permalink raw reply	[flat|nested] 17+ messages in thread
* [GIT PULL] firewire updates
@ 2008-06-20 15:13 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2008-06-20 15:13 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following FireWire subsystem updates.
They fix a post 2.6.25 regression and an older panicking bug.

They also reword and reorder Kconfig menu prompts and help texts.
It's generally better to keep old prompt texts which people are used to
and may be mentioned in external documentation.  But there have been
incidents where not only endusers but even maintainers of one
distribution evidently did not understand the relationship between the
two 1394 stacks.

Shortlog, diffstat, combined diff:

Stefan Richter (9):
      firewire: don't panic on invalid AR request buffer
      firewire: fw-ohci: use of uninitialized data in AR handler
      firewire: fw-ohci: disable PHY packet reception into AR context
      firewire: fw-ohci: write selfIDBufferPtr before LinkControl.rcvSelfID
      firewire: fill_bus_reset_event needs lock protection
      firewire: fw-ohci: unify printk prefixes
      firewire: deadline for PHY config transmission
      firewire: Kconfig menu touch-up
      ieee1394: Kconfig menu touch-up

 drivers/firewire/Kconfig          |   32 ++++----
 drivers/firewire/fw-cdev.c        |    9 ++-
 drivers/firewire/fw-ohci.c        |  110 ++++++++++++++-------------
 drivers/firewire/fw-transaction.c |   52 +++++++++----
 drivers/ieee1394/Kconfig          |  118 ++++++++++++++++-------------
 5 files changed, 180 insertions(+), 141 deletions(-)


commit 9499fe2b340d19ef55c349de794db9d917e7403f
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Mon Jun 16 01:39:28 2008 +0200

    ieee1394: Kconfig menu touch-up
    
    Rename and reorder some prompts and modify some help texts.
    The result:
    
      -------------------- IEEE 1394 (FireWire) support --------------------
      *** Enable only one of the two stacks, unless you know what you are doing ***
      New FireWire stack, EXPERIMENTAL
        OHCI-1394 controllers
        Storage devices (SBP-2 protocol)
      Stable FireWire stack
        OHCI-1394 controllers
        PCILynx controller
        Storage devices (SBP-2 protocol)
          Enable replacement for physical DMA in SBP2
        IP over 1394
        raw1394 userspace interface
        video1394 userspace interface
        dv1394 userspace interface (deprecated)
        Excessive debugging output
    
    The old prompts for reference:
    
      -------------------- IEEE 1394 (FireWire) support --------------------
      IEEE 1394 (FireWire) support - alternative stack, EXPERIMENTAL
        Support for OHCI FireWire host controllers
        Support for storage devices (SBP-2 protocol driver)
      IEEE 1394 (FireWire) support
        *** Subsystem Options ***
        Excessive debugging output
        *** Controllers ***
        Texas Instruments PCILynx support
        OHCI-1394 support
        *** Protocols ***
        OHCI-1394 Video support
        SBP-2 support (Harddisks etc.)
          Enable replacement for physical DMA in SBP2
        IP over 1394
        OHCI-DV I/O support (deprecated)
        Raw IEEE1394 I/O support
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index 545663e..95f45f9 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -4,7 +4,7 @@ menu "IEEE 1394 (FireWire) support"
 source "drivers/firewire/Kconfig"
 
 config IEEE1394
-	tristate "IEEE 1394 (FireWire) support"
+	tristate "Stable FireWire stack"
 	depends on PCI || BROKEN
 	help
 	  IEEE 1394 describes a high performance serial bus, which is also
@@ -19,30 +19,45 @@ config IEEE1394
 	  To compile this driver as a module, say M here: the
 	  module will be called ieee1394.
 
-comment "Subsystem Options"
-	depends on IEEE1394
-
-config IEEE1394_VERBOSEDEBUG
-	bool "Excessive debugging output"
-	depends on IEEE1394
+config IEEE1394_OHCI1394
+	tristate "OHCI-1394 controllers"
+	depends on PCI && IEEE1394
 	help
-	  If you say Y here, you will get very verbose debugging logs from
-	  the subsystem which includes a dump of the header of every sent
-	  and received packet.  This can amount to a high amount of data
-	  collected in a very short time which is usually also saved to
-	  disk by the system logging daemons.
+	  Enable this driver if you have an IEEE 1394 controller based on the
+	  OHCI-1394 specification. The current driver is only tested with OHCI
+	  chipsets made by Texas Instruments and NEC. Most third-party vendors
+	  use one of these chipsets.  It should work with any OHCI-1394
+	  compliant card, however.
 
-	  Say Y if you really want or need the debugging output, everyone
-	  else says N.
+	  To compile this driver as a module, say M here: the
+	  module will be called ohci1394.
 
-comment "Controllers"
-	depends on IEEE1394
+	  NOTE:
 
-comment "Texas Instruments PCILynx requires I2C"
+	  You should only build either ohci1394 or the new firewire-ohci driver,
+	  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.
+
+comment "PCILynx controller requires I2C"
 	depends on IEEE1394 && I2C=n
 
 config IEEE1394_PCILYNX
-	tristate "Texas Instruments PCILynx support"
+	tristate "PCILynx controller"
 	depends on PCI && IEEE1394 && I2C
 	select I2C_ALGOBIT
 	help
@@ -57,35 +72,11 @@ config IEEE1394_PCILYNX
 	  PowerMacs G3 B&W contain the PCILynx controller.  Therefore
 	  almost everybody can say N here.
 
-config IEEE1394_OHCI1394
-	tristate "OHCI-1394 support"
-	depends on PCI && IEEE1394
-	help
-	  Enable this driver if you have an IEEE 1394 controller based on the
-	  OHCI-1394 specification. The current driver is only tested with OHCI
-	  chipsets made by Texas Instruments and NEC. Most third-party vendors
-	  use one of these chipsets.  It should work with any OHCI-1394
-	  compliant card, however.
-
-	  To compile this driver as a module, say M here: the
-	  module will be called ohci1394.
-
-comment "Protocols"
-	depends on IEEE1394
-
-config IEEE1394_VIDEO1394
-	tristate "OHCI-1394 Video support"
-	depends on IEEE1394 && IEEE1394_OHCI1394
-	help
-	  This option enables video device usage for OHCI-1394 cards.  Enable
-	  this option only if you have an IEEE 1394 video device connected to
-	  an OHCI-1394 card.
-
 comment "SBP-2 support (for storage devices) requires SCSI"
 	depends on IEEE1394 && SCSI=n
 
 config IEEE1394_SBP2
-	tristate "SBP-2 support (Harddisks etc.)"
+	tristate "Storage devices (SBP-2 protocol)"
 	depends on IEEE1394 && SCSI
 	help
 	  This option enables you to use SBP-2 devices connected to an IEEE
@@ -127,24 +118,47 @@ config IEEE1394_ETH1394
 
 	  The module is called eth1394 although it does not emulate Ethernet.
 
+config IEEE1394_RAWIO
+	tristate "raw1394 userspace interface"
+	depends on IEEE1394
+	help
+	  This option adds support for the raw1394 device file which enables
+	  direct communication of user programs with IEEE 1394 devices
+	  (isochronous and asynchronous).  Almost all application programs
+	  which access FireWire require this option.
+
+	  To compile this driver as a module, say M here: the module will be
+	  called raw1394.
+
+config IEEE1394_VIDEO1394
+	tristate "video1394 userspace interface"
+	depends on IEEE1394 && IEEE1394_OHCI1394
+	help
+	  This option adds support for the video1394 device files which enable
+	  isochronous communication of user programs with IEEE 1394 devices,
+	  especially video capture or export.  This interface is used by all
+	  libdc1394 based programs and by several other programs, in addition to
+	  the raw1394 interface.  It is generally not required for DV capture.
+
+	  To compile this driver as a module, say M here: the module will be
+	  called video1394.
+
 config IEEE1394_DV1394
-	tristate "OHCI-DV I/O support (deprecated)"
+	tristate "dv1394 userspace interface (deprecated)"
 	depends on IEEE1394 && IEEE1394_OHCI1394
 	help
 	  The dv1394 driver is unsupported and may be removed from Linux in a
 	  future release.  Its functionality is now provided by raw1394 together
 	  with libraries such as libiec61883.
 
-config IEEE1394_RAWIO
-	tristate "Raw IEEE1394 I/O support"
+config IEEE1394_VERBOSEDEBUG
+	bool "Excessive debugging output"
 	depends on IEEE1394
 	help
-	  This option adds support for the raw1394 device file which enables
-	  direct communication of user programs with the IEEE 1394 bus and thus
-	  with the attached peripherals.  Almost all application programs which
-	  access FireWire require this option.
+	  If you say Y here, you will get very verbose debugging logs from the
+	  ieee1394 drivers, including sent and received packet headers.  This
+	  will quickly result in large amounts of data sent to the system log.
 
-	  To compile this driver as a module, say M here: the module will be
-	  called raw1394.
+	  Say Y if you really need the debugging output.  Everyone else says N.
 
 endmenu

commit a7b64b8704b03c9972b114932fdf517e06153f11
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sat Jun 14 14:24:53 2008 +0200

    firewire: Kconfig menu touch-up
    
    Emphasize the recommendation to build only one stack.
    Trim the prompts to better fit into short attention spans.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index fb4d391..76f2671 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -1,28 +1,26 @@
-comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
+comment "A new alternative FireWire stack is available with EXPERIMENTAL=y"
 	depends on EXPERIMENTAL=n
 
+comment "Enable only one of the two stacks, unless you know what you are doing"
+	depends on EXPERIMENTAL
+
 config FIREWIRE
-	tristate "IEEE 1394 (FireWire) support - alternative stack, EXPERIMENTAL"
+	tristate "New FireWire stack, EXPERIMENTAL"
 	depends on EXPERIMENTAL
 	select CRC_ITU_T
 	help
 	  This is the "Juju" FireWire stack, a new alternative implementation
 	  designed for robustness and simplicity.  You can build either this
-	  stack, or the classic stack (the ieee1394 driver, ohci1394 etc.)
-	  or both.  Please read http://wiki.linux1394.org/JujuMigration before
-	  you enable the new stack.
+	  stack, or the old stack (the ieee1394 driver, ohci1394 etc.) or both.
+	  Please read http://wiki.linux1394.org/JujuMigration before you
+	  enable the new stack.
 
 	  To compile this driver as a module, say M here: the module will be
 	  called firewire-core.  It functionally replaces ieee1394, raw1394,
 	  and video1394.
 
-          NOTE:
-
-	  You should only build ONE of the stacks, unless you REALLY know what
-	  you are doing.
-
 config FIREWIRE_OHCI
-	tristate "Support for OHCI FireWire host controllers"
+	tristate "OHCI-1394 controllers"
 	depends on PCI && FIREWIRE
 	help
 	  Enable this driver if you have a FireWire controller based
@@ -33,12 +31,12 @@ config FIREWIRE_OHCI
 	  called firewire-ohci.  It replaces ohci1394 of the classic IEEE 1394
 	  stack.
 
-          NOTE:
+	  NOTE:
 
-	  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
+	  You should only build either firewire-ohci or the old ohci1394 driver,
+	  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
@@ -60,7 +58,7 @@ config FIREWIRE_OHCI_DEBUG
 	default y
 
 config FIREWIRE_SBP2
-	tristate "Support for storage devices (SBP-2 protocol driver)"
+	tristate "Storage devices (SBP-2 protocol)"
 	depends on FIREWIRE && SCSI
 	help
 	  This option enables you to use SBP-2 devices connected to a

commit ae1e53557911d7e60a637b2400173add958aae94
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Wed Jun 18 18:20:45 2008 +0200

    firewire: deadline for PHY config transmission
    
    If the low-level driver failed to initialize a card properly without
    noticing it, fw-core was blocked indefinitely when trying to send a
    PHY config packet.  This hung up the events kernel thread, e.g. locked
    up keyboard input.
    https://bugzilla.redhat.com/show_bug.cgi?id=444694
    https://bugzilla.redhat.com/show_bug.cgi?id=446763
    
    This problem was introduced between 2.6.25 and 2.6.26-rc1 by commit
    2a0a2590498be7b92e3e76409c9b8ee722e23c8f "firewire: wait until PHY
    configuration packet was transmitted (fix bus reset loop)".
    
    The solution is to wait with timeout.  I tested it with 7 different
    working controllers and 1 non-working controller.  On the working ones,
    the packet callback complete()s usually --- but not always --- before a
    timeout of 10ms.  Hence I chose a safer timeout of 100ms.
    
    On the few tests with the non-working controller ALi M5271, PHY config
    packet transmission always timed out so far.  (Fw-ohci needs to be fixed
    for this controller independently of this deadline fix.  Often the core
    doesn't even attempt to send a phy config because not even self ID
    reception works.)
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 7f92c45..03ae8a7 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -20,6 +20,7 @@
 
 #include <linux/completion.h>
 #include <linux/kernel.h>
+#include <linux/kref.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -297,37 +298,55 @@ EXPORT_SYMBOL(fw_send_request);
 struct fw_phy_packet {
 	struct fw_packet packet;
 	struct completion done;
+	struct kref kref;
 };
 
-static void
-transmit_phy_packet_callback(struct fw_packet *packet,
-			     struct fw_card *card, int status)
+static void phy_packet_release(struct kref *kref)
+{
+	struct fw_phy_packet *p =
+			container_of(kref, struct fw_phy_packet, kref);
+	kfree(p);
+}
+
+static void transmit_phy_packet_callback(struct fw_packet *packet,
+					 struct fw_card *card, int status)
 {
 	struct fw_phy_packet *p =
 			container_of(packet, struct fw_phy_packet, packet);
 
 	complete(&p->done);
+	kref_put(&p->kref, phy_packet_release);
 }
 
 void fw_send_phy_config(struct fw_card *card,
 			int node_id, int generation, int gap_count)
 {
-	struct fw_phy_packet p;
+	struct fw_phy_packet *p;
+	long timeout = DIV_ROUND_UP(HZ, 10);
 	u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) |
 		   PHY_CONFIG_ROOT_ID(node_id) |
 		   PHY_CONFIG_GAP_COUNT(gap_count);
 
-	p.packet.header[0] = data;
-	p.packet.header[1] = ~data;
-	p.packet.header_length = 8;
-	p.packet.payload_length = 0;
-	p.packet.speed = SCODE_100;
-	p.packet.generation = generation;
-	p.packet.callback = transmit_phy_packet_callback;
-	init_completion(&p.done);
-
-	card->driver->send_request(card, &p.packet);
-	wait_for_completion(&p.done);
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	if (p == NULL)
+		return;
+
+	p->packet.header[0] = data;
+	p->packet.header[1] = ~data;
+	p->packet.header_length = 8;
+	p->packet.payload_length = 0;
+	p->packet.speed = SCODE_100;
+	p->packet.generation = generation;
+	p->packet.callback = transmit_phy_packet_callback;
+	init_completion(&p->done);
+	kref_set(&p->kref, 2);
+
+	card->driver->send_request(card, &p->packet);
+	timeout = wait_for_completion_timeout(&p->done, timeout);
+	kref_put(&p->kref, phy_packet_release);
+
+	/* will leak p if the callback is never executed */
+	WARN_ON(timeout == 0);
 }
 
 void fw_flush_transactions(struct fw_card *card)

commit 161b96e782ec995c55843101976d9c35b57aa109
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sat Jun 14 14:23:43 2008 +0200

    firewire: fw-ohci: unify printk prefixes
    
    The messages which can be enabled by fw-ohci's debug module parameter
    are changed from KERN_DEBUG to KERN_NOTICE level and uniformly prefixed
    with "firewire_ohci: ".  This further simplifies communication with
    users when we ask them to capture debug messages.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 96e3cce..0b66306 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -265,27 +265,25 @@ static void log_irqs(u32 evt)
 	    !(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"		: "",
-	       evt & OHCI1394_RSPkt		? " AR_resp"		: "",
-	       evt & OHCI1394_reqTxComplete	? " AT_req"		: "",
-	       evt & OHCI1394_respTxComplete	? " AT_resp"		: "",
-	       evt & OHCI1394_isochRx		? " IR"			: "",
-	       evt & OHCI1394_isochTx		? " IT"			: "",
-	       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_regAccessFail | OHCI1394_busReset)
+	fw_notify("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"		: "",
+	    evt & OHCI1394_RSPkt		? " AR_resp"		: "",
+	    evt & OHCI1394_reqTxComplete	? " AT_req"		: "",
+	    evt & OHCI1394_respTxComplete	? " AT_resp"		: "",
+	    evt & OHCI1394_isochRx		? " IR"			: "",
+	    evt & OHCI1394_isochTx		? " IT"			: "",
+	    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_regAccessFail | OHCI1394_busReset)
 						? " ?"			: "");
 }
 
@@ -308,23 +306,22 @@ 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, "
-	       "local node ID %04x\n", self_id_count, generation, node_id);
+	fw_notify("%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)
-			printk(KERN_DEBUG "selfID 0: %08x, phy %d [%c%c%c] "
-			       "%s gc=%d %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" : "");
+			fw_notify("selfID 0: %08x, phy %d [%c%c%c] "
+			    "%s gc=%d %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" : "");
 		else
-			printk(KERN_DEBUG "selfID n: %08x, phy %d "
-			       "[%c%c%c%c%c%c%c%c]\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));
+			fw_notify("selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\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));
 }
 
 static const char *evts[] = {
@@ -373,15 +370,14 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
 			evt = 0x1f;
 
 	if (evt == OHCI1394_evt_bus_reset) {
-		printk(KERN_DEBUG "A%c evt_bus_reset, generation %d\n",
-		       dir, (header[2] >> 16) & 0xff);
+		fw_notify("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],
-		       header[0]);
+		fw_notify("A%c %s, %s, %08x\n",
+		    dir, evts[evt], phys[header[0] >> 30 & 0x3], header[0]);
 		return;
 	}
 
@@ -400,24 +396,23 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
 
 	switch (tcode) {
 	case 0xe: case 0xa:
-		printk(KERN_DEBUG "A%c %s, %s\n",
-		       dir, evts[evt], tcodes[tcode]);
+		fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]);
 		break;
 	case 0x0: case 0x1: case 0x4: case 0x5: case 0x9:
-		printk(KERN_DEBUG "A%c spd %x tl %02x, "
-		       "%04x -> %04x, %s, "
-		       "%s, %04x%08x%s\n",
-		       dir, speed, header[0] >> 10 & 0x3f,
-		       header[1] >> 16, header[0] >> 16, evts[evt],
-		       tcodes[tcode], header[1] & 0xffff, header[2], specific);
+		fw_notify("A%c spd %x tl %02x, "
+		    "%04x -> %04x, %s, "
+		    "%s, %04x%08x%s\n",
+		    dir, speed, header[0] >> 10 & 0x3f,
+		    header[1] >> 16, header[0] >> 16, evts[evt],
+		    tcodes[tcode], header[1] & 0xffff, header[2], specific);
 		break;
 	default:
-		printk(KERN_DEBUG "A%c spd %x tl %02x, "
-		       "%04x -> %04x, %s, "
-		       "%s%s\n",
-		       dir, speed, header[0] >> 10 & 0x3f,
-		       header[1] >> 16, header[0] >> 16, evts[evt],
-		       tcodes[tcode], specific);
+		fw_notify("A%c spd %x tl %02x, "
+		    "%04x -> %04x, %s, "
+		    "%s%s\n",
+		    dir, speed, header[0] >> 10 & 0x3f,
+		    header[1] >> 16, header[0] >> 16, evts[evt],
+		    tcodes[tcode], specific);
 	}
 }
 

commit 5cb84067d646fa3889463129dad8b218806b4698
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Fri Jun 6 22:11:30 2008 +0200

    firewire: fill_bus_reset_event needs lock protection
    
    Callers of fill_bus_reset_event() have to take card->lock.  Otherwise
    access to node data may oops if node removal is in progress.
    
    A lockless alternative would be
    
    -	event->local_node_id = card->local_node->node_id;
    +	tmp = fw_node_get(card->local_node);
    +	event->local_node_id = tmp->node_id;
    +	fw_node_put(tmp);
    
    and ditto with the other node pointers which fill_bus_reset_event()
    accesses.  But I went the locked route because one of the two callers
    already holds the lock.  As a bonus, we don't need the memory barrier
    anymore because device->generation and device->node_id are written in
    a card->lock protected section.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
    Signed-off-by: Kristian Høgsberg <krh@redhat.com>

diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index dda1401..c639915 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -205,6 +205,7 @@ fw_device_op_read(struct file *file,
 	return dequeue_event(client, buffer, count);
 }
 
+/* caller must hold card->lock so that node pointers can be dereferenced here */
 static void
 fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
 		     struct client *client)
@@ -214,7 +215,6 @@ fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
 	event->closure	     = client->bus_reset_closure;
 	event->type          = FW_CDEV_EVENT_BUS_RESET;
 	event->generation    = client->device->generation;
-	smp_rmb();           /* node_id must not be older than generation */
 	event->node_id       = client->device->node_id;
 	event->local_node_id = card->local_node->node_id;
 	event->bm_node_id    = 0; /* FIXME: We don't track the BM. */
@@ -274,6 +274,7 @@ 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;
+	struct fw_card *card = client->device->card;
 	unsigned long ret = 0;
 
 	client->version = get_info->version;
@@ -299,13 +300,17 @@ static int ioctl_get_info(struct client *client, void *buffer)
 	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);
+		unsigned long flags;
 
+		spin_lock_irqsave(&card->lock, flags);
 		fill_bus_reset_event(&bus_reset, client);
+		spin_unlock_irqrestore(&card->lock, flags);
+
 		if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset)))
 			return -EFAULT;
 	}
 
-	get_info->card = client->device->card->index;
+	get_info->card = card->index;
 
 	return 0;
 }

commit affc9c24ade666f9903163c12686da567dbfe06f
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Thu Jun 5 20:50:53 2008 +0200

    firewire: fw-ohci: write selfIDBufferPtr before LinkControl.rcvSelfID
    
    OHCI 1.1 clause 5.10 requires that selfIDBufferPtr is valid when a 1 is
    written into LinkControl.rcvSelfID.
    
    This driver bug has so far not been known to cause harm because most
    chips obviously accept a later selfIDBufferPtr write, at least before
    HCControl.linkEnable is written.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
    Signed-off-by: Jarod Wilson <jwilson@redhat.com>
    Signed-off-by: Kristian Høgsberg <krh@redhat.com>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 481d3f3..96e3cce 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -1473,6 +1473,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
 	reg_write(ohci, OHCI1394_HCControlClear,
 		  OHCI1394_HCControl_noByteSwapData);
 
+	reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
 	reg_write(ohci, OHCI1394_LinkControlClear,
 		  OHCI1394_LinkControl_rcvPhyPkt);
 	reg_write(ohci, OHCI1394_LinkControlSet,
@@ -1488,7 +1489,6 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
 	ar_context_run(&ohci->ar_request_ctx);
 	ar_context_run(&ohci->ar_response_ctx);
 
-	reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
 	reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
 	reg_write(ohci, OHCI1394_IntEventClear, ~0);
 	reg_write(ohci, OHCI1394_IntMaskClear, ~0);

commit e896ec4302f45fdaf2fc78aec0093eca5478fe28
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Thu Jun 5 20:49:38 2008 +0200

    firewire: fw-ohci: disable PHY packet reception into AR context
    
    We want the rcvPhyPkt bit in LinkControl off before we start using the
    chip.  However, the spec says that the reset value of it is undefined.
    Hence switch it explicitly off.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=244576#c48 shows that for
    example the nForce2 integrated FireWire controller seems to have it on
    by default.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
    Signed-off-by: Jarod Wilson <jwilson@redhat.com>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index b062e73..481d3f3 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -1473,6 +1473,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
 	reg_write(ohci, OHCI1394_HCControlClear,
 		  OHCI1394_HCControl_noByteSwapData);
 
+	reg_write(ohci, OHCI1394_LinkControlClear,
+		  OHCI1394_LinkControl_rcvPhyPkt);
 	reg_write(ohci, OHCI1394_LinkControlSet,
 		  OHCI1394_LinkControl_rcvSelfID |
 		  OHCI1394_LinkControl_cycleTimerEnable |

commit ccff962943df539c5860aa120eecc189d70a308b
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sat May 31 19:36:06 2008 +0200

    firewire: fw-ohci: use of uninitialized data in AR handler
    
    header_length and payload_length are filled with random data if an
    unknown tcode was read from the AR buffer (i.e. if the AR buffer
    contained invalid data).
    
    We still need a better strategy to recover from this, but at least
    handle_ar_packet now doesn't return out of bound buffer addresses
    anymore.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 4f02c55..b062e73 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -548,6 +548,11 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
 		p.header_length = 12;
 		p.payload_length = 0;
 		break;
+
+	default:
+		/* FIXME: Stop context, discard everything, and restart? */
+		p.header_length = 0;
+		p.payload_length = 0;
 	}
 
 	p.payload = (void *) buffer + p.header_length;

commit 0bf607c5b4edd13362e4add6ca1e81f8a9fbd47c
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sat May 31 19:01:26 2008 +0200

    firewire: don't panic on invalid AR request buffer
    
    BUG() at this place is wrong.  (Unless if the low level driver would
    already do higher-level input validation of incoming request headers.)
    
    Invalid incoming requests or bugs in the controller which corrupt the
    AR-req buffer needlessly crashed the box because this is run in tasklet
    context.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index ccf0e4c..7f92c45 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -572,7 +572,8 @@ allocate_request(struct fw_packet *p)
 		break;
 
 	default:
-		BUG();
+		fw_error("ERROR - corrupt request received - %08x %08x %08x\n",
+			 p->header[0], p->header[1], p->header[2]);
 		return NULL;
 	}
 

-- 
Stefan Richter
-=====-==--- -==- =-=--
http://arcgraph.de/sr/




^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [GIT PULL] FireWire updates post 2.6.24
@ 2008-01-30 22:53 Stefan Richter
  2008-02-02 13:05 ` [GIT PULL] IEEE 1394 regression fix Stefan Richter
  0 siblings, 1 reply; 17+ messages in thread
From: Stefan Richter @ 2008-01-30 22:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andrew Morton, linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following IEEE 1394/ FireWire subsystem updates.  Once
again it is almost all about bug fixes.  Most notable are David Moore's
fixes for isochronous reception which greatly enhance the new firewire
stack's usability in the IIDC domain (uncompressed video from industrial
cameras and webcams).  The storage driver firewire-sbp2 received some
attention too, prompted by user reports, but that's an ongoing story.

I let self-discipline slide this time and added 9 patches which have not
yet been in -mm and were not listed in the "What's in linux1394-2.6.git?"
report from January 17.  Half of those are bug fixes from November which
have been laying around waiting for last touch-up until we noticed in
January that they indeed address a good number of bug reports.  The other
new additions are bug fixes too.  Everything has been intensively tested
with affected and unaffected hardware.

Updated status of the new (still EXPERIMENTAL) drivers/firewire
subsystem:
  - integration with userspace libraries still with rough edges,
  - DV reception broken on OHCI 1.0 variants of VIA VT630x,
  - IP over 1394 still not implemented/ ported,
  - SBP-2 (storage) fragile during hotplugging on some setups.

Before distributors of kernel packages consider to enable the new
firewire drivers in parallel or instead of the classic ieee1394 drivers,
we ask that they first read up about all the caveats of the new drivers
at wiki.linux1394.org which we regularly update.

I will re-post the newly added patches in a reply.  Stat and shortlog of
the entire queue:

 MAINTAINERS                              |    4 +-
 drivers/firewire/fw-cdev.c               |    3 +-
 drivers/firewire/fw-device.c             |   38 ++-
 drivers/firewire/fw-device.h             |   12 +
 drivers/firewire/fw-ohci.c               |  390 +++++++++++++---------
 drivers/firewire/fw-sbp2.c               |  127 +++++---
 drivers/firewire/fw-topology.c           |    6 +
 drivers/firewire/fw-transaction.c        |    4 +-
 drivers/ieee1394/dma.c                   |   39 +--
 drivers/ieee1394/ieee1394_transactions.c |   68 ----
 drivers/ieee1394/ohci1394.c              |   12 +-
 drivers/ieee1394/raw1394.c               |    4 +-
 drivers/ieee1394/sbp2.c                  |   52 ++--
 drivers/ieee1394/sbp2.h                  |    1 -
 14 files changed, 424 insertions(+), 336 deletions(-)

David Moore (3):
      firewire: fw-ohci: Fix for dualbuffer three-or-more buffers
      firewire: fw-ohci: Bug fixes for packet-per-buffer support
      firewire: fw-ohci: Dynamically allocate buffers for DMA descriptors

Jarod Wilson (3):
      firewire: replace subtraction with bitwise and
      firewire: fw-sbp2: increase login orb reply timeout, fix "failed to login"
      firewire: fw-sbp2: Use sbp2 device-provided mgt orb timeout for logins

Joe Perches (1):
      ieee1394: Add missing "space"

Nick Piggin (1):
      ieee1394: nopage

Rabin Vincent (1):
      firewire: Fix extraction of source node id

Stefan Richter (17):
      ieee1394: sbp2: prepare for s/g chaining
      ieee1394: sbp2: s/g list access cosmetics
      ieee1394: small cleanup after "nopage"
      ieee1394: remove unused code
      ieee1394: sbp2: raise default transfer size limit
      ieee1394: ohci1394: don't schedule IT tasklets on IR events
      firewire: fw-sbp2: refactor workq and kref handling
      firewire: fw-sbp2: prepare for s/g chaining
      firewire: fw-sbp2: remove unused misleading macro
      firewire: fw-ohci: CycleTooLong interrupt management
      firewire vs. ieee1394: clarify MAINTAINERS
      firewire: fw-sbp2: skip unnecessary logout
      firewire: fw-sbp2: try to increase reconnect_hold (speed up reconnection)
      firewire: fw-sbp2: use device generation, not card generation
      firewire: fw-cdev: use device generation, not card generation
      firewire: enforce access order between generation and node ID, fix "giving up on config rom"
      firewire: fw-core: react on bus resets while the config ROM is being fetched

-- 
Stefan Richter
-=====-==--- ---= ====-
http://arcgraph.de/sr/


^ permalink raw reply	[flat|nested] 17+ messages in thread
* [GIT PULL] FireWire updates
@ 2007-10-31 18:24 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2007-10-31 18:24 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andrew Morton, linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following FireWire/ IEEE 1394 subsystem updates.
The bigger portion of this has been in -mm for a long time, held up by
another now fixed bug.

 drivers/firewire/fw-ohci.c               |   37 +++++++++++++++-------
 drivers/ieee1394/ieee1394_transactions.c |    2 -
 2 files changed, 25 insertions(+), 14 deletions(-)

Adrian Bunk (1):
      ieee1394: ieee1394_transactions.c: remove dead code

Kristian Høgsberg (1):
      firewire: Fix pci resume to not pass in a __be32 config rom.


Full log and diff:

commit 2ed45b07c957e37db88d7d3696b63eb79b0ef5ef
Author: Adrian Bunk <bunk@kernel.org>
Date:   Sun Oct 28 16:51:32 2007 +0100

    ieee1394: ieee1394_transactions.c: remove dead code
    
    This patch removes dead code spotted by the Intel C Compiler.
    
    Signed-off-by: Adrian Bunk <bunk@kernel.org>
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index c39c70a..6779893 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -235,7 +235,6 @@ int hpsb_packet_success(struct hpsb_packet *packet)
 				 packet->node_id);
 			return -EAGAIN;
 		}
-		BUG();
 
 	case ACK_BUSY_X:
 	case ACK_BUSY_A:
@@ -282,7 +281,6 @@ int hpsb_packet_success(struct hpsb_packet *packet)
 			 packet->ack_code, packet->node_id, packet->tcode);
 		return -EAGAIN;
 	}
-	BUG();
 }
 
 struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,

commit 0bd243c4d93583cd8e1786c0bd6982f6f9f94ab6
Author: Kristian Høgsberg <krh@redhat.com>
Date:   Tue Jun 5 19:27:05 2007 -0400

    firewire: Fix pci resume to not pass in a __be32 config rom.
    
    The ohci_enable() function shared between pci_probe and pci_resume
    takes a host endian config rom, but ohci->config_rom is __be32.  This
    sets up the config rom in the wrong endian on little endian machine,
    specifically, BusOptions will be initialized to a 0 max receive size.
    
    This patch changes the way we reuse the config rom so that we avoid
    this problem.
    
    Signed-off-by: Kristian Hoegsberg <krh@redhat.com>
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 6758832..c9b9081 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -984,8 +984,10 @@ static void bus_reset_tasklet(unsigned long data)
 	 */
 
 	if (ohci->next_config_rom != NULL) {
-		free_rom     = ohci->config_rom;
-		free_rom_bus = ohci->config_rom_bus;
+		if (ohci->next_config_rom != ohci->config_rom) {
+			free_rom      = ohci->config_rom;
+			free_rom_bus  = ohci->config_rom_bus;
+		}
 		ohci->config_rom      = ohci->next_config_rom;
 		ohci->config_rom_bus  = ohci->next_config_rom_bus;
 		ohci->next_config_rom = NULL;
@@ -1161,19 +1163,30 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
 	 * the right values in the bus reset tasklet.
 	 */
 
-	ohci->next_config_rom =
-		dma_alloc_coherent(ohci->card.device, CONFIG_ROM_SIZE,
-				   &ohci->next_config_rom_bus, GFP_KERNEL);
-	if (ohci->next_config_rom == NULL)
-		return -ENOMEM;
+	if (config_rom) {
+		ohci->next_config_rom =
+			dma_alloc_coherent(ohci->card.device, CONFIG_ROM_SIZE,
+					   &ohci->next_config_rom_bus,
+					   GFP_KERNEL);
+		if (ohci->next_config_rom == NULL)
+			return -ENOMEM;
 
-	memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE);
-	fw_memcpy_to_be32(ohci->next_config_rom, config_rom, length * 4);
+		memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE);
+		fw_memcpy_to_be32(ohci->next_config_rom, config_rom, length * 4);
+	} else {
+		/*
+		 * In the suspend case, config_rom is NULL, which
+		 * means that we just reuse the old config rom.
+		 */
+		ohci->next_config_rom = ohci->config_rom;
+		ohci->next_config_rom_bus = ohci->config_rom_bus;
+	}
 
-	ohci->next_header = config_rom[0];
+	ohci->next_header = be32_to_cpu(ohci->next_config_rom[0]);
 	ohci->next_config_rom[0] = 0;
 	reg_write(ohci, OHCI1394_ConfigROMhdr, 0);
-	reg_write(ohci, OHCI1394_BusOptions, config_rom[2]);
+	reg_write(ohci, OHCI1394_BusOptions,
+		  be32_to_cpu(ohci->next_config_rom[2]));
 	reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus);
 
 	reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);
@@ -1984,7 +1997,7 @@ static int pci_resume(struct pci_dev *pdev)
 		return err;
 	}
 
-	return ohci_enable(&ohci->card, ohci->config_rom, CONFIG_ROM_SIZE);
+	return ohci_enable(&ohci->card, NULL, 0);
 }
 #endif
 

-- 
Stefan Richter
-=====-=-=== =-=- =====
http://arcgraph.de/sr/


^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [GIT PULL] FireWire updates
@ 2007-10-22 18:25 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2007-10-22 18:25 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andrew Morton, linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following FireWire subsystem updates.
They have not been in -mm but they are trivial.

 drivers/firewire/fw-ohci.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

Stefan Richter (2):
      firewire: fw-ohci: log a note about unsupported features
      firewire: fw-ohci: shut up a superfluous compiler warning


Full log and diff:

commit 4b6d51ec62d9c57432430528d6293605794a9f1b
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sun Oct 21 11:20:07 2007 +0200

    firewire: fw-ohci: shut up a superfluous compiler warning
    
    New warning since commit ab88ca488b8af66c3defa165874e81e695319a19,
    "firewire: fw-ohci: missing dma_unmap_single":
    drivers/firewire/fw-ohci.c: In function 'at_context_transmit':
    drivers/firewire/fw-ohci.c:609: warning: 'payload_bus' may be used
     uninitialized in this function
    
    Access to payload_bus is conditional on packet->payload_length > 0,
    and that won't change while in at_context_queue_packet.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index e4b9a7d..6758832 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -606,7 +606,7 @@ static int
 at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
 {
 	struct fw_ohci *ohci = ctx->ohci;
-	dma_addr_t d_bus, payload_bus;
+	dma_addr_t d_bus, uninitialized_var(payload_bus);
 	struct driver_data *driver_data;
 	struct descriptor *d, *last;
 	__le32 *header;

commit c74e92c209cf30ae6003e042e7c017eb6c370b64
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date:   Sun Oct 21 10:43:11 2007 +0200

    firewire: fw-ohci: log a note about unsupported features
    
    because there seems to be more time needed to implement this.
    Also, change related error return values to more appropriate ones.
    
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 2f307c4..e4b9a7d 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -1459,7 +1459,7 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
 	/* FIXME: We need a fallback for pre 1.1 OHCI. */
 	if (callback == handle_ir_dualbuffer_packet &&
 	    ohci->version < OHCI_VERSION_1_1)
-		return ERR_PTR(-EINVAL);
+		return ERR_PTR(-ENOSYS);
 
 	spin_lock_irqsave(&ohci->lock, flags);
 	index = ffs(*mask) - 1;
@@ -1778,7 +1778,7 @@ ohci_queue_iso(struct fw_iso_context *base,
 							 buffer, payload);
 	else
 		/* FIXME: Implement fallback for OHCI 1.0 controllers. */
-		return -EINVAL;
+		return -ENOSYS;
 }
 
 static const struct fw_card_driver ohci_driver = {
@@ -1898,7 +1898,12 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
 	ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
 	fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n",
 		  dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff);
-
+	if (ohci->version < OHCI_VERSION_1_1) {
+		fw_notify("    Isochronous I/O is not yet implemented for "
+			  "OHCI 1.0 chips.\n");
+		fw_notify("    Cameras, audio devices etc. won't work on "
+			  "this controller with this driver version.\n");
+	}
 	return 0;
 
  fail_self_id:

-- 
Stefan Richter
-=====-=-=== =-=- =-==-
http://arcgraph.de/sr/


^ permalink raw reply related	[flat|nested] 17+ messages in thread
[parent not found: <tkrat.f5ba2b840fcda9e5@s5r6.in-berlin.de>]
* [GIT PULL] FireWire updates
@ 2007-07-09 22:41 Stefan Richter
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Richter @ 2007-07-09 22:41 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux1394-devel

Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive the following updates.  They have been in -mm for a while,
except for one or another smaller patch and the legacy ABI removal.

What's in there:
  - smaller fixes in the new firewire drivers
  - raw1394 now almost entirely fit for 32bit userland on 64bit kernel
  - removal of ABI parts of raw1394 that have been obsolete for years
  - ieee1394 converted away from class_device
  - a cleanup of ieee1394's nodemgr locks which was held back a little by
    driver core related changes in the last rounds
  - small cleanups

Diffstat and shortlog:

 .../ABI/removed/raw1394_legacy_isochronous         |   16 +
 Documentation/feature-removal-schedule.txt         |   10 -
 drivers/firewire/fw-card.c                         |    7 +-
 drivers/firewire/fw-cdev.c                         |    2 +-
 drivers/firewire/fw-device.c                       |   38 ++-
 drivers/firewire/fw-device.h                       |    1 +
 drivers/firewire/fw-ohci.c                         |    6 +-
 drivers/firewire/fw-sbp2.c                         |  117 ++--
 drivers/firewire/fw-topology.c                     |   66 +--
 drivers/firewire/fw-topology.h                     |   25 +-
 drivers/firewire/fw-transaction.h                  |    3 +-
 drivers/ieee1394/dv1394.c                          |    8 +-
 drivers/ieee1394/eth1394.c                         |    4 +-
 drivers/ieee1394/highlevel.c                       |   45 --
 drivers/ieee1394/highlevel.h                       |   16 +-
 drivers/ieee1394/hosts.c                           |   11 +-
 drivers/ieee1394/hosts.h                           |   10 +-
 drivers/ieee1394/ieee1394_core.c                   |    8 -
 drivers/ieee1394/ieee1394_core.h                   |   15 +-
 drivers/ieee1394/ieee1394_transactions.c           |   30 -
 drivers/ieee1394/ieee1394_transactions.h           |    2 -
 drivers/ieee1394/nodemgr.c                         |  185 ++++---
 drivers/ieee1394/nodemgr.h                         |    4 +-
 drivers/ieee1394/ohci1394.c                        |  272 +--------
 drivers/ieee1394/ohci1394.h                        |   14 -
 drivers/ieee1394/pcilynx.c                         |   16 +-
 drivers/ieee1394/raw1394-private.h                 |    5 -
 drivers/ieee1394/raw1394.c                         |  364 +++++-------
 drivers/ieee1394/raw1394.h                         |    4 +-
 drivers/ieee1394/sbp2.c                            |   15 +-
 drivers/ieee1394/sbp2.h                            |    2 +-
 drivers/ieee1394/video1394.c                       |   10 +-
 include/linux/firewire-cdev.h                      |  297 ++++++++-
 33 files changed, 745 insertions(+), 883 deletions(-)
 create mode 100644 Documentation/ABI/removed/raw1394_legacy_isochronous


Jay Fenlason (1):
      firewire: fw-sbp2: correctly dereference by container_of

Kay Sievers (1):
      ieee1394: convert ieee1394 from "struct class_device" to "struct device"

Kristian Høgsberg (1):
      firewire: Document userspace ioctl interface.

Petr Vandrovec (3):
      ieee1394: raw1394: Fix read() for 32bit userland on 64bit kernel
      ieee1394: raw1394: Fix write() for 32bit userland on 64bit kernel
      ieee1394: raw1394: Add ioctl() for 32bit userland on 64bit kernel

Stefan Richter (25):
      ieee1394: ohci1394: remove dead CONFIG variable
      ieee1394: add comments in struct hpsb_packet
      ieee1394: raw1394: Add ioctl() for 32bit userland on 64bit kernel, amendment
      ieee1394: raw1394: fix a 32/64-bits compat fix
      ieee1394: nodemgr: parallelize between several hosts
      ieee1394: eth1394: revert parent device to that in 2.6.20
      ieee1394: first minimal NUMA awareness
      ieee1394: sbp2: change some module parameters from int to bool
      ieee1394: remove old isochronous ABI
      firewire: fw-sbp2: remove unused struct member
      firewire: missing newline in printk
      firewire: remove unused macro
      firewire: optimize gap count with 1394b leaf nodes
      firewire: support S100B...S400B and link slower than PHY
      firewire: simplify a struct type
      firewire: fw-sbp2: implement max sectors limit for some old bridges
      firewire: fw-sbp2: let SCSI shutdown commands through before logout
      firewire: fw-sbp2: implement nonexclusive login
      firewire: fw-sbp2: use correct speed in sbp2_agent_reset
      firewire: fw-sbp2: memset wants string.h
      firewire: fw-sbp2: correctly align page tables
      firewire: fw-sbp2: add a boundary check
      firewire: fw-sbp2: fix DMA mapping of S/G tables
      firewire: fw-sbp2: fix DMA mapping of command ORBs
      firewire: fw-sbp2: fix DMA mapping of management ORBs
-- 
Stefan Richter
-=====-=-=== -=== -=-=-
http://arcgraph.de/sr/


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2009-10-14 21:28 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-04 20:49 [git pull] FireWire updates Stefan Richter
  -- strict thread matches above, loose matches on Subject: below --
2009-10-14 21:26 Stefan Richter
2009-02-06 14:58 Stefan Richter
2009-01-29 20:52 Stefan Richter
2008-10-27 16:25 Stefan Richter
2008-07-25 18:31 Stefan Richter
2008-06-20 15:13 [GIT PULL] firewire updates Stefan Richter
2008-01-30 22:53 [GIT PULL] FireWire updates post 2.6.24 Stefan Richter
2008-02-02 13:05 ` [GIT PULL] IEEE 1394 regression fix Stefan Richter
2008-02-25 17:58   ` [GIT PULL] FireWire updates Stefan Richter
2008-02-25 18:00     ` Stefan Richter
2008-03-02 12:47     ` Stefan Richter
2008-03-02 12:49       ` Stefan Richter
2008-03-14 18:07       ` Stefan Richter
2008-03-14 18:08         ` Stefan Richter
2007-10-31 18:24 Stefan Richter
2007-10-22 18:25 Stefan Richter
     [not found] <tkrat.f5ba2b840fcda9e5@s5r6.in-berlin.de>
2007-07-18 22:26 ` Stefan Richter
2007-07-09 22:41 Stefan Richter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).