aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/scsi/zfcp_aux.c27
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c7
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/s390/scsi/zfcp_erp.c6
-rw-r--r--drivers/s390/scsi/zfcp_fc.c1
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c70
6 files changed, 34 insertions, 78 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 12de1ce9a92d..6b94f8d0609c 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -245,9 +245,9 @@ struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
245 245
246 read_lock_irqsave(&port->unit_list_lock, flags); 246 read_lock_irqsave(&port->unit_list_lock, flags);
247 list_for_each_entry(unit, &port->unit_list, list) 247 list_for_each_entry(unit, &port->unit_list, list)
248 if ((unit->fcp_lun == fcp_lun) && 248 if (unit->fcp_lun == fcp_lun) {
249 !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE)) { 249 if (!get_device(&unit->sysfs_device))
250 get_device(&unit->sysfs_device); 250 unit = NULL;
251 read_unlock_irqrestore(&port->unit_list_lock, flags); 251 read_unlock_irqrestore(&port->unit_list_lock, flags);
252 return unit; 252 return unit;
253 } 253 }
@@ -270,9 +270,9 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
270 270
271 read_lock_irqsave(&adapter->port_list_lock, flags); 271 read_lock_irqsave(&adapter->port_list_lock, flags);
272 list_for_each_entry(port, &adapter->port_list, list) 272 list_for_each_entry(port, &adapter->port_list, list)
273 if ((port->wwpn == wwpn) && 273 if (port->wwpn == wwpn) {
274 !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE)) { 274 if (!get_device(&port->sysfs_device))
275 get_device(&port->sysfs_device); 275 port = NULL;
276 read_unlock_irqrestore(&adapter->port_list_lock, flags); 276 read_unlock_irqrestore(&adapter->port_list_lock, flags);
277 return port; 277 return port;
278 } 278 }
@@ -334,9 +334,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
334 } 334 }
335 retval = -EINVAL; 335 retval = -EINVAL;
336 336
337 /* mark unit unusable as long as sysfs registration is not complete */
338 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
339
340 INIT_WORK(&unit->scsi_work, zfcp_scsi_scan); 337 INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
341 338
342 spin_lock_init(&unit->latencies.lock); 339 spin_lock_init(&unit->latencies.lock);
@@ -360,7 +357,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
360 list_add_tail(&unit->list, &port->unit_list); 357 list_add_tail(&unit->list, &port->unit_list);
361 write_unlock_irq(&port->unit_list_lock); 358 write_unlock_irq(&port->unit_list_lock);
362 359
363 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
364 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); 360 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
365 361
366 return unit; 362 return unit;
@@ -565,17 +561,12 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
565 561
566 adapter->service_level.seq_print = zfcp_print_sl; 562 adapter->service_level.seq_print = zfcp_print_sl;
567 563
568 /* mark adapter unusable as long as sysfs registration is not complete */
569 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
570
571 dev_set_drvdata(&ccw_device->dev, adapter); 564 dev_set_drvdata(&ccw_device->dev, adapter);
572 565
573 if (sysfs_create_group(&ccw_device->dev.kobj, 566 if (sysfs_create_group(&ccw_device->dev.kobj,
574 &zfcp_sysfs_adapter_attrs)) 567 &zfcp_sysfs_adapter_attrs))
575 goto failed; 568 goto failed;
576 569
577 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
578
579 if (!zfcp_adapter_scsi_register(adapter)) 570 if (!zfcp_adapter_scsi_register(adapter))
580 return adapter; 571 return adapter;
581 572
@@ -692,9 +683,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
692 port->sysfs_device.parent = &adapter->ccw_device->dev; 683 port->sysfs_device.parent = &adapter->ccw_device->dev;
693 port->sysfs_device.release = zfcp_port_release; 684 port->sysfs_device.release = zfcp_port_release;
694 685
695 /* mark port unusable as long as sysfs registration is not complete */
696 atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
697
698 if (dev_set_name(&port->sysfs_device, "0x%016llx", 686 if (dev_set_name(&port->sysfs_device, "0x%016llx",
699 (unsigned long long)wwpn)) { 687 (unsigned long long)wwpn)) {
700 kfree(port); 688 kfree(port);
@@ -715,8 +703,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
715 list_add_tail(&port->list, &adapter->port_list); 703 list_add_tail(&port->list, &adapter->port_list);
716 write_unlock_irq(&adapter->port_list_lock); 704 write_unlock_irq(&adapter->port_list_lock);
717 705
718 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); 706 atomic_set_mask(status | ZFCP_STATUS_COMMON_RUNNING, &port->status);
719 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
720 707
721 return port; 708 return port;
722 709
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 4d35902a0cc5..c22cb72a5ae8 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -113,16 +113,11 @@ static void zfcp_ccw_remove(struct ccw_device *cdev)
113 write_lock_irq(&adapter->port_list_lock); 113 write_lock_irq(&adapter->port_list_lock);
114 list_for_each_entry_safe(port, p, &adapter->port_list, list) { 114 list_for_each_entry_safe(port, p, &adapter->port_list, list) {
115 write_lock(&port->unit_list_lock); 115 write_lock(&port->unit_list_lock);
116 list_for_each_entry_safe(unit, u, &port->unit_list, list) { 116 list_for_each_entry_safe(unit, u, &port->unit_list, list)
117 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
118 &unit->status);
119 list_move(&unit->list, &unit_remove_lh); 117 list_move(&unit->list, &unit_remove_lh);
120 }
121 write_unlock(&port->unit_list_lock); 118 write_unlock(&port->unit_list_lock);
122 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
123 list_move(&port->list, &port_remove_lh); 119 list_move(&port->list, &port_remove_lh);
124 } 120 }
125 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
126 write_unlock_irq(&adapter->port_list_lock); 121 write_unlock_irq(&adapter->port_list_lock);
127 zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */ 122 zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
128 123
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 7e84e1624d16..08fa31302f75 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -205,7 +205,6 @@ struct zfcp_ls_adisc {
205#define ZFCP_COMMON_FLAGS 0xfff00000 205#define ZFCP_COMMON_FLAGS 0xfff00000
206 206
207/* common status bits */ 207/* common status bits */
208#define ZFCP_STATUS_COMMON_REMOVE 0x80000000
209#define ZFCP_STATUS_COMMON_RUNNING 0x40000000 208#define ZFCP_STATUS_COMMON_RUNNING 0x40000000
210#define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000 209#define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000
211#define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000 210#define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 788fd3a4cd23..3454c2a3b6b1 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -174,7 +174,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
174 174
175 switch (need) { 175 switch (need) {
176 case ZFCP_ERP_ACTION_REOPEN_UNIT: 176 case ZFCP_ERP_ACTION_REOPEN_UNIT:
177 get_device(&unit->sysfs_device); 177 if (!get_device(&unit->sysfs_device))
178 return NULL;
178 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); 179 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
179 erp_action = &unit->erp_action; 180 erp_action = &unit->erp_action;
180 if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) 181 if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
@@ -183,7 +184,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
183 184
184 case ZFCP_ERP_ACTION_REOPEN_PORT: 185 case ZFCP_ERP_ACTION_REOPEN_PORT:
185 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: 186 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
186 get_device(&port->sysfs_device); 187 if (!get_device(&port->sysfs_device))
188 return NULL;
187 zfcp_erp_action_dismiss_port(port); 189 zfcp_erp_action_dismiss_port(port);
188 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); 190 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
189 erp_action = &port->erp_action; 191 erp_action = &port->erp_action;
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 3e3e72cc724b..9252b65a13a5 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -589,7 +589,6 @@ static void zfcp_fc_validate_port(struct zfcp_port *port, struct list_head *lh)
589 !list_empty(&port->unit_list)) 589 !list_empty(&port->unit_list))
590 return; 590 return;
591 591
592 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
593 list_move_tail(&port->list, lh); 592 list_move_tail(&port->list, lh);
594} 593}
595 594
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 901cc9a6ed20..35e920b4fd8a 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -104,10 +104,8 @@ static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \
104 unsigned long val; \ 104 unsigned long val; \
105 int retval = 0; \ 105 int retval = 0; \
106 \ 106 \
107 if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_REMOVE) { \ 107 if (!(_feat && get_device(&_feat->sysfs_device))) \
108 retval = -EBUSY; \ 108 return -EBUSY; \
109 goto out; \
110 } \
111 \ 109 \
112 if (strict_strtoul(buf, 0, &val) || val != 0) { \ 110 if (strict_strtoul(buf, 0, &val) || val != 0) { \
113 retval = -EINVAL; \ 111 retval = -EINVAL; \
@@ -120,6 +118,7 @@ static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \
120 _reopen_id, NULL); \ 118 _reopen_id, NULL); \
121 zfcp_erp_wait(_adapter); \ 119 zfcp_erp_wait(_adapter); \
122out: \ 120out: \
121 put_device(&_feat->sysfs_device); \
123 return retval ? retval : (ssize_t) count; \ 122 return retval ? retval : (ssize_t) count; \
124} \ 123} \
125static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \ 124static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \
@@ -161,11 +160,6 @@ static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev,
161 if (!adapter) 160 if (!adapter)
162 return -ENODEV; 161 return -ENODEV;
163 162
164 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
165 retval = -EBUSY;
166 goto out;
167 }
168
169 if (strict_strtoul(buf, 0, &val) || val != 0) { 163 if (strict_strtoul(buf, 0, &val) || val != 0) {
170 retval = -EINVAL; 164 retval = -EINVAL;
171 goto out; 165 goto out;
@@ -195,14 +189,9 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
195 if (!adapter) 189 if (!adapter)
196 return -ENODEV; 190 return -ENODEV;
197 191
198 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
199 ret = -EBUSY;
200 goto out;
201 }
202
203 ret = zfcp_fc_scan_ports(adapter); 192 ret = zfcp_fc_scan_ports(adapter);
204out:
205 zfcp_ccw_adapter_put(adapter); 193 zfcp_ccw_adapter_put(adapter);
194
206 return ret ? ret : (ssize_t) count; 195 return ret ? ret : (ssize_t) count;
207} 196}
208static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL, 197static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
@@ -216,28 +205,19 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
216 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 205 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
217 struct zfcp_port *port; 206 struct zfcp_port *port;
218 u64 wwpn; 207 u64 wwpn;
219 int retval = 0; 208 int retval = -EINVAL;
220 209
221 if (!adapter) 210 if (!adapter)
222 return -ENODEV; 211 return -ENODEV;
223 212
224 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { 213 if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn))
225 retval = -EBUSY;
226 goto out; 214 goto out;
227 }
228
229 if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) {
230 retval = -EINVAL;
231 goto out;
232 }
233 215
234 port = zfcp_get_port_by_wwpn(adapter, wwpn); 216 port = zfcp_get_port_by_wwpn(adapter, wwpn);
235 if (!port) { 217 if (!port)
236 retval = -ENXIO;
237 goto out; 218 goto out;
238 } 219 else
239 220 retval = 0;
240 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
241 221
242 write_lock_irq(&adapter->port_list_lock); 222 write_lock_irq(&adapter->port_list_lock);
243 list_del(&port->list); 223 list_del(&port->list);
@@ -283,10 +263,8 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
283 u64 fcp_lun; 263 u64 fcp_lun;
284 int retval = -EINVAL; 264 int retval = -EINVAL;
285 265
286 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { 266 if (!(port && get_device(&port->sysfs_device)))
287 retval = -EBUSY; 267 return -EBUSY;
288 goto out;
289 }
290 268
291 if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) 269 if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
292 goto out; 270 goto out;
@@ -294,13 +272,14 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
294 unit = zfcp_unit_enqueue(port, fcp_lun); 272 unit = zfcp_unit_enqueue(port, fcp_lun);
295 if (IS_ERR(unit)) 273 if (IS_ERR(unit))
296 goto out; 274 goto out;
297 275 else
298 retval = 0; 276 retval = 0;
299 277
300 zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); 278 zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
301 zfcp_erp_wait(unit->port->adapter); 279 zfcp_erp_wait(unit->port->adapter);
302 flush_work(&unit->scsi_work); 280 flush_work(&unit->scsi_work);
303out: 281out:
282 put_device(&port->sysfs_device);
304 return retval ? retval : (ssize_t) count; 283 return retval ? retval : (ssize_t) count;
305} 284}
306static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store); 285static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
@@ -313,29 +292,23 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
313 sysfs_device); 292 sysfs_device);
314 struct zfcp_unit *unit; 293 struct zfcp_unit *unit;
315 u64 fcp_lun; 294 u64 fcp_lun;
316 int retval = 0; 295 int retval = -EINVAL;
317 296
318 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { 297 if (!(port && get_device(&port->sysfs_device)))
319 retval = -EBUSY; 298 return -EBUSY;
320 goto out;
321 }
322 299
323 if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) { 300 if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
324 retval = -EINVAL;
325 goto out; 301 goto out;
326 }
327 302
328 unit = zfcp_get_unit_by_lun(port, fcp_lun); 303 unit = zfcp_get_unit_by_lun(port, fcp_lun);
329 if (!unit) { 304 if (!unit)
330 retval = -EINVAL;
331 goto out; 305 goto out;
332 } 306 else
307 retval = 0;
333 308
334 /* wait for possible timeout during SCSI probe */ 309 /* wait for possible timeout during SCSI probe */
335 flush_work(&unit->scsi_work); 310 flush_work(&unit->scsi_work);
336 311
337 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
338
339 write_lock_irq(&port->unit_list_lock); 312 write_lock_irq(&port->unit_list_lock);
340 list_del(&unit->list); 313 list_del(&unit->list);
341 write_unlock_irq(&port->unit_list_lock); 314 write_unlock_irq(&port->unit_list_lock);
@@ -345,6 +318,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
345 zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); 318 zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
346 zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs); 319 zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs);
347out: 320out:
321 put_device(&port->sysfs_device);
348 return retval ? retval : (ssize_t) count; 322 return retval ? retval : (ssize_t) count;
349} 323}
350static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); 324static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);