aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2005-12-05 16:28:59 -0500
committerJody McIntyre <scjody@modernduck.com>2005-12-05 16:28:59 -0500
commit61c7f775ca25ccfc0e51486103a724fb1a3a08f2 (patch)
tree90bbd7f117a3831f3bb38ca9bc512de039062f2f /drivers/ieee1394
parentc4fc108a8275f5eb77c9859725643a6870d20ef6 (diff)
ieee1394: write broadcast_channel only to select nodes (fixes device recognition)
Some old 1394-1995 SBP-2 bridges would hang if they received a broadcast write request to BROADCAST_CHANNEL before the config ROM was read. Affected devices include Datafab MD2-FW2 2.5" HDD and SmartDisk VST FWCDRW-V8 portable CD writer. The write request is now directed to specific nodes instead of being broadcast to all nodes at once, and it is only performed if a previous read request at this register succeeded. Fixes an old interoperability problem which was perceived as a 2.6.14-specific regression: http://marc.theaimsgroup.com/?t=113190586800003 Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> Signed-off-by: Jody McIntyre <scjody@modernduck.com>
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r--drivers/ieee1394/nodemgr.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index f4b6025fde61..01ab2bfa8d9d 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1346,6 +1346,33 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
1346} 1346}
1347 1347
1348 1348
1349/* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This
1350 * seems like an optional service but in the end it is practically mandatory
1351 * as a consequence of these clauses.
1352 *
1353 * Note that we cannot do a broadcast write to all nodes at once because some
1354 * pre-1394a devices would hang. */
1355static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
1356{
1357 const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
1358 quadlet_t bc_remote, bc_local;
1359 int ret;
1360
1361 if (!ne->host->is_irm || ne->generation != generation ||
1362 ne->nodeid == ne->host->node_id)
1363 return;
1364
1365 bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
1366
1367 /* Check if the register is implemented and 1394a compliant. */
1368 ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
1369 sizeof(bc_remote));
1370 if (!ret && bc_remote & cpu_to_be32(0x80000000) &&
1371 bc_remote != bc_local)
1372 hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
1373}
1374
1375
1349static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) 1376static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
1350{ 1377{
1351 struct device *dev; 1378 struct device *dev;
@@ -1357,6 +1384,8 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
1357 if (!dev) 1384 if (!dev)
1358 return; 1385 return;
1359 1386
1387 nodemgr_irm_write_bc(ne, generation);
1388
1360 /* If "needs_probe", then this is either a new or changed node we 1389 /* If "needs_probe", then this is either a new or changed node we
1361 * rescan totally. If the generation matches for an existing node 1390 * rescan totally. If the generation matches for an existing node
1362 * (one that existed prior to the bus reset) we send update calls 1391 * (one that existed prior to the bus reset) we send update calls
@@ -1429,9 +1458,7 @@ static int nodemgr_send_resume_packet(struct hpsb_host *host)
1429 return ret; 1458 return ret;
1430} 1459}
1431 1460
1432/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other 1461/* Perform a few high-level IRM responsibilities. */
1433 * nodes of the broadcast channel. (Really we're only setting the validity
1434 * bit). Other IRM responsibilities go in here as well. */
1435static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) 1462static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
1436{ 1463{
1437 quadlet_t bc; 1464 quadlet_t bc;
@@ -1440,13 +1467,8 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
1440 if (!host->is_irm || host->irm_id == (nodeid_t)-1) 1467 if (!host->is_irm || host->irm_id == (nodeid_t)-1)
1441 return 1; 1468 return 1;
1442 1469
1443 host->csr.broadcast_channel |= 0x40000000; /* set validity bit */ 1470 /* We are a 1394a-2000 compliant IRM. Set the validity bit. */
1444 1471 host->csr.broadcast_channel |= 0x40000000;
1445 bc = cpu_to_be32(host->csr.broadcast_channel);
1446
1447 hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host),
1448 (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL),
1449 &bc, sizeof(quadlet_t));
1450 1472
1451 /* If there is no bus manager then we should set the root node's 1473 /* If there is no bus manager then we should set the root node's
1452 * force_root bit to promote bus stability per the 1394 1474 * force_root bit to promote bus stability per the 1394