diff options
| -rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 1 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 9 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 55 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_unit.c | 8 | ||||
| -rw-r--r-- | drivers/scsi/cxgbi/libcxgbi.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/device_handler/scsi_dh_alua.c | 6 | ||||
| -rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/libsas/sas_phy.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/smartpqi/smartpqi_init.c | 2 |
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[]; | |||
| 167 | extern struct mutex zfcp_sysfs_port_units_mutex; | 167 | extern struct mutex zfcp_sysfs_port_units_mutex; |
| 168 | extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; | 168 | extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; |
| 169 | extern struct device_attribute *zfcp_sysfs_shost_attrs[]; | 169 | extern struct device_attribute *zfcp_sysfs_shost_attrs[]; |
| 170 | bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port); | ||
| 170 | 171 | ||
| 171 | /* zfcp_unit.c */ | 172 | /* zfcp_unit.c */ |
| 172 | extern int zfcp_unit_add(struct zfcp_port *, u64); | 173 | extern 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 | ||
| 236 | DEFINE_MUTEX(zfcp_sysfs_port_units_mutex); | 236 | DEFINE_MUTEX(zfcp_sysfs_port_units_mutex); |
| 237 | 237 | ||
| 238 | static 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 | |||
| 244 | bool 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 | |||
| 250 | static 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 | |||
| 278 | unlock_host_lock: | ||
| 279 | spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); | ||
| 280 | unlock_port_units_mutex: | ||
| 281 | mutex_unlock(&zfcp_sysfs_port_units_mutex); | ||
| 282 | return in_use; | ||
| 283 | } | ||
| 284 | |||
| 238 | static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, | 285 | static 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 | ||
| 174 | out: | 180 | out: |
| 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; |
