summary refs log tree commit diff
path: root/drivers/firewire
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 09:43:22 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 09:43:22 -0700
commitff830b8e5f999d1ccbd0282a666520f0b557daa4 (patch)
tree5979aba5ed48c93d658a208f3a1f714e9e1e8b67 /drivers/firewire
parent746942d06acdb4dd78d16baa5f3728a48a033bdd (diff)
parent625f0850a8e27b6a8d6fdb95056f35bc22d92b55 (diff)
downloadlinux-ff830b8e5f999d1ccbd0282a666520f0b557daa4.tar.gz
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  ieee1394: sbp2: remove a workaround for Momobay FX-3A
  firewire: sbp2: remove a workaround for Momobay FX-3A
  firewire: sbp2: fix status reception
  firewire: core: fix topology map response handler
  firewire: core: fix race with parallel PCI device probe
  firewire: core: header file cleanup
  firewire: ohci: fix Self ID Count register mask (safeguard against buffer overflow)
  ieee1394: raw1394: Do not leak memory on failed trylock.
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/core-card.c13
-rw-r--r--drivers/firewire/core-transaction.c2
-rw-r--r--drivers/firewire/core.h14
-rw-r--r--drivers/firewire/ohci.c4
-rw-r--r--drivers/firewire/sbp2.c16
5 files changed, 30 insertions, 19 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index f74edae5cb4c..e4864e894e4f 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -444,16 +444,13 @@ int fw_card_add(struct fw_card *card,
 	card->guid = guid;
 
 	mutex_lock(&card_mutex);
-	config_rom = generate_config_rom(card, &length);
-	list_add_tail(&card->link, &card_list);
-	mutex_unlock(&card_mutex);
 
+	config_rom = generate_config_rom(card, &length);
 	ret = card->driver->enable(card, config_rom, length);
-	if (ret < 0) {
-		mutex_lock(&card_mutex);
-		list_del(&card->link);
-		mutex_unlock(&card_mutex);
-	}
+	if (ret == 0)
+		list_add_tail(&card->link, &card_list);
+
+	mutex_unlock(&card_mutex);
 
 	return ret;
 }
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 479b22f5a1eb..da628c72a462 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -834,7 +834,7 @@ static void handle_topology_map(struct fw_card *card, struct fw_request *request
 }
 
 static struct fw_address_handler topology_map = {
-	.length			= 0x200,
+	.length			= 0x400,
 	.address_callback	= handle_topology_map,
 };
 
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index 6052816be353..7ff6e7585152 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -96,6 +96,20 @@ int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
 int fw_compute_block_crc(u32 *block);
 void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);
 
+static inline struct fw_card *fw_card_get(struct fw_card *card)
+{
+	kref_get(&card->kref);
+
+	return card;
+}
+
+void fw_card_release(struct kref *kref);
+
+static inline void fw_card_put(struct fw_card *card)
+{
+	kref_put(&card->kref, fw_card_release);
+}
+
 
 /* -cdev */
 
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 76b321bb73f9..5d524254499e 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1279,8 +1279,8 @@ static void bus_reset_tasklet(unsigned long data)
 	 * the inverted quadlets and a header quadlet, we shift one
 	 * bit extra to get the actual number of self IDs.
 	 */
-	self_id_count = (reg >> 3) & 0x3ff;
-	if (self_id_count == 0) {
+	self_id_count = (reg >> 3) & 0xff;
+	if (self_id_count == 0 || self_id_count > 252) {
 		fw_notify("inconsistent self IDs\n");
 		return;
 	}
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index e5df822a8130..50f0176de615 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -354,8 +354,7 @@ static const struct {
 	/* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
 		.firmware_revision	= 0x002800,
 		.model			= 0x000000,
-		.workarounds		= SBP2_WORKAROUND_DELAY_INQUIRY |
-					  SBP2_WORKAROUND_POWER_CONDITION,
+		.workarounds		= SBP2_WORKAROUND_POWER_CONDITION,
 	},
 	/* Initio bridges, actually only needed for some older ones */ {
 		.firmware_revision	= 0x000200,
@@ -425,19 +424,20 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
 	struct sbp2_logical_unit *lu = callback_data;
 	struct sbp2_orb *orb;
 	struct sbp2_status status;
-	size_t header_size;
 	unsigned long flags;
 
 	if (tcode != TCODE_WRITE_BLOCK_REQUEST ||
-	    length == 0 || length > sizeof(status)) {
+	    length < 8 || length > sizeof(status)) {
 		fw_send_response(card, request, RCODE_TYPE_ERROR);
 		return;
 	}
 
-	header_size = min(length, 2 * sizeof(u32));
-	fw_memcpy_from_be32(&status, payload, header_size);
-	if (length > header_size)
-		memcpy(status.data, payload + 8, length - header_size);
+	status.status  = be32_to_cpup(payload);
+	status.orb_low = be32_to_cpup(payload + 4);
+	memset(status.data, 0, sizeof(status.data));
+	if (length > 8)
+		memcpy(status.data, payload + 8, length - 8);
+
 	if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) {
 		fw_notify("non-orb related status write, not handled\n");
 		fw_send_response(card, request, RCODE_COMPLETE);