aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_aux.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/s390/scsi/zfcp_aux.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c445
1 files changed, 205 insertions, 240 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 2889e5f2dfd3..1e6183a86ce5 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Module interface and handling of zfcp data structures. 4 * Module interface and handling of zfcp data structures.
5 * 5 *
6 * Copyright IBM Corporation 2002, 2009 6 * Copyright IBM Corporation 2002, 2010
7 */ 7 */
8 8
9/* 9/*
@@ -30,7 +30,10 @@
30 30
31#include <linux/miscdevice.h> 31#include <linux/miscdevice.h>
32#include <linux/seq_file.h> 32#include <linux/seq_file.h>
33#include <linux/slab.h>
33#include "zfcp_ext.h" 34#include "zfcp_ext.h"
35#include "zfcp_fc.h"
36#include "zfcp_reqlist.h"
34 37
35#define ZFCP_BUS_ID_SIZE 20 38#define ZFCP_BUS_ID_SIZE 20
36 39
@@ -48,80 +51,42 @@ static struct kmem_cache *zfcp_cache_hw_align(const char *name,
48 return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL); 51 return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL);
49} 52}
50 53
51static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter)
52{
53 int idx;
54
55 adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head),
56 GFP_KERNEL);
57 if (!adapter->req_list)
58 return -ENOMEM;
59
60 for (idx = 0; idx < REQUEST_LIST_SIZE; idx++)
61 INIT_LIST_HEAD(&adapter->req_list[idx]);
62 return 0;
63}
64
65/**
66 * zfcp_reqlist_isempty - is the request list empty
67 * @adapter: pointer to struct zfcp_adapter
68 *
69 * Returns: true if list is empty, false otherwise
70 */
71int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
72{
73 unsigned int idx;
74
75 for (idx = 0; idx < REQUEST_LIST_SIZE; idx++)
76 if (!list_empty(&adapter->req_list[idx]))
77 return 0;
78 return 1;
79}
80
81static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) 54static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
82{ 55{
83 struct ccw_device *ccwdev; 56 struct ccw_device *cdev;
84 struct zfcp_adapter *adapter; 57 struct zfcp_adapter *adapter;
85 struct zfcp_port *port; 58 struct zfcp_port *port;
86 struct zfcp_unit *unit; 59 struct zfcp_unit *unit;
87 60
88 ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); 61 cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
89 if (!ccwdev) 62 if (!cdev)
90 return; 63 return;
91 64
92 if (ccw_device_set_online(ccwdev)) 65 if (ccw_device_set_online(cdev))
93 goto out_ccwdev; 66 goto out_ccw_device;
94 67
95 mutex_lock(&zfcp_data.config_mutex); 68 adapter = zfcp_ccw_adapter_by_cdev(cdev);
96 adapter = dev_get_drvdata(&ccwdev->dev);
97 if (!adapter) 69 if (!adapter)
98 goto out_unlock; 70 goto out_ccw_device;
99 zfcp_adapter_get(adapter);
100 71
101 port = zfcp_get_port_by_wwpn(adapter, wwpn); 72 port = zfcp_get_port_by_wwpn(adapter, wwpn);
102 if (!port) 73 if (!port)
103 goto out_port; 74 goto out_port;
104 75
105 zfcp_port_get(port);
106 unit = zfcp_unit_enqueue(port, lun); 76 unit = zfcp_unit_enqueue(port, lun);
107 if (IS_ERR(unit)) 77 if (IS_ERR(unit))
108 goto out_unit; 78 goto out_unit;
109 mutex_unlock(&zfcp_data.config_mutex);
110 79
111 zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL); 80 zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
112 zfcp_erp_wait(adapter); 81 zfcp_erp_wait(adapter);
113 flush_work(&unit->scsi_work); 82 flush_work(&unit->scsi_work);
114 83
115 mutex_lock(&zfcp_data.config_mutex);
116 zfcp_unit_put(unit);
117out_unit: 84out_unit:
118 zfcp_port_put(port); 85 put_device(&port->dev);
119out_port: 86out_port:
120 zfcp_adapter_put(adapter); 87 zfcp_ccw_adapter_put(adapter);
121out_unlock: 88out_ccw_device:
122 mutex_unlock(&zfcp_data.config_mutex); 89 put_device(&cdev->dev);
123out_ccwdev:
124 put_device(&ccwdev->dev);
125 return; 90 return;
126} 91}
127 92
@@ -167,7 +132,7 @@ static int __init zfcp_module_init(void)
167 int retval = -ENOMEM; 132 int retval = -ENOMEM;
168 133
169 zfcp_data.gpn_ft_cache = zfcp_cache_hw_align("zfcp_gpn", 134 zfcp_data.gpn_ft_cache = zfcp_cache_hw_align("zfcp_gpn",
170 sizeof(struct ct_iu_gpn_ft_req)); 135 sizeof(struct zfcp_fc_gpn_ft_req));
171 if (!zfcp_data.gpn_ft_cache) 136 if (!zfcp_data.gpn_ft_cache)
172 goto out; 137 goto out;
173 138
@@ -182,12 +147,14 @@ static int __init zfcp_module_init(void)
182 goto out_sr_cache; 147 goto out_sr_cache;
183 148
184 zfcp_data.gid_pn_cache = zfcp_cache_hw_align("zfcp_gid", 149 zfcp_data.gid_pn_cache = zfcp_cache_hw_align("zfcp_gid",
185 sizeof(struct zfcp_gid_pn_data)); 150 sizeof(struct zfcp_fc_gid_pn));
186 if (!zfcp_data.gid_pn_cache) 151 if (!zfcp_data.gid_pn_cache)
187 goto out_gid_cache; 152 goto out_gid_cache;
188 153
189 mutex_init(&zfcp_data.config_mutex); 154 zfcp_data.adisc_cache = zfcp_cache_hw_align("zfcp_adisc",
190 rwlock_init(&zfcp_data.config_lock); 155 sizeof(struct zfcp_fc_els_adisc));
156 if (!zfcp_data.adisc_cache)
157 goto out_adisc_cache;
191 158
192 zfcp_data.scsi_transport_template = 159 zfcp_data.scsi_transport_template =
193 fc_attach_transport(&zfcp_transport_functions); 160 fc_attach_transport(&zfcp_transport_functions);
@@ -200,7 +167,7 @@ static int __init zfcp_module_init(void)
200 goto out_misc; 167 goto out_misc;
201 } 168 }
202 169
203 retval = zfcp_ccw_register(); 170 retval = ccw_driver_register(&zfcp_ccw_driver);
204 if (retval) { 171 if (retval) {
205 pr_err("The zfcp device driver could not register with " 172 pr_err("The zfcp device driver could not register with "
206 "the common I/O layer\n"); 173 "the common I/O layer\n");
@@ -216,6 +183,8 @@ out_ccw_register:
216out_misc: 183out_misc:
217 fc_release_transport(zfcp_data.scsi_transport_template); 184 fc_release_transport(zfcp_data.scsi_transport_template);
218out_transport: 185out_transport:
186 kmem_cache_destroy(zfcp_data.adisc_cache);
187out_adisc_cache:
219 kmem_cache_destroy(zfcp_data.gid_pn_cache); 188 kmem_cache_destroy(zfcp_data.gid_pn_cache);
220out_gid_cache: 189out_gid_cache:
221 kmem_cache_destroy(zfcp_data.sr_buffer_cache); 190 kmem_cache_destroy(zfcp_data.sr_buffer_cache);
@@ -229,6 +198,20 @@ out:
229 198
230module_init(zfcp_module_init); 199module_init(zfcp_module_init);
231 200
201static void __exit zfcp_module_exit(void)
202{
203 ccw_driver_unregister(&zfcp_ccw_driver);
204 misc_deregister(&zfcp_cfdc_misc);
205 fc_release_transport(zfcp_data.scsi_transport_template);
206 kmem_cache_destroy(zfcp_data.adisc_cache);
207 kmem_cache_destroy(zfcp_data.gid_pn_cache);
208 kmem_cache_destroy(zfcp_data.sr_buffer_cache);
209 kmem_cache_destroy(zfcp_data.qtcb_cache);
210 kmem_cache_destroy(zfcp_data.gpn_ft_cache);
211}
212
213module_exit(zfcp_module_exit);
214
232/** 215/**
233 * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN 216 * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN
234 * @port: pointer to port to search for unit 217 * @port: pointer to port to search for unit
@@ -238,12 +221,18 @@ module_init(zfcp_module_init);
238 */ 221 */
239struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun) 222struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
240{ 223{
224 unsigned long flags;
241 struct zfcp_unit *unit; 225 struct zfcp_unit *unit;
242 226
243 list_for_each_entry(unit, &port->unit_list_head, list) 227 read_lock_irqsave(&port->unit_list_lock, flags);
244 if ((unit->fcp_lun == fcp_lun) && 228 list_for_each_entry(unit, &port->unit_list, list)
245 !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE)) 229 if (unit->fcp_lun == fcp_lun) {
246 return unit; 230 if (!get_device(&unit->dev))
231 unit = NULL;
232 read_unlock_irqrestore(&port->unit_list_lock, flags);
233 return unit;
234 }
235 read_unlock_irqrestore(&port->unit_list_lock, flags);
247 return NULL; 236 return NULL;
248} 237}
249 238
@@ -257,18 +246,34 @@ struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
257struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, 246struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
258 u64 wwpn) 247 u64 wwpn)
259{ 248{
249 unsigned long flags;
260 struct zfcp_port *port; 250 struct zfcp_port *port;
261 251
262 list_for_each_entry(port, &adapter->port_list_head, list) 252 read_lock_irqsave(&adapter->port_list_lock, flags);
263 if ((port->wwpn == wwpn) && 253 list_for_each_entry(port, &adapter->port_list, list)
264 !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE)) 254 if (port->wwpn == wwpn) {
255 if (!get_device(&port->dev))
256 port = NULL;
257 read_unlock_irqrestore(&adapter->port_list_lock, flags);
265 return port; 258 return port;
259 }
260 read_unlock_irqrestore(&adapter->port_list_lock, flags);
266 return NULL; 261 return NULL;
267} 262}
268 263
269static void zfcp_sysfs_unit_release(struct device *dev) 264/**
265 * zfcp_unit_release - dequeue unit
266 * @dev: pointer to device
267 *
268 * waits until all work is done on unit and removes it then from the unit->list
269 * of the associated port.
270 */
271static void zfcp_unit_release(struct device *dev)
270{ 272{
271 kfree(container_of(dev, struct zfcp_unit, sysfs_device)); 273 struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
274
275 put_device(&unit->port->dev);
276 kfree(unit);
272} 277}
273 278
274/** 279/**
@@ -276,43 +281,40 @@ static void zfcp_sysfs_unit_release(struct device *dev)
276 * @port: pointer to port where unit is added 281 * @port: pointer to port where unit is added
277 * @fcp_lun: FCP LUN of unit to be enqueued 282 * @fcp_lun: FCP LUN of unit to be enqueued
278 * Returns: pointer to enqueued unit on success, ERR_PTR on error 283 * Returns: pointer to enqueued unit on success, ERR_PTR on error
279 * Locks: config_mutex must be held to serialize changes to the unit list
280 * 284 *
281 * Sets up some unit internal structures and creates sysfs entry. 285 * Sets up some unit internal structures and creates sysfs entry.
282 */ 286 */
283struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun) 287struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
284{ 288{
285 struct zfcp_unit *unit; 289 struct zfcp_unit *unit;
290 int retval = -ENOMEM;
291
292 get_device(&port->dev);
286 293
287 read_lock_irq(&zfcp_data.config_lock); 294 unit = zfcp_get_unit_by_lun(port, fcp_lun);
288 if (zfcp_get_unit_by_lun(port, fcp_lun)) { 295 if (unit) {
289 read_unlock_irq(&zfcp_data.config_lock); 296 put_device(&unit->dev);
290 return ERR_PTR(-EINVAL); 297 retval = -EEXIST;
298 goto err_out;
291 } 299 }
292 read_unlock_irq(&zfcp_data.config_lock);
293 300
294 unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); 301 unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
295 if (!unit) 302 if (!unit)
296 return ERR_PTR(-ENOMEM); 303 goto err_out;
297
298 atomic_set(&unit->refcount, 0);
299 init_waitqueue_head(&unit->remove_wq);
300 INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
301 304
302 unit->port = port; 305 unit->port = port;
303 unit->fcp_lun = fcp_lun; 306 unit->fcp_lun = fcp_lun;
307 unit->dev.parent = &port->dev;
308 unit->dev.release = zfcp_unit_release;
304 309
305 if (dev_set_name(&unit->sysfs_device, "0x%016llx", 310 if (dev_set_name(&unit->dev, "0x%016llx",
306 (unsigned long long) fcp_lun)) { 311 (unsigned long long) fcp_lun)) {
307 kfree(unit); 312 kfree(unit);
308 return ERR_PTR(-ENOMEM); 313 goto err_out;
309 } 314 }
310 unit->sysfs_device.parent = &port->sysfs_device; 315 retval = -EINVAL;
311 unit->sysfs_device.release = zfcp_sysfs_unit_release;
312 dev_set_drvdata(&unit->sysfs_device, unit);
313 316
314 /* mark unit unusable as long as sysfs registration is not complete */ 317 INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
315 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
316 318
317 spin_lock_init(&unit->latencies.lock); 319 spin_lock_init(&unit->latencies.lock);
318 unit->latencies.write.channel.min = 0xFFFFFFFF; 320 unit->latencies.write.channel.min = 0xFFFFFFFF;
@@ -322,52 +324,31 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
322 unit->latencies.cmd.channel.min = 0xFFFFFFFF; 324 unit->latencies.cmd.channel.min = 0xFFFFFFFF;
323 unit->latencies.cmd.fabric.min = 0xFFFFFFFF; 325 unit->latencies.cmd.fabric.min = 0xFFFFFFFF;
324 326
325 if (device_register(&unit->sysfs_device)) { 327 if (device_register(&unit->dev)) {
326 put_device(&unit->sysfs_device); 328 put_device(&unit->dev);
327 return ERR_PTR(-EINVAL); 329 goto err_out;
328 } 330 }
329 331
330 if (sysfs_create_group(&unit->sysfs_device.kobj, 332 if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs))
331 &zfcp_sysfs_unit_attrs)) { 333 goto err_out_put;
332 device_unregister(&unit->sysfs_device);
333 return ERR_PTR(-EINVAL);
334 }
335 334
336 zfcp_unit_get(unit); 335 write_lock_irq(&port->unit_list_lock);
336 list_add_tail(&unit->list, &port->unit_list);
337 write_unlock_irq(&port->unit_list_lock);
337 338
338 write_lock_irq(&zfcp_data.config_lock);
339 list_add_tail(&unit->list, &port->unit_list_head);
340 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
341 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); 339 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
342 340
343 write_unlock_irq(&zfcp_data.config_lock);
344
345 zfcp_port_get(port);
346
347 return unit; 341 return unit;
348}
349 342
350/** 343err_out_put:
351 * zfcp_unit_dequeue - dequeue unit 344 device_unregister(&unit->dev);
352 * @unit: pointer to zfcp_unit 345err_out:
353 * 346 put_device(&port->dev);
354 * waits until all work is done on unit and removes it then from the unit->list 347 return ERR_PTR(retval);
355 * of the associated port.
356 */
357void zfcp_unit_dequeue(struct zfcp_unit *unit)
358{
359 wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0);
360 write_lock_irq(&zfcp_data.config_lock);
361 list_del(&unit->list);
362 write_unlock_irq(&zfcp_data.config_lock);
363 zfcp_port_put(unit->port);
364 sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs);
365 device_unregister(&unit->sysfs_device);
366} 348}
367 349
368static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) 350static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
369{ 351{
370 /* must only be called with zfcp_data.config_mutex taken */
371 adapter->pool.erp_req = 352 adapter->pool.erp_req =
372 mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req)); 353 mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
373 if (!adapter->pool.erp_req) 354 if (!adapter->pool.erp_req)
@@ -405,9 +386,9 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
405 if (!adapter->pool.status_read_data) 386 if (!adapter->pool.status_read_data)
406 return -ENOMEM; 387 return -ENOMEM;
407 388
408 adapter->pool.gid_pn_data = 389 adapter->pool.gid_pn =
409 mempool_create_slab_pool(1, zfcp_data.gid_pn_cache); 390 mempool_create_slab_pool(1, zfcp_data.gid_pn_cache);
410 if (!adapter->pool.gid_pn_data) 391 if (!adapter->pool.gid_pn)
411 return -ENOMEM; 392 return -ENOMEM;
412 393
413 return 0; 394 return 0;
@@ -415,7 +396,6 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
415 396
416static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) 397static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
417{ 398{
418 /* zfcp_data.config_mutex must be held */
419 if (adapter->pool.erp_req) 399 if (adapter->pool.erp_req)
420 mempool_destroy(adapter->pool.erp_req); 400 mempool_destroy(adapter->pool.erp_req);
421 if (adapter->pool.scsi_req) 401 if (adapter->pool.scsi_req)
@@ -428,8 +408,8 @@ static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
428 mempool_destroy(adapter->pool.status_read_req); 408 mempool_destroy(adapter->pool.status_read_req);
429 if (adapter->pool.status_read_data) 409 if (adapter->pool.status_read_data)
430 mempool_destroy(adapter->pool.status_read_data); 410 mempool_destroy(adapter->pool.status_read_data);
431 if (adapter->pool.gid_pn_data) 411 if (adapter->pool.gid_pn)
432 mempool_destroy(adapter->pool.gid_pn_data); 412 mempool_destroy(adapter->pool.gid_pn);
433} 413}
434 414
435/** 415/**
@@ -497,139 +477,142 @@ static void zfcp_destroy_adapter_work_queue(struct zfcp_adapter *adapter)
497 * zfcp_adapter_enqueue - enqueue a new adapter to the list 477 * zfcp_adapter_enqueue - enqueue a new adapter to the list
498 * @ccw_device: pointer to the struct cc_device 478 * @ccw_device: pointer to the struct cc_device
499 * 479 *
500 * Returns: 0 if a new adapter was successfully enqueued 480 * Returns: struct zfcp_adapter*
501 * -ENOMEM if alloc failed
502 * Enqueues an adapter at the end of the adapter list in the driver data. 481 * Enqueues an adapter at the end of the adapter list in the driver data.
503 * All adapter internal structures are set up. 482 * All adapter internal structures are set up.
504 * Proc-fs entries are also created. 483 * Proc-fs entries are also created.
505 * locks: config_mutex must be held to serialize changes to the adapter list
506 */ 484 */
507int zfcp_adapter_enqueue(struct ccw_device *ccw_device) 485struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
508{ 486{
509 struct zfcp_adapter *adapter; 487 struct zfcp_adapter *adapter;
510 488
511 /* 489 if (!get_device(&ccw_device->dev))
512 * Note: It is safe to release the list_lock, as any list changes 490 return ERR_PTR(-ENODEV);
513 * are protected by the config_mutex, which must be held to get here
514 */
515 491
516 adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL); 492 adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
517 if (!adapter) 493 if (!adapter) {
518 return -ENOMEM; 494 put_device(&ccw_device->dev);
495 return ERR_PTR(-ENOMEM);
496 }
497
498 kref_init(&adapter->ref);
519 499
520 ccw_device->handler = NULL; 500 ccw_device->handler = NULL;
521 adapter->ccw_device = ccw_device; 501 adapter->ccw_device = ccw_device;
522 atomic_set(&adapter->refcount, 0); 502
503 INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
504 INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports);
523 505
524 if (zfcp_qdio_setup(adapter)) 506 if (zfcp_qdio_setup(adapter))
525 goto qdio_failed; 507 goto failed;
526 508
527 if (zfcp_allocate_low_mem_buffers(adapter)) 509 if (zfcp_allocate_low_mem_buffers(adapter))
528 goto low_mem_buffers_failed; 510 goto failed;
529 511
530 if (zfcp_reqlist_alloc(adapter)) 512 adapter->req_list = zfcp_reqlist_alloc();
531 goto low_mem_buffers_failed; 513 if (!adapter->req_list)
514 goto failed;
532 515
533 if (zfcp_dbf_adapter_register(adapter)) 516 if (zfcp_dbf_adapter_register(adapter))
534 goto debug_register_failed; 517 goto failed;
535 518
536 if (zfcp_setup_adapter_work_queue(adapter)) 519 if (zfcp_setup_adapter_work_queue(adapter))
537 goto work_queue_failed; 520 goto failed;
538 521
539 if (zfcp_fc_gs_setup(adapter)) 522 if (zfcp_fc_gs_setup(adapter))
540 goto generic_services_failed; 523 goto failed;
524
525 rwlock_init(&adapter->port_list_lock);
526 INIT_LIST_HEAD(&adapter->port_list);
541 527
542 init_waitqueue_head(&adapter->remove_wq);
543 init_waitqueue_head(&adapter->erp_ready_wq); 528 init_waitqueue_head(&adapter->erp_ready_wq);
544 init_waitqueue_head(&adapter->erp_done_wqh); 529 init_waitqueue_head(&adapter->erp_done_wqh);
545 530
546 INIT_LIST_HEAD(&adapter->port_list_head);
547 INIT_LIST_HEAD(&adapter->erp_ready_head); 531 INIT_LIST_HEAD(&adapter->erp_ready_head);
548 INIT_LIST_HEAD(&adapter->erp_running_head); 532 INIT_LIST_HEAD(&adapter->erp_running_head);
549 533
550 spin_lock_init(&adapter->req_list_lock);
551
552 rwlock_init(&adapter->erp_lock); 534 rwlock_init(&adapter->erp_lock);
553 rwlock_init(&adapter->abort_lock); 535 rwlock_init(&adapter->abort_lock);
554 536
555 if (zfcp_erp_thread_setup(adapter)) 537 if (zfcp_erp_thread_setup(adapter))
556 goto erp_thread_failed; 538 goto failed;
557
558 INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
559 INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
560 539
561 adapter->service_level.seq_print = zfcp_print_sl; 540 adapter->service_level.seq_print = zfcp_print_sl;
562 541
563 /* mark adapter unusable as long as sysfs registration is not complete */
564 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
565
566 dev_set_drvdata(&ccw_device->dev, adapter); 542 dev_set_drvdata(&ccw_device->dev, adapter);
567 543
568 if (sysfs_create_group(&ccw_device->dev.kobj, 544 if (sysfs_create_group(&ccw_device->dev.kobj,
569 &zfcp_sysfs_adapter_attrs)) 545 &zfcp_sysfs_adapter_attrs))
570 goto sysfs_failed; 546 goto failed;
571
572 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
573 547
574 if (!zfcp_adapter_scsi_register(adapter)) 548 if (!zfcp_adapter_scsi_register(adapter))
575 return 0; 549 return adapter;
576 550
577sysfs_failed: 551failed:
578 zfcp_erp_thread_kill(adapter); 552 zfcp_adapter_unregister(adapter);
579erp_thread_failed: 553 return ERR_PTR(-ENOMEM);
580 zfcp_fc_gs_destroy(adapter); 554}
581generic_services_failed: 555
556void zfcp_adapter_unregister(struct zfcp_adapter *adapter)
557{
558 struct ccw_device *cdev = adapter->ccw_device;
559
560 cancel_work_sync(&adapter->scan_work);
561 cancel_work_sync(&adapter->stat_work);
582 zfcp_destroy_adapter_work_queue(adapter); 562 zfcp_destroy_adapter_work_queue(adapter);
583work_queue_failed: 563
564 zfcp_fc_wka_ports_force_offline(adapter->gs);
565 zfcp_adapter_scsi_unregister(adapter);
566 sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs);
567
568 zfcp_erp_thread_kill(adapter);
584 zfcp_dbf_adapter_unregister(adapter->dbf); 569 zfcp_dbf_adapter_unregister(adapter->dbf);
585debug_register_failed:
586 dev_set_drvdata(&ccw_device->dev, NULL);
587 kfree(adapter->req_list);
588low_mem_buffers_failed:
589 zfcp_free_low_mem_buffers(adapter);
590qdio_failed:
591 zfcp_qdio_destroy(adapter->qdio); 570 zfcp_qdio_destroy(adapter->qdio);
592 kfree(adapter); 571
593 return -ENOMEM; 572 zfcp_ccw_adapter_put(adapter); /* final put to release */
594} 573}
595 574
596/** 575/**
597 * zfcp_adapter_dequeue - remove the adapter from the resource list 576 * zfcp_adapter_release - remove the adapter from the resource list
598 * @adapter: pointer to struct zfcp_adapter which should be removed 577 * @ref: pointer to struct kref
599 * locks: adapter list write lock is assumed to be held by caller 578 * locks: adapter list write lock is assumed to be held by caller
600 */ 579 */
601void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) 580void zfcp_adapter_release(struct kref *ref)
602{ 581{
603 int retval = 0; 582 struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter,
604 unsigned long flags; 583 ref);
584 struct ccw_device *cdev = adapter->ccw_device;
605 585
606 cancel_work_sync(&adapter->stat_work);
607 zfcp_fc_wka_ports_force_offline(adapter->gs);
608 sysfs_remove_group(&adapter->ccw_device->dev.kobj,
609 &zfcp_sysfs_adapter_attrs);
610 dev_set_drvdata(&adapter->ccw_device->dev, NULL); 586 dev_set_drvdata(&adapter->ccw_device->dev, NULL);
611 /* sanity check: no pending FSF requests */
612 spin_lock_irqsave(&adapter->req_list_lock, flags);
613 retval = zfcp_reqlist_isempty(adapter);
614 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
615 if (!retval)
616 return;
617
618 zfcp_fc_gs_destroy(adapter); 587 zfcp_fc_gs_destroy(adapter);
619 zfcp_erp_thread_kill(adapter);
620 zfcp_destroy_adapter_work_queue(adapter);
621 zfcp_dbf_adapter_unregister(adapter->dbf);
622 zfcp_free_low_mem_buffers(adapter); 588 zfcp_free_low_mem_buffers(adapter);
623 zfcp_qdio_destroy(adapter->qdio);
624 kfree(adapter->req_list); 589 kfree(adapter->req_list);
625 kfree(adapter->fc_stats); 590 kfree(adapter->fc_stats);
626 kfree(adapter->stats_reset_data); 591 kfree(adapter->stats_reset_data);
627 kfree(adapter); 592 kfree(adapter);
593 put_device(&cdev->dev);
628} 594}
629 595
630static void zfcp_sysfs_port_release(struct device *dev) 596/**
597 * zfcp_device_unregister - remove port, unit from system
598 * @dev: reference to device which is to be removed
599 * @grp: related reference to attribute group
600 *
601 * Helper function to unregister port, unit from system
602 */
603void zfcp_device_unregister(struct device *dev,
604 const struct attribute_group *grp)
631{ 605{
632 kfree(container_of(dev, struct zfcp_port, sysfs_device)); 606 sysfs_remove_group(&dev->kobj, grp);
607 device_unregister(dev);
608}
609
610static void zfcp_port_release(struct device *dev)
611{
612 struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
613
614 zfcp_ccw_adapter_put(port->adapter);
615 kfree(port);
633} 616}
634 617
635/** 618/**
@@ -639,7 +622,6 @@ static void zfcp_sysfs_port_release(struct device *dev)
639 * @status: initial status for the port 622 * @status: initial status for the port
640 * @d_id: destination id of the remote port to be enqueued 623 * @d_id: destination id of the remote port to be enqueued
641 * Returns: pointer to enqueued port on success, ERR_PTR on error 624 * Returns: pointer to enqueued port on success, ERR_PTR on error
642 * Locks: config_mutex must be held to serialize changes to the port list
643 * 625 *
644 * All port internal structures are set up and the sysfs entry is generated. 626 * All port internal structures are set up and the sysfs entry is generated.
645 * d_id is used to enqueue ports with a well known address like the Directory 627 * d_id is used to enqueue ports with a well known address like the Directory
@@ -649,20 +631,24 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
649 u32 status, u32 d_id) 631 u32 status, u32 d_id)
650{ 632{
651 struct zfcp_port *port; 633 struct zfcp_port *port;
634 int retval = -ENOMEM;
635
636 kref_get(&adapter->ref);
652 637
653 read_lock_irq(&zfcp_data.config_lock); 638 port = zfcp_get_port_by_wwpn(adapter, wwpn);
654 if (zfcp_get_port_by_wwpn(adapter, wwpn)) { 639 if (port) {
655 read_unlock_irq(&zfcp_data.config_lock); 640 put_device(&port->dev);
656 return ERR_PTR(-EINVAL); 641 retval = -EEXIST;
642 goto err_out;
657 } 643 }
658 read_unlock_irq(&zfcp_data.config_lock);
659 644
660 port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); 645 port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
661 if (!port) 646 if (!port)
662 return ERR_PTR(-ENOMEM); 647 goto err_out;
648
649 rwlock_init(&port->unit_list_lock);
650 INIT_LIST_HEAD(&port->unit_list);
663 651
664 init_waitqueue_head(&port->remove_wq);
665 INIT_LIST_HEAD(&port->unit_list_head);
666 INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup); 652 INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
667 INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work); 653 INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
668 INIT_WORK(&port->rport_work, zfcp_scsi_rport_work); 654 INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
@@ -671,58 +657,37 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
671 port->d_id = d_id; 657 port->d_id = d_id;
672 port->wwpn = wwpn; 658 port->wwpn = wwpn;
673 port->rport_task = RPORT_NONE; 659 port->rport_task = RPORT_NONE;
660 port->dev.parent = &adapter->ccw_device->dev;
661 port->dev.release = zfcp_port_release;
674 662
675 /* mark port unusable as long as sysfs registration is not complete */ 663 if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) {
676 atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
677 atomic_set(&port->refcount, 0);
678
679 if (dev_set_name(&port->sysfs_device, "0x%016llx",
680 (unsigned long long)wwpn)) {
681 kfree(port); 664 kfree(port);
682 return ERR_PTR(-ENOMEM); 665 goto err_out;
683 }
684 port->sysfs_device.parent = &adapter->ccw_device->dev;
685 port->sysfs_device.release = zfcp_sysfs_port_release;
686 dev_set_drvdata(&port->sysfs_device, port);
687
688 if (device_register(&port->sysfs_device)) {
689 put_device(&port->sysfs_device);
690 return ERR_PTR(-EINVAL);
691 } 666 }
667 retval = -EINVAL;
692 668
693 if (sysfs_create_group(&port->sysfs_device.kobj, 669 if (device_register(&port->dev)) {
694 &zfcp_sysfs_port_attrs)) { 670 put_device(&port->dev);
695 device_unregister(&port->sysfs_device); 671 goto err_out;
696 return ERR_PTR(-EINVAL);
697 } 672 }
698 673
699 zfcp_port_get(port); 674 if (sysfs_create_group(&port->dev.kobj,
675 &zfcp_sysfs_port_attrs))
676 goto err_out_put;
700 677
701 write_lock_irq(&zfcp_data.config_lock); 678 write_lock_irq(&adapter->port_list_lock);
702 list_add_tail(&port->list, &adapter->port_list_head); 679 list_add_tail(&port->list, &adapter->port_list);
703 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); 680 write_unlock_irq(&adapter->port_list_lock);
704 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
705 681
706 write_unlock_irq(&zfcp_data.config_lock); 682 atomic_set_mask(status | ZFCP_STATUS_COMMON_RUNNING, &port->status);
707 683
708 zfcp_adapter_get(adapter);
709 return port; 684 return port;
710}
711 685
712/** 686err_out_put:
713 * zfcp_port_dequeue - dequeues a port from the port list of the adapter 687 device_unregister(&port->dev);
714 * @port: pointer to struct zfcp_port which should be removed 688err_out:
715 */ 689 zfcp_ccw_adapter_put(adapter);
716void zfcp_port_dequeue(struct zfcp_port *port) 690 return ERR_PTR(retval);
717{
718 write_lock_irq(&zfcp_data.config_lock);
719 list_del(&port->list);
720 write_unlock_irq(&zfcp_data.config_lock);
721 wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
722 cancel_work_sync(&port->rport_work); /* usually not necessary */
723 zfcp_adapter_put(port->adapter);
724 sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
725 device_unregister(&port->sysfs_device);
726} 691}
727 692
728/** 693/**