diff options
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 1 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_discover.c | 32 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 8 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_internal.h | 1 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_port.c | 3 | ||||
-rw-r--r-- | include/scsi/libsas.h | 3 | ||||
-rw-r--r-- | include/scsi/scsi_transport_sas.h | 1 |
7 files changed, 27 insertions, 22 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 70be4425ae0b..2b3637b40dde 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -730,7 +730,6 @@ int sas_discover_sata(struct domain_device *dev) | |||
730 | if (res) | 730 | if (res) |
731 | return res; | 731 | return res; |
732 | 732 | ||
733 | sas_discover_event(dev->port, DISCE_PROBE); | ||
734 | return 0; | 733 | return 0; |
735 | } | 734 | } |
736 | 735 | ||
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 14f714d05767..e4fd078e4175 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c | |||
@@ -212,13 +212,9 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev) | |||
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | static void sas_probe_devices(struct work_struct *work) | 215 | static void sas_probe_devices(struct asd_sas_port *port) |
216 | { | 216 | { |
217 | struct domain_device *dev, *n; | 217 | struct domain_device *dev, *n; |
218 | struct sas_discovery_event *ev = to_sas_discovery_event(work); | ||
219 | struct asd_sas_port *port = ev->port; | ||
220 | |||
221 | clear_bit(DISCE_PROBE, &port->disc.pending); | ||
222 | 218 | ||
223 | /* devices must be domain members before link recovery and probe */ | 219 | /* devices must be domain members before link recovery and probe */ |
224 | list_for_each_entry(dev, &port->disco_list, disco_list_node) { | 220 | list_for_each_entry(dev, &port->disco_list, disco_list_node) { |
@@ -294,7 +290,6 @@ int sas_discover_end_dev(struct domain_device *dev) | |||
294 | res = sas_notify_lldd_dev_found(dev); | 290 | res = sas_notify_lldd_dev_found(dev); |
295 | if (res) | 291 | if (res) |
296 | return res; | 292 | return res; |
297 | sas_discover_event(dev->port, DISCE_PROBE); | ||
298 | 293 | ||
299 | return 0; | 294 | return 0; |
300 | } | 295 | } |
@@ -353,13 +348,9 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d | |||
353 | sas_put_device(dev); | 348 | sas_put_device(dev); |
354 | } | 349 | } |
355 | 350 | ||
356 | static void sas_destruct_devices(struct work_struct *work) | 351 | void sas_destruct_devices(struct asd_sas_port *port) |
357 | { | 352 | { |
358 | struct domain_device *dev, *n; | 353 | struct domain_device *dev, *n; |
359 | struct sas_discovery_event *ev = to_sas_discovery_event(work); | ||
360 | struct asd_sas_port *port = ev->port; | ||
361 | |||
362 | clear_bit(DISCE_DESTRUCT, &port->disc.pending); | ||
363 | 354 | ||
364 | list_for_each_entry_safe(dev, n, &port->destroy_list, disco_list_node) { | 355 | list_for_each_entry_safe(dev, n, &port->destroy_list, disco_list_node) { |
365 | list_del_init(&dev->disco_list_node); | 356 | list_del_init(&dev->disco_list_node); |
@@ -370,6 +361,16 @@ static void sas_destruct_devices(struct work_struct *work) | |||
370 | } | 361 | } |
371 | } | 362 | } |
372 | 363 | ||
364 | static void sas_destruct_ports(struct asd_sas_port *port) | ||
365 | { | ||
366 | struct sas_port *sas_port, *p; | ||
367 | |||
368 | list_for_each_entry_safe(sas_port, p, &port->sas_port_del_list, del_list) { | ||
369 | list_del_init(&sas_port->del_list); | ||
370 | sas_port_delete(sas_port); | ||
371 | } | ||
372 | } | ||
373 | |||
373 | void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) | 374 | void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) |
374 | { | 375 | { |
375 | if (!test_bit(SAS_DEV_DESTROY, &dev->state) && | 376 | if (!test_bit(SAS_DEV_DESTROY, &dev->state) && |
@@ -384,7 +385,6 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) | |||
384 | if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { | 385 | if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { |
385 | sas_rphy_unlink(dev->rphy); | 386 | sas_rphy_unlink(dev->rphy); |
386 | list_move_tail(&dev->disco_list_node, &port->destroy_list); | 387 | list_move_tail(&dev->disco_list_node, &port->destroy_list); |
387 | sas_discover_event(dev->port, DISCE_DESTRUCT); | ||
388 | } | 388 | } |
389 | } | 389 | } |
390 | 390 | ||
@@ -490,6 +490,8 @@ static void sas_discover_domain(struct work_struct *work) | |||
490 | port->port_dev = NULL; | 490 | port->port_dev = NULL; |
491 | } | 491 | } |
492 | 492 | ||
493 | sas_probe_devices(port); | ||
494 | |||
493 | SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id, | 495 | SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id, |
494 | task_pid_nr(current), error); | 496 | task_pid_nr(current), error); |
495 | } | 497 | } |
@@ -523,6 +525,10 @@ static void sas_revalidate_domain(struct work_struct *work) | |||
523 | port->id, task_pid_nr(current), res); | 525 | port->id, task_pid_nr(current), res); |
524 | out: | 526 | out: |
525 | mutex_unlock(&ha->disco_mutex); | 527 | mutex_unlock(&ha->disco_mutex); |
528 | |||
529 | sas_destruct_devices(port); | ||
530 | sas_destruct_ports(port); | ||
531 | sas_probe_devices(port); | ||
526 | } | 532 | } |
527 | 533 | ||
528 | /* ---------- Events ---------- */ | 534 | /* ---------- Events ---------- */ |
@@ -578,10 +584,8 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) | |||
578 | static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = { | 584 | static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = { |
579 | [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, | 585 | [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, |
580 | [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, | 586 | [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, |
581 | [DISCE_PROBE] = sas_probe_devices, | ||
582 | [DISCE_SUSPEND] = sas_suspend_devices, | 587 | [DISCE_SUSPEND] = sas_suspend_devices, |
583 | [DISCE_RESUME] = sas_resume_devices, | 588 | [DISCE_RESUME] = sas_resume_devices, |
584 | [DISCE_DESTRUCT] = sas_destruct_devices, | ||
585 | }; | 589 | }; |
586 | 590 | ||
587 | disc->pending = 0; | 591 | disc->pending = 0; |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index a8a57b0593e3..7444d40e261c 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -1916,7 +1916,8 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent, | |||
1916 | sas_port_delete_phy(phy->port, phy->phy); | 1916 | sas_port_delete_phy(phy->port, phy->phy); |
1917 | sas_device_set_phy(found, phy->port); | 1917 | sas_device_set_phy(found, phy->port); |
1918 | if (phy->port->num_phys == 0) | 1918 | if (phy->port->num_phys == 0) |
1919 | sas_port_delete(phy->port); | 1919 | list_add_tail(&phy->port->del_list, |
1920 | &parent->port->sas_port_del_list); | ||
1920 | phy->port = NULL; | 1921 | phy->port = NULL; |
1921 | } | 1922 | } |
1922 | } | 1923 | } |
@@ -2124,7 +2125,7 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) | |||
2124 | struct domain_device *dev = NULL; | 2125 | struct domain_device *dev = NULL; |
2125 | 2126 | ||
2126 | res = sas_find_bcast_dev(port_dev, &dev); | 2127 | res = sas_find_bcast_dev(port_dev, &dev); |
2127 | while (res == 0 && dev) { | 2128 | if (res == 0 && dev) { |
2128 | struct expander_device *ex = &dev->ex_dev; | 2129 | struct expander_device *ex = &dev->ex_dev; |
2129 | int i = 0, phy_id; | 2130 | int i = 0, phy_id; |
2130 | 2131 | ||
@@ -2136,9 +2137,6 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) | |||
2136 | res = sas_rediscover(dev, phy_id); | 2137 | res = sas_rediscover(dev, phy_id); |
2137 | i = phy_id + 1; | 2138 | i = phy_id + 1; |
2138 | } while (i < ex->num_phys); | 2139 | } while (i < ex->num_phys); |
2139 | |||
2140 | dev = NULL; | ||
2141 | res = sas_find_bcast_dev(port_dev, &dev); | ||
2142 | } | 2140 | } |
2143 | return res; | 2141 | return res; |
2144 | } | 2142 | } |
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index d8826a747690..50e12d662ffe 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h | |||
@@ -101,6 +101,7 @@ int sas_try_ata_reset(struct asd_sas_phy *phy); | |||
101 | void sas_hae_reset(struct work_struct *work); | 101 | void sas_hae_reset(struct work_struct *work); |
102 | 102 | ||
103 | void sas_free_device(struct kref *kref); | 103 | void sas_free_device(struct kref *kref); |
104 | void sas_destruct_devices(struct asd_sas_port *port); | ||
104 | 105 | ||
105 | extern const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS]; | 106 | extern const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS]; |
106 | extern const work_func_t sas_port_event_fns[PORT_NUM_EVENTS]; | 107 | extern const work_func_t sas_port_event_fns[PORT_NUM_EVENTS]; |
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index 64722f42b256..f07e55d3aa73 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c | |||
@@ -66,6 +66,7 @@ static void sas_resume_port(struct asd_sas_phy *phy) | |||
66 | rc = sas_notify_lldd_dev_found(dev); | 66 | rc = sas_notify_lldd_dev_found(dev); |
67 | if (rc) { | 67 | if (rc) { |
68 | sas_unregister_dev(port, dev); | 68 | sas_unregister_dev(port, dev); |
69 | sas_destruct_devices(port); | ||
69 | continue; | 70 | continue; |
70 | } | 71 | } |
71 | 72 | ||
@@ -220,6 +221,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone) | |||
220 | 221 | ||
221 | if (port->num_phys == 1) { | 222 | if (port->num_phys == 1) { |
222 | sas_unregister_domain_devices(port, gone); | 223 | sas_unregister_domain_devices(port, gone); |
224 | sas_destruct_devices(port); | ||
223 | sas_port_delete(port->port); | 225 | sas_port_delete(port->port); |
224 | port->port = NULL; | 226 | port->port = NULL; |
225 | } else { | 227 | } else { |
@@ -317,6 +319,7 @@ static void sas_init_port(struct asd_sas_port *port, | |||
317 | INIT_LIST_HEAD(&port->dev_list); | 319 | INIT_LIST_HEAD(&port->dev_list); |
318 | INIT_LIST_HEAD(&port->disco_list); | 320 | INIT_LIST_HEAD(&port->disco_list); |
319 | INIT_LIST_HEAD(&port->destroy_list); | 321 | INIT_LIST_HEAD(&port->destroy_list); |
322 | INIT_LIST_HEAD(&port->sas_port_del_list); | ||
320 | spin_lock_init(&port->phy_list_lock); | 323 | spin_lock_init(&port->phy_list_lock); |
321 | INIT_LIST_HEAD(&port->phy_list); | 324 | INIT_LIST_HEAD(&port->phy_list); |
322 | port->ha = sas_ha; | 325 | port->ha = sas_ha; |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 6255bb5ed1e4..1cab6f7af425 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -82,10 +82,8 @@ enum phy_event { | |||
82 | enum discover_event { | 82 | enum discover_event { |
83 | DISCE_DISCOVER_DOMAIN = 0U, | 83 | DISCE_DISCOVER_DOMAIN = 0U, |
84 | DISCE_REVALIDATE_DOMAIN, | 84 | DISCE_REVALIDATE_DOMAIN, |
85 | DISCE_PROBE, | ||
86 | DISCE_SUSPEND, | 85 | DISCE_SUSPEND, |
87 | DISCE_RESUME, | 86 | DISCE_RESUME, |
88 | DISCE_DESTRUCT, | ||
89 | DISC_NUM_EVENTS, | 87 | DISC_NUM_EVENTS, |
90 | }; | 88 | }; |
91 | 89 | ||
@@ -262,6 +260,7 @@ struct asd_sas_port { | |||
262 | struct list_head dev_list; | 260 | struct list_head dev_list; |
263 | struct list_head disco_list; | 261 | struct list_head disco_list; |
264 | struct list_head destroy_list; | 262 | struct list_head destroy_list; |
263 | struct list_head sas_port_del_list; | ||
265 | enum sas_linkrate linkrate; | 264 | enum sas_linkrate linkrate; |
266 | 265 | ||
267 | struct sas_work work; | 266 | struct sas_work work; |
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 62895b405933..05ec927a3c72 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h | |||
@@ -156,6 +156,7 @@ struct sas_port { | |||
156 | 156 | ||
157 | struct mutex phy_list_mutex; | 157 | struct mutex phy_list_mutex; |
158 | struct list_head phy_list; | 158 | struct list_head phy_list; |
159 | struct list_head del_list; /* libsas only */ | ||
159 | }; | 160 | }; |
160 | 161 | ||
161 | #define dev_to_sas_port(d) \ | 162 | #define dev_to_sas_port(d) \ |