aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_aux.c
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/scsi/zfcp_aux.c
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/scsi/zfcp_aux.c')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c231
1 files changed, 108 insertions, 123 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/**