aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2009-11-24 10:53:59 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:02:02 -0500
commitf3450c7b917201bb49d67032e9f60d5125675d6a (patch)
tree404b1c23490b0a5ba3d6cbbb14e64381a12a108a /drivers/s390
parentecf0c7721b104c0ce9c8ca534c911f6310cf92a8 (diff)
[SCSI] zfcp: Replace local reference counting with common kref
Replace the local reference counting by already available mechanisms offered by kref. Where possible existing device structures were used, including the same functionality. Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c231
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c16
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c5
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c2
-rw-r--r--drivers/s390/scsi/zfcp_def.h53
-rw-r--r--drivers/s390/scsi/zfcp_erp.c20
-rw-r--r--drivers/s390/scsi/zfcp_ext.h6
-rw-r--r--drivers/s390/scsi/zfcp_fc.c42
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c12
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c23
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c44
11 files changed, 196 insertions, 258 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 883e13948ace..8492ceac1409 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -96,13 +96,12 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
96 adapter = dev_get_drvdata(&ccwdev->dev); 96 adapter = dev_get_drvdata(&ccwdev->dev);
97 if (!adapter) 97 if (!adapter)
98 goto out_unlock; 98 goto out_unlock;
99 zfcp_adapter_get(adapter); 99 kref_get(&adapter->ref);
100 100
101 port = zfcp_get_port_by_wwpn(adapter, wwpn); 101 port = zfcp_get_port_by_wwpn(adapter, wwpn);
102 if (!port) 102 if (!port)
103 goto out_port; 103 goto out_port;
104 104
105 zfcp_port_get(port);
106 unit = zfcp_unit_enqueue(port, lun); 105 unit = zfcp_unit_enqueue(port, lun);
107 if (IS_ERR(unit)) 106 if (IS_ERR(unit))
108 goto out_unit; 107 goto out_unit;
@@ -113,11 +112,10 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
113 flush_work(&unit->scsi_work); 112 flush_work(&unit->scsi_work);
114 113
115 mutex_lock(&zfcp_data.config_mutex); 114 mutex_lock(&zfcp_data.config_mutex);
116 zfcp_unit_put(unit);
117out_unit: 115out_unit:
118 zfcp_port_put(port); 116 put_device(&port->sysfs_device);
119out_port: 117out_port:
120 zfcp_adapter_put(adapter); 118 kref_put(&adapter->ref, zfcp_adapter_release);
121out_unlock: 119out_unlock:
122 mutex_unlock(&zfcp_data.config_mutex); 120 mutex_unlock(&zfcp_data.config_mutex);
123out_ccwdev: 121out_ccwdev:
@@ -244,7 +242,7 @@ struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
244 list_for_each_entry(unit, &port->unit_list, list) 242 list_for_each_entry(unit, &port->unit_list, list)
245 if ((unit->fcp_lun == fcp_lun) && 243 if ((unit->fcp_lun == fcp_lun) &&
246 !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE)) { 244 !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE)) {
247 zfcp_unit_get(unit); 245 get_device(&unit->sysfs_device);
248 read_unlock_irqrestore(&port->unit_list_lock, flags); 246 read_unlock_irqrestore(&port->unit_list_lock, flags);
249 return unit; 247 return unit;
250 } 248 }
@@ -269,7 +267,7 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
269 list_for_each_entry(port, &adapter->port_list, list) 267 list_for_each_entry(port, &adapter->port_list, list)
270 if ((port->wwpn == wwpn) && 268 if ((port->wwpn == wwpn) &&
271 !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE)) { 269 !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE)) {
272 zfcp_port_get(port); 270 get_device(&port->sysfs_device);
273 read_unlock_irqrestore(&adapter->port_list_lock, flags); 271 read_unlock_irqrestore(&adapter->port_list_lock, flags);
274 return port; 272 return port;
275 } 273 }
@@ -277,9 +275,20 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
277 return NULL; 275 return NULL;
278} 276}
279 277
280static void zfcp_sysfs_unit_release(struct device *dev) 278/**
279 * zfcp_unit_release - dequeue unit
280 * @dev: pointer to device
281 *
282 * waits until all work is done on unit and removes it then from the unit->list
283 * of the associated port.
284 */
285static void zfcp_unit_release(struct device *dev)
281{ 286{
282 kfree(container_of(dev, struct zfcp_unit, sysfs_device)); 287 struct zfcp_unit *unit = container_of(dev, struct zfcp_unit,
288 sysfs_device);
289
290 put_device(&unit->port->sysfs_device);
291 kfree(unit);
283} 292}
284 293
285/** 294/**
@@ -294,36 +303,39 @@ static void zfcp_sysfs_unit_release(struct device *dev)
294struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun) 303struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
295{ 304{
296 struct zfcp_unit *unit; 305 struct zfcp_unit *unit;
306 int retval = -ENOMEM;
307
308 get_device(&port->sysfs_device);
297 309
298 unit = zfcp_get_unit_by_lun(port, fcp_lun); 310 unit = zfcp_get_unit_by_lun(port, fcp_lun);
299 if (unit) { 311 if (unit) {
300 zfcp_unit_put(unit); 312 put_device(&unit->sysfs_device);
301 return ERR_PTR(-EINVAL); 313 retval = -EEXIST;
314 goto err_out;
302 } 315 }
303 316
304 unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); 317 unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
305 if (!unit) 318 if (!unit)
306 return ERR_PTR(-ENOMEM); 319 goto err_out;
307
308 atomic_set(&unit->refcount, 0);
309 init_waitqueue_head(&unit->remove_wq);
310 INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
311 320
312 unit->port = port; 321 unit->port = port;
313 unit->fcp_lun = fcp_lun; 322 unit->fcp_lun = fcp_lun;
323 unit->sysfs_device.parent = &port->sysfs_device;
324 unit->sysfs_device.release = zfcp_unit_release;
314 325
315 if (dev_set_name(&unit->sysfs_device, "0x%016llx", 326 if (dev_set_name(&unit->sysfs_device, "0x%016llx",
316 (unsigned long long) fcp_lun)) { 327 (unsigned long long) fcp_lun)) {
317 kfree(unit); 328 kfree(unit);
318 return ERR_PTR(-ENOMEM); 329 goto err_out;
319 } 330 }
320 unit->sysfs_device.parent = &port->sysfs_device;
321 unit->sysfs_device.release = zfcp_sysfs_unit_release;
322 dev_set_drvdata(&unit->sysfs_device, unit); 331 dev_set_drvdata(&unit->sysfs_device, unit);
332 retval = -EINVAL;
323 333
324 /* mark unit unusable as long as sysfs registration is not complete */ 334 /* mark unit unusable as long as sysfs registration is not complete */
325 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); 335 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
326 336
337 INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
338
327 spin_lock_init(&unit->latencies.lock); 339 spin_lock_init(&unit->latencies.lock);
328 unit->latencies.write.channel.min = 0xFFFFFFFF; 340 unit->latencies.write.channel.min = 0xFFFFFFFF;
329 unit->latencies.write.fabric.min = 0xFFFFFFFF; 341 unit->latencies.write.fabric.min = 0xFFFFFFFF;
@@ -334,16 +346,12 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
334 346
335 if (device_register(&unit->sysfs_device)) { 347 if (device_register(&unit->sysfs_device)) {
336 put_device(&unit->sysfs_device); 348 put_device(&unit->sysfs_device);
337 return ERR_PTR(-EINVAL); 349 goto err_out;
338 } 350 }
339 351
340 if (sysfs_create_group(&unit->sysfs_device.kobj, 352 if (sysfs_create_group(&unit->sysfs_device.kobj,
341 &zfcp_sysfs_unit_attrs)) { 353 &zfcp_sysfs_unit_attrs))
342 device_unregister(&unit->sysfs_device); 354 goto err_out_put;
343 return ERR_PTR(-EINVAL);
344 }
345
346 zfcp_unit_get(unit);
347 355
348 write_lock_irq(&port->unit_list_lock); 356 write_lock_irq(&port->unit_list_lock);
349 list_add_tail(&unit->list, &port->unit_list); 357 list_add_tail(&unit->list, &port->unit_list);
@@ -352,27 +360,13 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
352 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); 360 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
353 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); 361 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
354 362
355 zfcp_port_get(port);
356
357 return unit; 363 return unit;
358}
359
360/**
361 * zfcp_unit_dequeue - dequeue unit
362 * @unit: pointer to zfcp_unit
363 *
364 * waits until all work is done on unit and removes it then from the unit->list
365 * of the associated port.
366 */
367void zfcp_unit_dequeue(struct zfcp_unit *unit)
368{
369 struct zfcp_port *port = unit->port;
370 364
371 wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0); 365err_out_put:
372 list_del(&unit->list); /* no list locking required */
373 zfcp_port_put(port);
374 sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs);
375 device_unregister(&unit->sysfs_device); 366 device_unregister(&unit->sysfs_device);
367err_out:
368 put_device(&port->sysfs_device);
369 return ERR_PTR(retval);
376} 370}
377 371
378static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) 372static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
@@ -518,41 +512,44 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
518{ 512{
519 struct zfcp_adapter *adapter; 513 struct zfcp_adapter *adapter;
520 514
521 /* 515 if (!get_device(&ccw_device->dev))
522 * Note: It is safe to release the list_lock, as any list changes 516 return -ENODEV;
523 * are protected by the config_mutex, which must be held to get here
524 */
525 517
526 adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL); 518 adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
527 if (!adapter) 519 if (!adapter) {
520 put_device(&ccw_device->dev);
528 return -ENOMEM; 521 return -ENOMEM;
522 }
523
524 kref_init(&adapter->ref);
529 525
530 ccw_device->handler = NULL; 526 ccw_device->handler = NULL;
531 adapter->ccw_device = ccw_device; 527 adapter->ccw_device = ccw_device;
532 atomic_set(&adapter->refcount, 0); 528
529 INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
530 INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
533 531
534 if (zfcp_qdio_setup(adapter)) 532 if (zfcp_qdio_setup(adapter))
535 goto qdio_failed; 533 goto failed;
536 534
537 if (zfcp_allocate_low_mem_buffers(adapter)) 535 if (zfcp_allocate_low_mem_buffers(adapter))
538 goto low_mem_buffers_failed; 536 goto failed;
539 537
540 if (zfcp_reqlist_alloc(adapter)) 538 if (zfcp_reqlist_alloc(adapter))
541 goto low_mem_buffers_failed; 539 goto failed;
542 540
543 if (zfcp_dbf_adapter_register(adapter)) 541 if (zfcp_dbf_adapter_register(adapter))
544 goto debug_register_failed; 542 goto failed;
545 543
546 if (zfcp_setup_adapter_work_queue(adapter)) 544 if (zfcp_setup_adapter_work_queue(adapter))
547 goto work_queue_failed; 545 goto failed;
548 546
549 if (zfcp_fc_gs_setup(adapter)) 547 if (zfcp_fc_gs_setup(adapter))
550 goto generic_services_failed; 548 goto failed;
551 549
552 rwlock_init(&adapter->port_list_lock); 550 rwlock_init(&adapter->port_list_lock);
553 INIT_LIST_HEAD(&adapter->port_list); 551 INIT_LIST_HEAD(&adapter->port_list);
554 552
555 init_waitqueue_head(&adapter->remove_wq);
556 init_waitqueue_head(&adapter->erp_ready_wq); 553 init_waitqueue_head(&adapter->erp_ready_wq);
557 init_waitqueue_head(&adapter->erp_done_wqh); 554 init_waitqueue_head(&adapter->erp_done_wqh);
558 555
@@ -565,10 +562,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
565 rwlock_init(&adapter->abort_lock); 562 rwlock_init(&adapter->abort_lock);
566 563
567 if (zfcp_erp_thread_setup(adapter)) 564 if (zfcp_erp_thread_setup(adapter))
568 goto erp_thread_failed; 565 goto failed;
569
570 INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
571 INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
572 566
573 adapter->service_level.seq_print = zfcp_print_sl; 567 adapter->service_level.seq_print = zfcp_print_sl;
574 568
@@ -579,54 +573,37 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
579 573
580 if (sysfs_create_group(&ccw_device->dev.kobj, 574 if (sysfs_create_group(&ccw_device->dev.kobj,
581 &zfcp_sysfs_adapter_attrs)) 575 &zfcp_sysfs_adapter_attrs))
582 goto sysfs_failed; 576 goto failed;
583 577
584 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); 578 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
585 579
586 if (!zfcp_adapter_scsi_register(adapter)) 580 if (!zfcp_adapter_scsi_register(adapter))
587 return 0; 581 return 0;
588 582
589sysfs_failed: 583failed:
590 zfcp_erp_thread_kill(adapter); 584 kref_put(&adapter->ref, zfcp_adapter_release);
591erp_thread_failed:
592 zfcp_fc_gs_destroy(adapter);
593generic_services_failed:
594 zfcp_destroy_adapter_work_queue(adapter);
595work_queue_failed:
596 zfcp_dbf_adapter_unregister(adapter->dbf);
597debug_register_failed:
598 dev_set_drvdata(&ccw_device->dev, NULL);
599 kfree(adapter->req_list);
600low_mem_buffers_failed:
601 zfcp_free_low_mem_buffers(adapter);
602qdio_failed:
603 zfcp_qdio_destroy(adapter->qdio);
604 kfree(adapter);
605 return -ENOMEM; 585 return -ENOMEM;
606} 586}
607 587
608/** 588/**
609 * zfcp_adapter_dequeue - remove the adapter from the resource list 589 * zfcp_adapter_release - remove the adapter from the resource list
610 * @adapter: pointer to struct zfcp_adapter which should be removed 590 * @ref: pointer to struct kref
611 * locks: adapter list write lock is assumed to be held by caller 591 * locks: adapter list write lock is assumed to be held by caller
612 */ 592 */
613void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) 593void zfcp_adapter_release(struct kref *ref)
614{ 594{
615 int retval = 0; 595 struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter,
616 unsigned long flags; 596 ref);
597 struct ccw_device *ccw_device = adapter->ccw_device;
617 598
618 cancel_work_sync(&adapter->stat_work); 599 cancel_work_sync(&adapter->stat_work);
600
619 zfcp_fc_wka_ports_force_offline(adapter->gs); 601 zfcp_fc_wka_ports_force_offline(adapter->gs);
620 sysfs_remove_group(&adapter->ccw_device->dev.kobj, 602 sysfs_remove_group(&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs);
621 &zfcp_sysfs_adapter_attrs); 603
622 dev_set_drvdata(&adapter->ccw_device->dev, NULL); 604 dev_set_drvdata(&ccw_device->dev, NULL);
623 /* sanity check: no pending FSF requests */
624 spin_lock_irqsave(&adapter->req_list_lock, flags);
625 retval = zfcp_reqlist_isempty(adapter);
626 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
627 if (!retval)
628 return;
629 605
606 dev_set_drvdata(&adapter->ccw_device->dev, NULL);
630 zfcp_fc_gs_destroy(adapter); 607 zfcp_fc_gs_destroy(adapter);
631 zfcp_erp_thread_kill(adapter); 608 zfcp_erp_thread_kill(adapter);
632 zfcp_destroy_adapter_work_queue(adapter); 609 zfcp_destroy_adapter_work_queue(adapter);
@@ -637,11 +614,30 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
637 kfree(adapter->fc_stats); 614 kfree(adapter->fc_stats);
638 kfree(adapter->stats_reset_data); 615 kfree(adapter->stats_reset_data);
639 kfree(adapter); 616 kfree(adapter);
617 put_device(&ccw_device->dev);
618}
619
620/**
621 * zfcp_device_unregister - remove port, unit from system
622 * @dev: reference to device which is to be removed
623 * @grp: related reference to attribute group
624 *
625 * Helper function to unregister port, unit from system
626 */
627void zfcp_device_unregister(struct device *dev,
628 const struct attribute_group *grp)
629{
630 sysfs_remove_group(&dev->kobj, grp);
631 device_unregister(dev);
640} 632}
641 633
642static void zfcp_sysfs_port_release(struct device *dev) 634static void zfcp_port_release(struct device *dev)
643{ 635{
644 kfree(container_of(dev, struct zfcp_port, sysfs_device)); 636 struct zfcp_port *port = container_of(dev, struct zfcp_port,
637 sysfs_device);
638
639 kref_put(&port->adapter->ref, zfcp_adapter_release);
640 kfree(port);
645} 641}
646 642
647/** 643/**
@@ -661,21 +657,24 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
661 u32 status, u32 d_id) 657 u32 status, u32 d_id)
662{ 658{
663 struct zfcp_port *port; 659 struct zfcp_port *port;
660 int retval = -ENOMEM;
661
662 kref_get(&adapter->ref);
664 663
665 port = zfcp_get_port_by_wwpn(adapter, wwpn); 664 port = zfcp_get_port_by_wwpn(adapter, wwpn);
666 if (port) { 665 if (port) {
667 zfcp_port_put(port); 666 put_device(&port->sysfs_device);
668 return ERR_PTR(-EEXIST); 667 retval = -EEXIST;
668 goto err_out;
669 } 669 }
670 670
671 port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); 671 port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
672 if (!port) 672 if (!port)
673 return ERR_PTR(-ENOMEM); 673 goto err_out;
674 674
675 rwlock_init(&port->unit_list_lock); 675 rwlock_init(&port->unit_list_lock);
676 INIT_LIST_HEAD(&port->unit_list); 676 INIT_LIST_HEAD(&port->unit_list);
677 677
678 init_waitqueue_head(&port->remove_wq);
679 INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup); 678 INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
680 INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work); 679 INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
681 INIT_WORK(&port->rport_work, zfcp_scsi_rport_work); 680 INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
@@ -684,32 +683,28 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
684 port->d_id = d_id; 683 port->d_id = d_id;
685 port->wwpn = wwpn; 684 port->wwpn = wwpn;
686 port->rport_task = RPORT_NONE; 685 port->rport_task = RPORT_NONE;
686 port->sysfs_device.parent = &adapter->ccw_device->dev;
687 port->sysfs_device.release = zfcp_port_release;
687 688
688 /* mark port unusable as long as sysfs registration is not complete */ 689 /* mark port unusable as long as sysfs registration is not complete */
689 atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); 690 atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
690 atomic_set(&port->refcount, 0);
691 691
692 if (dev_set_name(&port->sysfs_device, "0x%016llx", 692 if (dev_set_name(&port->sysfs_device, "0x%016llx",
693 (unsigned long long)wwpn)) { 693 (unsigned long long)wwpn)) {
694 kfree(port); 694 kfree(port);
695 return ERR_PTR(-ENOMEM); 695 goto err_out;
696 } 696 }
697 port->sysfs_device.parent = &adapter->ccw_device->dev;
698 port->sysfs_device.release = zfcp_sysfs_port_release;
699 dev_set_drvdata(&port->sysfs_device, port); 697 dev_set_drvdata(&port->sysfs_device, port);
698 retval = -EINVAL;
700 699
701 if (device_register(&port->sysfs_device)) { 700 if (device_register(&port->sysfs_device)) {
702 put_device(&port->sysfs_device); 701 put_device(&port->sysfs_device);
703 return ERR_PTR(-EINVAL); 702 goto err_out;
704 } 703 }
705 704
706 if (sysfs_create_group(&port->sysfs_device.kobj, 705 if (sysfs_create_group(&port->sysfs_device.kobj,
707 &zfcp_sysfs_port_attrs)) { 706 &zfcp_sysfs_port_attrs))
708 device_unregister(&port->sysfs_device); 707 goto err_out_put;
709 return ERR_PTR(-EINVAL);
710 }
711
712 zfcp_port_get(port);
713 708
714 write_lock_irq(&adapter->port_list_lock); 709 write_lock_irq(&adapter->port_list_lock);
715 list_add_tail(&port->list, &adapter->port_list); 710 list_add_tail(&port->list, &adapter->port_list);
@@ -718,23 +713,13 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
718 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); 713 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
719 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); 714 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
720 715
721 zfcp_adapter_get(adapter);
722 return port; 716 return port;
723}
724 717
725/** 718err_out_put:
726 * zfcp_port_dequeue - dequeues a port from the port list of the adapter
727 * @port: pointer to struct zfcp_port which should be removed
728 */
729void zfcp_port_dequeue(struct zfcp_port *port)
730{
731 struct zfcp_adapter *adapter = port->adapter;
732
733 list_del(&port->list); /* no list locking required here */
734 wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
735 zfcp_adapter_put(adapter);
736 sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
737 device_unregister(&port->sysfs_device); 719 device_unregister(&port->sysfs_device);
720err_out:
721 kref_put(&adapter->ref, zfcp_adapter_release);
722 return ERR_PTR(retval);
738} 723}
739 724
740/** 725/**
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index aca2047dc2d5..c89dbe250377 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -128,13 +128,15 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
128 write_unlock_irq(&adapter->port_list_lock); 128 write_unlock_irq(&adapter->port_list_lock);
129 mutex_unlock(&zfcp_data.config_mutex); 129 mutex_unlock(&zfcp_data.config_mutex);
130 130
131 list_for_each_entry_safe(port, p, &port_remove_lh, list) { 131 list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
132 list_for_each_entry_safe(unit, u, &unit_remove_lh, list) 132 zfcp_device_unregister(&unit->sysfs_device,
133 zfcp_unit_dequeue(unit); 133 &zfcp_sysfs_unit_attrs);
134 zfcp_port_dequeue(port); 134
135 } 135 list_for_each_entry_safe(port, p, &port_remove_lh, list)
136 wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); 136 zfcp_device_unregister(&port->sysfs_device,
137 zfcp_adapter_dequeue(adapter); 137 &zfcp_sysfs_port_attrs);
138
139 kref_put(&adapter->ref, zfcp_adapter_release);
138} 140}
139 141
140/** 142/**
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index ef681dfed0cc..856f82dbcb1b 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -98,7 +98,7 @@ static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
98 if (!adapter) 98 if (!adapter)
99 goto out_put; 99 goto out_put;
100 100
101 zfcp_adapter_get(adapter); 101 kref_get(&adapter->ref);
102out_put: 102out_put:
103 put_device(&ccwdev->dev); 103 put_device(&ccwdev->dev);
104out: 104out:
@@ -212,7 +212,6 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
212 retval = -ENXIO; 212 retval = -ENXIO;
213 goto free_buffer; 213 goto free_buffer;
214 } 214 }
215 zfcp_adapter_get(adapter);
216 215
217 retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg, 216 retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
218 data_user->control_file); 217 data_user->control_file);
@@ -245,7 +244,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
245 free_sg: 244 free_sg:
246 zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES); 245 zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
247 adapter_put: 246 adapter_put:
248 zfcp_adapter_put(adapter); 247 kref_put(&adapter->ref, zfcp_adapter_release);
249 free_buffer: 248 free_buffer:
250 kfree(data); 249 kfree(data);
251 no_mem_sense: 250 no_mem_sense:
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 215b70749e95..fe818cd29dc1 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -1067,6 +1067,8 @@ err_out:
1067 */ 1067 */
1068void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf) 1068void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
1069{ 1069{
1070 if (!dbf)
1071 return;
1070 debug_unregister(dbf->scsi); 1072 debug_unregister(dbf->scsi);
1071 debug_unregister(dbf->san); 1073 debug_unregister(dbf->san);
1072 debug_unregister(dbf->hba); 1074 debug_unregister(dbf->hba);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index e45a08d6c98e..55dc402c3aec 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -446,9 +446,7 @@ struct zfcp_qdio {
446}; 446};
447 447
448struct zfcp_adapter { 448struct zfcp_adapter {
449 atomic_t refcount; /* reference count */ 449 struct kref ref;
450 wait_queue_head_t remove_wq; /* can be used to wait for
451 refcount drop to zero */
452 u64 peer_wwnn; /* P2P peer WWNN */ 450 u64 peer_wwnn; /* P2P peer WWNN */
453 u64 peer_wwpn; /* P2P peer WWPN */ 451 u64 peer_wwpn; /* P2P peer WWPN */
454 u32 peer_d_id; /* P2P peer D_ID */ 452 u32 peer_d_id; /* P2P peer D_ID */
@@ -501,9 +499,6 @@ struct zfcp_port {
501 struct device sysfs_device; /* sysfs device */ 499 struct device sysfs_device; /* sysfs device */
502 struct fc_rport *rport; /* rport of fc transport class */ 500 struct fc_rport *rport; /* rport of fc transport class */
503 struct list_head list; /* list of remote ports */ 501 struct list_head list; /* list of remote ports */
504 atomic_t refcount; /* reference count */
505 wait_queue_head_t remove_wq; /* can be used to wait for
506 refcount drop to zero */
507 struct zfcp_adapter *adapter; /* adapter used to access port */ 502 struct zfcp_adapter *adapter; /* adapter used to access port */
508 struct list_head unit_list; /* head of logical unit list */ 503 struct list_head unit_list; /* head of logical unit list */
509 rwlock_t unit_list_lock; /* unit list lock */ 504 rwlock_t unit_list_lock; /* unit list lock */
@@ -525,9 +520,6 @@ struct zfcp_port {
525struct zfcp_unit { 520struct zfcp_unit {
526 struct device sysfs_device; /* sysfs device */ 521 struct device sysfs_device; /* sysfs device */
527 struct list_head list; /* list of logical units */ 522 struct list_head list; /* list of logical units */
528 atomic_t refcount; /* reference count */
529 wait_queue_head_t remove_wq; /* can be used to wait for
530 refcount drop to zero */
531 struct zfcp_port *port; /* remote port of unit */ 523 struct zfcp_port *port; /* remote port of unit */
532 atomic_t status; /* status of this logical unit */ 524 atomic_t status; /* status of this logical unit */
533 u64 fcp_lun; /* own FCP_LUN */ 525 u64 fcp_lun; /* own FCP_LUN */
@@ -656,47 +648,4 @@ zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req)
656 return NULL; 648 return NULL;
657} 649}
658 650
659/*
660 * functions needed for reference/usage counting
661 */
662
663static inline void
664zfcp_unit_get(struct zfcp_unit *unit)
665{
666 atomic_inc(&unit->refcount);
667}
668
669static inline void
670zfcp_unit_put(struct zfcp_unit *unit)
671{
672 if (atomic_dec_return(&unit->refcount) == 0)
673 wake_up(&unit->remove_wq);
674}
675
676static inline void
677zfcp_port_get(struct zfcp_port *port)
678{
679 atomic_inc(&port->refcount);
680}
681
682static inline void
683zfcp_port_put(struct zfcp_port *port)
684{
685 if (atomic_dec_return(&port->refcount) == 0)
686 wake_up(&port->remove_wq);
687}
688
689static inline void
690zfcp_adapter_get(struct zfcp_adapter *adapter)
691{
692 atomic_inc(&adapter->refcount);
693}
694
695static inline void
696zfcp_adapter_put(struct zfcp_adapter *adapter)
697{
698 if (atomic_dec_return(&adapter->refcount) == 0)
699 wake_up(&adapter->remove_wq);
700}
701
702#endif /* ZFCP_DEF_H */ 651#endif /* ZFCP_DEF_H */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 464f0473877a..788fd3a4cd23 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -174,7 +174,7 @@ 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 zfcp_unit_get(unit); 177 get_device(&unit->sysfs_device);
178 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); 178 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
179 erp_action = &unit->erp_action; 179 erp_action = &unit->erp_action;
180 if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) 180 if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
@@ -183,7 +183,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
183 183
184 case ZFCP_ERP_ACTION_REOPEN_PORT: 184 case ZFCP_ERP_ACTION_REOPEN_PORT:
185 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: 185 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
186 zfcp_port_get(port); 186 get_device(&port->sysfs_device);
187 zfcp_erp_action_dismiss_port(port); 187 zfcp_erp_action_dismiss_port(port);
188 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); 188 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
189 erp_action = &port->erp_action; 189 erp_action = &port->erp_action;
@@ -192,7 +192,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
192 break; 192 break;
193 193
194 case ZFCP_ERP_ACTION_REOPEN_ADAPTER: 194 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
195 zfcp_adapter_get(adapter); 195 kref_get(&adapter->ref);
196 zfcp_erp_action_dismiss_adapter(adapter); 196 zfcp_erp_action_dismiss_adapter(adapter);
197 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); 197 atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
198 erp_action = &adapter->erp_action; 198 erp_action = &adapter->erp_action;
@@ -1177,19 +1177,19 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
1177 switch (act->action) { 1177 switch (act->action) {
1178 case ZFCP_ERP_ACTION_REOPEN_UNIT: 1178 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1179 if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) { 1179 if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
1180 zfcp_unit_get(unit); 1180 get_device(&unit->sysfs_device);
1181 if (scsi_queue_work(unit->port->adapter->scsi_host, 1181 if (scsi_queue_work(unit->port->adapter->scsi_host,
1182 &unit->scsi_work) <= 0) 1182 &unit->scsi_work) <= 0)
1183 zfcp_unit_put(unit); 1183 put_device(&unit->sysfs_device);
1184 } 1184 }
1185 zfcp_unit_put(unit); 1185 put_device(&unit->sysfs_device);
1186 break; 1186 break;
1187 1187
1188 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: 1188 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
1189 case ZFCP_ERP_ACTION_REOPEN_PORT: 1189 case ZFCP_ERP_ACTION_REOPEN_PORT:
1190 if (result == ZFCP_ERP_SUCCEEDED) 1190 if (result == ZFCP_ERP_SUCCEEDED)
1191 zfcp_scsi_schedule_rport_register(port); 1191 zfcp_scsi_schedule_rport_register(port);
1192 zfcp_port_put(port); 1192 put_device(&port->sysfs_device);
1193 break; 1193 break;
1194 1194
1195 case ZFCP_ERP_ACTION_REOPEN_ADAPTER: 1195 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
@@ -1198,7 +1198,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
1198 schedule_work(&adapter->scan_work); 1198 schedule_work(&adapter->scan_work);
1199 } else 1199 } else
1200 unregister_service_level(&adapter->service_level); 1200 unregister_service_level(&adapter->service_level);
1201 zfcp_adapter_put(adapter); 1201 kref_put(&adapter->ref, zfcp_adapter_release);
1202 break; 1202 break;
1203 } 1203 }
1204} 1204}
@@ -1224,8 +1224,9 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
1224 unsigned long flags; 1224 unsigned long flags;
1225 struct zfcp_adapter *adapter = erp_action->adapter; 1225 struct zfcp_adapter *adapter = erp_action->adapter;
1226 1226
1227 write_lock_irqsave(&adapter->erp_lock, flags); 1227 kref_get(&adapter->ref);
1228 1228
1229 write_lock_irqsave(&adapter->erp_lock, flags);
1229 zfcp_erp_strategy_check_fsfreq(erp_action); 1230 zfcp_erp_strategy_check_fsfreq(erp_action);
1230 1231
1231 if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { 1232 if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
@@ -1282,6 +1283,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
1282 if (retval != ZFCP_ERP_CONTINUES) 1283 if (retval != ZFCP_ERP_CONTINUES)
1283 zfcp_erp_action_cleanup(erp_action, retval); 1284 zfcp_erp_action_cleanup(erp_action, retval);
1284 1285
1286 kref_put(&adapter->ref, zfcp_adapter_release);
1285 return retval; 1287 return retval;
1286} 1288}
1287 1289
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index b3f28deb4505..3106c3be6395 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -15,15 +15,15 @@
15extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64); 15extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
16extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64); 16extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
17extern int zfcp_adapter_enqueue(struct ccw_device *); 17extern int zfcp_adapter_enqueue(struct ccw_device *);
18extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
19extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32, 18extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
20 u32); 19 u32);
21extern void zfcp_port_dequeue(struct zfcp_port *);
22extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64); 20extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
23extern void zfcp_unit_dequeue(struct zfcp_unit *);
24extern int zfcp_reqlist_isempty(struct zfcp_adapter *); 21extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
25extern void zfcp_sg_free_table(struct scatterlist *, int); 22extern void zfcp_sg_free_table(struct scatterlist *, int);
26extern int zfcp_sg_setup_table(struct scatterlist *, int); 23extern int zfcp_sg_setup_table(struct scatterlist *, int);
24extern void zfcp_device_unregister(struct device *,
25 const struct attribute_group *);
26extern void zfcp_adapter_release(struct kref *);
27 27
28/* zfcp_ccw.c */ 28/* zfcp_ccw.c */
29extern int zfcp_ccw_register(void); 29extern int zfcp_ccw_register(void);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index c7efdc51df63..6fa1bcbec0a9 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -134,6 +134,8 @@ static void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
134 134
135void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs) 135void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs)
136{ 136{
137 if (!gs)
138 return;
137 zfcp_fc_wka_port_force_offline(&gs->ms); 139 zfcp_fc_wka_port_force_offline(&gs->ms);
138 zfcp_fc_wka_port_force_offline(&gs->ts); 140 zfcp_fc_wka_port_force_offline(&gs->ts);
139 zfcp_fc_wka_port_force_offline(&gs->ds); 141 zfcp_fc_wka_port_force_offline(&gs->ds);
@@ -356,7 +358,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
356 358
357 zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL); 359 zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
358out: 360out:
359 zfcp_port_put(port); 361 put_device(&port->sysfs_device);
360} 362}
361 363
362/** 364/**
@@ -365,9 +367,9 @@ out:
365 */ 367 */
366void zfcp_fc_trigger_did_lookup(struct zfcp_port *port) 368void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
367{ 369{
368 zfcp_port_get(port); 370 get_device(&port->sysfs_device);
369 if (!queue_work(port->adapter->work_queue, &port->gid_pn_work)) 371 if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
370 zfcp_port_put(port); 372 put_device(&port->sysfs_device);
371} 373}
372 374
373/** 375/**
@@ -426,7 +428,7 @@ static void zfcp_fc_adisc_handler(unsigned long data)
426 zfcp_scsi_schedule_rport_register(port); 428 zfcp_scsi_schedule_rport_register(port);
427 out: 429 out:
428 atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); 430 atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
429 zfcp_port_put(port); 431 put_device(&port->sysfs_device);
430 kfree(adisc); 432 kfree(adisc);
431} 433}
432 434
@@ -468,7 +470,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
468 container_of(work, struct zfcp_port, test_link_work); 470 container_of(work, struct zfcp_port, test_link_work);
469 int retval; 471 int retval;
470 472
471 zfcp_port_get(port); 473 get_device(&port->sysfs_device);
472 port->rport_task = RPORT_DEL; 474 port->rport_task = RPORT_DEL;
473 zfcp_scsi_rport_work(&port->rport_work); 475 zfcp_scsi_rport_work(&port->rport_work);
474 476
@@ -487,7 +489,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
487 zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL); 489 zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
488 490
489out: 491out:
490 zfcp_port_put(port); 492 put_device(&port->sysfs_device);
491} 493}
492 494
493/** 495/**
@@ -500,9 +502,9 @@ out:
500 */ 502 */
501void zfcp_fc_test_link(struct zfcp_port *port) 503void zfcp_fc_test_link(struct zfcp_port *port)
502{ 504{
503 zfcp_port_get(port); 505 get_device(&port->sysfs_device);
504 if (!queue_work(port->adapter->work_queue, &port->test_link_work)) 506 if (!queue_work(port->adapter->work_queue, &port->test_link_work))
505 zfcp_port_put(port); 507 put_device(&port->sysfs_device);
506} 508}
507 509
508static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num) 510static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
@@ -576,7 +578,7 @@ static int zfcp_fc_send_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
576 return ret; 578 return ret;
577} 579}
578 580
579static void zfcp_fc_validate_port(struct zfcp_port *port) 581static void zfcp_fc_validate_port(struct zfcp_port *port, struct list_head *lh)
580{ 582{
581 if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)) 583 if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC))
582 return; 584 return;
@@ -584,13 +586,11 @@ static void zfcp_fc_validate_port(struct zfcp_port *port)
584 atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); 586 atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status);
585 587
586 if ((port->supported_classes != 0) || 588 if ((port->supported_classes != 0) ||
587 !list_empty(&port->unit_list)) { 589 !list_empty(&port->unit_list))
588 zfcp_port_put(port);
589 return; 590 return;
590 } 591
591 zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL); 592 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
592 zfcp_port_put(port); 593 list_move_tail(&port->list, lh);
593 zfcp_port_dequeue(port);
594} 594}
595 595
596static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries) 596static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
@@ -602,6 +602,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
602 struct zfcp_adapter *adapter = ct->wka_port->adapter; 602 struct zfcp_adapter *adapter = ct->wka_port->adapter;
603 struct zfcp_port *port, *tmp; 603 struct zfcp_port *port, *tmp;
604 unsigned long flags; 604 unsigned long flags;
605 LIST_HEAD(remove_lh);
605 u32 d_id; 606 u32 d_id;
606 int ret = 0, x, last = 0; 607 int ret = 0, x, last = 0;
607 608
@@ -652,9 +653,16 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
652 zfcp_erp_wait(adapter); 653 zfcp_erp_wait(adapter);
653 write_lock_irqsave(&adapter->port_list_lock, flags); 654 write_lock_irqsave(&adapter->port_list_lock, flags);
654 list_for_each_entry_safe(port, tmp, &adapter->port_list, list) 655 list_for_each_entry_safe(port, tmp, &adapter->port_list, list)
655 zfcp_fc_validate_port(port); 656 zfcp_fc_validate_port(port, &remove_lh);
656 write_unlock_irqrestore(&adapter->port_list_lock, flags); 657 write_unlock_irqrestore(&adapter->port_list_lock, flags);
657 mutex_unlock(&zfcp_data.config_mutex); 658 mutex_unlock(&zfcp_data.config_mutex);
659
660 list_for_each_entry_safe(port, tmp, &remove_lh, list) {
661 zfcp_erp_port_shutdown(port, 0, "fcegpf2", NULL);
662 zfcp_device_unregister(&port->sysfs_device,
663 &zfcp_sysfs_port_attrs);
664 }
665
658 return ret; 666 return ret;
659} 667}
660 668
@@ -763,7 +771,7 @@ int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job)
763 } 771 }
764 772
765 els_fc_job->els.d_id = port->d_id; 773 els_fc_job->els.d_id = port->d_id;
766 zfcp_port_put(port); 774 put_device(&port->sysfs_device);
767 } else { 775 } else {
768 port_did = job->request->rqst_data.h_els.port_id; 776 port_did = job->request->rqst_data.h_els.port_id;
769 els_fc_job->els.d_id = (port_did[0] << 16) + 777 els_fc_job->els.d_id = (port_did[0] << 16) +
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 9df62f686812..3aad70916289 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1492,7 +1492,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1492 } 1492 }
1493 1493
1494out: 1494out:
1495 zfcp_port_put(port); 1495 put_device(&port->sysfs_device);
1496} 1496}
1497 1497
1498/** 1498/**
@@ -1530,14 +1530,14 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
1530 req->data = port; 1530 req->data = port;
1531 req->erp_action = erp_action; 1531 req->erp_action = erp_action;
1532 erp_action->fsf_req = req; 1532 erp_action->fsf_req = req;
1533 zfcp_port_get(port); 1533 get_device(&port->sysfs_device);
1534 1534
1535 zfcp_fsf_start_erp_timer(req); 1535 zfcp_fsf_start_erp_timer(req);
1536 retval = zfcp_fsf_req_send(req); 1536 retval = zfcp_fsf_req_send(req);
1537 if (retval) { 1537 if (retval) {
1538 zfcp_fsf_req_free(req); 1538 zfcp_fsf_req_free(req);
1539 erp_action->fsf_req = NULL; 1539 erp_action->fsf_req = NULL;
1540 zfcp_port_put(port); 1540 put_device(&port->sysfs_device);
1541 } 1541 }
1542out: 1542out:
1543 spin_unlock_bh(&qdio->req_q_lock); 1543 spin_unlock_bh(&qdio->req_q_lock);
@@ -2335,7 +2335,7 @@ skip_fsfstatus:
2335 else { 2335 else {
2336 zfcp_fsf_send_fcp_command_task_handler(req); 2336 zfcp_fsf_send_fcp_command_task_handler(req);
2337 req->unit = NULL; 2337 req->unit = NULL;
2338 zfcp_unit_put(unit); 2338 put_device(&unit->sysfs_device);
2339 } 2339 }
2340} 2340}
2341 2341
@@ -2387,7 +2387,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
2387 } 2387 }
2388 2388
2389 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; 2389 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
2390 zfcp_unit_get(unit); 2390 get_device(&unit->sysfs_device);
2391 req->unit = unit; 2391 req->unit = unit;
2392 req->data = scsi_cmnd; 2392 req->data = scsi_cmnd;
2393 req->handler = zfcp_fsf_send_fcp_command_handler; 2393 req->handler = zfcp_fsf_send_fcp_command_handler;
@@ -2463,7 +2463,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
2463 goto out; 2463 goto out;
2464 2464
2465failed_scsi_cmnd: 2465failed_scsi_cmnd:
2466 zfcp_unit_put(unit); 2466 put_device(&unit->sysfs_device);
2467 zfcp_fsf_req_free(req); 2467 zfcp_fsf_req_free(req);
2468 scsi_cmnd->host_scribble = NULL; 2468 scsi_cmnd->host_scribble = NULL;
2469out: 2469out:
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 6feece3b2e36..39a621d729e9 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -52,7 +52,7 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
52{ 52{
53 struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; 53 struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
54 unit->device = NULL; 54 unit->device = NULL;
55 zfcp_unit_put(unit); 55 put_device(&unit->sysfs_device);
56} 56}
57 57
58static int zfcp_scsi_slave_configure(struct scsi_device *sdp) 58static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
@@ -335,8 +335,7 @@ void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
335 335
336 read_lock_irq(&adapter->port_list_lock); 336 read_lock_irq(&adapter->port_list_lock);
337 list_for_each_entry(port, &adapter->port_list, list) 337 list_for_each_entry(port, &adapter->port_list, list)
338 if (port->rport) 338 port->rport = NULL;
339 port->rport = NULL;
340 read_unlock_irq(&adapter->port_list_lock); 339 read_unlock_irq(&adapter->port_list_lock);
341 340
342 fc_remove_host(shost); 341 fc_remove_host(shost);
@@ -356,7 +355,7 @@ zfcp_init_fc_host_stats(struct zfcp_adapter *adapter)
356 fc_stats = kmalloc(sizeof(*fc_stats), GFP_KERNEL); 355 fc_stats = kmalloc(sizeof(*fc_stats), GFP_KERNEL);
357 if (!fc_stats) 356 if (!fc_stats)
358 return NULL; 357 return NULL;
359 adapter->fc_stats = fc_stats; /* freed in adater_dequeue */ 358 adapter->fc_stats = fc_stats; /* freed in adapter_release */
360 } 359 }
361 memset(adapter->fc_stats, 0, sizeof(*adapter->fc_stats)); 360 memset(adapter->fc_stats, 0, sizeof(*adapter->fc_stats));
362 return adapter->fc_stats; 361 return adapter->fc_stats;
@@ -472,7 +471,7 @@ static void zfcp_reset_fc_host_stats(struct Scsi_Host *shost)
472 adapter->stats_reset = jiffies/HZ; 471 adapter->stats_reset = jiffies/HZ;
473 kfree(adapter->stats_reset_data); 472 kfree(adapter->stats_reset_data);
474 adapter->stats_reset_data = data; /* finally freed in 473 adapter->stats_reset_data = data; /* finally freed in
475 adapter_dequeue */ 474 adapter_release */
476 } 475 }
477} 476}
478 477
@@ -517,7 +516,7 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
517 516
518 if (port) { 517 if (port) {
519 zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL); 518 zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
520 zfcp_port_put(port); 519 put_device(&port->sysfs_device);
521 } 520 }
522} 521}
523 522
@@ -559,23 +558,23 @@ static void zfcp_scsi_rport_block(struct zfcp_port *port)
559 558
560void zfcp_scsi_schedule_rport_register(struct zfcp_port *port) 559void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)
561{ 560{
562 zfcp_port_get(port); 561 get_device(&port->sysfs_device);
563 port->rport_task = RPORT_ADD; 562 port->rport_task = RPORT_ADD;
564 563
565 if (!queue_work(port->adapter->work_queue, &port->rport_work)) 564 if (!queue_work(port->adapter->work_queue, &port->rport_work))
566 zfcp_port_put(port); 565 put_device(&port->sysfs_device);
567} 566}
568 567
569void zfcp_scsi_schedule_rport_block(struct zfcp_port *port) 568void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
570{ 569{
571 zfcp_port_get(port); 570 get_device(&port->sysfs_device);
572 port->rport_task = RPORT_DEL; 571 port->rport_task = RPORT_DEL;
573 572
574 if (port->rport && queue_work(port->adapter->work_queue, 573 if (port->rport && queue_work(port->adapter->work_queue,
575 &port->rport_work)) 574 &port->rport_work))
576 return; 575 return;
577 576
578 zfcp_port_put(port); 577 put_device(&port->sysfs_device);
579} 578}
580 579
581void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter) 580void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter)
@@ -604,7 +603,7 @@ void zfcp_scsi_rport_work(struct work_struct *work)
604 } 603 }
605 } 604 }
606 605
607 zfcp_port_put(port); 606 put_device(&port->sysfs_device);
608} 607}
609 608
610 609
@@ -622,7 +621,7 @@ void zfcp_scsi_scan(struct work_struct *work)
622 scsilun_to_int((struct scsi_lun *) 621 scsilun_to_int((struct scsi_lun *)
623 &unit->fcp_lun), 0); 622 &unit->fcp_lun), 0);
624 623
625 zfcp_unit_put(unit); 624 put_device(&unit->sysfs_device);
626} 625}
627 626
628static int zfcp_execute_fc_job(struct fc_bsg_job *job) 627static int zfcp_execute_fc_job(struct fc_bsg_job *job)
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 8430b518357e..b4a7e17932c5 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * sysfs attributes. 4 * sysfs attributes.
5 * 5 *
6 * Copyright IBM Corporation 2008 6 * Copyright IBM Corporation 2008, 2009
7 */ 7 */
8 8
9#define KMSG_COMPONENT "zfcp" 9#define KMSG_COMPONENT "zfcp"
@@ -140,7 +140,6 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
140 struct zfcp_port *port; 140 struct zfcp_port *port;
141 u64 wwpn; 141 u64 wwpn;
142 int retval = 0; 142 int retval = 0;
143 LIST_HEAD(port_remove_lh);
144 143
145 mutex_lock(&zfcp_data.config_mutex); 144 mutex_lock(&zfcp_data.config_mutex);
146 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { 145 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
@@ -154,23 +153,21 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
154 } 153 }
155 154
156 port = zfcp_get_port_by_wwpn(adapter, wwpn); 155 port = zfcp_get_port_by_wwpn(adapter, wwpn);
157 if (port && (atomic_read(&port->refcount) == 1)) {
158 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
159 write_lock_irq(&adapter->port_list_lock);
160 list_move(&port->list, &port_remove_lh);
161 write_unlock_irq(&adapter->port_list_lock);
162 } else
163 port = NULL;
164
165 if (!port) { 156 if (!port) {
166 retval = -ENXIO; 157 retval = -ENXIO;
167 goto out; 158 goto out;
168 } 159 }
169 160
161 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
162
163 write_lock_irq(&adapter->port_list_lock);
164 list_del(&port->list);
165 write_unlock_irq(&adapter->port_list_lock);
166
167 put_device(&port->sysfs_device);
168
170 zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL); 169 zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL);
171 zfcp_erp_wait(adapter); 170 zfcp_device_unregister(&port->sysfs_device, &zfcp_sysfs_port_attrs);
172 zfcp_port_put(port);
173 zfcp_port_dequeue(port);
174 out: 171 out:
175 mutex_unlock(&zfcp_data.config_mutex); 172 mutex_unlock(&zfcp_data.config_mutex);
176 return retval ? retval : (ssize_t) count; 173 return retval ? retval : (ssize_t) count;
@@ -224,7 +221,6 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
224 zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); 221 zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
225 zfcp_erp_wait(unit->port->adapter); 222 zfcp_erp_wait(unit->port->adapter);
226 flush_work(&unit->scsi_work); 223 flush_work(&unit->scsi_work);
227 zfcp_unit_put(unit);
228out: 224out:
229 mutex_unlock(&zfcp_data.config_mutex); 225 mutex_unlock(&zfcp_data.config_mutex);
230 return retval ? retval : (ssize_t) count; 226 return retval ? retval : (ssize_t) count;
@@ -239,7 +235,6 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
239 struct zfcp_unit *unit; 235 struct zfcp_unit *unit;
240 u64 fcp_lun; 236 u64 fcp_lun;
241 int retval = 0; 237 int retval = 0;
242 LIST_HEAD(unit_remove_lh);
243 238
244 mutex_lock(&zfcp_data.config_mutex); 239 mutex_lock(&zfcp_data.config_mutex);
245 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { 240 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
@@ -261,19 +256,16 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
261 /* wait for possible timeout during SCSI probe */ 256 /* wait for possible timeout during SCSI probe */
262 flush_work(&unit->scsi_work); 257 flush_work(&unit->scsi_work);
263 258
264 if (atomic_read(&unit->refcount) == 1) { 259 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
265 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); 260
261 write_lock_irq(&port->unit_list_lock);
262 list_del(&unit->list);
263 write_unlock_irq(&port->unit_list_lock);
266 264
267 write_lock_irq(&port->unit_list_lock); 265 put_device(&unit->sysfs_device);
268 list_move(&unit->list, &unit_remove_lh);
269 write_unlock_irq(&port->unit_list_lock);
270 266
271 zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); 267 zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
272 zfcp_erp_wait(unit->port->adapter); 268 zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs);
273 zfcp_unit_put(unit);
274 zfcp_unit_dequeue(unit);
275 } else
276 zfcp_unit_put(unit);
277out: 269out:
278 mutex_unlock(&zfcp_data.config_mutex); 270 mutex_unlock(&zfcp_data.config_mutex);
279 return retval ? retval : (ssize_t) count; 271 return retval ? retval : (ssize_t) count;