| .. | .. |
|---|
| 4 | 4 | * |
|---|
| 5 | 5 | * Module interface and handling of zfcp data structures. |
|---|
| 6 | 6 | * |
|---|
| 7 | | - * Copyright IBM Corp. 2002, 2013 |
|---|
| 7 | + * Copyright IBM Corp. 2002, 2020 |
|---|
| 8 | 8 | */ |
|---|
| 9 | 9 | |
|---|
| 10 | 10 | /* |
|---|
| .. | .. |
|---|
| 25 | 25 | * Martin Petermann |
|---|
| 26 | 26 | * Sven Schuetz |
|---|
| 27 | 27 | * Steffen Maier |
|---|
| 28 | + * Benjamin Block |
|---|
| 28 | 29 | */ |
|---|
| 29 | 30 | |
|---|
| 30 | 31 | #define KMSG_COMPONENT "zfcp" |
|---|
| .. | .. |
|---|
| 36 | 37 | #include "zfcp_ext.h" |
|---|
| 37 | 38 | #include "zfcp_fc.h" |
|---|
| 38 | 39 | #include "zfcp_reqlist.h" |
|---|
| 40 | +#include "zfcp_diag.h" |
|---|
| 39 | 41 | |
|---|
| 40 | 42 | #define ZFCP_BUS_ID_SIZE 20 |
|---|
| 41 | 43 | |
|---|
| .. | .. |
|---|
| 123 | 125 | static int __init zfcp_module_init(void) |
|---|
| 124 | 126 | { |
|---|
| 125 | 127 | int retval = -ENOMEM; |
|---|
| 128 | + |
|---|
| 129 | + if (zfcp_experimental_dix) |
|---|
| 130 | + pr_warn("DIX is enabled. It is experimental and might cause problems\n"); |
|---|
| 126 | 131 | |
|---|
| 127 | 132 | zfcp_fsf_qtcb_cache = zfcp_cache_hw_align("zfcp_fsf_qtcb", |
|---|
| 128 | 133 | sizeof(struct fsf_qtcb)); |
|---|
| .. | .. |
|---|
| 248 | 253 | |
|---|
| 249 | 254 | static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) |
|---|
| 250 | 255 | { |
|---|
| 251 | | - if (adapter->pool.erp_req) |
|---|
| 252 | | - mempool_destroy(adapter->pool.erp_req); |
|---|
| 253 | | - if (adapter->pool.scsi_req) |
|---|
| 254 | | - mempool_destroy(adapter->pool.scsi_req); |
|---|
| 255 | | - if (adapter->pool.scsi_abort) |
|---|
| 256 | | - mempool_destroy(adapter->pool.scsi_abort); |
|---|
| 257 | | - if (adapter->pool.qtcb_pool) |
|---|
| 258 | | - mempool_destroy(adapter->pool.qtcb_pool); |
|---|
| 259 | | - if (adapter->pool.status_read_req) |
|---|
| 260 | | - mempool_destroy(adapter->pool.status_read_req); |
|---|
| 261 | | - if (adapter->pool.sr_data) |
|---|
| 262 | | - mempool_destroy(adapter->pool.sr_data); |
|---|
| 263 | | - if (adapter->pool.gid_pn) |
|---|
| 264 | | - mempool_destroy(adapter->pool.gid_pn); |
|---|
| 256 | + mempool_destroy(adapter->pool.erp_req); |
|---|
| 257 | + mempool_destroy(adapter->pool.scsi_req); |
|---|
| 258 | + mempool_destroy(adapter->pool.scsi_abort); |
|---|
| 259 | + mempool_destroy(adapter->pool.qtcb_pool); |
|---|
| 260 | + mempool_destroy(adapter->pool.status_read_req); |
|---|
| 261 | + mempool_destroy(adapter->pool.sr_data); |
|---|
| 262 | + mempool_destroy(adapter->pool.gid_pn); |
|---|
| 265 | 263 | } |
|---|
| 266 | 264 | |
|---|
| 267 | 265 | /** |
|---|
| 268 | 266 | * zfcp_status_read_refill - refill the long running status_read_requests |
|---|
| 269 | 267 | * @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled |
|---|
| 270 | 268 | * |
|---|
| 271 | | - * Returns: 0 on success, 1 otherwise |
|---|
| 272 | | - * |
|---|
| 273 | | - * if there are 16 or more status_read requests missing an adapter_reopen |
|---|
| 274 | | - * is triggered |
|---|
| 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 |
|---|
| 275 | 273 | */ |
|---|
| 276 | 274 | int zfcp_status_read_refill(struct zfcp_adapter *adapter) |
|---|
| 277 | 275 | { |
|---|
| .. | .. |
|---|
| 360 | 358 | |
|---|
| 361 | 359 | adapter->erp_action.adapter = adapter; |
|---|
| 362 | 360 | |
|---|
| 361 | + if (zfcp_diag_adapter_setup(adapter)) |
|---|
| 362 | + goto failed; |
|---|
| 363 | + |
|---|
| 363 | 364 | if (zfcp_qdio_setup(adapter)) |
|---|
| 364 | 365 | goto failed; |
|---|
| 365 | 366 | |
|---|
| .. | .. |
|---|
| 406 | 407 | &zfcp_sysfs_adapter_attrs)) |
|---|
| 407 | 408 | goto failed; |
|---|
| 408 | 409 | |
|---|
| 410 | + if (zfcp_diag_sysfs_setup(adapter)) |
|---|
| 411 | + goto failed; |
|---|
| 412 | + |
|---|
| 409 | 413 | /* report size limit per scatter-gather segment */ |
|---|
| 410 | | - adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; |
|---|
| 411 | 414 | adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; |
|---|
| 412 | 415 | |
|---|
| 413 | 416 | adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM; |
|---|
| 414 | 417 | |
|---|
| 415 | | - if (!zfcp_scsi_adapter_register(adapter)) |
|---|
| 416 | | - return adapter; |
|---|
| 418 | + return adapter; |
|---|
| 417 | 419 | |
|---|
| 418 | 420 | failed: |
|---|
| 419 | 421 | zfcp_adapter_unregister(adapter); |
|---|
| .. | .. |
|---|
| 431 | 433 | |
|---|
| 432 | 434 | zfcp_fc_wka_ports_force_offline(adapter->gs); |
|---|
| 433 | 435 | zfcp_scsi_adapter_unregister(adapter); |
|---|
| 436 | + zfcp_diag_sysfs_destroy(adapter); |
|---|
| 434 | 437 | sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs); |
|---|
| 435 | 438 | |
|---|
| 436 | 439 | zfcp_erp_thread_kill(adapter); |
|---|
| .. | .. |
|---|
| 454 | 457 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); |
|---|
| 455 | 458 | zfcp_fc_gs_destroy(adapter); |
|---|
| 456 | 459 | zfcp_free_low_mem_buffers(adapter); |
|---|
| 460 | + zfcp_diag_adapter_free(adapter); |
|---|
| 457 | 461 | kfree(adapter->req_list); |
|---|
| 458 | 462 | kfree(adapter->fc_stats); |
|---|
| 459 | 463 | kfree(adapter->stats_reset_data); |
|---|
| .. | .. |
|---|
| 541 | 545 | err_out: |
|---|
| 542 | 546 | zfcp_ccw_adapter_put(adapter); |
|---|
| 543 | 547 | return ERR_PTR(retval); |
|---|
| 544 | | -} |
|---|
| 545 | | - |
|---|
| 546 | | -/** |
|---|
| 547 | | - * zfcp_sg_free_table - free memory used by scatterlists |
|---|
| 548 | | - * @sg: pointer to scatterlist |
|---|
| 549 | | - * @count: number of scatterlist which are to be free'ed |
|---|
| 550 | | - * the scatterlist are expected to reference pages always |
|---|
| 551 | | - */ |
|---|
| 552 | | -void zfcp_sg_free_table(struct scatterlist *sg, int count) |
|---|
| 553 | | -{ |
|---|
| 554 | | - int i; |
|---|
| 555 | | - |
|---|
| 556 | | - for (i = 0; i < count; i++, sg++) |
|---|
| 557 | | - if (sg) |
|---|
| 558 | | - free_page((unsigned long) sg_virt(sg)); |
|---|
| 559 | | - else |
|---|
| 560 | | - break; |
|---|
| 561 | | -} |
|---|
| 562 | | - |
|---|
| 563 | | -/** |
|---|
| 564 | | - * zfcp_sg_setup_table - init scatterlist and allocate, assign buffers |
|---|
| 565 | | - * @sg: pointer to struct scatterlist |
|---|
| 566 | | - * @count: number of scatterlists which should be assigned with buffers |
|---|
| 567 | | - * of size page |
|---|
| 568 | | - * |
|---|
| 569 | | - * Returns: 0 on success, -ENOMEM otherwise |
|---|
| 570 | | - */ |
|---|
| 571 | | -int zfcp_sg_setup_table(struct scatterlist *sg, int count) |
|---|
| 572 | | -{ |
|---|
| 573 | | - void *addr; |
|---|
| 574 | | - int i; |
|---|
| 575 | | - |
|---|
| 576 | | - sg_init_table(sg, count); |
|---|
| 577 | | - for (i = 0; i < count; i++, sg++) { |
|---|
| 578 | | - addr = (void *) get_zeroed_page(GFP_KERNEL); |
|---|
| 579 | | - if (!addr) { |
|---|
| 580 | | - zfcp_sg_free_table(sg, i); |
|---|
| 581 | | - return -ENOMEM; |
|---|
| 582 | | - } |
|---|
| 583 | | - sg_set_buf(sg, addr, PAGE_SIZE); |
|---|
| 584 | | - } |
|---|
| 585 | | - return 0; |
|---|
| 586 | 548 | } |
|---|