Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394

+58 -10
+1
drivers/ieee1394/hosts.h
··· 41 41 /* this nodes state */ 42 42 unsigned in_bus_reset:1; 43 43 unsigned is_shutdown:1; 44 + unsigned resume_packet_sent:1; 44 45 45 46 /* this nodes' duties on the bus */ 46 47 unsigned is_root:1;
+57 -10
drivers/ieee1394/nodemgr.c
··· 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. */ 1358 + static 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 + 1352 1379 static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) 1353 1380 { 1354 1381 struct device *dev; ··· 1386 1359 dev = get_device(&ne->device); 1387 1360 if (!dev) 1388 1361 return; 1362 + 1363 + nodemgr_irm_write_bc(ne, generation); 1389 1364 1390 1365 /* If "needs_probe", then this is either a new or changed node we 1391 1366 * rescan totally. If the generation matches for an existing node ··· 1442 1413 return; 1443 1414 } 1444 1415 1445 - /* Because we are a 1394a-2000 compliant IRM, we need to inform all the other 1446 - * nodes of the broadcast channel. (Really we're only setting the validity 1447 - * bit). Other IRM responsibilities go in here as well. */ 1416 + static int nodemgr_send_resume_packet(struct hpsb_host *host) 1417 + { 1418 + struct hpsb_packet *packet; 1419 + int ret = 1; 1420 + 1421 + packet = hpsb_make_phypacket(host, 1422 + 0x003c0000 | NODEID_TO_NODE(host->node_id) << 24); 1423 + if (packet) { 1424 + packet->no_waiter = 1; 1425 + packet->generation = get_hpsb_generation(host); 1426 + ret = hpsb_send_packet(packet); 1427 + } 1428 + if (ret) 1429 + HPSB_WARN("fw-host%d: Failed to broadcast resume packet", 1430 + host->id); 1431 + return ret; 1432 + } 1433 + 1434 + /* Perform a few high-level IRM responsibilities. */ 1448 1435 static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) 1449 1436 { 1450 1437 quadlet_t bc; ··· 1469 1424 if (!host->is_irm || host->irm_id == (nodeid_t)-1) 1470 1425 return 1; 1471 1426 1472 - host->csr.broadcast_channel |= 0x40000000; /* set validity bit */ 1473 - 1474 - bc = cpu_to_be32(host->csr.broadcast_channel); 1475 - 1476 - hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host), 1477 - (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL), 1478 - &bc, sizeof(quadlet_t)); 1427 + /* We are a 1394a-2000 compliant IRM. Set the validity bit. */ 1428 + host->csr.broadcast_channel |= 0x40000000; 1479 1429 1480 1430 /* If there is no bus manager then we should set the root node's 1481 1431 * force_root bit to promote bus stability per the 1394 ··· 1502 1462 return 0; 1503 1463 } 1504 1464 } 1465 + 1466 + /* Some devices suspend their ports while being connected to an inactive 1467 + * host adapter, i.e. if connected before the low-level driver is 1468 + * loaded. They become visible either when physically unplugged and 1469 + * replugged, or when receiving a resume packet. Send one once. */ 1470 + if (!host->resume_packet_sent && !nodemgr_send_resume_packet(host)) 1471 + host->resume_packet_sent = 1; 1505 1472 1506 1473 return 1; 1507 1474 }