diff options
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r-- | drivers/ieee1394/hosts.h | 1 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 67 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.c | 6 |
3 files changed, 64 insertions, 10 deletions
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index 38f42112dff0..ae9b02cc013f 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h | |||
@@ -41,6 +41,7 @@ struct hpsb_host { | |||
41 | /* this nodes state */ | 41 | /* this nodes state */ |
42 | unsigned in_bus_reset:1; | 42 | unsigned in_bus_reset:1; |
43 | unsigned is_shutdown:1; | 43 | unsigned is_shutdown:1; |
44 | unsigned resume_packet_sent:1; | ||
44 | 45 | ||
45 | /* this nodes' duties on the bus */ | 46 | /* this nodes' duties on the bus */ |
46 | unsigned is_root:1; | 47 | unsigned is_root:1; |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 7fff5a1d2ea4..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. */ | ||
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 | static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) | 1379 | static 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 |
@@ -1413,9 +1442,25 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1413 | return; | 1442 | return; |
1414 | } | 1443 | } |
1415 | 1444 | ||
1416 | /* Because we are a 1394a-2000 compliant IRM, we need to inform all the other | 1445 | static int nodemgr_send_resume_packet(struct hpsb_host *host) |
1417 | * nodes of the broadcast channel. (Really we're only setting the validity | 1446 | { |
1418 | * bit). Other IRM responsibilities go in here as well. */ | 1447 | struct hpsb_packet *packet; |
1448 | int ret = 1; | ||
1449 | |||
1450 | packet = hpsb_make_phypacket(host, | ||
1451 | 0x003c0000 | NODEID_TO_NODE(host->node_id) << 24); | ||
1452 | if (packet) { | ||
1453 | packet->no_waiter = 1; | ||
1454 | packet->generation = get_hpsb_generation(host); | ||
1455 | ret = hpsb_send_packet(packet); | ||
1456 | } | ||
1457 | if (ret) | ||
1458 | HPSB_WARN("fw-host%d: Failed to broadcast resume packet", | ||
1459 | host->id); | ||
1460 | return ret; | ||
1461 | } | ||
1462 | |||
1463 | /* Perform a few high-level IRM responsibilities. */ | ||
1419 | static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) | 1464 | static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) |
1420 | { | 1465 | { |
1421 | quadlet_t bc; | 1466 | quadlet_t bc; |
@@ -1424,13 +1469,8 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) | |||
1424 | if (!host->is_irm || host->irm_id == (nodeid_t)-1) | 1469 | if (!host->is_irm || host->irm_id == (nodeid_t)-1) |
1425 | return 1; | 1470 | return 1; |
1426 | 1471 | ||
1427 | host->csr.broadcast_channel |= 0x40000000; /* set validity bit */ | 1472 | /* We are a 1394a-2000 compliant IRM. Set the validity bit. */ |
1428 | 1473 | host->csr.broadcast_channel |= 0x40000000; | |
1429 | bc = cpu_to_be32(host->csr.broadcast_channel); | ||
1430 | |||
1431 | hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host), | ||
1432 | (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL), | ||
1433 | &bc, sizeof(quadlet_t)); | ||
1434 | 1474 | ||
1435 | /* 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 |
1436 | * force_root bit to promote bus stability per the 1394 | 1476 | * force_root bit to promote bus stability per the 1394 |
@@ -1463,6 +1503,13 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) | |||
1463 | } | 1503 | } |
1464 | } | 1504 | } |
1465 | 1505 | ||
1506 | /* Some devices suspend their ports while being connected to an inactive | ||
1507 | * host adapter, i.e. if connected before the low-level driver is | ||
1508 | * loaded. They become visible either when physically unplugged and | ||
1509 | * replugged, or when receiving a resume packet. Send one once. */ | ||
1510 | if (!host->resume_packet_sent && !nodemgr_send_resume_packet(host)) | ||
1511 | host->resume_packet_sent = 1; | ||
1512 | |||
1466 | return 1; | 1513 | return 1; |
1467 | } | 1514 | } |
1468 | 1515 | ||
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 12cec7c4a342..f7e18ccc5c0a 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -2350,6 +2350,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
2350 | struct scsi_cmnd *SCpnt = NULL; | 2350 | struct scsi_cmnd *SCpnt = NULL; |
2351 | u32 scsi_status = SBP2_SCSI_STATUS_GOOD; | 2351 | u32 scsi_status = SBP2_SCSI_STATUS_GOOD; |
2352 | struct sbp2_command_info *command; | 2352 | struct sbp2_command_info *command; |
2353 | unsigned long flags; | ||
2353 | 2354 | ||
2354 | SBP2_DEBUG("sbp2_handle_status_write"); | 2355 | SBP2_DEBUG("sbp2_handle_status_write"); |
2355 | 2356 | ||
@@ -2451,9 +2452,11 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
2451 | * null out last orb so that next time around we write directly to the orb pointer... | 2452 | * null out last orb so that next time around we write directly to the orb pointer... |
2452 | * Quick start saves one 1394 bus transaction. | 2453 | * Quick start saves one 1394 bus transaction. |
2453 | */ | 2454 | */ |
2455 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); | ||
2454 | if (list_empty(&scsi_id->sbp2_command_orb_inuse)) { | 2456 | if (list_empty(&scsi_id->sbp2_command_orb_inuse)) { |
2455 | scsi_id->last_orb = NULL; | 2457 | scsi_id->last_orb = NULL; |
2456 | } | 2458 | } |
2459 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | ||
2457 | 2460 | ||
2458 | } else { | 2461 | } else { |
2459 | 2462 | ||
@@ -2563,9 +2566,11 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id | |||
2563 | struct sbp2scsi_host_info *hi = scsi_id->hi; | 2566 | struct sbp2scsi_host_info *hi = scsi_id->hi; |
2564 | struct list_head *lh; | 2567 | struct list_head *lh; |
2565 | struct sbp2_command_info *command; | 2568 | struct sbp2_command_info *command; |
2569 | unsigned long flags; | ||
2566 | 2570 | ||
2567 | SBP2_DEBUG("sbp2scsi_complete_all_commands"); | 2571 | SBP2_DEBUG("sbp2scsi_complete_all_commands"); |
2568 | 2572 | ||
2573 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); | ||
2569 | while (!list_empty(&scsi_id->sbp2_command_orb_inuse)) { | 2574 | while (!list_empty(&scsi_id->sbp2_command_orb_inuse)) { |
2570 | SBP2_DEBUG("Found pending command to complete"); | 2575 | SBP2_DEBUG("Found pending command to complete"); |
2571 | lh = scsi_id->sbp2_command_orb_inuse.next; | 2576 | lh = scsi_id->sbp2_command_orb_inuse.next; |
@@ -2582,6 +2587,7 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id | |||
2582 | command->Current_done(command->Current_SCpnt); | 2587 | command->Current_done(command->Current_SCpnt); |
2583 | } | 2588 | } |
2584 | } | 2589 | } |
2590 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | ||
2585 | 2591 | ||
2586 | return; | 2592 | return; |
2587 | } | 2593 | } |