LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] firewire: replace static ROM cache by allocated cache
@ 2008-03-02 18:35 Stefan Richter
  2008-03-03  0:48 ` [PATCH] firewire: reread config ROM when device reset the bus Stefan Richter
  0 siblings, 1 reply; 14+ messages in thread
From: Stefan Richter @ 2008-03-02 18:35 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel

read_bus_info_block() is repeatedly called by workqueue jobs.
These will step on each others toes eventually if there are multiple
workqueue threads, and we end up with corrupt config ROM images.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
 drivers/firewire/fw-device.c |   41 +++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 14 deletions(-)

Index: linux/drivers/firewire/fw-device.c
===================================================================
--- linux.orig/drivers/firewire/fw-device.c
+++ linux/drivers/firewire/fw-device.c
@@ -400,6 +400,9 @@ read_rom(struct fw_device *device, int g
 	return callback_data.rcode;
 }
 
+#define READ_BIB_ROM_SIZE	256
+#define READ_BIB_STACK_SIZE	16
+
 /*
  * Read the bus info block, perform a speed probe, and read all of the rest of
  * the config ROM.  We do all this with a cached bus generation.  If the bus
@@ -409,16 +412,23 @@ read_rom(struct fw_device *device, int g
  */
 static int read_bus_info_block(struct fw_device *device, int generation)
 {
-	static u32 rom[256];
-	u32 stack[16], sp, key;
-	int i, end, length;
+	u32 *rom, *stack;
+	u32 sp, key;
+	int i, end, length, ret = -1;
+
+	rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE +
+		      sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL);
+	if (rom == NULL)
+		return -ENOMEM;
+
+	stack = &rom[READ_BIB_ROM_SIZE];
 
 	device->max_speed = SCODE_100;
 
 	/* First read the bus info block. */
 	for (i = 0; i < 5; i++) {
 		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
-			return -1;
+			goto out;
 		/*
 		 * As per IEEE1212 7.2, during power-up, devices can
 		 * reply with a 0 for the first quadlet of the config
@@ -428,7 +438,7 @@ static int read_bus_info_block(struct fw
 		 * retry mechanism will try again later.
 		 */
 		if (i == 0 && rom[i] == 0)
-			return -1;
+			goto out;
 	}
 
 	device->max_speed = device->node->max_speed;
@@ -478,26 +488,26 @@ static int read_bus_info_block(struct fw
 		 */
 		key = stack[--sp];
 		i = key & 0xffffff;
-		if (i >= ARRAY_SIZE(rom))
+		if (i >= READ_BIB_ROM_SIZE)
 			/*
 			 * The reference points outside the standard
 			 * config rom area, something's fishy.
 			 */
-			return -1;
+			goto out;
 
 		/* Read header quadlet for the block to get the length. */
 		if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
-			return -1;
+			goto out;
 		end = i + (rom[i] >> 16) + 1;
 		i++;
-		if (end > ARRAY_SIZE(rom))
+		if (end > READ_BIB_ROM_SIZE)
 			/*
 			 * This block extends outside standard config
 			 * area (and the array we're reading it
 			 * into).  That's broken, so ignore this
 			 * device.
 			 */
-			return -1;
+			goto out;
 
 		/*
 		 * Now read in the block.  If this is a directory
@@ -507,9 +517,9 @@ static int read_bus_info_block(struct fw
 		while (i < end) {
 			if (read_rom(device, generation, i, &rom[i]) !=
 			    RCODE_COMPLETE)
-				return -1;
+				goto out;
 			if ((key >> 30) == 3 && (rom[i] >> 30) > 1 &&
-			    sp < ARRAY_SIZE(stack))
+			    sp < READ_BIB_STACK_SIZE)
 				stack[sp++] = i + rom[i];
 			i++;
 		}
@@ -519,11 +529,14 @@ static int read_bus_info_block(struct fw
 
 	device->config_rom = kmalloc(length * 4, GFP_KERNEL);
 	if (device->config_rom == NULL)
-		return -1;
+		goto out;
 	memcpy(device->config_rom, rom, length * 4);
 	device->config_rom_length = length;
+	ret = 0;
+ out:
+	kfree(rom);
 
-	return 0;
+	return ret;
 }
 
 static void fw_unit_release(struct device *dev)

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


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

end of thread, other threads:[~2008-03-06  1:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-02 18:35 [PATCH] firewire: replace static ROM cache by allocated cache Stefan Richter
2008-03-03  0:48 ` [PATCH] firewire: reread config ROM when device reset the bus Stefan Richter
2008-03-03 16:17   ` Kristian Høgsberg
2008-03-03 16:51     ` Stefan Richter
2008-03-03 17:28       ` Kristian Høgsberg
2008-03-03 17:58         ` Stefan Richter
2008-03-03 18:35           ` Stefan Richter
2008-03-04  5:54             ` Greg KH
2008-03-04  8:39               ` Stefan Richter
2008-03-05  0:34     ` [PATCH update] " Stefan Richter
2008-03-05  0:48       ` Stefan Richter
2008-03-05 23:53         ` Stefan Richter
2008-03-06  1:25           ` Stefan Richter
2008-03-03 20:28   ` [PATCH] " Jarod Wilson

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).