aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;