1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * zfcp device driver |
4 | * |
5 | * Module interface and handling of zfcp data structures. |
6 | * |
7 | * Copyright IBM Corp. 2002, 2020 |
8 | */ |
9 | |
10 | /* |
11 | * Driver authors: |
12 | * Martin Peschke (originator of the driver) |
13 | * Raimund Schroeder |
14 | * Aron Zeh |
15 | * Wolfgang Taphorn |
16 | * Stefan Bader |
17 | * Heiko Carstens (kernel 2.6 port of the driver) |
18 | * Andreas Herrmann |
19 | * Maxim Shchetynin |
20 | * Volker Sameske |
21 | * Ralph Wuerthner |
22 | * Michael Loehr |
23 | * Swen Schillig |
24 | * Christof Schmitt |
25 | * Martin Petermann |
26 | * Sven Schuetz |
27 | * Steffen Maier |
28 | * Benjamin Block |
29 | */ |
30 | |
31 | #define KMSG_COMPONENT "zfcp" |
32 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
33 | |
34 | #include <linux/seq_file.h> |
35 | #include <linux/slab.h> |
36 | #include <linux/module.h> |
37 | #include "zfcp_ext.h" |
38 | #include "zfcp_fc.h" |
39 | #include "zfcp_reqlist.h" |
40 | #include "zfcp_diag.h" |
41 | |
42 | #define ZFCP_BUS_ID_SIZE 20 |
43 | |
44 | MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com" ); |
45 | MODULE_DESCRIPTION("FCP HBA driver" ); |
46 | MODULE_LICENSE("GPL" ); |
47 | |
48 | static char *init_device; |
49 | module_param_named(device, init_device, charp, 0400); |
50 | MODULE_PARM_DESC(device, "specify initial device" ); |
51 | |
52 | static struct kmem_cache * __init zfcp_cache_hw_align(const char *name, |
53 | unsigned long size) |
54 | { |
55 | return kmem_cache_create(name, size, roundup_pow_of_two(size), flags: 0, NULL); |
56 | } |
57 | |
58 | static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) |
59 | { |
60 | struct ccw_device *cdev; |
61 | struct zfcp_adapter *adapter; |
62 | struct zfcp_port *port; |
63 | |
64 | cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); |
65 | if (!cdev) |
66 | return; |
67 | |
68 | if (ccw_device_set_online(cdev)) |
69 | goto out_ccw_device; |
70 | |
71 | adapter = zfcp_ccw_adapter_by_cdev(cdev); |
72 | if (!adapter) |
73 | goto out_ccw_device; |
74 | |
75 | port = zfcp_get_port_by_wwpn(adapter, wwpn); |
76 | if (!port) |
77 | goto out_port; |
78 | flush_work(work: &port->rport_work); |
79 | |
80 | zfcp_unit_add(port, lun); |
81 | put_device(dev: &port->dev); |
82 | |
83 | out_port: |
84 | zfcp_ccw_adapter_put(adapter); |
85 | out_ccw_device: |
86 | put_device(dev: &cdev->dev); |
87 | return; |
88 | } |
89 | |
90 | static void __init zfcp_init_device_setup(char *devstr) |
91 | { |
92 | char *token; |
93 | char *str, *str_saved; |
94 | char busid[ZFCP_BUS_ID_SIZE]; |
95 | u64 wwpn, lun; |
96 | |
97 | /* duplicate devstr and keep the original for sysfs presentation*/ |
98 | str_saved = kstrdup(s: devstr, GFP_KERNEL); |
99 | str = str_saved; |
100 | if (!str) |
101 | return; |
102 | |
103 | token = strsep(&str, "," ); |
104 | if (!token || strlen(token) >= ZFCP_BUS_ID_SIZE) |
105 | goto err_out; |
106 | strscpy(p: busid, q: token, ZFCP_BUS_ID_SIZE); |
107 | |
108 | token = strsep(&str, "," ); |
109 | if (!token || kstrtoull(s: token, base: 0, res: (unsigned long long *) &wwpn)) |
110 | goto err_out; |
111 | |
112 | token = strsep(&str, "," ); |
113 | if (!token || kstrtoull(s: token, base: 0, res: (unsigned long long *) &lun)) |
114 | goto err_out; |
115 | |
116 | kfree(objp: str_saved); |
117 | zfcp_init_device_configure(busid, wwpn, lun); |
118 | return; |
119 | |
120 | err_out: |
121 | kfree(objp: str_saved); |
122 | pr_err("%s is not a valid SCSI device\n" , devstr); |
123 | } |
124 | |
125 | static int __init zfcp_module_init(void) |
126 | { |
127 | int retval = -ENOMEM; |
128 | |
129 | if (zfcp_experimental_dix) |
130 | pr_warn("DIX is enabled. It is experimental and might cause problems\n" ); |
131 | |
132 | zfcp_fsf_qtcb_cache = zfcp_cache_hw_align(name: "zfcp_fsf_qtcb" , |
133 | size: sizeof(struct fsf_qtcb)); |
134 | if (!zfcp_fsf_qtcb_cache) |
135 | goto out_qtcb_cache; |
136 | |
137 | zfcp_fc_req_cache = zfcp_cache_hw_align(name: "zfcp_fc_req" , |
138 | size: sizeof(struct zfcp_fc_req)); |
139 | if (!zfcp_fc_req_cache) |
140 | goto out_fc_cache; |
141 | |
142 | zfcp_scsi_transport_template = |
143 | fc_attach_transport(&zfcp_transport_functions); |
144 | if (!zfcp_scsi_transport_template) |
145 | goto out_transport; |
146 | scsi_transport_reserve_device(t: zfcp_scsi_transport_template, |
147 | space: sizeof(struct zfcp_scsi_dev)); |
148 | |
149 | retval = ccw_driver_register(&zfcp_ccw_driver); |
150 | if (retval) { |
151 | pr_err("The zfcp device driver could not register with " |
152 | "the common I/O layer\n" ); |
153 | goto out_ccw_register; |
154 | } |
155 | |
156 | if (init_device) |
157 | zfcp_init_device_setup(devstr: init_device); |
158 | return 0; |
159 | |
160 | out_ccw_register: |
161 | fc_release_transport(zfcp_scsi_transport_template); |
162 | out_transport: |
163 | kmem_cache_destroy(s: zfcp_fc_req_cache); |
164 | out_fc_cache: |
165 | kmem_cache_destroy(s: zfcp_fsf_qtcb_cache); |
166 | out_qtcb_cache: |
167 | return retval; |
168 | } |
169 | |
170 | module_init(zfcp_module_init); |
171 | |
172 | static void __exit zfcp_module_exit(void) |
173 | { |
174 | ccw_driver_unregister(&zfcp_ccw_driver); |
175 | fc_release_transport(zfcp_scsi_transport_template); |
176 | kmem_cache_destroy(s: zfcp_fc_req_cache); |
177 | kmem_cache_destroy(s: zfcp_fsf_qtcb_cache); |
178 | } |
179 | |
180 | module_exit(zfcp_module_exit); |
181 | |
182 | /** |
183 | * zfcp_get_port_by_wwpn - find port in port list of adapter by wwpn |
184 | * @adapter: pointer to adapter to search for port |
185 | * @wwpn: wwpn to search for |
186 | * |
187 | * Returns: pointer to zfcp_port or NULL |
188 | */ |
189 | struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, |
190 | u64 wwpn) |
191 | { |
192 | unsigned long flags; |
193 | struct zfcp_port *port; |
194 | |
195 | read_lock_irqsave(&adapter->port_list_lock, flags); |
196 | list_for_each_entry(port, &adapter->port_list, list) |
197 | if (port->wwpn == wwpn) { |
198 | if (!get_device(dev: &port->dev)) |
199 | port = NULL; |
200 | read_unlock_irqrestore(&adapter->port_list_lock, flags); |
201 | return port; |
202 | } |
203 | read_unlock_irqrestore(&adapter->port_list_lock, flags); |
204 | return NULL; |
205 | } |
206 | |
207 | static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) |
208 | { |
209 | adapter->pool.erp_req = |
210 | mempool_create_kmalloc_pool(min_nr: 1, size: sizeof(struct zfcp_fsf_req)); |
211 | if (!adapter->pool.erp_req) |
212 | return -ENOMEM; |
213 | |
214 | adapter->pool.gid_pn_req = |
215 | mempool_create_kmalloc_pool(min_nr: 1, size: sizeof(struct zfcp_fsf_req)); |
216 | if (!adapter->pool.gid_pn_req) |
217 | return -ENOMEM; |
218 | |
219 | adapter->pool.scsi_req = |
220 | mempool_create_kmalloc_pool(min_nr: 1, size: sizeof(struct zfcp_fsf_req)); |
221 | if (!adapter->pool.scsi_req) |
222 | return -ENOMEM; |
223 | |
224 | adapter->pool.scsi_abort = |
225 | mempool_create_kmalloc_pool(min_nr: 1, size: sizeof(struct zfcp_fsf_req)); |
226 | if (!adapter->pool.scsi_abort) |
227 | return -ENOMEM; |
228 | |
229 | adapter->pool.status_read_req = |
230 | mempool_create_kmalloc_pool(FSF_STATUS_READS_RECOM, |
231 | size: sizeof(struct zfcp_fsf_req)); |
232 | if (!adapter->pool.status_read_req) |
233 | return -ENOMEM; |
234 | |
235 | adapter->pool.qtcb_pool = |
236 | mempool_create_slab_pool(min_nr: 4, kc: zfcp_fsf_qtcb_cache); |
237 | if (!adapter->pool.qtcb_pool) |
238 | return -ENOMEM; |
239 | |
240 | BUILD_BUG_ON(sizeof(struct fsf_status_read_buffer) > PAGE_SIZE); |
241 | adapter->pool.sr_data = |
242 | mempool_create_page_pool(FSF_STATUS_READS_RECOM, order: 0); |
243 | if (!adapter->pool.sr_data) |
244 | return -ENOMEM; |
245 | |
246 | adapter->pool.gid_pn = |
247 | mempool_create_slab_pool(min_nr: 1, kc: zfcp_fc_req_cache); |
248 | if (!adapter->pool.gid_pn) |
249 | return -ENOMEM; |
250 | |
251 | return 0; |
252 | } |
253 | |
254 | static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) |
255 | { |
256 | mempool_destroy(pool: adapter->pool.erp_req); |
257 | mempool_destroy(pool: adapter->pool.scsi_req); |
258 | mempool_destroy(pool: adapter->pool.scsi_abort); |
259 | mempool_destroy(pool: adapter->pool.qtcb_pool); |
260 | mempool_destroy(pool: adapter->pool.status_read_req); |
261 | mempool_destroy(pool: adapter->pool.sr_data); |
262 | mempool_destroy(pool: adapter->pool.gid_pn); |
263 | } |
264 | |
265 | /** |
266 | * zfcp_status_read_refill - refill the long running status_read_requests |
267 | * @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled |
268 | * |
269 | * Return: |
270 | * * 0 on success meaning at least one status read is pending |
271 | * * 1 if posting failed and not a single status read buffer is pending, |
272 | * also triggers adapter reopen recovery |
273 | */ |
274 | int zfcp_status_read_refill(struct zfcp_adapter *adapter) |
275 | { |
276 | while (atomic_add_unless(v: &adapter->stat_miss, a: -1, u: 0)) |
277 | if (zfcp_fsf_status_read(adapter->qdio)) { |
278 | atomic_inc(v: &adapter->stat_miss); /* undo add -1 */ |
279 | if (atomic_read(v: &adapter->stat_miss) >= |
280 | adapter->stat_read_buf_num) { |
281 | zfcp_erp_adapter_reopen(adapter, 0, "axsref1" ); |
282 | return 1; |
283 | } |
284 | break; |
285 | } |
286 | return 0; |
287 | } |
288 | |
289 | static void _zfcp_status_read_scheduler(struct work_struct *work) |
290 | { |
291 | zfcp_status_read_refill(container_of(work, struct zfcp_adapter, |
292 | stat_work)); |
293 | } |
294 | |
295 | static void zfcp_version_change_lost_work(struct work_struct *work) |
296 | { |
297 | struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter, |
298 | version_change_lost_work); |
299 | |
300 | zfcp_fsf_exchange_config_data_sync(adapter->qdio, NULL); |
301 | } |
302 | |
303 | static void zfcp_print_sl(struct seq_file *m, struct service_level *sl) |
304 | { |
305 | struct zfcp_adapter *adapter = |
306 | container_of(sl, struct zfcp_adapter, service_level); |
307 | |
308 | seq_printf(m, fmt: "zfcp: %s microcode level %x\n" , |
309 | dev_name(dev: &adapter->ccw_device->dev), |
310 | adapter->fsf_lic_version); |
311 | } |
312 | |
313 | static int zfcp_setup_adapter_work_queue(struct zfcp_adapter *adapter) |
314 | { |
315 | char name[TASK_COMM_LEN]; |
316 | |
317 | snprintf(buf: name, size: sizeof(name), fmt: "zfcp_q_%s" , |
318 | dev_name(dev: &adapter->ccw_device->dev)); |
319 | adapter->work_queue = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); |
320 | |
321 | if (adapter->work_queue) |
322 | return 0; |
323 | return -ENOMEM; |
324 | } |
325 | |
326 | static void zfcp_destroy_adapter_work_queue(struct zfcp_adapter *adapter) |
327 | { |
328 | if (adapter->work_queue) |
329 | destroy_workqueue(wq: adapter->work_queue); |
330 | adapter->work_queue = NULL; |
331 | |
332 | } |
333 | |
334 | /** |
335 | * zfcp_adapter_enqueue - enqueue a new adapter to the list |
336 | * @ccw_device: pointer to the struct cc_device |
337 | * |
338 | * Returns: struct zfcp_adapter* |
339 | * Enqueues an adapter at the end of the adapter list in the driver data. |
340 | * All adapter internal structures are set up. |
341 | * Proc-fs entries are also created. |
342 | */ |
343 | struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) |
344 | { |
345 | struct zfcp_adapter *adapter; |
346 | |
347 | if (!get_device(dev: &ccw_device->dev)) |
348 | return ERR_PTR(error: -ENODEV); |
349 | |
350 | adapter = kzalloc(size: sizeof(struct zfcp_adapter), GFP_KERNEL); |
351 | if (!adapter) { |
352 | put_device(dev: &ccw_device->dev); |
353 | return ERR_PTR(error: -ENOMEM); |
354 | } |
355 | |
356 | kref_init(kref: &adapter->ref); |
357 | |
358 | ccw_device->handler = NULL; |
359 | adapter->ccw_device = ccw_device; |
360 | |
361 | INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); |
362 | INIT_DELAYED_WORK(&adapter->scan_work, zfcp_fc_scan_ports); |
363 | INIT_WORK(&adapter->ns_up_work, zfcp_fc_sym_name_update); |
364 | INIT_WORK(&adapter->version_change_lost_work, |
365 | zfcp_version_change_lost_work); |
366 | |
367 | adapter->next_port_scan = jiffies; |
368 | |
369 | adapter->erp_action.adapter = adapter; |
370 | |
371 | if (zfcp_diag_adapter_setup(adapter)) |
372 | goto failed; |
373 | |
374 | if (zfcp_qdio_setup(adapter)) |
375 | goto failed; |
376 | |
377 | if (zfcp_allocate_low_mem_buffers(adapter)) |
378 | goto failed; |
379 | |
380 | adapter->req_list = zfcp_reqlist_alloc(); |
381 | if (!adapter->req_list) |
382 | goto failed; |
383 | |
384 | if (zfcp_dbf_adapter_register(adapter)) |
385 | goto failed; |
386 | |
387 | if (zfcp_setup_adapter_work_queue(adapter)) |
388 | goto failed; |
389 | |
390 | if (zfcp_fc_gs_setup(adapter)) |
391 | goto failed; |
392 | |
393 | rwlock_init(&adapter->port_list_lock); |
394 | INIT_LIST_HEAD(list: &adapter->port_list); |
395 | |
396 | INIT_LIST_HEAD(list: &adapter->events.list); |
397 | INIT_WORK(&adapter->events.work, zfcp_fc_post_event); |
398 | spin_lock_init(&adapter->events.list_lock); |
399 | |
400 | init_waitqueue_head(&adapter->erp_ready_wq); |
401 | init_waitqueue_head(&adapter->erp_done_wqh); |
402 | |
403 | INIT_LIST_HEAD(list: &adapter->erp_ready_head); |
404 | INIT_LIST_HEAD(list: &adapter->erp_running_head); |
405 | |
406 | rwlock_init(&adapter->erp_lock); |
407 | rwlock_init(&adapter->abort_lock); |
408 | |
409 | if (zfcp_erp_thread_setup(adapter)) |
410 | goto failed; |
411 | |
412 | adapter->service_level.seq_print = zfcp_print_sl; |
413 | |
414 | dev_set_drvdata(dev: &ccw_device->dev, data: adapter); |
415 | |
416 | if (device_add_groups(dev: &ccw_device->dev, groups: zfcp_sysfs_adapter_attr_groups)) |
417 | goto err_sysfs; |
418 | |
419 | /* report size limit per scatter-gather segment */ |
420 | adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; |
421 | |
422 | adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM; |
423 | |
424 | return adapter; |
425 | |
426 | err_sysfs: |
427 | failed: |
428 | /* TODO: make this more fine-granular */ |
429 | cancel_delayed_work_sync(dwork: &adapter->scan_work); |
430 | cancel_work_sync(work: &adapter->stat_work); |
431 | cancel_work_sync(work: &adapter->ns_up_work); |
432 | cancel_work_sync(work: &adapter->version_change_lost_work); |
433 | zfcp_destroy_adapter_work_queue(adapter); |
434 | |
435 | zfcp_fc_wka_ports_force_offline(adapter->gs); |
436 | zfcp_scsi_adapter_unregister(adapter); |
437 | |
438 | zfcp_erp_thread_kill(adapter); |
439 | zfcp_dbf_adapter_unregister(adapter); |
440 | zfcp_qdio_destroy(adapter->qdio); |
441 | |
442 | zfcp_ccw_adapter_put(adapter); /* final put to release */ |
443 | return ERR_PTR(error: -ENOMEM); |
444 | } |
445 | |
446 | void zfcp_adapter_unregister(struct zfcp_adapter *adapter) |
447 | { |
448 | struct ccw_device *cdev = adapter->ccw_device; |
449 | |
450 | cancel_delayed_work_sync(dwork: &adapter->scan_work); |
451 | cancel_work_sync(work: &adapter->stat_work); |
452 | cancel_work_sync(work: &adapter->ns_up_work); |
453 | cancel_work_sync(work: &adapter->version_change_lost_work); |
454 | zfcp_destroy_adapter_work_queue(adapter); |
455 | |
456 | zfcp_fc_wka_ports_force_offline(adapter->gs); |
457 | zfcp_scsi_adapter_unregister(adapter); |
458 | device_remove_groups(dev: &cdev->dev, groups: zfcp_sysfs_adapter_attr_groups); |
459 | |
460 | zfcp_erp_thread_kill(adapter); |
461 | zfcp_dbf_adapter_unregister(adapter); |
462 | zfcp_qdio_destroy(adapter->qdio); |
463 | |
464 | zfcp_ccw_adapter_put(adapter); /* final put to release */ |
465 | } |
466 | |
467 | /** |
468 | * zfcp_adapter_release - remove the adapter from the resource list |
469 | * @ref: pointer to struct kref |
470 | * locks: adapter list write lock is assumed to be held by caller |
471 | */ |
472 | void zfcp_adapter_release(struct kref *ref) |
473 | { |
474 | struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter, |
475 | ref); |
476 | struct ccw_device *cdev = adapter->ccw_device; |
477 | |
478 | dev_set_drvdata(dev: &adapter->ccw_device->dev, NULL); |
479 | zfcp_fc_gs_destroy(adapter); |
480 | zfcp_free_low_mem_buffers(adapter); |
481 | zfcp_diag_adapter_free(adapter); |
482 | kfree(objp: adapter->req_list); |
483 | kfree(objp: adapter->fc_stats); |
484 | kfree(objp: adapter->stats_reset_data); |
485 | kfree(objp: adapter); |
486 | put_device(dev: &cdev->dev); |
487 | } |
488 | |
489 | static void zfcp_port_release(struct device *dev) |
490 | { |
491 | struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); |
492 | |
493 | zfcp_ccw_adapter_put(port->adapter); |
494 | kfree(objp: port); |
495 | } |
496 | |
497 | /** |
498 | * zfcp_port_enqueue - enqueue port to port list of adapter |
499 | * @adapter: adapter where remote port is added |
500 | * @wwpn: WWPN of the remote port to be enqueued |
501 | * @status: initial status for the port |
502 | * @d_id: destination id of the remote port to be enqueued |
503 | * Returns: pointer to enqueued port on success, ERR_PTR on error |
504 | * |
505 | * All port internal structures are set up and the sysfs entry is generated. |
506 | * d_id is used to enqueue ports with a well known address like the Directory |
507 | * Service for nameserver lookup. |
508 | */ |
509 | struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, |
510 | u32 status, u32 d_id) |
511 | { |
512 | struct zfcp_port *port; |
513 | int retval = -ENOMEM; |
514 | |
515 | kref_get(kref: &adapter->ref); |
516 | |
517 | port = zfcp_get_port_by_wwpn(adapter, wwpn); |
518 | if (port) { |
519 | put_device(dev: &port->dev); |
520 | retval = -EEXIST; |
521 | goto err_put; |
522 | } |
523 | |
524 | port = kzalloc(size: sizeof(struct zfcp_port), GFP_KERNEL); |
525 | if (!port) |
526 | goto err_put; |
527 | |
528 | rwlock_init(&port->unit_list_lock); |
529 | INIT_LIST_HEAD(list: &port->unit_list); |
530 | atomic_set(v: &port->units, i: 0); |
531 | |
532 | INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup); |
533 | INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work); |
534 | INIT_WORK(&port->rport_work, zfcp_scsi_rport_work); |
535 | |
536 | port->adapter = adapter; |
537 | port->d_id = d_id; |
538 | port->wwpn = wwpn; |
539 | port->rport_task = RPORT_NONE; |
540 | port->dev.parent = &adapter->ccw_device->dev; |
541 | port->dev.groups = zfcp_port_attr_groups; |
542 | port->dev.release = zfcp_port_release; |
543 | |
544 | port->erp_action.adapter = adapter; |
545 | port->erp_action.port = port; |
546 | |
547 | if (dev_set_name(dev: &port->dev, name: "0x%016llx" , (unsigned long long)wwpn)) { |
548 | kfree(objp: port); |
549 | goto err_put; |
550 | } |
551 | retval = -EINVAL; |
552 | |
553 | if (device_register(dev: &port->dev)) { |
554 | put_device(dev: &port->dev); |
555 | goto err_out; |
556 | } |
557 | |
558 | write_lock_irq(&adapter->port_list_lock); |
559 | list_add_tail(new: &port->list, head: &adapter->port_list); |
560 | write_unlock_irq(&adapter->port_list_lock); |
561 | |
562 | atomic_or(i: status | ZFCP_STATUS_COMMON_RUNNING, v: &port->status); |
563 | |
564 | return port; |
565 | |
566 | err_put: |
567 | zfcp_ccw_adapter_put(adapter); |
568 | err_out: |
569 | return ERR_PTR(error: retval); |
570 | } |
571 | |