aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/csr1212.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-12-13 17:12:06 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-01-04 17:50:34 -0500
commit0bed1819687b50a769a1fee6d91cb0ef79b011b4 (patch)
treebc5c36dda1f8e8de697ca3bb2b4d170cb77183c6 /drivers/ieee1394/csr1212.c
parentc1fc58d63d754b82070881c62601551464afa19d (diff)
ieee1394: ignore nonzero Bus_Info_Block.max_rom, fetch config ROM in quadlets
It is already known that buggy firmwares exist which report a bogus link_spd in their config ROM bus info block. We now got the first report of a bogus max_rom too (Freecom FireWire Hard Drive 1TB, http://bugzilla.kernel.org/show_bug.cgi?id=12206). I suspect other OSs only use quadlet reads to fetch the config ROM, otherwise the firmware authors would have noticed their mistake. Hence limit ieee1394's config ROM fetching routine to quadlets as the safe minimum regardless of what the bus info block says. This will potentially slow the bus reset handling by nodemgr somewhat down. But most existing devices support only quadlet reads anyway, hence there will often be no actual difference to before this change. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/ieee1394/csr1212.c')
-rw-r--r--drivers/ieee1394/csr1212.c45
1 files changed, 14 insertions, 31 deletions
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
index 5e38a68b8af2..a6dfeb0b3372 100644
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -1077,15 +1077,10 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
1077 int i; 1077 int i;
1078 int ret; 1078 int ret;
1079 1079
1080 /* IEEE 1212 says that the entire bus info block should be readable in
1081 * a single transaction regardless of the max_rom value.
1082 * Unfortunately, many IEEE 1394 devices do not abide by that, so the
1083 * bus info block will be read 1 quadlet at a time. The rest of the
1084 * ConfigROM will be read according to the max_rom field. */
1085 for (i = 0; i < csr->bus_info_len; i += sizeof(u32)) { 1080 for (i = 0; i < csr->bus_info_len; i += sizeof(u32)) {
1086 ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i, 1081 ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
1087 sizeof(u32), &csr->cache_head->data[bytes_to_quads(i)], 1082 &csr->cache_head->data[bytes_to_quads(i)],
1088 csr->private); 1083 csr->private);
1089 if (ret != CSR1212_SUCCESS) 1084 if (ret != CSR1212_SUCCESS)
1090 return ret; 1085 return ret;
1091 1086
@@ -1104,8 +1099,8 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
1104 * a time. */ 1099 * a time. */
1105 for (i = csr->bus_info_len; i <= csr->crc_len; i += sizeof(u32)) { 1100 for (i = csr->bus_info_len; i <= csr->crc_len; i += sizeof(u32)) {
1106 ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i, 1101 ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
1107 sizeof(u32), &csr->cache_head->data[bytes_to_quads(i)], 1102 &csr->cache_head->data[bytes_to_quads(i)],
1108 csr->private); 1103 csr->private);
1109 if (ret != CSR1212_SUCCESS) 1104 if (ret != CSR1212_SUCCESS)
1110 return ret; 1105 return ret;
1111 } 1106 }
@@ -1289,7 +1284,7 @@ csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
1289 1284
1290 if (csr->ops->bus_read(csr, 1285 if (csr->ops->bus_read(csr,
1291 CSR1212_REGISTER_SPACE_BASE + kv->offset, 1286 CSR1212_REGISTER_SPACE_BASE + kv->offset,
1292 sizeof(u32), &q, csr->private)) 1287 &q, csr->private))
1293 return -EIO; 1288 return -EIO;
1294 1289
1295 kv->value.leaf.len = be32_to_cpu(q) >> 16; 1290 kv->value.leaf.len = be32_to_cpu(q) >> 16;
@@ -1372,17 +1367,8 @@ csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
1372 addr = (CSR1212_CSR_ARCH_REG_SPACE_BASE + cache->offset + 1367 addr = (CSR1212_CSR_ARCH_REG_SPACE_BASE + cache->offset +
1373 cr->offset_end) & ~(csr->max_rom - 1); 1368 cr->offset_end) & ~(csr->max_rom - 1);
1374 1369
1375 if (csr->ops->bus_read(csr, addr, csr->max_rom, cache_ptr, 1370 if (csr->ops->bus_read(csr, addr, cache_ptr, csr->private))
1376 csr->private)) { 1371 return -EIO;
1377 if (csr->max_rom == 4)
1378 /* We've got problems! */
1379 return -EIO;
1380
1381 /* Apperently the max_rom value was a lie, set it to
1382 * do quadlet reads and try again. */
1383 csr->max_rom = 4;
1384 continue;
1385 }
1386 1372
1387 cr->offset_end += csr->max_rom - (cr->offset_end & 1373 cr->offset_end += csr->max_rom - (cr->offset_end &
1388 (csr->max_rom - 1)); 1374 (csr->max_rom - 1));
@@ -1433,7 +1419,6 @@ csr1212_get_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
1433 1419
1434int csr1212_parse_csr(struct csr1212_csr *csr) 1420int csr1212_parse_csr(struct csr1212_csr *csr)
1435{ 1421{
1436 static const int mr_map[] = { 4, 64, 1024, 0 };
1437 struct csr1212_dentry *dentry; 1422 struct csr1212_dentry *dentry;
1438 int ret; 1423 int ret;
1439 1424
@@ -1443,15 +1428,13 @@ int csr1212_parse_csr(struct csr1212_csr *csr)
1443 if (ret != CSR1212_SUCCESS) 1428 if (ret != CSR1212_SUCCESS)
1444 return ret; 1429 return ret;
1445 1430
1446 if (!csr->ops->get_max_rom) { 1431 /*
1447 csr->max_rom = mr_map[0]; /* default value */ 1432 * There has been a buggy firmware with bus_info_block.max_rom > 0
1448 } else { 1433 * spotted which actually only supported quadlet read requests to the
1449 int i = csr->ops->get_max_rom(csr->bus_info_data, 1434 * config ROM. Therefore read everything quadlet by quadlet regardless
1450 csr->private); 1435 * of what the bus info block says.
1451 if (i & ~0x3) 1436 */
1452 return -EINVAL; 1437 csr->max_rom = 4;
1453 csr->max_rom = mr_map[i];
1454 }
1455 1438
1456 csr->cache_head->layout_head = csr->root_kv; 1439 csr->cache_head->layout_head = csr->root_kv;
1457 csr->cache_head->layout_tail = csr->root_kv; 1440 csr->cache_head->layout_tail = csr->root_kv;