aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c9
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c55
-rw-r--r--drivers/s390/scsi/zfcp_unit.c8
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c4
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c6
-rw-r--r--drivers/scsi/libsas/sas_expander.c2
-rw-r--r--drivers/scsi/libsas/sas_phy.c3
-rw-r--r--drivers/scsi/smartpqi/smartpqi_init.c2
9 files changed, 76 insertions, 14 deletions
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index c6acca521ffe..31e8a7240fd7 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -167,6 +167,7 @@ extern const struct attribute_group *zfcp_port_attr_groups[];
167extern struct mutex zfcp_sysfs_port_units_mutex; 167extern struct mutex zfcp_sysfs_port_units_mutex;
168extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; 168extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
169extern struct device_attribute *zfcp_sysfs_shost_attrs[]; 169extern struct device_attribute *zfcp_sysfs_shost_attrs[];
170bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port);
170 171
171/* zfcp_unit.c */ 172/* zfcp_unit.c */
172extern int zfcp_unit_add(struct zfcp_port *, u64); 173extern int zfcp_unit_add(struct zfcp_port *, u64);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 221d0dfb8493..e9ded2befa0d 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -129,6 +129,15 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
129 129
130 zfcp_sdev->erp_action.port = port; 130 zfcp_sdev->erp_action.port = port;
131 131
132 mutex_lock(&zfcp_sysfs_port_units_mutex);
133 if (zfcp_sysfs_port_is_removing(port)) {
134 /* port is already gone */
135 mutex_unlock(&zfcp_sysfs_port_units_mutex);
136 put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
137 return -ENXIO;
138 }
139 mutex_unlock(&zfcp_sysfs_port_units_mutex);
140
132 unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev)); 141 unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
133 if (unit) 142 if (unit)
134 put_device(&unit->dev); 143 put_device(&unit->dev);
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index b277be6f7611..af197e2b3e69 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -235,6 +235,53 @@ static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
235 235
236DEFINE_MUTEX(zfcp_sysfs_port_units_mutex); 236DEFINE_MUTEX(zfcp_sysfs_port_units_mutex);
237 237
238static void zfcp_sysfs_port_set_removing(struct zfcp_port *const port)
239{
240 lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
241 atomic_set(&port->units, -1);
242}
243
244bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port)
245{
246 lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
247 return atomic_read(&port->units) == -1;
248}
249
250static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port)
251{
252 struct zfcp_adapter *const adapter = port->adapter;
253 unsigned long flags;
254 struct scsi_device *sdev;
255 bool in_use = true;
256
257 mutex_lock(&zfcp_sysfs_port_units_mutex);
258 if (atomic_read(&port->units) > 0)
259 goto unlock_port_units_mutex; /* zfcp_unit(s) under port */
260
261 spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
262 __shost_for_each_device(sdev, adapter->scsi_host) {
263 const struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
264
265 if (sdev->sdev_state == SDEV_DEL ||
266 sdev->sdev_state == SDEV_CANCEL)
267 continue;
268 if (zsdev->port != port)
269 continue;
270 /* alive scsi_device under port of interest */
271 goto unlock_host_lock;
272 }
273
274 /* port is about to be removed, so no more unit_add or slave_alloc */
275 zfcp_sysfs_port_set_removing(port);
276 in_use = false;
277
278unlock_host_lock:
279 spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags);
280unlock_port_units_mutex:
281 mutex_unlock(&zfcp_sysfs_port_units_mutex);
282 return in_use;
283}
284
238static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, 285static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
239 struct device_attribute *attr, 286 struct device_attribute *attr,
240 const char *buf, size_t count) 287 const char *buf, size_t count)
@@ -257,15 +304,11 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
257 else 304 else
258 retval = 0; 305 retval = 0;
259 306
260 mutex_lock(&zfcp_sysfs_port_units_mutex); 307 if (zfcp_sysfs_port_in_use(port)) {
261 if (atomic_read(&port->units) > 0) {
262 retval = -EBUSY; 308 retval = -EBUSY;
263 mutex_unlock(&zfcp_sysfs_port_units_mutex); 309 put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
264 goto out; 310 goto out;
265 } 311 }
266 /* port is about to be removed, so no more unit_add */
267 atomic_set(&port->units, -1);
268 mutex_unlock(&zfcp_sysfs_port_units_mutex);
269 312
270 write_lock_irq(&adapter->port_list_lock); 313 write_lock_irq(&adapter->port_list_lock);
271 list_del(&port->list); 314 list_del(&port->list);
diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c
index 1bf0a0984a09..e67bf7388cae 100644
--- a/drivers/s390/scsi/zfcp_unit.c
+++ b/drivers/s390/scsi/zfcp_unit.c
@@ -124,7 +124,7 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
124 int retval = 0; 124 int retval = 0;
125 125
126 mutex_lock(&zfcp_sysfs_port_units_mutex); 126 mutex_lock(&zfcp_sysfs_port_units_mutex);
127 if (atomic_read(&port->units) == -1) { 127 if (zfcp_sysfs_port_is_removing(port)) {
128 /* port is already gone */ 128 /* port is already gone */
129 retval = -ENODEV; 129 retval = -ENODEV;
130 goto out; 130 goto out;
@@ -168,8 +168,14 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
168 write_lock_irq(&port->unit_list_lock); 168 write_lock_irq(&port->unit_list_lock);
169 list_add_tail(&unit->list, &port->unit_list); 169 list_add_tail(&unit->list, &port->unit_list);
170 write_unlock_irq(&port->unit_list_lock); 170 write_unlock_irq(&port->unit_list_lock);
171 /*
172 * lock order: shost->scan_mutex before zfcp_sysfs_port_units_mutex
173 * due to zfcp_unit_scsi_scan() => zfcp_scsi_slave_alloc()
174 */
175 mutex_unlock(&zfcp_sysfs_port_units_mutex);
171 176
172 zfcp_unit_scsi_scan(unit); 177 zfcp_unit_scsi_scan(unit);
178 return retval;
173 179
174out: 180out:
175 mutex_unlock(&zfcp_sysfs_port_units_mutex); 181 mutex_unlock(&zfcp_sysfs_port_units_mutex);
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index 8b915d4ed98d..7d43e014bd21 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -639,6 +639,10 @@ cxgbi_check_route(struct sockaddr *dst_addr, int ifindex)
639 639
640 if (ndev->flags & IFF_LOOPBACK) { 640 if (ndev->flags & IFF_LOOPBACK) {
641 ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr); 641 ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr);
642 if (!ndev) {
643 err = -ENETUNREACH;
644 goto rel_neigh;
645 }
642 mtu = ndev->mtu; 646 mtu = ndev->mtu;
643 pr_info("rt dev %s, loopback -> %s, mtu %u.\n", 647 pr_info("rt dev %s, loopback -> %s, mtu %u.\n",
644 n->dev->name, ndev->name, mtu); 648 n->dev->name, ndev->name, mtu);
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index a7a4a772f501..f0066f8a1786 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -1160,10 +1160,8 @@ static int __init alua_init(void)
1160 int r; 1160 int r;
1161 1161
1162 kaluad_wq = alloc_workqueue("kaluad", WQ_MEM_RECLAIM, 0); 1162 kaluad_wq = alloc_workqueue("kaluad", WQ_MEM_RECLAIM, 0);
1163 if (!kaluad_wq) { 1163 if (!kaluad_wq)
1164 /* Temporary failure, bypass */ 1164 return -ENOMEM;
1165 return SCSI_DH_DEV_TEMP_BUSY;
1166 }
1167 1165
1168 r = scsi_register_device_handler(&alua_dh); 1166 r = scsi_register_device_handler(&alua_dh);
1169 if (r != 0) { 1167 if (r != 0) {
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 83f2fd70ce76..9f7e2457360e 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -1019,6 +1019,8 @@ static struct domain_device *sas_ex_discover_expander(
1019 list_del(&child->dev_list_node); 1019 list_del(&child->dev_list_node);
1020 spin_unlock_irq(&parent->port->dev_list_lock); 1020 spin_unlock_irq(&parent->port->dev_list_lock);
1021 sas_put_device(child); 1021 sas_put_device(child);
1022 sas_port_delete(phy->port);
1023 phy->port = NULL;
1022 return NULL; 1024 return NULL;
1023 } 1025 }
1024 list_add_tail(&child->siblings, &parent->ex_dev.children); 1026 list_add_tail(&child->siblings, &parent->ex_dev.children);
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c
index e030e1452136..b71f5ac6c7dc 100644
--- a/drivers/scsi/libsas/sas_phy.c
+++ b/drivers/scsi/libsas/sas_phy.c
@@ -35,7 +35,6 @@ static void sas_phye_loss_of_signal(struct work_struct *work)
35 struct asd_sas_event *ev = to_asd_sas_event(work); 35 struct asd_sas_event *ev = to_asd_sas_event(work);
36 struct asd_sas_phy *phy = ev->phy; 36 struct asd_sas_phy *phy = ev->phy;
37 37
38 phy->in_shutdown = 0;
39 phy->error = 0; 38 phy->error = 0;
40 sas_deform_port(phy, 1); 39 sas_deform_port(phy, 1);
41} 40}
@@ -45,7 +44,6 @@ static void sas_phye_oob_done(struct work_struct *work)
45 struct asd_sas_event *ev = to_asd_sas_event(work); 44 struct asd_sas_event *ev = to_asd_sas_event(work);
46 struct asd_sas_phy *phy = ev->phy; 45 struct asd_sas_phy *phy = ev->phy;
47 46
48 phy->in_shutdown = 0;
49 phy->error = 0; 47 phy->error = 0;
50} 48}
51 49
@@ -126,6 +124,7 @@ static void sas_phye_shutdown(struct work_struct *work)
126 ret); 124 ret);
127 } else 125 } else
128 pr_notice("phy%d is not enabled, cannot shutdown\n", phy->id); 126 pr_notice("phy%d is not enabled, cannot shutdown\n", phy->id);
127 phy->in_shutdown = 0;
129} 128}
130 129
131/* ---------- Phy class registration ---------- */ 130/* ---------- Phy class registration ---------- */
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index b17761eafca9..d6be4e8f4a8f 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -7291,7 +7291,7 @@ static int pqi_pci_init(struct pqi_ctrl_info *ctrl_info)
7291 else 7291 else
7292 mask = DMA_BIT_MASK(32); 7292 mask = DMA_BIT_MASK(32);
7293 7293
7294 rc = dma_set_mask(&ctrl_info->pci_dev->dev, mask); 7294 rc = dma_set_mask_and_coherent(&ctrl_info->pci_dev->dev, mask);
7295 if (rc) { 7295 if (rc) {
7296 dev_err(&ctrl_info->pci_dev->dev, "failed to set DMA mask\n"); 7296 dev_err(&ctrl_info->pci_dev->dev, "failed to set DMA mask\n");
7297 goto disable_device; 7297 goto disable_device;