aboutsummaryrefslogtreecommitdiffstats
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-12 23:21:12 -0500
commitd51e86c18a479f1dbcef3aa20e58ad04d1233016 (patch)
treec6dd3b79a4276908451d8daa8587347a03ca7f1c
parent48622b7bde008387218a416586e9d072b385f1ae (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> (cherry picked from 61c7f775ca25ccfc0e51486103a724fb1a3a08f2 commit)
-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 f7c3dbaf5802..0ea37b1bccb2 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1349,6 +1349,33 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
1349} 1349}
1350 1350
1351 1351
1352/* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This
1353 * seems like an optional service but in the end it is practically mandatory
1354 * as a consequence of these clauses.
1355 *
1356 * Note that we cannot do a broadcast write to all nodes at once because some
1357 * pre-1394a devices would hang. */
1358static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
1359{
1360 const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
1361 quadlet_t bc_remote, bc_local;
1362 int ret;
1363
1364 if (!ne->host->is_irm || ne->generation != generation ||
1365 ne->nodeid == ne->host->node_id)
1366 return;
1367
1368 bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
1369
1370 /* Check if the register is implemented and 1394a compliant. */
1371 ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
1372 sizeof(bc_remote));
1373 if (!ret && bc_remote & cpu_to_be32(0x80000000) &&
1374 bc_remote != bc_local)
1375 hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
1376}
1377
1378
1352static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) 1379static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
1353{ 1380{
1354 struct device *dev; 1381 struct device *dev;
@@ -1360,6 +1387,8 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
1360 if (!dev) 1387 if (!dev)
1361 return; 1388 return;
1362 1389
1390 nodemgr_irm_write_bc(ne, generation);
1391
1363 /* If "needs_probe", then this is either a new or changed node we 1392 /* If "needs_probe", then this is either a new or changed node we
1364 * rescan totally. If the generation matches for an existing node 1393 * rescan totally. If the generation matches for an existing node
1365 * (one that existed prior to the bus reset) we send update calls 1394 * (one that existed prior to the bus reset) we send update calls
@@ -1431,9 +1460,7 @@ static int nodemgr_send_resume_packet(struct hpsb_host *host)
1431 return ret; 1460 return ret;
1432} 1461}
1433 1462
1434/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other 1463/* Perform a few high-level IRM responsibilities. */
1435 * nodes of the broadcast channel. (Really we're only setting the validity
1436 * bit). Other IRM responsibilities go in here as well. */
1437static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) 1464static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
1438{ 1465{
1439 quadlet_t bc; 1466 quadlet_t bc;
@@ -1442,13 +1469,8 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
1442 if (!host->is_irm || host->irm_id == (nodeid_t)-1) 1469 if (!host->is_irm || host->irm_id == (nodeid_t)-1)
1443 return 1; 1470 return 1;
1444 1471
1445 host->csr.broadcast_channel |= 0x40000000; /* set validity bit */ 1472 /* We are a 1394a-2000 compliant IRM. Set the validity bit. */
1446 1473 host->csr.broadcast_channel |= 0x40000000;
1447 bc = cpu_to_be32(host->csr.broadcast_channel);
1448
1449 hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host),
1450 (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL),
1451 &bc, sizeof(quadlet_t));
1452 1474
1453 /* If there is no bus manager then we should set the root node's 1475 /* If there is no bus manager then we should set the root node's
1454 * force_root bit to promote bus stability per the 1394 1476 * force_root bit to promote bus stability per the 1394