diff options
| author | H. Peter Anvin <hpa@zytor.com> | 2008-08-26 01:45:37 -0400 |
|---|---|---|
| committer | H. Peter Anvin <hpa@zytor.com> | 2008-08-26 01:45:37 -0400 |
| commit | 94d4ac2f4a58c6e37876827c6688c61cef21290c (patch) | |
| tree | 732f4e4794f3c116041242f69754637f75c0dd57 /drivers/ieee1394 | |
| parent | ed21763e7b0b3fb50e4efd9d4bc17ef5b035d304 (diff) | |
| parent | 08970fc4e0385790a7b093adfaa4165a189f9eb0 (diff) | |
Merge branch 'x86/urgent' into x86/cleanups
Diffstat (limited to 'drivers/ieee1394')
| -rw-r--r-- | drivers/ieee1394/nodemgr.c | 63 | ||||
| -rw-r--r-- | drivers/ieee1394/nodemgr.h | 2 | ||||
| -rw-r--r-- | drivers/ieee1394/sbp2.c | 25 |
3 files changed, 52 insertions, 38 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 994a21e5a0aa..16240a789650 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
| @@ -844,7 +844,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr | |||
| 844 | ne->host = host; | 844 | ne->host = host; |
| 845 | ne->nodeid = nodeid; | 845 | ne->nodeid = nodeid; |
| 846 | ne->generation = generation; | 846 | ne->generation = generation; |
| 847 | ne->needs_probe = 1; | 847 | ne->needs_probe = true; |
| 848 | 848 | ||
| 849 | ne->guid = guid; | 849 | ne->guid = guid; |
| 850 | ne->guid_vendor_id = (guid >> 40) & 0xffffff; | 850 | ne->guid_vendor_id = (guid >> 40) & 0xffffff; |
| @@ -1144,7 +1144,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent | |||
| 1144 | struct csr1212_keyval *kv, *vendor_name_kv = NULL; | 1144 | struct csr1212_keyval *kv, *vendor_name_kv = NULL; |
| 1145 | u8 last_key_id = 0; | 1145 | u8 last_key_id = 0; |
| 1146 | 1146 | ||
| 1147 | ne->needs_probe = 0; | 1147 | ne->needs_probe = false; |
| 1148 | 1148 | ||
| 1149 | csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) { | 1149 | csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) { |
| 1150 | switch (kv->key.id) { | 1150 | switch (kv->key.id) { |
| @@ -1295,7 +1295,7 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, | |||
| 1295 | nodemgr_update_bus_options(ne); | 1295 | nodemgr_update_bus_options(ne); |
| 1296 | 1296 | ||
| 1297 | /* Mark the node as new, so it gets re-probed */ | 1297 | /* Mark the node as new, so it gets re-probed */ |
| 1298 | ne->needs_probe = 1; | 1298 | ne->needs_probe = true; |
| 1299 | } else { | 1299 | } else { |
| 1300 | /* old cache is valid, so update its generation */ | 1300 | /* old cache is valid, so update its generation */ |
| 1301 | struct nodemgr_csr_info *ci = ne->csr->private; | 1301 | struct nodemgr_csr_info *ci = ne->csr->private; |
| @@ -1566,57 +1566,60 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge | |||
| 1566 | struct probe_param { | 1566 | struct probe_param { |
| 1567 | struct host_info *hi; | 1567 | struct host_info *hi; |
| 1568 | int generation; | 1568 | int generation; |
| 1569 | bool probe_now; | ||
| 1569 | }; | 1570 | }; |
| 1570 | 1571 | ||
| 1571 | static int __nodemgr_node_probe(struct device *dev, void *data) | 1572 | static int node_probe(struct device *dev, void *data) |
| 1572 | { | 1573 | { |
| 1573 | struct probe_param *param = (struct probe_param *)data; | 1574 | struct probe_param *p = data; |
| 1574 | struct node_entry *ne; | 1575 | struct node_entry *ne; |
| 1575 | 1576 | ||
| 1577 | if (p->generation != get_hpsb_generation(p->hi->host)) | ||
| 1578 | return -EAGAIN; | ||
| 1579 | |||
| 1576 | ne = container_of(dev, struct node_entry, node_dev); | 1580 | ne = container_of(dev, struct node_entry, node_dev); |
| 1577 | if (!ne->needs_probe) | 1581 | if (ne->needs_probe == p->probe_now) |
| 1578 | nodemgr_probe_ne(param->hi, ne, param->generation); | 1582 | nodemgr_probe_ne(p->hi, ne, p->generation); |
| 1579 | if (ne->needs_probe) | ||
| 1580 | nodemgr_probe_ne(param->hi, ne, param->generation); | ||
| 1581 | return 0; | 1583 | return 0; |
| 1582 | } | 1584 | } |
| 1583 | 1585 | ||
| 1584 | static void nodemgr_node_probe(struct host_info *hi, int generation) | 1586 | static void nodemgr_node_probe(struct host_info *hi, int generation) |
| 1585 | { | 1587 | { |
| 1586 | struct hpsb_host *host = hi->host; | 1588 | struct probe_param p; |
| 1587 | struct probe_param param; | ||
| 1588 | 1589 | ||
| 1589 | param.hi = hi; | 1590 | p.hi = hi; |
| 1590 | param.generation = generation; | 1591 | p.generation = generation; |
| 1591 | /* Do some processing of the nodes we've probed. This pulls them | 1592 | /* |
| 1593 | * Do some processing of the nodes we've probed. This pulls them | ||
| 1592 | * into the sysfs layer if needed, and can result in processing of | 1594 | * into the sysfs layer if needed, and can result in processing of |
| 1593 | * unit-directories, or just updating the node and it's | 1595 | * unit-directories, or just updating the node and it's |
| 1594 | * unit-directories. | 1596 | * unit-directories. |
| 1595 | * | 1597 | * |
| 1596 | * Run updates before probes. Usually, updates are time-critical | 1598 | * Run updates before probes. Usually, updates are time-critical |
| 1597 | * while probes are time-consuming. (Well, those probes need some | 1599 | * while probes are time-consuming. |
| 1598 | * improvement...) */ | ||
| 1599 | |||
| 1600 | class_for_each_device(&nodemgr_ne_class, NULL, ¶m, | ||
| 1601 | __nodemgr_node_probe); | ||
| 1602 | |||
| 1603 | /* If we had a bus reset while we were scanning the bus, it is | ||
| 1604 | * possible that we did not probe all nodes. In that case, we | ||
| 1605 | * skip the clean up for now, since we could remove nodes that | ||
| 1606 | * were still on the bus. Another bus scan is pending which will | ||
| 1607 | * do the clean up eventually. | ||
| 1608 | * | 1600 | * |
| 1601 | * Meanwhile, another bus reset may have happened. In this case we | ||
| 1602 | * skip everything here and let the next bus scan handle it. | ||
| 1603 | * Otherwise we may prematurely remove nodes which are still there. | ||
| 1604 | */ | ||
| 1605 | p.probe_now = false; | ||
| 1606 | if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) | ||
| 1607 | return; | ||
| 1608 | |||
| 1609 | p.probe_now = true; | ||
| 1610 | if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) | ||
| 1611 | return; | ||
| 1612 | /* | ||
| 1609 | * Now let's tell the bus to rescan our devices. This may seem | 1613 | * Now let's tell the bus to rescan our devices. This may seem |
| 1610 | * like overhead, but the driver-model core will only scan a | 1614 | * like overhead, but the driver-model core will only scan a |
| 1611 | * device for a driver when either the device is added, or when a | 1615 | * device for a driver when either the device is added, or when a |
| 1612 | * new driver is added. A bus reset is a good reason to rescan | 1616 | * new driver is added. A bus reset is a good reason to rescan |
| 1613 | * devices that were there before. For example, an sbp2 device | 1617 | * devices that were there before. For example, an sbp2 device |
| 1614 | * may become available for login, if the host that held it was | 1618 | * may become available for login, if the host that held it was |
| 1615 | * just removed. */ | 1619 | * just removed. |
| 1616 | 1620 | */ | |
| 1617 | if (generation == get_hpsb_generation(host)) | 1621 | if (bus_rescan_devices(&ieee1394_bus_type) != 0) |
| 1618 | if (bus_rescan_devices(&ieee1394_bus_type)) | 1622 | HPSB_DEBUG("bus_rescan_devices had an error"); |
| 1619 | HPSB_DEBUG("bus_rescan_devices had an error"); | ||
| 1620 | } | 1623 | } |
| 1621 | 1624 | ||
| 1622 | static int nodemgr_send_resume_packet(struct hpsb_host *host) | 1625 | static int nodemgr_send_resume_packet(struct hpsb_host *host) |
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h index 919e92e2a955..6eb26465a84c 100644 --- a/drivers/ieee1394/nodemgr.h +++ b/drivers/ieee1394/nodemgr.h | |||
| @@ -97,7 +97,7 @@ struct node_entry { | |||
| 97 | struct hpsb_host *host; /* Host this node is attached to */ | 97 | struct hpsb_host *host; /* Host this node is attached to */ |
| 98 | nodeid_t nodeid; /* NodeID */ | 98 | nodeid_t nodeid; /* NodeID */ |
| 99 | struct bus_options busopt; /* Bus Options */ | 99 | struct bus_options busopt; /* Bus Options */ |
| 100 | int needs_probe; | 100 | bool needs_probe; |
| 101 | unsigned int generation; /* Synced with hpsb generation */ | 101 | unsigned int generation; /* Synced with hpsb generation */ |
| 102 | 102 | ||
| 103 | /* The following is read from the config rom */ | 103 | /* The following is read from the config rom */ |
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 9cbf3154d243..1d6ad3435537 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
| @@ -731,15 +731,26 @@ static int sbp2_update(struct unit_directory *ud) | |||
| 731 | { | 731 | { |
| 732 | struct sbp2_lu *lu = ud->device.driver_data; | 732 | struct sbp2_lu *lu = ud->device.driver_data; |
| 733 | 733 | ||
| 734 | if (sbp2_reconnect_device(lu)) { | 734 | if (sbp2_reconnect_device(lu) != 0) { |
| 735 | /* Reconnect has failed. Perhaps we didn't reconnect fast | 735 | /* |
| 736 | * enough. Try a regular login, but first log out just in | 736 | * Reconnect failed. If another bus reset happened, |
| 737 | * case of any weirdness. */ | 737 | * let nodemgr proceed and call sbp2_update again later |
| 738 | * (or sbp2_remove if this node went away). | ||
| 739 | */ | ||
| 740 | if (!hpsb_node_entry_valid(lu->ne)) | ||
| 741 | return 0; | ||
| 742 | /* | ||
| 743 | * Or the target rejected the reconnect because we weren't | ||
| 744 | * fast enough. Try a regular login, but first log out | ||
| 745 | * just in case of any weirdness. | ||
| 746 | */ | ||
| 738 | sbp2_logout_device(lu); | 747 | sbp2_logout_device(lu); |
| 739 | 748 | ||
| 740 | if (sbp2_login_device(lu)) { | 749 | if (sbp2_login_device(lu) != 0) { |
| 741 | /* Login failed too, just fail, and the backend | 750 | if (!hpsb_node_entry_valid(lu->ne)) |
| 742 | * will call our sbp2_remove for us */ | 751 | return 0; |
| 752 | |||
| 753 | /* Maybe another initiator won the login. */ | ||
| 743 | SBP2_ERR("Failed to reconnect to sbp2 device!"); | 754 | SBP2_ERR("Failed to reconnect to sbp2 device!"); |
| 744 | return -EBUSY; | 755 | return -EBUSY; |
| 745 | } | 756 | } |
