| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * QLogic Fibre Channel HBA Driver |
|---|
| 3 | 4 | * Copyright (c) 2003-2014 QLogic Corporation |
|---|
| 4 | | - * |
|---|
| 5 | | - * See LICENSE.qla2xxx for copyright and licensing details. |
|---|
| 6 | 5 | */ |
|---|
| 7 | 6 | #include "qla_def.h" |
|---|
| 8 | 7 | |
|---|
| .. | .. |
|---|
| 14 | 13 | #include <linux/kobject.h> |
|---|
| 15 | 14 | #include <linux/slab.h> |
|---|
| 16 | 15 | #include <linux/blk-mq-pci.h> |
|---|
| 16 | +#include <linux/refcount.h> |
|---|
| 17 | +#include <linux/crash_dump.h> |
|---|
| 18 | + |
|---|
| 17 | 19 | #include <scsi/scsi_tcq.h> |
|---|
| 18 | 20 | #include <scsi/scsicam.h> |
|---|
| 19 | 21 | #include <scsi/scsi_transport.h> |
|---|
| .. | .. |
|---|
| 33 | 35 | */ |
|---|
| 34 | 36 | struct kmem_cache *srb_cachep; |
|---|
| 35 | 37 | |
|---|
| 38 | +int ql2xfulldump_on_mpifail; |
|---|
| 39 | +module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR); |
|---|
| 40 | +MODULE_PARM_DESC(ql2xfulldump_on_mpifail, |
|---|
| 41 | + "Set this to take full dump on MPI hang."); |
|---|
| 42 | + |
|---|
| 43 | +int ql2xenforce_iocb_limit = 1; |
|---|
| 44 | +module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR); |
|---|
| 45 | +MODULE_PARM_DESC(ql2xenforce_iocb_limit, |
|---|
| 46 | + "Enforce IOCB throttling, to avoid FW congestion. (default: 1)"); |
|---|
| 47 | + |
|---|
| 36 | 48 | /* |
|---|
| 37 | 49 | * CT6 CTX allocation cache |
|---|
| 38 | 50 | */ |
|---|
| .. | .. |
|---|
| 40 | 52 | /* |
|---|
| 41 | 53 | * error level for logging |
|---|
| 42 | 54 | */ |
|---|
| 43 | | -int ql_errlev = ql_log_all; |
|---|
| 55 | +uint ql_errlev = 0x8001; |
|---|
| 44 | 56 | |
|---|
| 45 | 57 | static int ql2xenableclass2; |
|---|
| 46 | 58 | module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR); |
|---|
| .. | .. |
|---|
| 65 | 77 | MODULE_PARM_DESC(ql2xplogiabsentdevice, |
|---|
| 66 | 78 | "Option to enable PLOGI to devices that are not present after " |
|---|
| 67 | 79 | "a Fabric scan. This is needed for several broken switches. " |
|---|
| 68 | | - "Default is 0 - no PLOGI. 1 - perfom PLOGI."); |
|---|
| 80 | + "Default is 0 - no PLOGI. 1 - perform PLOGI."); |
|---|
| 69 | 81 | |
|---|
| 70 | | -int ql2xloginretrycount = 0; |
|---|
| 82 | +int ql2xloginretrycount; |
|---|
| 71 | 83 | module_param(ql2xloginretrycount, int, S_IRUGO); |
|---|
| 72 | 84 | MODULE_PARM_DESC(ql2xloginretrycount, |
|---|
| 73 | 85 | "Specify an alternate value for the NVRAM login retry count."); |
|---|
| .. | .. |
|---|
| 106 | 118 | "Set to control shifting of command type processing " |
|---|
| 107 | 119 | "based on total number of SG elements."); |
|---|
| 108 | 120 | |
|---|
| 109 | | -int ql2xfdmienable=1; |
|---|
| 121 | +int ql2xfdmienable = 1; |
|---|
| 110 | 122 | module_param(ql2xfdmienable, int, S_IRUGO|S_IWUSR); |
|---|
| 111 | 123 | module_param_named(fdmi, ql2xfdmienable, int, S_IRUGO|S_IWUSR); |
|---|
| 112 | 124 | MODULE_PARM_DESC(ql2xfdmienable, |
|---|
| 113 | 125 | "Enables FDMI registrations. " |
|---|
| 114 | | - "0 - no FDMI. Default is 1 - perform FDMI."); |
|---|
| 126 | + "0 - no FDMI registrations. " |
|---|
| 127 | + "1 - provide FDMI registrations (default)."); |
|---|
| 115 | 128 | |
|---|
| 116 | 129 | #define MAX_Q_DEPTH 64 |
|---|
| 117 | 130 | static int ql2xmaxqdepth = MAX_Q_DEPTH; |
|---|
| .. | .. |
|---|
| 120 | 133 | "Maximum queue depth to set for each LUN. " |
|---|
| 121 | 134 | "Default is 64."); |
|---|
| 122 | 135 | |
|---|
| 123 | | -#if (IS_ENABLED(CONFIG_NVME_FC)) |
|---|
| 124 | | -int ql2xenabledif; |
|---|
| 125 | | -#else |
|---|
| 126 | 136 | int ql2xenabledif = 2; |
|---|
| 127 | | -#endif |
|---|
| 128 | 137 | module_param(ql2xenabledif, int, S_IRUGO); |
|---|
| 129 | 138 | MODULE_PARM_DESC(ql2xenabledif, |
|---|
| 130 | 139 | " Enable T10-CRC-DIF:\n" |
|---|
| .. | .. |
|---|
| 152 | 161 | " 1 -- Error isolation enabled only for DIX Type 0\n" |
|---|
| 153 | 162 | " 2 -- Error isolation enabled for all Types\n"); |
|---|
| 154 | 163 | |
|---|
| 155 | | -int ql2xiidmaenable=1; |
|---|
| 164 | +int ql2xiidmaenable = 1; |
|---|
| 156 | 165 | module_param(ql2xiidmaenable, int, S_IRUGO); |
|---|
| 157 | 166 | MODULE_PARM_DESC(ql2xiidmaenable, |
|---|
| 158 | 167 | "Enables iIDMA settings " |
|---|
| .. | .. |
|---|
| 198 | 207 | module_param(ql2xasynctmfenable, int, S_IRUGO); |
|---|
| 199 | 208 | MODULE_PARM_DESC(ql2xasynctmfenable, |
|---|
| 200 | 209 | "Enables issue of TM IOCBs asynchronously via IOCB mechanism" |
|---|
| 201 | | - "Default is 0 - Issue TM IOCBs via mailbox mechanism."); |
|---|
| 210 | + "Default is 1 - Issue TM IOCBs via mailbox mechanism."); |
|---|
| 202 | 211 | |
|---|
| 203 | 212 | int ql2xdontresethba; |
|---|
| 204 | 213 | module_param(ql2xdontresethba, int, S_IRUGO|S_IWUSR); |
|---|
| .. | .. |
|---|
| 226 | 235 | "0 - MiniDump disabled. " |
|---|
| 227 | 236 | "1 (Default) - MiniDump enabled."); |
|---|
| 228 | 237 | |
|---|
| 229 | | -int ql2xexlogins = 0; |
|---|
| 238 | +int ql2xexlogins; |
|---|
| 230 | 239 | module_param(ql2xexlogins, uint, S_IRUGO|S_IWUSR); |
|---|
| 231 | 240 | MODULE_PARM_DESC(ql2xexlogins, |
|---|
| 232 | 241 | "Number of extended Logins. " |
|---|
| .. | .. |
|---|
| 242 | 251 | MODULE_PARM_DESC(ql2xiniexchg, |
|---|
| 243 | 252 | "Number of initiator exchanges."); |
|---|
| 244 | 253 | |
|---|
| 245 | | -int ql2xfwholdabts = 0; |
|---|
| 254 | +int ql2xfwholdabts; |
|---|
| 246 | 255 | module_param(ql2xfwholdabts, int, S_IRUGO); |
|---|
| 247 | 256 | MODULE_PARM_DESC(ql2xfwholdabts, |
|---|
| 248 | 257 | "Allow FW to hold status IOCB until ABTS rsp received. " |
|---|
| .. | .. |
|---|
| 277 | 286 | "Reserve 1/2 of emergency exchanges for ELS.\n" |
|---|
| 278 | 287 | " 0 (default): disabled"); |
|---|
| 279 | 288 | |
|---|
| 280 | | -/* |
|---|
| 281 | | - * SCSI host template entry points |
|---|
| 282 | | - */ |
|---|
| 283 | | -static int qla2xxx_slave_configure(struct scsi_device * device); |
|---|
| 284 | | -static int qla2xxx_slave_alloc(struct scsi_device *); |
|---|
| 285 | | -static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time); |
|---|
| 286 | | -static void qla2xxx_scan_start(struct Scsi_Host *); |
|---|
| 287 | | -static void qla2xxx_slave_destroy(struct scsi_device *); |
|---|
| 288 | | -static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd); |
|---|
| 289 | | -static int qla2xxx_eh_abort(struct scsi_cmnd *); |
|---|
| 290 | | -static int qla2xxx_eh_device_reset(struct scsi_cmnd *); |
|---|
| 291 | | -static int qla2xxx_eh_target_reset(struct scsi_cmnd *); |
|---|
| 292 | | -static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); |
|---|
| 293 | | -static int qla2xxx_eh_host_reset(struct scsi_cmnd *); |
|---|
| 289 | +static int ql2xprotmask; |
|---|
| 290 | +module_param(ql2xprotmask, int, 0644); |
|---|
| 291 | +MODULE_PARM_DESC(ql2xprotmask, |
|---|
| 292 | + "Override DIF/DIX protection capabilities mask\n" |
|---|
| 293 | + "Default is 0 which sets protection mask based on " |
|---|
| 294 | + "capabilities reported by HBA firmware.\n"); |
|---|
| 295 | + |
|---|
| 296 | +static int ql2xprotguard; |
|---|
| 297 | +module_param(ql2xprotguard, int, 0644); |
|---|
| 298 | +MODULE_PARM_DESC(ql2xprotguard, "Override choice of DIX checksum\n" |
|---|
| 299 | + " 0 -- Let HBA firmware decide\n" |
|---|
| 300 | + " 1 -- Force T10 CRC\n" |
|---|
| 301 | + " 2 -- Force IP checksum\n"); |
|---|
| 302 | + |
|---|
| 303 | +int ql2xdifbundlinginternalbuffers; |
|---|
| 304 | +module_param(ql2xdifbundlinginternalbuffers, int, 0644); |
|---|
| 305 | +MODULE_PARM_DESC(ql2xdifbundlinginternalbuffers, |
|---|
| 306 | + "Force using internal buffers for DIF information\n" |
|---|
| 307 | + "0 (Default). Based on check.\n" |
|---|
| 308 | + "1 Force using internal buffers\n"); |
|---|
| 309 | + |
|---|
| 310 | +int ql2xsmartsan; |
|---|
| 311 | +module_param(ql2xsmartsan, int, 0444); |
|---|
| 312 | +module_param_named(smartsan, ql2xsmartsan, int, 0444); |
|---|
| 313 | +MODULE_PARM_DESC(ql2xsmartsan, |
|---|
| 314 | + "Send SmartSAN Management Attributes for FDMI Registration." |
|---|
| 315 | + " Default is 0 - No SmartSAN registration," |
|---|
| 316 | + " 1 - Register SmartSAN Management Attributes."); |
|---|
| 317 | + |
|---|
| 318 | +int ql2xrdpenable; |
|---|
| 319 | +module_param(ql2xrdpenable, int, 0444); |
|---|
| 320 | +module_param_named(rdpenable, ql2xrdpenable, int, 0444); |
|---|
| 321 | +MODULE_PARM_DESC(ql2xrdpenable, |
|---|
| 322 | + "Enables RDP responses. " |
|---|
| 323 | + "0 - no RDP responses (default). " |
|---|
| 324 | + "1 - provide RDP responses."); |
|---|
| 294 | 325 | |
|---|
| 295 | 326 | static void qla2x00_clear_drv_active(struct qla_hw_data *); |
|---|
| 296 | 327 | static void qla2x00_free_device(scsi_qla_host_t *); |
|---|
| 297 | 328 | static int qla2xxx_map_queues(struct Scsi_Host *shost); |
|---|
| 298 | 329 | static void qla2x00_destroy_deferred_work(struct qla_hw_data *); |
|---|
| 299 | 330 | |
|---|
| 300 | | - |
|---|
| 301 | | -struct scsi_host_template qla2xxx_driver_template = { |
|---|
| 302 | | - .module = THIS_MODULE, |
|---|
| 303 | | - .name = QLA2XXX_DRIVER_NAME, |
|---|
| 304 | | - .queuecommand = qla2xxx_queuecommand, |
|---|
| 305 | | - |
|---|
| 306 | | - .eh_timed_out = fc_eh_timed_out, |
|---|
| 307 | | - .eh_abort_handler = qla2xxx_eh_abort, |
|---|
| 308 | | - .eh_device_reset_handler = qla2xxx_eh_device_reset, |
|---|
| 309 | | - .eh_target_reset_handler = qla2xxx_eh_target_reset, |
|---|
| 310 | | - .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
|---|
| 311 | | - .eh_host_reset_handler = qla2xxx_eh_host_reset, |
|---|
| 312 | | - |
|---|
| 313 | | - .slave_configure = qla2xxx_slave_configure, |
|---|
| 314 | | - |
|---|
| 315 | | - .slave_alloc = qla2xxx_slave_alloc, |
|---|
| 316 | | - .slave_destroy = qla2xxx_slave_destroy, |
|---|
| 317 | | - .scan_finished = qla2xxx_scan_finished, |
|---|
| 318 | | - .scan_start = qla2xxx_scan_start, |
|---|
| 319 | | - .change_queue_depth = scsi_change_queue_depth, |
|---|
| 320 | | - .map_queues = qla2xxx_map_queues, |
|---|
| 321 | | - .this_id = -1, |
|---|
| 322 | | - .cmd_per_lun = 3, |
|---|
| 323 | | - .use_clustering = ENABLE_CLUSTERING, |
|---|
| 324 | | - .sg_tablesize = SG_ALL, |
|---|
| 325 | | - |
|---|
| 326 | | - .max_sectors = 0xFFFF, |
|---|
| 327 | | - .shost_attrs = qla2x00_host_attrs, |
|---|
| 328 | | - |
|---|
| 329 | | - .supported_mode = MODE_INITIATOR, |
|---|
| 330 | | - .track_queue_depth = 1, |
|---|
| 331 | | -}; |
|---|
| 332 | 331 | |
|---|
| 333 | 332 | static struct scsi_transport_template *qla2xxx_transport_template = NULL; |
|---|
| 334 | 333 | struct scsi_transport_template *qla2xxx_transport_vport_template = NULL; |
|---|
| .. | .. |
|---|
| 383 | 382 | struct rsp_que *rsp) |
|---|
| 384 | 383 | { |
|---|
| 385 | 384 | struct qla_hw_data *ha = vha->hw; |
|---|
| 385 | + |
|---|
| 386 | 386 | rsp->qpair = ha->base_qpair; |
|---|
| 387 | 387 | rsp->req = req; |
|---|
| 388 | + ha->base_qpair->hw = ha; |
|---|
| 388 | 389 | ha->base_qpair->req = req; |
|---|
| 389 | 390 | ha->base_qpair->rsp = rsp; |
|---|
| 390 | 391 | ha->base_qpair->vha = vha; |
|---|
| 391 | 392 | ha->base_qpair->qp_lock_ptr = &ha->hardware_lock; |
|---|
| 392 | 393 | ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0; |
|---|
| 393 | 394 | ha->base_qpair->msix = &ha->msix_entries[QLA_MSIX_RSP_Q]; |
|---|
| 395 | + ha->base_qpair->srb_mempool = ha->srb_mempool; |
|---|
| 394 | 396 | INIT_LIST_HEAD(&ha->base_qpair->hints_list); |
|---|
| 395 | 397 | ha->base_qpair->enable_class_2 = ql2xenableclass2; |
|---|
| 396 | 398 | /* init qpair to this cpu. Will adjust at run time. */ |
|---|
| 397 | 399 | qla_cpu_update(rsp->qpair, raw_smp_processor_id()); |
|---|
| 398 | 400 | ha->base_qpair->pdev = ha->pdev; |
|---|
| 399 | 401 | |
|---|
| 400 | | - if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) |
|---|
| 402 | + if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) |
|---|
| 401 | 403 | ha->base_qpair->reqq_start_iocbs = qla_83xx_start_iocbs; |
|---|
| 402 | 404 | } |
|---|
| 403 | 405 | |
|---|
| .. | .. |
|---|
| 405 | 407 | struct rsp_que *rsp) |
|---|
| 406 | 408 | { |
|---|
| 407 | 409 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
|---|
| 410 | + |
|---|
| 408 | 411 | ha->req_q_map = kcalloc(ha->max_req_queues, sizeof(struct req_que *), |
|---|
| 409 | 412 | GFP_KERNEL); |
|---|
| 410 | 413 | if (!ha->req_q_map) { |
|---|
| .. | .. |
|---|
| 550 | 553 | } |
|---|
| 551 | 554 | |
|---|
| 552 | 555 | static char * |
|---|
| 553 | | -qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str) |
|---|
| 556 | +qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len) |
|---|
| 554 | 557 | { |
|---|
| 555 | 558 | struct qla_hw_data *ha = vha->hw; |
|---|
| 556 | | - static char *pci_bus_modes[] = { |
|---|
| 559 | + static const char *const pci_bus_modes[] = { |
|---|
| 557 | 560 | "33", "66", "100", "133", |
|---|
| 558 | 561 | }; |
|---|
| 559 | 562 | uint16_t pci_bus; |
|---|
| 560 | 563 | |
|---|
| 561 | | - strcpy(str, "PCI"); |
|---|
| 562 | 564 | pci_bus = (ha->pci_attr & (BIT_9 | BIT_10)) >> 9; |
|---|
| 563 | 565 | if (pci_bus) { |
|---|
| 564 | | - strcat(str, "-X ("); |
|---|
| 565 | | - strcat(str, pci_bus_modes[pci_bus]); |
|---|
| 566 | + snprintf(str, str_len, "PCI-X (%s MHz)", |
|---|
| 567 | + pci_bus_modes[pci_bus]); |
|---|
| 566 | 568 | } else { |
|---|
| 567 | 569 | pci_bus = (ha->pci_attr & BIT_8) >> 8; |
|---|
| 568 | | - strcat(str, " ("); |
|---|
| 569 | | - strcat(str, pci_bus_modes[pci_bus]); |
|---|
| 570 | + snprintf(str, str_len, "PCI (%s MHz)", pci_bus_modes[pci_bus]); |
|---|
| 570 | 571 | } |
|---|
| 571 | | - strcat(str, " MHz)"); |
|---|
| 572 | 572 | |
|---|
| 573 | | - return (str); |
|---|
| 573 | + return str; |
|---|
| 574 | 574 | } |
|---|
| 575 | 575 | |
|---|
| 576 | 576 | static char * |
|---|
| 577 | | -qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str) |
|---|
| 577 | +qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len) |
|---|
| 578 | 578 | { |
|---|
| 579 | | - static char *pci_bus_modes[] = { "33", "66", "100", "133", }; |
|---|
| 579 | + static const char *const pci_bus_modes[] = { |
|---|
| 580 | + "33", "66", "100", "133", |
|---|
| 581 | + }; |
|---|
| 580 | 582 | struct qla_hw_data *ha = vha->hw; |
|---|
| 581 | 583 | uint32_t pci_bus; |
|---|
| 582 | 584 | |
|---|
| 583 | 585 | if (pci_is_pcie(ha->pdev)) { |
|---|
| 584 | | - char lwstr[6]; |
|---|
| 585 | 586 | uint32_t lstat, lspeed, lwidth; |
|---|
| 587 | + const char *speed_str; |
|---|
| 586 | 588 | |
|---|
| 587 | 589 | pcie_capability_read_dword(ha->pdev, PCI_EXP_LNKCAP, &lstat); |
|---|
| 588 | 590 | lspeed = lstat & PCI_EXP_LNKCAP_SLS; |
|---|
| 589 | 591 | lwidth = (lstat & PCI_EXP_LNKCAP_MLW) >> 4; |
|---|
| 590 | 592 | |
|---|
| 591 | | - strcpy(str, "PCIe ("); |
|---|
| 592 | 593 | switch (lspeed) { |
|---|
| 593 | 594 | case 1: |
|---|
| 594 | | - strcat(str, "2.5GT/s "); |
|---|
| 595 | + speed_str = "2.5GT/s"; |
|---|
| 595 | 596 | break; |
|---|
| 596 | 597 | case 2: |
|---|
| 597 | | - strcat(str, "5.0GT/s "); |
|---|
| 598 | + speed_str = "5.0GT/s"; |
|---|
| 598 | 599 | break; |
|---|
| 599 | 600 | case 3: |
|---|
| 600 | | - strcat(str, "8.0GT/s "); |
|---|
| 601 | + speed_str = "8.0GT/s"; |
|---|
| 602 | + break; |
|---|
| 603 | + case 4: |
|---|
| 604 | + speed_str = "16.0GT/s"; |
|---|
| 601 | 605 | break; |
|---|
| 602 | 606 | default: |
|---|
| 603 | | - strcat(str, "<unknown> "); |
|---|
| 607 | + speed_str = "<unknown>"; |
|---|
| 604 | 608 | break; |
|---|
| 605 | 609 | } |
|---|
| 606 | | - snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); |
|---|
| 607 | | - strcat(str, lwstr); |
|---|
| 610 | + snprintf(str, str_len, "PCIe (%s x%d)", speed_str, lwidth); |
|---|
| 608 | 611 | |
|---|
| 609 | 612 | return str; |
|---|
| 610 | 613 | } |
|---|
| 611 | 614 | |
|---|
| 612 | | - strcpy(str, "PCI"); |
|---|
| 613 | 615 | pci_bus = (ha->pci_attr & CSRX_PCIX_BUS_MODE_MASK) >> 8; |
|---|
| 614 | | - if (pci_bus == 0 || pci_bus == 8) { |
|---|
| 615 | | - strcat(str, " ("); |
|---|
| 616 | | - strcat(str, pci_bus_modes[pci_bus >> 3]); |
|---|
| 617 | | - } else { |
|---|
| 618 | | - strcat(str, "-X "); |
|---|
| 619 | | - if (pci_bus & BIT_2) |
|---|
| 620 | | - strcat(str, "Mode 2"); |
|---|
| 621 | | - else |
|---|
| 622 | | - strcat(str, "Mode 1"); |
|---|
| 623 | | - strcat(str, " ("); |
|---|
| 624 | | - strcat(str, pci_bus_modes[pci_bus & ~BIT_2]); |
|---|
| 625 | | - } |
|---|
| 626 | | - strcat(str, " MHz)"); |
|---|
| 616 | + if (pci_bus == 0 || pci_bus == 8) |
|---|
| 617 | + snprintf(str, str_len, "PCI (%s MHz)", |
|---|
| 618 | + pci_bus_modes[pci_bus >> 3]); |
|---|
| 619 | + else |
|---|
| 620 | + snprintf(str, str_len, "PCI-X Mode %d (%s MHz)", |
|---|
| 621 | + pci_bus & 4 ? 2 : 1, |
|---|
| 622 | + pci_bus_modes[pci_bus & 3]); |
|---|
| 627 | 623 | |
|---|
| 628 | 624 | return str; |
|---|
| 629 | 625 | } |
|---|
| .. | .. |
|---|
| 676 | 672 | return str; |
|---|
| 677 | 673 | } |
|---|
| 678 | 674 | |
|---|
| 679 | | -void |
|---|
| 680 | | -qla2x00_sp_free_dma(void *ptr) |
|---|
| 675 | +void qla2x00_sp_free_dma(srb_t *sp) |
|---|
| 681 | 676 | { |
|---|
| 682 | | - srb_t *sp = ptr; |
|---|
| 683 | 677 | struct qla_hw_data *ha = sp->vha->hw; |
|---|
| 684 | 678 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
|---|
| 685 | | - void *ctx = GET_CMD_CTX_SP(sp); |
|---|
| 686 | 679 | |
|---|
| 687 | 680 | if (sp->flags & SRB_DMA_VALID) { |
|---|
| 688 | 681 | scsi_dma_unmap(cmd); |
|---|
| .. | .. |
|---|
| 695 | 688 | sp->flags &= ~SRB_CRC_PROT_DMA_VALID; |
|---|
| 696 | 689 | } |
|---|
| 697 | 690 | |
|---|
| 698 | | - if (!ctx) |
|---|
| 699 | | - goto end; |
|---|
| 700 | | - |
|---|
| 701 | 691 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { |
|---|
| 702 | 692 | /* List assured to be having elements */ |
|---|
| 703 | | - qla2x00_clean_dsd_pool(ha, ctx); |
|---|
| 693 | + qla2x00_clean_dsd_pool(ha, sp->u.scmd.crc_ctx); |
|---|
| 704 | 694 | sp->flags &= ~SRB_CRC_CTX_DSD_VALID; |
|---|
| 705 | 695 | } |
|---|
| 706 | 696 | |
|---|
| 707 | 697 | if (sp->flags & SRB_CRC_CTX_DMA_VALID) { |
|---|
| 708 | | - struct crc_context *ctx0 = ctx; |
|---|
| 698 | + struct crc_context *ctx0 = sp->u.scmd.crc_ctx; |
|---|
| 709 | 699 | |
|---|
| 710 | 700 | dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma); |
|---|
| 711 | 701 | sp->flags &= ~SRB_CRC_CTX_DMA_VALID; |
|---|
| 712 | 702 | } |
|---|
| 713 | 703 | |
|---|
| 714 | 704 | if (sp->flags & SRB_FCP_CMND_DMA_VALID) { |
|---|
| 715 | | - struct ct6_dsd *ctx1 = ctx; |
|---|
| 705 | + struct ct6_dsd *ctx1 = sp->u.scmd.ct6_ctx; |
|---|
| 716 | 706 | |
|---|
| 717 | 707 | dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd, |
|---|
| 718 | 708 | ctx1->fcp_cmnd_dma); |
|---|
| .. | .. |
|---|
| 721 | 711 | ha->gbl_dsd_avail += ctx1->dsd_use_cnt; |
|---|
| 722 | 712 | mempool_free(ctx1, ha->ctx_mempool); |
|---|
| 723 | 713 | } |
|---|
| 724 | | - |
|---|
| 725 | | -end: |
|---|
| 726 | | - if (sp->type != SRB_NVME_CMD && sp->type != SRB_NVME_LS) { |
|---|
| 727 | | - CMD_SP(cmd) = NULL; |
|---|
| 728 | | - qla2x00_rel_sp(sp); |
|---|
| 729 | | - } |
|---|
| 730 | 714 | } |
|---|
| 731 | 715 | |
|---|
| 732 | | -void |
|---|
| 733 | | -qla2x00_sp_compl(void *ptr, int res) |
|---|
| 716 | +void qla2x00_sp_compl(srb_t *sp, int res) |
|---|
| 734 | 717 | { |
|---|
| 735 | | - srb_t *sp = ptr; |
|---|
| 736 | 718 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
|---|
| 737 | | - |
|---|
| 738 | | - cmd->result = res; |
|---|
| 739 | | - |
|---|
| 740 | | - if (atomic_read(&sp->ref_count) == 0) { |
|---|
| 741 | | - ql_dbg(ql_dbg_io, sp->vha, 0x3015, |
|---|
| 742 | | - "SP reference-count to ZERO -- sp=%p cmd=%p.\n", |
|---|
| 743 | | - sp, GET_CMD_SP(sp)); |
|---|
| 744 | | - if (ql2xextended_error_logging & ql_dbg_io) |
|---|
| 745 | | - WARN_ON(atomic_read(&sp->ref_count) == 0); |
|---|
| 746 | | - return; |
|---|
| 747 | | - } |
|---|
| 748 | | - if (!atomic_dec_and_test(&sp->ref_count)) |
|---|
| 749 | | - return; |
|---|
| 719 | + struct completion *comp = sp->comp; |
|---|
| 750 | 720 | |
|---|
| 751 | 721 | sp->free(sp); |
|---|
| 722 | + cmd->result = res; |
|---|
| 723 | + CMD_SP(cmd) = NULL; |
|---|
| 752 | 724 | cmd->scsi_done(cmd); |
|---|
| 725 | + if (comp) |
|---|
| 726 | + complete(comp); |
|---|
| 753 | 727 | } |
|---|
| 754 | 728 | |
|---|
| 755 | | -void |
|---|
| 756 | | -qla2xxx_qpair_sp_free_dma(void *ptr) |
|---|
| 729 | +void qla2xxx_qpair_sp_free_dma(srb_t *sp) |
|---|
| 757 | 730 | { |
|---|
| 758 | | - srb_t *sp = (srb_t *)ptr; |
|---|
| 759 | 731 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
|---|
| 760 | 732 | struct qla_hw_data *ha = sp->fcport->vha->hw; |
|---|
| 761 | | - void *ctx = GET_CMD_CTX_SP(sp); |
|---|
| 762 | 733 | |
|---|
| 763 | 734 | if (sp->flags & SRB_DMA_VALID) { |
|---|
| 764 | 735 | scsi_dma_unmap(cmd); |
|---|
| .. | .. |
|---|
| 771 | 742 | sp->flags &= ~SRB_CRC_PROT_DMA_VALID; |
|---|
| 772 | 743 | } |
|---|
| 773 | 744 | |
|---|
| 774 | | - if (!ctx) |
|---|
| 775 | | - goto end; |
|---|
| 776 | | - |
|---|
| 777 | 745 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { |
|---|
| 778 | 746 | /* List assured to be having elements */ |
|---|
| 779 | | - qla2x00_clean_dsd_pool(ha, ctx); |
|---|
| 747 | + qla2x00_clean_dsd_pool(ha, sp->u.scmd.crc_ctx); |
|---|
| 780 | 748 | sp->flags &= ~SRB_CRC_CTX_DSD_VALID; |
|---|
| 781 | 749 | } |
|---|
| 782 | 750 | |
|---|
| 783 | | - if (sp->flags & SRB_CRC_CTX_DMA_VALID) { |
|---|
| 784 | | - struct crc_context *ctx0 = ctx; |
|---|
| 751 | + if (sp->flags & SRB_DIF_BUNDL_DMA_VALID) { |
|---|
| 752 | + struct crc_context *difctx = sp->u.scmd.crc_ctx; |
|---|
| 753 | + struct dsd_dma *dif_dsd, *nxt_dsd; |
|---|
| 785 | 754 | |
|---|
| 786 | | - dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma); |
|---|
| 787 | | - sp->flags &= ~SRB_CRC_CTX_DMA_VALID; |
|---|
| 755 | + list_for_each_entry_safe(dif_dsd, nxt_dsd, |
|---|
| 756 | + &difctx->ldif_dma_hndl_list, list) { |
|---|
| 757 | + list_del(&dif_dsd->list); |
|---|
| 758 | + dma_pool_free(ha->dif_bundl_pool, dif_dsd->dsd_addr, |
|---|
| 759 | + dif_dsd->dsd_list_dma); |
|---|
| 760 | + kfree(dif_dsd); |
|---|
| 761 | + difctx->no_dif_bundl--; |
|---|
| 762 | + } |
|---|
| 763 | + |
|---|
| 764 | + list_for_each_entry_safe(dif_dsd, nxt_dsd, |
|---|
| 765 | + &difctx->ldif_dsd_list, list) { |
|---|
| 766 | + list_del(&dif_dsd->list); |
|---|
| 767 | + dma_pool_free(ha->dl_dma_pool, dif_dsd->dsd_addr, |
|---|
| 768 | + dif_dsd->dsd_list_dma); |
|---|
| 769 | + kfree(dif_dsd); |
|---|
| 770 | + difctx->no_ldif_dsd--; |
|---|
| 771 | + } |
|---|
| 772 | + |
|---|
| 773 | + if (difctx->no_ldif_dsd) { |
|---|
| 774 | + ql_dbg(ql_dbg_tgt+ql_dbg_verbose, sp->vha, 0xe022, |
|---|
| 775 | + "%s: difctx->no_ldif_dsd=%x\n", |
|---|
| 776 | + __func__, difctx->no_ldif_dsd); |
|---|
| 777 | + } |
|---|
| 778 | + |
|---|
| 779 | + if (difctx->no_dif_bundl) { |
|---|
| 780 | + ql_dbg(ql_dbg_tgt+ql_dbg_verbose, sp->vha, 0xe022, |
|---|
| 781 | + "%s: difctx->no_dif_bundl=%x\n", |
|---|
| 782 | + __func__, difctx->no_dif_bundl); |
|---|
| 783 | + } |
|---|
| 784 | + sp->flags &= ~SRB_DIF_BUNDL_DMA_VALID; |
|---|
| 788 | 785 | } |
|---|
| 789 | 786 | |
|---|
| 790 | 787 | if (sp->flags & SRB_FCP_CMND_DMA_VALID) { |
|---|
| 791 | | - struct ct6_dsd *ctx1 = ctx; |
|---|
| 788 | + struct ct6_dsd *ctx1 = sp->u.scmd.ct6_ctx; |
|---|
| 789 | + |
|---|
| 792 | 790 | dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd, |
|---|
| 793 | 791 | ctx1->fcp_cmnd_dma); |
|---|
| 794 | 792 | list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list); |
|---|
| 795 | 793 | ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt; |
|---|
| 796 | 794 | ha->gbl_dsd_avail += ctx1->dsd_use_cnt; |
|---|
| 797 | 795 | mempool_free(ctx1, ha->ctx_mempool); |
|---|
| 796 | + sp->flags &= ~SRB_FCP_CMND_DMA_VALID; |
|---|
| 798 | 797 | } |
|---|
| 799 | | -end: |
|---|
| 800 | | - CMD_SP(cmd) = NULL; |
|---|
| 801 | | - qla2xxx_rel_qpair_sp(sp->qpair, sp); |
|---|
| 798 | + |
|---|
| 799 | + if (sp->flags & SRB_CRC_CTX_DMA_VALID) { |
|---|
| 800 | + struct crc_context *ctx0 = sp->u.scmd.crc_ctx; |
|---|
| 801 | + |
|---|
| 802 | + dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma); |
|---|
| 803 | + sp->flags &= ~SRB_CRC_CTX_DMA_VALID; |
|---|
| 804 | + } |
|---|
| 802 | 805 | } |
|---|
| 803 | 806 | |
|---|
| 804 | | -void |
|---|
| 805 | | -qla2xxx_qpair_sp_compl(void *ptr, int res) |
|---|
| 807 | +void qla2xxx_qpair_sp_compl(srb_t *sp, int res) |
|---|
| 806 | 808 | { |
|---|
| 807 | | - srb_t *sp = ptr; |
|---|
| 808 | 809 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
|---|
| 809 | | - |
|---|
| 810 | | - cmd->result = res; |
|---|
| 811 | | - |
|---|
| 812 | | - if (atomic_read(&sp->ref_count) == 0) { |
|---|
| 813 | | - ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3079, |
|---|
| 814 | | - "SP reference-count to ZERO -- sp=%p cmd=%p.\n", |
|---|
| 815 | | - sp, GET_CMD_SP(sp)); |
|---|
| 816 | | - if (ql2xextended_error_logging & ql_dbg_io) |
|---|
| 817 | | - WARN_ON(atomic_read(&sp->ref_count) == 0); |
|---|
| 818 | | - return; |
|---|
| 819 | | - } |
|---|
| 820 | | - if (!atomic_dec_and_test(&sp->ref_count)) |
|---|
| 821 | | - return; |
|---|
| 810 | + struct completion *comp = sp->comp; |
|---|
| 822 | 811 | |
|---|
| 823 | 812 | sp->free(sp); |
|---|
| 813 | + cmd->result = res; |
|---|
| 814 | + CMD_SP(cmd) = NULL; |
|---|
| 824 | 815 | cmd->scsi_done(cmd); |
|---|
| 816 | + if (comp) |
|---|
| 817 | + complete(comp); |
|---|
| 825 | 818 | } |
|---|
| 826 | 819 | |
|---|
| 827 | | -/* If we are SP1 here, we need to still take and release the host_lock as SP1 |
|---|
| 828 | | - * does not have the changes necessary to avoid taking host->host_lock. |
|---|
| 829 | | - */ |
|---|
| 830 | 820 | static int |
|---|
| 831 | 821 | qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
|---|
| 832 | 822 | { |
|---|
| .. | .. |
|---|
| 837 | 827 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
|---|
| 838 | 828 | srb_t *sp; |
|---|
| 839 | 829 | int rval; |
|---|
| 840 | | - struct qla_qpair *qpair = NULL; |
|---|
| 841 | | - uint32_t tag; |
|---|
| 842 | | - uint16_t hwq; |
|---|
| 843 | 830 | |
|---|
| 844 | | - if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags))) { |
|---|
| 831 | + if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags)) || |
|---|
| 832 | + WARN_ON_ONCE(!rport)) { |
|---|
| 845 | 833 | cmd->result = DID_NO_CONNECT << 16; |
|---|
| 846 | 834 | goto qc24_fail_command; |
|---|
| 847 | 835 | } |
|---|
| 848 | 836 | |
|---|
| 849 | 837 | if (ha->mqenable) { |
|---|
| 850 | | - if (shost_use_blk_mq(vha->host)) { |
|---|
| 851 | | - tag = blk_mq_unique_tag(cmd->request); |
|---|
| 852 | | - hwq = blk_mq_unique_tag_to_hwq(tag); |
|---|
| 853 | | - qpair = ha->queue_pair_map[hwq]; |
|---|
| 854 | | - } else if (vha->vp_idx && vha->qpair) { |
|---|
| 855 | | - qpair = vha->qpair; |
|---|
| 856 | | - } |
|---|
| 838 | + uint32_t tag; |
|---|
| 839 | + uint16_t hwq; |
|---|
| 840 | + struct qla_qpair *qpair = NULL; |
|---|
| 841 | + |
|---|
| 842 | + tag = blk_mq_unique_tag(cmd->request); |
|---|
| 843 | + hwq = blk_mq_unique_tag_to_hwq(tag); |
|---|
| 844 | + qpair = ha->queue_pair_map[hwq]; |
|---|
| 857 | 845 | |
|---|
| 858 | 846 | if (qpair) |
|---|
| 859 | 847 | return qla2xxx_mqueuecommand(host, cmd, qpair); |
|---|
| .. | .. |
|---|
| 896 | 884 | goto qc24_fail_command; |
|---|
| 897 | 885 | } |
|---|
| 898 | 886 | |
|---|
| 899 | | - if (atomic_read(&fcport->state) != FCS_ONLINE) { |
|---|
| 887 | + if (atomic_read(&fcport->state) != FCS_ONLINE || fcport->deleted) { |
|---|
| 900 | 888 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
|---|
| 901 | 889 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
|---|
| 902 | 890 | ql_dbg(ql_dbg_io, vha, 0x3005, |
|---|
| .. | .. |
|---|
| 920 | 908 | else |
|---|
| 921 | 909 | goto qc24_target_busy; |
|---|
| 922 | 910 | |
|---|
| 923 | | - sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); |
|---|
| 924 | | - if (!sp) |
|---|
| 925 | | - goto qc24_host_busy; |
|---|
| 911 | + sp = scsi_cmd_priv(cmd); |
|---|
| 912 | + qla2xxx_init_sp(sp, vha, vha->hw->base_qpair, fcport); |
|---|
| 926 | 913 | |
|---|
| 927 | 914 | sp->u.scmd.cmd = cmd; |
|---|
| 928 | 915 | sp->type = SRB_SCSI_CMD; |
|---|
| 929 | | - atomic_set(&sp->ref_count, 1); |
|---|
| 916 | + |
|---|
| 930 | 917 | CMD_SP(cmd) = (void *)sp; |
|---|
| 931 | 918 | sp->free = qla2x00_sp_free_dma; |
|---|
| 932 | 919 | sp->done = qla2x00_sp_compl; |
|---|
| .. | .. |
|---|
| 942 | 929 | |
|---|
| 943 | 930 | qc24_host_busy_free_sp: |
|---|
| 944 | 931 | sp->free(sp); |
|---|
| 945 | | - |
|---|
| 946 | | -qc24_host_busy: |
|---|
| 947 | | - return SCSI_MLQUEUE_HOST_BUSY; |
|---|
| 948 | 932 | |
|---|
| 949 | 933 | qc24_target_busy: |
|---|
| 950 | 934 | return SCSI_MLQUEUE_TARGET_BUSY; |
|---|
| .. | .. |
|---|
| 968 | 952 | srb_t *sp; |
|---|
| 969 | 953 | int rval; |
|---|
| 970 | 954 | |
|---|
| 971 | | - rval = fc_remote_port_chkready(rport); |
|---|
| 955 | + rval = rport ? fc_remote_port_chkready(rport) : FC_PORTSTATE_OFFLINE; |
|---|
| 972 | 956 | if (rval) { |
|---|
| 973 | 957 | cmd->result = rval; |
|---|
| 974 | 958 | ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3076, |
|---|
| .. | .. |
|---|
| 982 | 966 | goto qc24_fail_command; |
|---|
| 983 | 967 | } |
|---|
| 984 | 968 | |
|---|
| 985 | | - if (atomic_read(&fcport->state) != FCS_ONLINE) { |
|---|
| 969 | + if (atomic_read(&fcport->state) != FCS_ONLINE || fcport->deleted) { |
|---|
| 986 | 970 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
|---|
| 987 | 971 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
|---|
| 988 | 972 | ql_dbg(ql_dbg_io, vha, 0x3077, |
|---|
| .. | .. |
|---|
| 1006 | 990 | else |
|---|
| 1007 | 991 | goto qc24_target_busy; |
|---|
| 1008 | 992 | |
|---|
| 1009 | | - sp = qla2xxx_get_qpair_sp(qpair, fcport, GFP_ATOMIC); |
|---|
| 1010 | | - if (!sp) |
|---|
| 1011 | | - goto qc24_host_busy; |
|---|
| 993 | + sp = scsi_cmd_priv(cmd); |
|---|
| 994 | + qla2xxx_init_sp(sp, vha, qpair, fcport); |
|---|
| 1012 | 995 | |
|---|
| 1013 | 996 | sp->u.scmd.cmd = cmd; |
|---|
| 1014 | 997 | sp->type = SRB_SCSI_CMD; |
|---|
| 1015 | | - atomic_set(&sp->ref_count, 1); |
|---|
| 1016 | 998 | CMD_SP(cmd) = (void *)sp; |
|---|
| 1017 | 999 | sp->free = qla2xxx_qpair_sp_free_dma; |
|---|
| 1018 | 1000 | sp->done = qla2xxx_qpair_sp_compl; |
|---|
| 1019 | | - sp->qpair = qpair; |
|---|
| 1020 | 1001 | |
|---|
| 1021 | 1002 | rval = ha->isp_ops->start_scsi_mq(sp); |
|---|
| 1022 | 1003 | if (rval != QLA_SUCCESS) { |
|---|
| .. | .. |
|---|
| 1029 | 1010 | |
|---|
| 1030 | 1011 | qc24_host_busy_free_sp: |
|---|
| 1031 | 1012 | sp->free(sp); |
|---|
| 1032 | | - |
|---|
| 1033 | | -qc24_host_busy: |
|---|
| 1034 | | - return SCSI_MLQUEUE_HOST_BUSY; |
|---|
| 1035 | 1013 | |
|---|
| 1036 | 1014 | qc24_target_busy: |
|---|
| 1037 | 1015 | return SCSI_MLQUEUE_TARGET_BUSY; |
|---|
| .. | .. |
|---|
| 1051 | 1029 | * cmd = Scsi Command to wait on. |
|---|
| 1052 | 1030 | * |
|---|
| 1053 | 1031 | * Return: |
|---|
| 1054 | | - * Not Found : 0 |
|---|
| 1055 | | - * Found : 1 |
|---|
| 1032 | + * Completed in time : QLA_SUCCESS |
|---|
| 1033 | + * Did not complete in time : QLA_FUNCTION_FAILED |
|---|
| 1056 | 1034 | */ |
|---|
| 1057 | 1035 | static int |
|---|
| 1058 | 1036 | qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) |
|---|
| .. | .. |
|---|
| 1143 | 1121 | void |
|---|
| 1144 | 1122 | qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha) |
|---|
| 1145 | 1123 | { |
|---|
| 1146 | | - qla2x00_mark_all_devices_lost(vha, 0); |
|---|
| 1124 | + u8 i; |
|---|
| 1147 | 1125 | |
|---|
| 1148 | | - wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha), 10*HZ); |
|---|
| 1126 | + qla2x00_mark_all_devices_lost(vha); |
|---|
| 1127 | + |
|---|
| 1128 | + for (i = 0; i < 10; i++) { |
|---|
| 1129 | + if (wait_event_timeout(vha->fcport_waitQ, |
|---|
| 1130 | + test_fcport_count(vha), HZ) > 0) |
|---|
| 1131 | + break; |
|---|
| 1132 | + } |
|---|
| 1133 | + |
|---|
| 1134 | + flush_workqueue(vha->hw->wq); |
|---|
| 1149 | 1135 | } |
|---|
| 1150 | 1136 | |
|---|
| 1151 | 1137 | /* |
|---|
| .. | .. |
|---|
| 1204 | 1190 | return return_status; |
|---|
| 1205 | 1191 | } |
|---|
| 1206 | 1192 | |
|---|
| 1207 | | -static void |
|---|
| 1208 | | -sp_get(struct srb *sp) |
|---|
| 1209 | | -{ |
|---|
| 1210 | | - atomic_inc(&sp->ref_count); |
|---|
| 1211 | | -} |
|---|
| 1212 | | - |
|---|
| 1213 | 1193 | #define ISP_REG_DISCONNECT 0xffffffffU |
|---|
| 1214 | 1194 | /************************************************************************** |
|---|
| 1215 | 1195 | * qla2x00_isp_reg_stat |
|---|
| .. | .. |
|---|
| 1233 | 1213 | struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; |
|---|
| 1234 | 1214 | |
|---|
| 1235 | 1215 | if (IS_P3P_TYPE(ha)) |
|---|
| 1236 | | - return ((RD_REG_DWORD(®82->host_int)) == ISP_REG_DISCONNECT); |
|---|
| 1216 | + return ((rd_reg_dword(®82->host_int)) == ISP_REG_DISCONNECT); |
|---|
| 1237 | 1217 | else |
|---|
| 1238 | | - return ((RD_REG_DWORD(®->host_status)) == |
|---|
| 1218 | + return ((rd_reg_dword(®->host_status)) == |
|---|
| 1239 | 1219 | ISP_REG_DISCONNECT); |
|---|
| 1240 | 1220 | } |
|---|
| 1241 | 1221 | |
|---|
| .. | .. |
|---|
| 1258 | 1238 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) |
|---|
| 1259 | 1239 | { |
|---|
| 1260 | 1240 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
|---|
| 1241 | + DECLARE_COMPLETION_ONSTACK(comp); |
|---|
| 1261 | 1242 | srb_t *sp; |
|---|
| 1262 | 1243 | int ret; |
|---|
| 1263 | 1244 | unsigned int id; |
|---|
| 1264 | 1245 | uint64_t lun; |
|---|
| 1265 | | - unsigned long flags; |
|---|
| 1266 | | - int rval, wait = 0; |
|---|
| 1246 | + int rval; |
|---|
| 1267 | 1247 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1248 | + uint32_t ratov_j; |
|---|
| 1249 | + struct qla_qpair *qpair; |
|---|
| 1250 | + unsigned long flags; |
|---|
| 1251 | + int fast_fail_status = SUCCESS; |
|---|
| 1268 | 1252 | |
|---|
| 1269 | 1253 | if (qla2x00_isp_reg_stat(ha)) { |
|---|
| 1270 | 1254 | ql_log(ql_log_info, vha, 0x8042, |
|---|
| 1271 | 1255 | "PCI/Register disconnect, exiting.\n"); |
|---|
| 1272 | 1256 | return FAILED; |
|---|
| 1273 | 1257 | } |
|---|
| 1274 | | - if (!CMD_SP(cmd)) |
|---|
| 1275 | | - return SUCCESS; |
|---|
| 1276 | 1258 | |
|---|
| 1259 | + /* Save any FAST_IO_FAIL value to return later if abort succeeds */ |
|---|
| 1277 | 1260 | ret = fc_block_scsi_eh(cmd); |
|---|
| 1278 | 1261 | if (ret != 0) |
|---|
| 1279 | | - return ret; |
|---|
| 1280 | | - ret = SUCCESS; |
|---|
| 1262 | + fast_fail_status = ret; |
|---|
| 1263 | + |
|---|
| 1264 | + sp = scsi_cmd_priv(cmd); |
|---|
| 1265 | + qpair = sp->qpair; |
|---|
| 1266 | + |
|---|
| 1267 | + if ((sp->fcport && sp->fcport->deleted) || !qpair) |
|---|
| 1268 | + return fast_fail_status != SUCCESS ? fast_fail_status : FAILED; |
|---|
| 1269 | + |
|---|
| 1270 | + spin_lock_irqsave(qpair->qp_lock_ptr, flags); |
|---|
| 1271 | + sp->comp = ∁ |
|---|
| 1272 | + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); |
|---|
| 1273 | + |
|---|
| 1281 | 1274 | |
|---|
| 1282 | 1275 | id = cmd->device->id; |
|---|
| 1283 | 1276 | lun = cmd->device->lun; |
|---|
| 1284 | | - |
|---|
| 1285 | | - spin_lock_irqsave(&ha->hardware_lock, flags); |
|---|
| 1286 | | - sp = (srb_t *) CMD_SP(cmd); |
|---|
| 1287 | | - if (!sp) { |
|---|
| 1288 | | - spin_unlock_irqrestore(&ha->hardware_lock, flags); |
|---|
| 1289 | | - return SUCCESS; |
|---|
| 1290 | | - } |
|---|
| 1291 | 1277 | |
|---|
| 1292 | 1278 | ql_dbg(ql_dbg_taskm, vha, 0x8002, |
|---|
| 1293 | 1279 | "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n", |
|---|
| 1294 | 1280 | vha->host_no, id, lun, sp, cmd, sp->handle); |
|---|
| 1295 | 1281 | |
|---|
| 1296 | | - /* Get a reference to the sp and drop the lock.*/ |
|---|
| 1297 | | - sp_get(sp); |
|---|
| 1298 | | - |
|---|
| 1299 | | - spin_unlock_irqrestore(&ha->hardware_lock, flags); |
|---|
| 1282 | + /* |
|---|
| 1283 | + * Abort will release the original Command/sp from FW. Let the |
|---|
| 1284 | + * original command call scsi_done. In return, he will wakeup |
|---|
| 1285 | + * this sleeping thread. |
|---|
| 1286 | + */ |
|---|
| 1300 | 1287 | rval = ha->isp_ops->abort_command(sp); |
|---|
| 1301 | | - if (rval) { |
|---|
| 1302 | | - if (rval == QLA_FUNCTION_PARAMETER_ERROR) |
|---|
| 1303 | | - ret = SUCCESS; |
|---|
| 1304 | | - else |
|---|
| 1288 | + |
|---|
| 1289 | + ql_dbg(ql_dbg_taskm, vha, 0x8003, |
|---|
| 1290 | + "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval); |
|---|
| 1291 | + |
|---|
| 1292 | + /* Wait for the command completion. */ |
|---|
| 1293 | + ratov_j = ha->r_a_tov/10 * 4 * 1000; |
|---|
| 1294 | + ratov_j = msecs_to_jiffies(ratov_j); |
|---|
| 1295 | + switch (rval) { |
|---|
| 1296 | + case QLA_SUCCESS: |
|---|
| 1297 | + if (!wait_for_completion_timeout(&comp, ratov_j)) { |
|---|
| 1298 | + ql_dbg(ql_dbg_taskm, vha, 0xffff, |
|---|
| 1299 | + "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", |
|---|
| 1300 | + __func__, ha->r_a_tov/10); |
|---|
| 1305 | 1301 | ret = FAILED; |
|---|
| 1306 | | - |
|---|
| 1307 | | - ql_dbg(ql_dbg_taskm, vha, 0x8003, |
|---|
| 1308 | | - "Abort command mbx failed cmd=%p, rval=%x.\n", cmd, rval); |
|---|
| 1309 | | - } else { |
|---|
| 1310 | | - ql_dbg(ql_dbg_taskm, vha, 0x8004, |
|---|
| 1311 | | - "Abort command mbx success cmd=%p.\n", cmd); |
|---|
| 1312 | | - wait = 1; |
|---|
| 1313 | | - } |
|---|
| 1314 | | - |
|---|
| 1315 | | - spin_lock_irqsave(&ha->hardware_lock, flags); |
|---|
| 1316 | | - sp->done(sp, 0); |
|---|
| 1317 | | - spin_unlock_irqrestore(&ha->hardware_lock, flags); |
|---|
| 1318 | | - |
|---|
| 1319 | | - /* Did the command return during mailbox execution? */ |
|---|
| 1320 | | - if (ret == FAILED && !CMD_SP(cmd)) |
|---|
| 1321 | | - ret = SUCCESS; |
|---|
| 1322 | | - |
|---|
| 1323 | | - /* Wait for the command to be returned. */ |
|---|
| 1324 | | - if (wait) { |
|---|
| 1325 | | - if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) { |
|---|
| 1326 | | - ql_log(ql_log_warn, vha, 0x8006, |
|---|
| 1327 | | - "Abort handler timed out cmd=%p.\n", cmd); |
|---|
| 1328 | | - ret = FAILED; |
|---|
| 1302 | + } else { |
|---|
| 1303 | + ret = fast_fail_status; |
|---|
| 1329 | 1304 | } |
|---|
| 1305 | + break; |
|---|
| 1306 | + default: |
|---|
| 1307 | + ret = FAILED; |
|---|
| 1308 | + break; |
|---|
| 1330 | 1309 | } |
|---|
| 1310 | + |
|---|
| 1311 | + sp->comp = NULL; |
|---|
| 1331 | 1312 | |
|---|
| 1332 | 1313 | ql_log(ql_log_info, vha, 0x801c, |
|---|
| 1333 | | - "Abort command issued nexus=%ld:%d:%llu -- %d %x.\n", |
|---|
| 1334 | | - vha->host_no, id, lun, wait, ret); |
|---|
| 1314 | + "Abort command issued nexus=%ld:%d:%llu -- %x.\n", |
|---|
| 1315 | + vha->host_no, id, lun, ret); |
|---|
| 1335 | 1316 | |
|---|
| 1336 | 1317 | return ret; |
|---|
| 1337 | 1318 | } |
|---|
| 1338 | 1319 | |
|---|
| 1320 | +/* |
|---|
| 1321 | + * Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED. |
|---|
| 1322 | + */ |
|---|
| 1339 | 1323 | int |
|---|
| 1340 | 1324 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, |
|---|
| 1341 | 1325 | uint64_t l, enum nexus_wait_type type) |
|---|
| .. | .. |
|---|
| 1409 | 1393 | if (err != 0) |
|---|
| 1410 | 1394 | return err; |
|---|
| 1411 | 1395 | |
|---|
| 1396 | + if (fcport->deleted) |
|---|
| 1397 | + return SUCCESS; |
|---|
| 1398 | + |
|---|
| 1412 | 1399 | ql_log(ql_log_info, vha, 0x8009, |
|---|
| 1413 | 1400 | "%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no, |
|---|
| 1414 | 1401 | cmd->device->id, cmd->device->lun, cmd); |
|---|
| .. | .. |
|---|
| 1420 | 1407 | goto eh_reset_failed; |
|---|
| 1421 | 1408 | } |
|---|
| 1422 | 1409 | err = 2; |
|---|
| 1423 | | - if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1) |
|---|
| 1410 | + if (do_reset(fcport, cmd->device->lun, 1) |
|---|
| 1424 | 1411 | != QLA_SUCCESS) { |
|---|
| 1425 | 1412 | ql_log(ql_log_warn, vha, 0x800c, |
|---|
| 1426 | 1413 | "do_reset failed for cmd=%p.\n", cmd); |
|---|
| .. | .. |
|---|
| 1522 | 1509 | if (ret != 0) |
|---|
| 1523 | 1510 | return ret; |
|---|
| 1524 | 1511 | ret = FAILED; |
|---|
| 1512 | + |
|---|
| 1513 | + if (qla2x00_chip_is_down(vha)) |
|---|
| 1514 | + return ret; |
|---|
| 1525 | 1515 | |
|---|
| 1526 | 1516 | ql_log(ql_log_info, vha, 0x8012, |
|---|
| 1527 | 1517 | "BUS RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun); |
|---|
| .. | .. |
|---|
| 1664 | 1654 | if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) { |
|---|
| 1665 | 1655 | atomic_set(&vha->loop_state, LOOP_DOWN); |
|---|
| 1666 | 1656 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
|---|
| 1667 | | - qla2x00_mark_all_devices_lost(vha, 0); |
|---|
| 1657 | + qla2x00_mark_all_devices_lost(vha); |
|---|
| 1668 | 1658 | ret = qla2x00_full_login_lip(vha); |
|---|
| 1669 | 1659 | if (ret != QLA_SUCCESS) { |
|---|
| 1670 | 1660 | ql_dbg(ql_dbg_taskm, vha, 0x802d, |
|---|
| .. | .. |
|---|
| 1685 | 1675 | return QLA_SUCCESS; |
|---|
| 1686 | 1676 | } |
|---|
| 1687 | 1677 | |
|---|
| 1678 | +/* |
|---|
| 1679 | + * The caller must ensure that no completion interrupts will happen |
|---|
| 1680 | + * while this function is in progress. |
|---|
| 1681 | + */ |
|---|
| 1682 | +static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, |
|---|
| 1683 | + unsigned long *flags) |
|---|
| 1684 | + __releases(qp->qp_lock_ptr) |
|---|
| 1685 | + __acquires(qp->qp_lock_ptr) |
|---|
| 1686 | +{ |
|---|
| 1687 | + DECLARE_COMPLETION_ONSTACK(comp); |
|---|
| 1688 | + scsi_qla_host_t *vha = qp->vha; |
|---|
| 1689 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 1690 | + struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
|---|
| 1691 | + int rval; |
|---|
| 1692 | + bool ret_cmd; |
|---|
| 1693 | + uint32_t ratov_j; |
|---|
| 1694 | + |
|---|
| 1695 | + lockdep_assert_held(qp->qp_lock_ptr); |
|---|
| 1696 | + |
|---|
| 1697 | + if (qla2x00_chip_is_down(vha)) { |
|---|
| 1698 | + sp->done(sp, res); |
|---|
| 1699 | + return; |
|---|
| 1700 | + } |
|---|
| 1701 | + |
|---|
| 1702 | + if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS || |
|---|
| 1703 | + (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy && |
|---|
| 1704 | + !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && |
|---|
| 1705 | + !qla2x00_isp_reg_stat(ha))) { |
|---|
| 1706 | + if (sp->comp) { |
|---|
| 1707 | + sp->done(sp, res); |
|---|
| 1708 | + return; |
|---|
| 1709 | + } |
|---|
| 1710 | + |
|---|
| 1711 | + sp->comp = ∁ |
|---|
| 1712 | + spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); |
|---|
| 1713 | + |
|---|
| 1714 | + rval = ha->isp_ops->abort_command(sp); |
|---|
| 1715 | + /* Wait for command completion. */ |
|---|
| 1716 | + ret_cmd = false; |
|---|
| 1717 | + ratov_j = ha->r_a_tov/10 * 4 * 1000; |
|---|
| 1718 | + ratov_j = msecs_to_jiffies(ratov_j); |
|---|
| 1719 | + switch (rval) { |
|---|
| 1720 | + case QLA_SUCCESS: |
|---|
| 1721 | + if (wait_for_completion_timeout(&comp, ratov_j)) { |
|---|
| 1722 | + ql_dbg(ql_dbg_taskm, vha, 0xffff, |
|---|
| 1723 | + "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", |
|---|
| 1724 | + __func__, ha->r_a_tov/10); |
|---|
| 1725 | + ret_cmd = true; |
|---|
| 1726 | + } |
|---|
| 1727 | + /* else FW return SP to driver */ |
|---|
| 1728 | + break; |
|---|
| 1729 | + default: |
|---|
| 1730 | + ret_cmd = true; |
|---|
| 1731 | + break; |
|---|
| 1732 | + } |
|---|
| 1733 | + |
|---|
| 1734 | + spin_lock_irqsave(qp->qp_lock_ptr, *flags); |
|---|
| 1735 | + if (ret_cmd && blk_mq_request_started(cmd->request)) |
|---|
| 1736 | + sp->done(sp, res); |
|---|
| 1737 | + } else { |
|---|
| 1738 | + sp->done(sp, res); |
|---|
| 1739 | + } |
|---|
| 1740 | +} |
|---|
| 1741 | + |
|---|
| 1742 | +/* |
|---|
| 1743 | + * The caller must ensure that no completion interrupts will happen |
|---|
| 1744 | + * while this function is in progress. |
|---|
| 1745 | + */ |
|---|
| 1688 | 1746 | static void |
|---|
| 1689 | 1747 | __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) |
|---|
| 1690 | 1748 | { |
|---|
| 1691 | | - int cnt, status; |
|---|
| 1749 | + int cnt; |
|---|
| 1692 | 1750 | unsigned long flags; |
|---|
| 1693 | 1751 | srb_t *sp; |
|---|
| 1694 | 1752 | scsi_qla_host_t *vha = qp->vha; |
|---|
| .. | .. |
|---|
| 1696 | 1754 | struct req_que *req; |
|---|
| 1697 | 1755 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
|---|
| 1698 | 1756 | struct qla_tgt_cmd *cmd; |
|---|
| 1699 | | - uint8_t trace = 0; |
|---|
| 1700 | 1757 | |
|---|
| 1701 | 1758 | if (!ha->req_q_map) |
|---|
| 1702 | 1759 | return; |
|---|
| .. | .. |
|---|
| 1705 | 1762 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { |
|---|
| 1706 | 1763 | sp = req->outstanding_cmds[cnt]; |
|---|
| 1707 | 1764 | if (sp) { |
|---|
| 1708 | | - req->outstanding_cmds[cnt] = NULL; |
|---|
| 1709 | | - if (sp->cmd_type == TYPE_SRB) { |
|---|
| 1710 | | - if (sp->type == SRB_NVME_CMD || |
|---|
| 1711 | | - sp->type == SRB_NVME_LS) { |
|---|
| 1712 | | - sp_get(sp); |
|---|
| 1713 | | - spin_unlock_irqrestore(qp->qp_lock_ptr, |
|---|
| 1714 | | - flags); |
|---|
| 1715 | | - qla_nvme_abort(ha, sp, res); |
|---|
| 1716 | | - spin_lock_irqsave(qp->qp_lock_ptr, |
|---|
| 1717 | | - flags); |
|---|
| 1718 | | - } else if (GET_CMD_SP(sp) && |
|---|
| 1719 | | - !ha->flags.eeh_busy && |
|---|
| 1720 | | - (!test_bit(ABORT_ISP_ACTIVE, |
|---|
| 1721 | | - &vha->dpc_flags)) && |
|---|
| 1722 | | - !qla2x00_isp_reg_stat(ha) && |
|---|
| 1723 | | - (sp->type == SRB_SCSI_CMD)) { |
|---|
| 1724 | | - /* |
|---|
| 1725 | | - * Don't abort commands in |
|---|
| 1726 | | - * adapter during EEH |
|---|
| 1727 | | - * recovery as it's not |
|---|
| 1728 | | - * accessible/responding. |
|---|
| 1729 | | - * |
|---|
| 1730 | | - * Get a reference to the sp |
|---|
| 1731 | | - * and drop the lock. The |
|---|
| 1732 | | - * reference ensures this |
|---|
| 1733 | | - * sp->done() call and not the |
|---|
| 1734 | | - * call in qla2xxx_eh_abort() |
|---|
| 1735 | | - * ends the SCSI command (with |
|---|
| 1736 | | - * result 'res'). |
|---|
| 1737 | | - */ |
|---|
| 1738 | | - sp_get(sp); |
|---|
| 1739 | | - spin_unlock_irqrestore(qp->qp_lock_ptr, |
|---|
| 1740 | | - flags); |
|---|
| 1741 | | - status = qla2xxx_eh_abort( |
|---|
| 1742 | | - GET_CMD_SP(sp)); |
|---|
| 1743 | | - spin_lock_irqsave(qp->qp_lock_ptr, |
|---|
| 1744 | | - flags); |
|---|
| 1745 | | - /* |
|---|
| 1746 | | - * Get rid of extra reference |
|---|
| 1747 | | - * if immediate exit from |
|---|
| 1748 | | - * ql2xxx_eh_abort |
|---|
| 1749 | | - */ |
|---|
| 1750 | | - if (status == FAILED && |
|---|
| 1751 | | - (qla2x00_isp_reg_stat(ha))) |
|---|
| 1752 | | - atomic_dec( |
|---|
| 1753 | | - &sp->ref_count); |
|---|
| 1754 | | - } |
|---|
| 1755 | | - sp->done(sp, res); |
|---|
| 1756 | | - } else { |
|---|
| 1765 | + switch (sp->cmd_type) { |
|---|
| 1766 | + case TYPE_SRB: |
|---|
| 1767 | + qla2x00_abort_srb(qp, sp, res, &flags); |
|---|
| 1768 | + break; |
|---|
| 1769 | + case TYPE_TGT_CMD: |
|---|
| 1757 | 1770 | if (!vha->hw->tgt.tgt_ops || !tgt || |
|---|
| 1758 | 1771 | qla_ini_mode_enabled(vha)) { |
|---|
| 1759 | | - if (!trace) |
|---|
| 1760 | | - ql_dbg(ql_dbg_tgt_mgt, |
|---|
| 1761 | | - vha, 0xf003, |
|---|
| 1762 | | - "HOST-ABORT-HNDLR: dpc_flags=%lx. Target mode disabled\n", |
|---|
| 1763 | | - vha->dpc_flags); |
|---|
| 1772 | + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003, |
|---|
| 1773 | + "HOST-ABORT-HNDLR: dpc_flags=%lx. Target mode disabled\n", |
|---|
| 1774 | + vha->dpc_flags); |
|---|
| 1764 | 1775 | continue; |
|---|
| 1765 | 1776 | } |
|---|
| 1766 | 1777 | cmd = (struct qla_tgt_cmd *)sp; |
|---|
| 1767 | | - qlt_abort_cmd_on_host_reset(cmd->vha, cmd); |
|---|
| 1778 | + cmd->aborted = 1; |
|---|
| 1779 | + break; |
|---|
| 1780 | + case TYPE_TGT_TMCMD: |
|---|
| 1781 | + /* Skip task management functions. */ |
|---|
| 1782 | + break; |
|---|
| 1783 | + default: |
|---|
| 1784 | + break; |
|---|
| 1768 | 1785 | } |
|---|
| 1786 | + req->outstanding_cmds[cnt] = NULL; |
|---|
| 1769 | 1787 | } |
|---|
| 1770 | 1788 | } |
|---|
| 1771 | 1789 | spin_unlock_irqrestore(qp->qp_lock_ptr, flags); |
|---|
| 1772 | 1790 | } |
|---|
| 1773 | 1791 | |
|---|
| 1792 | +/* |
|---|
| 1793 | + * The caller must ensure that no completion interrupts will happen |
|---|
| 1794 | + * while this function is in progress. |
|---|
| 1795 | + */ |
|---|
| 1774 | 1796 | void |
|---|
| 1775 | 1797 | qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) |
|---|
| 1776 | 1798 | { |
|---|
| 1777 | 1799 | int que; |
|---|
| 1778 | 1800 | struct qla_hw_data *ha = vha->hw; |
|---|
| 1779 | 1801 | |
|---|
| 1802 | + /* Continue only if initialization complete. */ |
|---|
| 1803 | + if (!ha->base_qpair) |
|---|
| 1804 | + return; |
|---|
| 1780 | 1805 | __qla2x00_abort_all_cmds(ha->base_qpair, res); |
|---|
| 1781 | 1806 | |
|---|
| 1807 | + if (!ha->queue_pair_map) |
|---|
| 1808 | + return; |
|---|
| 1782 | 1809 | for (que = 0; que < ha->max_qpairs; que++) { |
|---|
| 1783 | 1810 | if (!ha->queue_pair_map[que]) |
|---|
| 1784 | 1811 | continue; |
|---|
| .. | .. |
|---|
| 1835 | 1862 | if (!dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(64))) { |
|---|
| 1836 | 1863 | /* Any upper-dword bits set? */ |
|---|
| 1837 | 1864 | if (MSD(dma_get_required_mask(&ha->pdev->dev)) && |
|---|
| 1838 | | - !pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(64))) { |
|---|
| 1865 | + !dma_set_coherent_mask(&ha->pdev->dev, DMA_BIT_MASK(64))) { |
|---|
| 1839 | 1866 | /* Ok, a 64bit DMA mask is applicable. */ |
|---|
| 1840 | 1867 | ha->flags.enable_64bit_addressing = 1; |
|---|
| 1841 | 1868 | ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64; |
|---|
| .. | .. |
|---|
| 1845 | 1872 | } |
|---|
| 1846 | 1873 | |
|---|
| 1847 | 1874 | dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(32)); |
|---|
| 1848 | | - pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(32)); |
|---|
| 1875 | + dma_set_coherent_mask(&ha->pdev->dev, DMA_BIT_MASK(32)); |
|---|
| 1849 | 1876 | } |
|---|
| 1850 | 1877 | |
|---|
| 1851 | 1878 | static void |
|---|
| .. | .. |
|---|
| 1857 | 1884 | spin_lock_irqsave(&ha->hardware_lock, flags); |
|---|
| 1858 | 1885 | ha->interrupts_on = 1; |
|---|
| 1859 | 1886 | /* enable risc and host interrupts */ |
|---|
| 1860 | | - WRT_REG_WORD(®->ictrl, ICR_EN_INT | ICR_EN_RISC); |
|---|
| 1861 | | - RD_REG_WORD(®->ictrl); |
|---|
| 1887 | + wrt_reg_word(®->ictrl, ICR_EN_INT | ICR_EN_RISC); |
|---|
| 1888 | + rd_reg_word(®->ictrl); |
|---|
| 1862 | 1889 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
|---|
| 1863 | 1890 | |
|---|
| 1864 | 1891 | } |
|---|
| .. | .. |
|---|
| 1872 | 1899 | spin_lock_irqsave(&ha->hardware_lock, flags); |
|---|
| 1873 | 1900 | ha->interrupts_on = 0; |
|---|
| 1874 | 1901 | /* disable risc and host interrupts */ |
|---|
| 1875 | | - WRT_REG_WORD(®->ictrl, 0); |
|---|
| 1876 | | - RD_REG_WORD(®->ictrl); |
|---|
| 1902 | + wrt_reg_word(®->ictrl, 0); |
|---|
| 1903 | + rd_reg_word(®->ictrl); |
|---|
| 1877 | 1904 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
|---|
| 1878 | 1905 | } |
|---|
| 1879 | 1906 | |
|---|
| .. | .. |
|---|
| 1885 | 1912 | |
|---|
| 1886 | 1913 | spin_lock_irqsave(&ha->hardware_lock, flags); |
|---|
| 1887 | 1914 | ha->interrupts_on = 1; |
|---|
| 1888 | | - WRT_REG_DWORD(®->ictrl, ICRX_EN_RISC_INT); |
|---|
| 1889 | | - RD_REG_DWORD(®->ictrl); |
|---|
| 1915 | + wrt_reg_dword(®->ictrl, ICRX_EN_RISC_INT); |
|---|
| 1916 | + rd_reg_dword(®->ictrl); |
|---|
| 1890 | 1917 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
|---|
| 1891 | 1918 | } |
|---|
| 1892 | 1919 | |
|---|
| .. | .. |
|---|
| 1900 | 1927 | return; |
|---|
| 1901 | 1928 | spin_lock_irqsave(&ha->hardware_lock, flags); |
|---|
| 1902 | 1929 | ha->interrupts_on = 0; |
|---|
| 1903 | | - WRT_REG_DWORD(®->ictrl, 0); |
|---|
| 1904 | | - RD_REG_DWORD(®->ictrl); |
|---|
| 1930 | + wrt_reg_dword(®->ictrl, 0); |
|---|
| 1931 | + rd_reg_dword(®->ictrl); |
|---|
| 1905 | 1932 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
|---|
| 1906 | 1933 | } |
|---|
| 1907 | 1934 | |
|---|
| .. | .. |
|---|
| 2264 | 2291 | .config_rings = qla24xx_config_rings, |
|---|
| 2265 | 2292 | .reset_adapter = qla24xx_reset_adapter, |
|---|
| 2266 | 2293 | .nvram_config = qla81xx_nvram_config, |
|---|
| 2267 | | - .update_fw_options = qla81xx_update_fw_options, |
|---|
| 2294 | + .update_fw_options = qla24xx_update_fw_options, |
|---|
| 2268 | 2295 | .load_risc = qla81xx_load_risc, |
|---|
| 2269 | 2296 | .pci_info_str = qla24xx_pci_info_str, |
|---|
| 2270 | 2297 | .fw_version_str = qla24xx_fw_version_str, |
|---|
| .. | .. |
|---|
| 2381 | 2408 | .config_rings = qla24xx_config_rings, |
|---|
| 2382 | 2409 | .reset_adapter = qla24xx_reset_adapter, |
|---|
| 2383 | 2410 | .nvram_config = qla81xx_nvram_config, |
|---|
| 2384 | | - .update_fw_options = qla81xx_update_fw_options, |
|---|
| 2411 | + .update_fw_options = qla24xx_update_fw_options, |
|---|
| 2385 | 2412 | .load_risc = qla81xx_load_risc, |
|---|
| 2386 | 2413 | .pci_info_str = qla24xx_pci_info_str, |
|---|
| 2387 | 2414 | .fw_version_str = qla24xx_fw_version_str, |
|---|
| .. | .. |
|---|
| 2459 | 2486 | .config_rings = qla24xx_config_rings, |
|---|
| 2460 | 2487 | .reset_adapter = qla24xx_reset_adapter, |
|---|
| 2461 | 2488 | .nvram_config = qla81xx_nvram_config, |
|---|
| 2462 | | - .update_fw_options = qla81xx_update_fw_options, |
|---|
| 2489 | + .update_fw_options = qla24xx_update_fw_options, |
|---|
| 2463 | 2490 | .load_risc = qla81xx_load_risc, |
|---|
| 2464 | 2491 | .pci_info_str = qla24xx_pci_info_str, |
|---|
| 2465 | 2492 | .fw_version_str = qla24xx_fw_version_str, |
|---|
| .. | .. |
|---|
| 2478 | 2505 | .read_nvram = NULL, |
|---|
| 2479 | 2506 | .write_nvram = NULL, |
|---|
| 2480 | 2507 | .fw_dump = qla27xx_fwdump, |
|---|
| 2508 | + .mpi_fw_dump = qla27xx_mpi_fwdump, |
|---|
| 2481 | 2509 | .beacon_on = qla24xx_beacon_on, |
|---|
| 2482 | 2510 | .beacon_off = qla24xx_beacon_off, |
|---|
| 2483 | 2511 | .beacon_blink = qla83xx_beacon_blink, |
|---|
| .. | .. |
|---|
| 2636 | 2664 | ha->device_type |= DT_T10_PI; |
|---|
| 2637 | 2665 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
|---|
| 2638 | 2666 | break; |
|---|
| 2667 | + case PCI_DEVICE_ID_QLOGIC_ISP2081: |
|---|
| 2668 | + case PCI_DEVICE_ID_QLOGIC_ISP2089: |
|---|
| 2669 | + ha->isp_type |= DT_ISP2081; |
|---|
| 2670 | + ha->device_type |= DT_ZIO_SUPPORTED; |
|---|
| 2671 | + ha->device_type |= DT_FWI2; |
|---|
| 2672 | + ha->device_type |= DT_IIDMA; |
|---|
| 2673 | + ha->device_type |= DT_T10_PI; |
|---|
| 2674 | + ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
|---|
| 2675 | + break; |
|---|
| 2676 | + case PCI_DEVICE_ID_QLOGIC_ISP2281: |
|---|
| 2677 | + case PCI_DEVICE_ID_QLOGIC_ISP2289: |
|---|
| 2678 | + ha->isp_type |= DT_ISP2281; |
|---|
| 2679 | + ha->device_type |= DT_ZIO_SUPPORTED; |
|---|
| 2680 | + ha->device_type |= DT_FWI2; |
|---|
| 2681 | + ha->device_type |= DT_IIDMA; |
|---|
| 2682 | + ha->device_type |= DT_T10_PI; |
|---|
| 2683 | + ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
|---|
| 2684 | + break; |
|---|
| 2639 | 2685 | } |
|---|
| 2640 | 2686 | |
|---|
| 2641 | 2687 | if (IS_QLA82XX(ha)) |
|---|
| .. | .. |
|---|
| 2643 | 2689 | else { |
|---|
| 2644 | 2690 | /* Get adapter physical port no from interrupt pin register. */ |
|---|
| 2645 | 2691 | pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no); |
|---|
| 2646 | | - if (IS_QLA27XX(ha)) |
|---|
| 2692 | + if (IS_QLA25XX(ha) || IS_QLA2031(ha) || |
|---|
| 2693 | + IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
|---|
| 2647 | 2694 | ha->port_no--; |
|---|
| 2648 | 2695 | else |
|---|
| 2649 | 2696 | ha->port_no = !(ha->port_no & 1); |
|---|
| .. | .. |
|---|
| 2740 | 2787 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 || |
|---|
| 2741 | 2788 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071 || |
|---|
| 2742 | 2789 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2271 || |
|---|
| 2743 | | - pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2261) { |
|---|
| 2790 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2261 || |
|---|
| 2791 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2081 || |
|---|
| 2792 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2281 || |
|---|
| 2793 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2089 || |
|---|
| 2794 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2289) { |
|---|
| 2744 | 2795 | bars = pci_select_bars(pdev, IORESOURCE_MEM); |
|---|
| 2745 | 2796 | mem_only = 1; |
|---|
| 2746 | 2797 | ql_dbg_pci(ql_dbg_init, pdev, 0x0007, |
|---|
| .. | .. |
|---|
| 2755 | 2806 | } else { |
|---|
| 2756 | 2807 | if (pci_enable_device(pdev)) |
|---|
| 2757 | 2808 | return ret; |
|---|
| 2809 | + } |
|---|
| 2810 | + |
|---|
| 2811 | + if (is_kdump_kernel()) { |
|---|
| 2812 | + ql2xmqsupport = 0; |
|---|
| 2813 | + ql2xallocfwdump = 0; |
|---|
| 2758 | 2814 | } |
|---|
| 2759 | 2815 | |
|---|
| 2760 | 2816 | /* This may fail but that's ok */ |
|---|
| .. | .. |
|---|
| 2789 | 2845 | |
|---|
| 2790 | 2846 | /* Set EEH reset type to fundamental if required by hba */ |
|---|
| 2791 | 2847 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) || |
|---|
| 2792 | | - IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
|---|
| 2848 | + IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
|---|
| 2793 | 2849 | pdev->needs_freset = 1; |
|---|
| 2794 | 2850 | |
|---|
| 2795 | 2851 | ha->prev_topology = 0; |
|---|
| .. | .. |
|---|
| 2800 | 2856 | atomic_set(&ha->num_pend_mbx_stage1, 0); |
|---|
| 2801 | 2857 | atomic_set(&ha->num_pend_mbx_stage2, 0); |
|---|
| 2802 | 2858 | atomic_set(&ha->num_pend_mbx_stage3, 0); |
|---|
| 2859 | + atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD); |
|---|
| 2860 | + ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD; |
|---|
| 2803 | 2861 | |
|---|
| 2804 | 2862 | /* Assign ISP specific operations. */ |
|---|
| 2805 | 2863 | if (IS_QLA2100(ha)) { |
|---|
| .. | .. |
|---|
| 2966 | 3024 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX; |
|---|
| 2967 | 3025 | ha->nvram_conf_off = ~0; |
|---|
| 2968 | 3026 | ha->nvram_data_off = ~0; |
|---|
| 3027 | + } else if (IS_QLA28XX(ha)) { |
|---|
| 3028 | + ha->portnum = PCI_FUNC(ha->pdev->devfn); |
|---|
| 3029 | + ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400; |
|---|
| 3030 | + ha->mbx_count = MAILBOX_REGISTER_COUNT; |
|---|
| 3031 | + req_length = REQUEST_ENTRY_CNT_24XX; |
|---|
| 3032 | + rsp_length = RESPONSE_ENTRY_CNT_2300; |
|---|
| 3033 | + ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; |
|---|
| 3034 | + ha->max_loop_id = SNS_LAST_LOOP_ID_2300; |
|---|
| 3035 | + ha->init_cb_size = sizeof(struct mid_init_cb_81xx); |
|---|
| 3036 | + ha->gid_list_info_size = 8; |
|---|
| 3037 | + ha->optrom_size = OPTROM_SIZE_28XX; |
|---|
| 3038 | + ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; |
|---|
| 3039 | + ha->isp_ops = &qla27xx_isp_ops; |
|---|
| 3040 | + ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_28XX; |
|---|
| 3041 | + ha->flash_data_off = FARX_ACCESS_FLASH_DATA_28XX; |
|---|
| 3042 | + ha->nvram_conf_off = ~0; |
|---|
| 3043 | + ha->nvram_data_off = ~0; |
|---|
| 2969 | 3044 | } |
|---|
| 2970 | 3045 | |
|---|
| 2971 | 3046 | ql_dbg_pci(ql_dbg_init, pdev, 0x001e, |
|---|
| .. | .. |
|---|
| 3090 | 3165 | ql_log(ql_log_fatal, base_vha, 0x003d, |
|---|
| 3091 | 3166 | "Failed to allocate memory for queue pointers..." |
|---|
| 3092 | 3167 | "aborting.\n"); |
|---|
| 3168 | + ret = -ENODEV; |
|---|
| 3093 | 3169 | goto probe_failed; |
|---|
| 3094 | 3170 | } |
|---|
| 3095 | 3171 | |
|---|
| 3096 | | - if (ha->mqenable && shost_use_blk_mq(host)) { |
|---|
| 3172 | + if (ha->mqenable) { |
|---|
| 3097 | 3173 | /* number of hardware queues supported by blk/scsi-mq*/ |
|---|
| 3098 | 3174 | host->nr_hw_queues = ha->max_qpairs; |
|---|
| 3099 | 3175 | |
|---|
| .. | .. |
|---|
| 3131 | 3207 | req->req_q_out = &ha->iobase->isp24.req_q_out; |
|---|
| 3132 | 3208 | rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in; |
|---|
| 3133 | 3209 | rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out; |
|---|
| 3134 | | - if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
|---|
| 3210 | + if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
|---|
| 3211 | + IS_QLA28XX(ha)) { |
|---|
| 3135 | 3212 | req->req_q_in = &ha->mqiobase->isp25mq.req_q_in; |
|---|
| 3136 | 3213 | req->req_q_out = &ha->mqiobase->isp25mq.req_q_out; |
|---|
| 3137 | 3214 | rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in; |
|---|
| .. | .. |
|---|
| 3209 | 3286 | base_vha->mgmt_svr_loop_id, host->sg_tablesize); |
|---|
| 3210 | 3287 | |
|---|
| 3211 | 3288 | if (ha->mqenable) { |
|---|
| 3212 | | - bool mq = false; |
|---|
| 3213 | 3289 | bool startit = false; |
|---|
| 3214 | 3290 | |
|---|
| 3215 | | - if (QLA_TGT_MODE_ENABLED()) { |
|---|
| 3216 | | - mq = true; |
|---|
| 3291 | + if (QLA_TGT_MODE_ENABLED()) |
|---|
| 3217 | 3292 | startit = false; |
|---|
| 3218 | | - } |
|---|
| 3219 | 3293 | |
|---|
| 3220 | | - if ((ql2x_ini_mode == QLA2XXX_INI_MODE_ENABLED) && |
|---|
| 3221 | | - shost_use_blk_mq(host)) { |
|---|
| 3222 | | - mq = true; |
|---|
| 3294 | + if (ql2x_ini_mode == QLA2XXX_INI_MODE_ENABLED) |
|---|
| 3223 | 3295 | startit = true; |
|---|
| 3224 | | - } |
|---|
| 3225 | 3296 | |
|---|
| 3226 | | - if (mq) { |
|---|
| 3227 | | - /* Create start of day qpairs for Block MQ */ |
|---|
| 3228 | | - for (i = 0; i < ha->max_qpairs; i++) |
|---|
| 3229 | | - qla2xxx_create_qpair(base_vha, 5, 0, startit); |
|---|
| 3230 | | - } |
|---|
| 3297 | + /* Create start of day qpairs for Block MQ */ |
|---|
| 3298 | + for (i = 0; i < ha->max_qpairs; i++) |
|---|
| 3299 | + qla2xxx_create_qpair(base_vha, 5, 0, startit); |
|---|
| 3231 | 3300 | } |
|---|
| 3301 | + qla_init_iocb_limit(base_vha); |
|---|
| 3232 | 3302 | |
|---|
| 3233 | 3303 | if (ha->flags.running_gold_fw) |
|---|
| 3234 | 3304 | goto skip_dpc; |
|---|
| .. | .. |
|---|
| 3288 | 3358 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { |
|---|
| 3289 | 3359 | if (ha->fw_attributes & BIT_4) { |
|---|
| 3290 | 3360 | int prot = 0, guard; |
|---|
| 3361 | + |
|---|
| 3291 | 3362 | base_vha->flags.difdix_supported = 1; |
|---|
| 3292 | 3363 | ql_dbg(ql_dbg_init, base_vha, 0x00f1, |
|---|
| 3293 | 3364 | "Registering for DIF/DIX type 1 and 3 protection.\n"); |
|---|
| 3294 | 3365 | if (ql2xenabledif == 1) |
|---|
| 3295 | 3366 | prot = SHOST_DIX_TYPE0_PROTECTION; |
|---|
| 3296 | | - scsi_host_set_prot(host, |
|---|
| 3297 | | - prot | SHOST_DIF_TYPE1_PROTECTION |
|---|
| 3298 | | - | SHOST_DIF_TYPE2_PROTECTION |
|---|
| 3299 | | - | SHOST_DIF_TYPE3_PROTECTION |
|---|
| 3300 | | - | SHOST_DIX_TYPE1_PROTECTION |
|---|
| 3301 | | - | SHOST_DIX_TYPE2_PROTECTION |
|---|
| 3302 | | - | SHOST_DIX_TYPE3_PROTECTION); |
|---|
| 3367 | + if (ql2xprotmask) |
|---|
| 3368 | + scsi_host_set_prot(host, ql2xprotmask); |
|---|
| 3369 | + else |
|---|
| 3370 | + scsi_host_set_prot(host, |
|---|
| 3371 | + prot | SHOST_DIF_TYPE1_PROTECTION |
|---|
| 3372 | + | SHOST_DIF_TYPE2_PROTECTION |
|---|
| 3373 | + | SHOST_DIF_TYPE3_PROTECTION |
|---|
| 3374 | + | SHOST_DIX_TYPE1_PROTECTION |
|---|
| 3375 | + | SHOST_DIX_TYPE2_PROTECTION |
|---|
| 3376 | + | SHOST_DIX_TYPE3_PROTECTION); |
|---|
| 3303 | 3377 | |
|---|
| 3304 | 3378 | guard = SHOST_DIX_GUARD_CRC; |
|---|
| 3305 | 3379 | |
|---|
| .. | .. |
|---|
| 3307 | 3381 | (ql2xenabledif > 1 || IS_PI_DIFB_DIX0_CAPABLE(ha))) |
|---|
| 3308 | 3382 | guard |= SHOST_DIX_GUARD_IP; |
|---|
| 3309 | 3383 | |
|---|
| 3310 | | - scsi_host_set_guard(host, guard); |
|---|
| 3384 | + if (ql2xprotguard) |
|---|
| 3385 | + scsi_host_set_guard(host, ql2xprotguard); |
|---|
| 3386 | + else |
|---|
| 3387 | + scsi_host_set_guard(host, guard); |
|---|
| 3311 | 3388 | } else |
|---|
| 3312 | 3389 | base_vha->flags.difdix_supported = 0; |
|---|
| 3313 | 3390 | } |
|---|
| .. | .. |
|---|
| 3358 | 3435 | "QLogic %s - %s.\n", ha->model_number, ha->model_desc); |
|---|
| 3359 | 3436 | ql_log(ql_log_info, base_vha, 0x00fc, |
|---|
| 3360 | 3437 | "ISP%04X: %s @ %s hdma%c host#=%ld fw=%s.\n", |
|---|
| 3361 | | - pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info), |
|---|
| 3438 | + pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info, |
|---|
| 3439 | + sizeof(pci_info)), |
|---|
| 3362 | 3440 | pci_name(pdev), ha->flags.enable_64bit_addressing ? '+' : '-', |
|---|
| 3363 | 3441 | base_vha->host_no, |
|---|
| 3364 | 3442 | ha->isp_ops->fw_version_str(base_vha, fw_str, sizeof(fw_str))); |
|---|
| .. | .. |
|---|
| 3369 | 3447 | |
|---|
| 3370 | 3448 | if (test_bit(UNLOADING, &base_vha->dpc_flags)) |
|---|
| 3371 | 3449 | return -ENODEV; |
|---|
| 3372 | | - |
|---|
| 3373 | | - if (ha->flags.detected_lr_sfp) { |
|---|
| 3374 | | - ql_log(ql_log_info, base_vha, 0xffff, |
|---|
| 3375 | | - "Reset chip to pick up LR SFP setting\n"); |
|---|
| 3376 | | - set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); |
|---|
| 3377 | | - qla2xxx_wake_dpc(base_vha); |
|---|
| 3378 | | - } |
|---|
| 3379 | 3450 | |
|---|
| 3380 | 3451 | return 0; |
|---|
| 3381 | 3452 | |
|---|
| .. | .. |
|---|
| 3433 | 3504 | return ret; |
|---|
| 3434 | 3505 | } |
|---|
| 3435 | 3506 | |
|---|
| 3507 | +static void __qla_set_remove_flag(scsi_qla_host_t *base_vha) |
|---|
| 3508 | +{ |
|---|
| 3509 | + scsi_qla_host_t *vp; |
|---|
| 3510 | + unsigned long flags; |
|---|
| 3511 | + struct qla_hw_data *ha; |
|---|
| 3512 | + |
|---|
| 3513 | + if (!base_vha) |
|---|
| 3514 | + return; |
|---|
| 3515 | + |
|---|
| 3516 | + ha = base_vha->hw; |
|---|
| 3517 | + |
|---|
| 3518 | + spin_lock_irqsave(&ha->vport_slock, flags); |
|---|
| 3519 | + list_for_each_entry(vp, &ha->vp_list, list) |
|---|
| 3520 | + set_bit(PFLG_DRIVER_REMOVING, &vp->pci_flags); |
|---|
| 3521 | + |
|---|
| 3522 | + /* |
|---|
| 3523 | + * Indicate device removal to prevent future board_disable |
|---|
| 3524 | + * and wait until any pending board_disable has completed. |
|---|
| 3525 | + */ |
|---|
| 3526 | + set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags); |
|---|
| 3527 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
|---|
| 3528 | +} |
|---|
| 3529 | + |
|---|
| 3436 | 3530 | static void |
|---|
| 3437 | 3531 | qla2x00_shutdown(struct pci_dev *pdev) |
|---|
| 3438 | 3532 | { |
|---|
| .. | .. |
|---|
| 3449 | 3543 | * Prevent future board_disable and wait |
|---|
| 3450 | 3544 | * until any pending board_disable has completed. |
|---|
| 3451 | 3545 | */ |
|---|
| 3452 | | - set_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags); |
|---|
| 3546 | + __qla_set_remove_flag(vha); |
|---|
| 3453 | 3547 | cancel_work_sync(&ha->board_disable); |
|---|
| 3454 | 3548 | |
|---|
| 3455 | 3549 | if (!atomic_read(&pdev->enable_cnt)) |
|---|
| .. | .. |
|---|
| 3469 | 3563 | if (ha->eft) |
|---|
| 3470 | 3564 | qla2x00_disable_eft_trace(vha); |
|---|
| 3471 | 3565 | |
|---|
| 3472 | | - if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { |
|---|
| 3566 | + if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
|---|
| 3567 | + IS_QLA28XX(ha)) { |
|---|
| 3473 | 3568 | if (ha->flags.fw_started) |
|---|
| 3474 | 3569 | qla2x00_abort_isp_cleanup(vha); |
|---|
| 3475 | 3570 | } else { |
|---|
| .. | .. |
|---|
| 3578 | 3673 | if (ha->mqiobase) |
|---|
| 3579 | 3674 | iounmap(ha->mqiobase); |
|---|
| 3580 | 3675 | |
|---|
| 3581 | | - if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) && ha->msixbase) |
|---|
| 3676 | + if (ha->msixbase) |
|---|
| 3582 | 3677 | iounmap(ha->msixbase); |
|---|
| 3583 | 3678 | } |
|---|
| 3584 | 3679 | } |
|---|
| .. | .. |
|---|
| 3607 | 3702 | ha = base_vha->hw; |
|---|
| 3608 | 3703 | ql_log(ql_log_info, base_vha, 0xb079, |
|---|
| 3609 | 3704 | "Removing driver\n"); |
|---|
| 3610 | | - |
|---|
| 3611 | | - /* Indicate device removal to prevent future board_disable and wait |
|---|
| 3612 | | - * until any pending board_disable has completed. */ |
|---|
| 3613 | | - set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags); |
|---|
| 3705 | + __qla_set_remove_flag(base_vha); |
|---|
| 3614 | 3706 | cancel_work_sync(&ha->board_disable); |
|---|
| 3615 | 3707 | |
|---|
| 3616 | 3708 | /* |
|---|
| .. | .. |
|---|
| 3636 | 3728 | if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) |
|---|
| 3637 | 3729 | return; |
|---|
| 3638 | 3730 | |
|---|
| 3639 | | - if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { |
|---|
| 3731 | + if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
|---|
| 3732 | + IS_QLA28XX(ha)) { |
|---|
| 3640 | 3733 | if (ha->flags.fw_started) |
|---|
| 3641 | 3734 | qla2x00_abort_isp_cleanup(base_vha); |
|---|
| 3642 | 3735 | } else if (!IS_QLAFX00(ha)) { |
|---|
| .. | .. |
|---|
| 3666 | 3759 | qlafx00_driver_shutdown(base_vha, 20); |
|---|
| 3667 | 3760 | |
|---|
| 3668 | 3761 | qla2x00_delete_all_vps(ha, base_vha); |
|---|
| 3669 | | - |
|---|
| 3670 | | - qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); |
|---|
| 3671 | 3762 | |
|---|
| 3672 | 3763 | qla2x00_dfs_remove(base_vha); |
|---|
| 3673 | 3764 | |
|---|
| .. | .. |
|---|
| 3714 | 3805 | pci_disable_device(pdev); |
|---|
| 3715 | 3806 | } |
|---|
| 3716 | 3807 | |
|---|
| 3808 | +static inline void |
|---|
| 3809 | +qla24xx_free_purex_list(struct purex_list *list) |
|---|
| 3810 | +{ |
|---|
| 3811 | + struct list_head *item, *next; |
|---|
| 3812 | + ulong flags; |
|---|
| 3813 | + |
|---|
| 3814 | + spin_lock_irqsave(&list->lock, flags); |
|---|
| 3815 | + list_for_each_safe(item, next, &list->head) { |
|---|
| 3816 | + list_del(item); |
|---|
| 3817 | + kfree(list_entry(item, struct purex_item, list)); |
|---|
| 3818 | + } |
|---|
| 3819 | + spin_unlock_irqrestore(&list->lock, flags); |
|---|
| 3820 | +} |
|---|
| 3821 | + |
|---|
| 3717 | 3822 | static void |
|---|
| 3718 | 3823 | qla2x00_free_device(scsi_qla_host_t *vha) |
|---|
| 3719 | 3824 | { |
|---|
| .. | .. |
|---|
| 3746 | 3851 | } |
|---|
| 3747 | 3852 | |
|---|
| 3748 | 3853 | |
|---|
| 3854 | + qla24xx_free_purex_list(&vha->purex_list); |
|---|
| 3855 | + |
|---|
| 3749 | 3856 | qla2x00_mem_free(ha); |
|---|
| 3750 | 3857 | |
|---|
| 3751 | 3858 | qla82xx_md_free(vha); |
|---|
| .. | .. |
|---|
| 3757 | 3864 | { |
|---|
| 3758 | 3865 | fc_port_t *fcport, *tfcport; |
|---|
| 3759 | 3866 | |
|---|
| 3760 | | - list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) { |
|---|
| 3761 | | - list_del(&fcport->list); |
|---|
| 3762 | | - qla2x00_clear_loop_id(fcport); |
|---|
| 3763 | | - kfree(fcport); |
|---|
| 3764 | | - } |
|---|
| 3867 | + list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) |
|---|
| 3868 | + qla2x00_free_fcport(fcport); |
|---|
| 3765 | 3869 | } |
|---|
| 3766 | 3870 | |
|---|
| 3767 | 3871 | static inline void |
|---|
| 3768 | | -qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, |
|---|
| 3769 | | - int defer) |
|---|
| 3872 | +qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport) |
|---|
| 3770 | 3873 | { |
|---|
| 3771 | | - struct fc_rport *rport; |
|---|
| 3772 | | - scsi_qla_host_t *base_vha; |
|---|
| 3773 | | - unsigned long flags; |
|---|
| 3874 | + int now; |
|---|
| 3774 | 3875 | |
|---|
| 3775 | 3876 | if (!fcport->rport) |
|---|
| 3776 | 3877 | return; |
|---|
| 3777 | 3878 | |
|---|
| 3778 | | - rport = fcport->rport; |
|---|
| 3779 | | - if (defer) { |
|---|
| 3780 | | - base_vha = pci_get_drvdata(vha->hw->pdev); |
|---|
| 3781 | | - spin_lock_irqsave(vha->host->host_lock, flags); |
|---|
| 3782 | | - fcport->drport = rport; |
|---|
| 3783 | | - spin_unlock_irqrestore(vha->host->host_lock, flags); |
|---|
| 3784 | | - qlt_do_generation_tick(vha, &base_vha->total_fcport_update_gen); |
|---|
| 3785 | | - set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); |
|---|
| 3786 | | - qla2xxx_wake_dpc(base_vha); |
|---|
| 3787 | | - } else { |
|---|
| 3788 | | - int now; |
|---|
| 3789 | | - if (rport) { |
|---|
| 3790 | | - ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, |
|---|
| 3791 | | - "%s %8phN. rport %p roles %x\n", |
|---|
| 3792 | | - __func__, fcport->port_name, rport, |
|---|
| 3793 | | - rport->roles); |
|---|
| 3794 | | - fc_remote_port_delete(rport); |
|---|
| 3795 | | - } |
|---|
| 3796 | | - qlt_do_generation_tick(vha, &now); |
|---|
| 3879 | + if (fcport->rport) { |
|---|
| 3880 | + ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, |
|---|
| 3881 | + "%s %8phN. rport %p roles %x\n", |
|---|
| 3882 | + __func__, fcport->port_name, fcport->rport, |
|---|
| 3883 | + fcport->rport->roles); |
|---|
| 3884 | + fc_remote_port_delete(fcport->rport); |
|---|
| 3797 | 3885 | } |
|---|
| 3886 | + qlt_do_generation_tick(vha, &now); |
|---|
| 3798 | 3887 | } |
|---|
| 3799 | 3888 | |
|---|
| 3800 | 3889 | /* |
|---|
| .. | .. |
|---|
| 3807 | 3896 | * Context: |
|---|
| 3808 | 3897 | */ |
|---|
| 3809 | 3898 | void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, |
|---|
| 3810 | | - int do_login, int defer) |
|---|
| 3899 | + int do_login) |
|---|
| 3811 | 3900 | { |
|---|
| 3812 | 3901 | if (IS_QLAFX00(vha->hw)) { |
|---|
| 3813 | 3902 | qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); |
|---|
| 3814 | | - qla2x00_schedule_rport_del(vha, fcport, defer); |
|---|
| 3903 | + qla2x00_schedule_rport_del(vha, fcport); |
|---|
| 3815 | 3904 | return; |
|---|
| 3816 | 3905 | } |
|---|
| 3817 | 3906 | |
|---|
| 3818 | 3907 | if (atomic_read(&fcport->state) == FCS_ONLINE && |
|---|
| 3819 | 3908 | vha->vp_idx == fcport->vha->vp_idx) { |
|---|
| 3820 | 3909 | qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); |
|---|
| 3821 | | - qla2x00_schedule_rport_del(vha, fcport, defer); |
|---|
| 3910 | + qla2x00_schedule_rport_del(vha, fcport); |
|---|
| 3822 | 3911 | } |
|---|
| 3823 | 3912 | /* |
|---|
| 3824 | 3913 | * We may need to retry the login, so don't change the state of the |
|---|
| .. | .. |
|---|
| 3833 | 3922 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); |
|---|
| 3834 | 3923 | } |
|---|
| 3835 | 3924 | |
|---|
| 3836 | | -/* |
|---|
| 3837 | | - * qla2x00_mark_all_devices_lost |
|---|
| 3838 | | - * Updates fcport state when device goes offline. |
|---|
| 3839 | | - * |
|---|
| 3840 | | - * Input: |
|---|
| 3841 | | - * ha = adapter block pointer. |
|---|
| 3842 | | - * fcport = port structure pointer. |
|---|
| 3843 | | - * |
|---|
| 3844 | | - * Return: |
|---|
| 3845 | | - * None. |
|---|
| 3846 | | - * |
|---|
| 3847 | | - * Context: |
|---|
| 3848 | | - */ |
|---|
| 3849 | 3925 | void |
|---|
| 3850 | | -qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) |
|---|
| 3926 | +qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha) |
|---|
| 3851 | 3927 | { |
|---|
| 3852 | 3928 | fc_port_t *fcport; |
|---|
| 3853 | 3929 | |
|---|
| .. | .. |
|---|
| 3855 | 3931 | "Mark all dev lost\n"); |
|---|
| 3856 | 3932 | |
|---|
| 3857 | 3933 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
|---|
| 3934 | + if (fcport->loop_id != FC_NO_LOOP_ID && |
|---|
| 3935 | + (fcport->flags & FCF_FCP2_DEVICE) && |
|---|
| 3936 | + fcport->port_type == FCT_TARGET && |
|---|
| 3937 | + !qla2x00_reset_active(vha)) { |
|---|
| 3938 | + ql_dbg(ql_dbg_disc, vha, 0x211a, |
|---|
| 3939 | + "Delaying session delete for FCP2 flags 0x%x port_type = 0x%x port_id=%06x %phC", |
|---|
| 3940 | + fcport->flags, fcport->port_type, |
|---|
| 3941 | + fcport->d_id.b24, fcport->port_name); |
|---|
| 3942 | + continue; |
|---|
| 3943 | + } |
|---|
| 3858 | 3944 | fcport->scan_state = 0; |
|---|
| 3859 | 3945 | qlt_schedule_sess_for_deletion(fcport); |
|---|
| 3860 | | - |
|---|
| 3861 | | - if (vha->vp_idx != 0 && vha->vp_idx != fcport->vha->vp_idx) |
|---|
| 3862 | | - continue; |
|---|
| 3863 | | - |
|---|
| 3864 | | - /* |
|---|
| 3865 | | - * No point in marking the device as lost, if the device is |
|---|
| 3866 | | - * already DEAD. |
|---|
| 3867 | | - */ |
|---|
| 3868 | | - if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) |
|---|
| 3869 | | - continue; |
|---|
| 3870 | | - if (atomic_read(&fcport->state) == FCS_ONLINE) { |
|---|
| 3871 | | - qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); |
|---|
| 3872 | | - if (defer) |
|---|
| 3873 | | - qla2x00_schedule_rport_del(vha, fcport, defer); |
|---|
| 3874 | | - else if (vha->vp_idx == fcport->vha->vp_idx) |
|---|
| 3875 | | - qla2x00_schedule_rport_del(vha, fcport, defer); |
|---|
| 3876 | | - } |
|---|
| 3877 | 3946 | } |
|---|
| 3947 | +} |
|---|
| 3948 | + |
|---|
| 3949 | +static void qla2x00_set_reserved_loop_ids(struct qla_hw_data *ha) |
|---|
| 3950 | +{ |
|---|
| 3951 | + int i; |
|---|
| 3952 | + |
|---|
| 3953 | + if (IS_FWI2_CAPABLE(ha)) |
|---|
| 3954 | + return; |
|---|
| 3955 | + |
|---|
| 3956 | + for (i = 0; i < SNS_FIRST_LOOP_ID; i++) |
|---|
| 3957 | + set_bit(i, ha->loop_id_map); |
|---|
| 3958 | + set_bit(MANAGEMENT_SERVER, ha->loop_id_map); |
|---|
| 3959 | + set_bit(BROADCAST, ha->loop_id_map); |
|---|
| 3878 | 3960 | } |
|---|
| 3879 | 3961 | |
|---|
| 3880 | 3962 | /* |
|---|
| .. | .. |
|---|
| 3958 | 4040 | "Failed to allocate memory for fcp_cmnd_dma_pool.\n"); |
|---|
| 3959 | 4041 | goto fail_dl_dma_pool; |
|---|
| 3960 | 4042 | } |
|---|
| 4043 | + |
|---|
| 4044 | + if (ql2xenabledif) { |
|---|
| 4045 | + u64 bufsize = DIF_BUNDLING_DMA_POOL_SIZE; |
|---|
| 4046 | + struct dsd_dma *dsd, *nxt; |
|---|
| 4047 | + uint i; |
|---|
| 4048 | + /* Creata a DMA pool of buffers for DIF bundling */ |
|---|
| 4049 | + ha->dif_bundl_pool = dma_pool_create(name, |
|---|
| 4050 | + &ha->pdev->dev, DIF_BUNDLING_DMA_POOL_SIZE, 8, 0); |
|---|
| 4051 | + if (!ha->dif_bundl_pool) { |
|---|
| 4052 | + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0024, |
|---|
| 4053 | + "%s: failed create dif_bundl_pool\n", |
|---|
| 4054 | + __func__); |
|---|
| 4055 | + goto fail_dif_bundl_dma_pool; |
|---|
| 4056 | + } |
|---|
| 4057 | + |
|---|
| 4058 | + INIT_LIST_HEAD(&ha->pool.good.head); |
|---|
| 4059 | + INIT_LIST_HEAD(&ha->pool.unusable.head); |
|---|
| 4060 | + ha->pool.good.count = 0; |
|---|
| 4061 | + ha->pool.unusable.count = 0; |
|---|
| 4062 | + for (i = 0; i < 128; i++) { |
|---|
| 4063 | + dsd = kzalloc(sizeof(*dsd), GFP_ATOMIC); |
|---|
| 4064 | + if (!dsd) { |
|---|
| 4065 | + ql_dbg_pci(ql_dbg_init, ha->pdev, |
|---|
| 4066 | + 0xe0ee, "%s: failed alloc dsd\n", |
|---|
| 4067 | + __func__); |
|---|
| 4068 | + return -ENOMEM; |
|---|
| 4069 | + } |
|---|
| 4070 | + ha->dif_bundle_kallocs++; |
|---|
| 4071 | + |
|---|
| 4072 | + dsd->dsd_addr = dma_pool_alloc( |
|---|
| 4073 | + ha->dif_bundl_pool, GFP_ATOMIC, |
|---|
| 4074 | + &dsd->dsd_list_dma); |
|---|
| 4075 | + if (!dsd->dsd_addr) { |
|---|
| 4076 | + ql_dbg_pci(ql_dbg_init, ha->pdev, |
|---|
| 4077 | + 0xe0ee, |
|---|
| 4078 | + "%s: failed alloc ->dsd_addr\n", |
|---|
| 4079 | + __func__); |
|---|
| 4080 | + kfree(dsd); |
|---|
| 4081 | + ha->dif_bundle_kallocs--; |
|---|
| 4082 | + continue; |
|---|
| 4083 | + } |
|---|
| 4084 | + ha->dif_bundle_dma_allocs++; |
|---|
| 4085 | + |
|---|
| 4086 | + /* |
|---|
| 4087 | + * if DMA buffer crosses 4G boundary, |
|---|
| 4088 | + * put it on bad list |
|---|
| 4089 | + */ |
|---|
| 4090 | + if (MSD(dsd->dsd_list_dma) ^ |
|---|
| 4091 | + MSD(dsd->dsd_list_dma + bufsize)) { |
|---|
| 4092 | + list_add_tail(&dsd->list, |
|---|
| 4093 | + &ha->pool.unusable.head); |
|---|
| 4094 | + ha->pool.unusable.count++; |
|---|
| 4095 | + } else { |
|---|
| 4096 | + list_add_tail(&dsd->list, |
|---|
| 4097 | + &ha->pool.good.head); |
|---|
| 4098 | + ha->pool.good.count++; |
|---|
| 4099 | + } |
|---|
| 4100 | + } |
|---|
| 4101 | + |
|---|
| 4102 | + /* return the good ones back to the pool */ |
|---|
| 4103 | + list_for_each_entry_safe(dsd, nxt, |
|---|
| 4104 | + &ha->pool.good.head, list) { |
|---|
| 4105 | + list_del(&dsd->list); |
|---|
| 4106 | + dma_pool_free(ha->dif_bundl_pool, |
|---|
| 4107 | + dsd->dsd_addr, dsd->dsd_list_dma); |
|---|
| 4108 | + ha->dif_bundle_dma_allocs--; |
|---|
| 4109 | + kfree(dsd); |
|---|
| 4110 | + ha->dif_bundle_kallocs--; |
|---|
| 4111 | + } |
|---|
| 4112 | + |
|---|
| 4113 | + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0024, |
|---|
| 4114 | + "%s: dif dma pool (good=%u unusable=%u)\n", |
|---|
| 4115 | + __func__, ha->pool.good.count, |
|---|
| 4116 | + ha->pool.unusable.count); |
|---|
| 4117 | + } |
|---|
| 4118 | + |
|---|
| 3961 | 4119 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0025, |
|---|
| 3962 | | - "dl_dma_pool=%p fcp_cmnd_dma_pool=%p.\n", |
|---|
| 3963 | | - ha->dl_dma_pool, ha->fcp_cmnd_dma_pool); |
|---|
| 4120 | + "dl_dma_pool=%p fcp_cmnd_dma_pool=%p dif_bundl_pool=%p.\n", |
|---|
| 4121 | + ha->dl_dma_pool, ha->fcp_cmnd_dma_pool, |
|---|
| 4122 | + ha->dif_bundl_pool); |
|---|
| 3964 | 4123 | } |
|---|
| 3965 | 4124 | |
|---|
| 3966 | 4125 | /* Allocate memory for SNS commands */ |
|---|
| .. | .. |
|---|
| 4042 | 4201 | ha->npiv_info = NULL; |
|---|
| 4043 | 4202 | |
|---|
| 4044 | 4203 | /* Get consistent memory allocated for EX-INIT-CB. */ |
|---|
| 4045 | | - if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { |
|---|
| 4204 | + if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
|---|
| 4205 | + IS_QLA28XX(ha)) { |
|---|
| 4046 | 4206 | ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, |
|---|
| 4047 | 4207 | &ha->ex_init_cb_dma); |
|---|
| 4048 | 4208 | if (!ha->ex_init_cb) |
|---|
| 4049 | 4209 | goto fail_ex_init_cb; |
|---|
| 4050 | 4210 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x002e, |
|---|
| 4051 | 4211 | "ex_init_cb=%p.\n", ha->ex_init_cb); |
|---|
| 4212 | + } |
|---|
| 4213 | + |
|---|
| 4214 | + /* Get consistent memory allocated for Special Features-CB. */ |
|---|
| 4215 | + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
|---|
| 4216 | + ha->sf_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, |
|---|
| 4217 | + &ha->sf_init_cb_dma); |
|---|
| 4218 | + if (!ha->sf_init_cb) |
|---|
| 4219 | + goto fail_sf_init_cb; |
|---|
| 4220 | + memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb)); |
|---|
| 4221 | + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199, |
|---|
| 4222 | + "sf_init_cb=%p.\n", ha->sf_init_cb); |
|---|
| 4052 | 4223 | } |
|---|
| 4053 | 4224 | |
|---|
| 4054 | 4225 | INIT_LIST_HEAD(&ha->gbl_dsd_list); |
|---|
| .. | .. |
|---|
| 4085 | 4256 | goto fail_sfp_data; |
|---|
| 4086 | 4257 | } |
|---|
| 4087 | 4258 | |
|---|
| 4259 | + ha->flt = dma_alloc_coherent(&ha->pdev->dev, |
|---|
| 4260 | + sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, &ha->flt_dma, |
|---|
| 4261 | + GFP_KERNEL); |
|---|
| 4262 | + if (!ha->flt) { |
|---|
| 4263 | + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011b, |
|---|
| 4264 | + "Unable to allocate memory for FLT.\n"); |
|---|
| 4265 | + goto fail_flt_buffer; |
|---|
| 4266 | + } |
|---|
| 4267 | + |
|---|
| 4088 | 4268 | return 0; |
|---|
| 4089 | 4269 | |
|---|
| 4270 | +fail_flt_buffer: |
|---|
| 4271 | + dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, |
|---|
| 4272 | + ha->sfp_data, ha->sfp_data_dma); |
|---|
| 4090 | 4273 | fail_sfp_data: |
|---|
| 4091 | 4274 | kfree(ha->loop_id_map); |
|---|
| 4092 | 4275 | fail_loop_id_map: |
|---|
| 4093 | 4276 | dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); |
|---|
| 4094 | 4277 | fail_async_pd: |
|---|
| 4278 | + dma_pool_free(ha->s_dma_pool, ha->sf_init_cb, ha->sf_init_cb_dma); |
|---|
| 4279 | +fail_sf_init_cb: |
|---|
| 4095 | 4280 | dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); |
|---|
| 4096 | 4281 | fail_ex_init_cb: |
|---|
| 4097 | 4282 | kfree(ha->npiv_info); |
|---|
| .. | .. |
|---|
| 4125 | 4310 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
|---|
| 4126 | 4311 | ha->sns_cmd, ha->sns_cmd_dma); |
|---|
| 4127 | 4312 | fail_dma_pool: |
|---|
| 4313 | + if (ql2xenabledif) { |
|---|
| 4314 | + struct dsd_dma *dsd, *nxt; |
|---|
| 4315 | + |
|---|
| 4316 | + list_for_each_entry_safe(dsd, nxt, &ha->pool.unusable.head, |
|---|
| 4317 | + list) { |
|---|
| 4318 | + list_del(&dsd->list); |
|---|
| 4319 | + dma_pool_free(ha->dif_bundl_pool, dsd->dsd_addr, |
|---|
| 4320 | + dsd->dsd_list_dma); |
|---|
| 4321 | + ha->dif_bundle_dma_allocs--; |
|---|
| 4322 | + kfree(dsd); |
|---|
| 4323 | + ha->dif_bundle_kallocs--; |
|---|
| 4324 | + ha->pool.unusable.count--; |
|---|
| 4325 | + } |
|---|
| 4326 | + dma_pool_destroy(ha->dif_bundl_pool); |
|---|
| 4327 | + ha->dif_bundl_pool = NULL; |
|---|
| 4328 | + } |
|---|
| 4329 | + |
|---|
| 4330 | +fail_dif_bundl_dma_pool: |
|---|
| 4128 | 4331 | if (IS_QLA82XX(ha) || ql2xenabledif) { |
|---|
| 4129 | 4332 | dma_pool_destroy(ha->fcp_cmnd_dma_pool); |
|---|
| 4130 | 4333 | ha->fcp_cmnd_dma_pool = NULL; |
|---|
| .. | .. |
|---|
| 4141 | 4344 | kfree(ha->nvram); |
|---|
| 4142 | 4345 | ha->nvram = NULL; |
|---|
| 4143 | 4346 | fail_free_ctx_mempool: |
|---|
| 4144 | | - if (ha->ctx_mempool) |
|---|
| 4145 | | - mempool_destroy(ha->ctx_mempool); |
|---|
| 4347 | + mempool_destroy(ha->ctx_mempool); |
|---|
| 4146 | 4348 | ha->ctx_mempool = NULL; |
|---|
| 4147 | 4349 | fail_free_srb_mempool: |
|---|
| 4148 | | - if (ha->srb_mempool) |
|---|
| 4149 | | - mempool_destroy(ha->srb_mempool); |
|---|
| 4350 | + mempool_destroy(ha->srb_mempool); |
|---|
| 4150 | 4351 | ha->srb_mempool = NULL; |
|---|
| 4151 | 4352 | fail_free_gid_list: |
|---|
| 4152 | 4353 | dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), |
|---|
| .. | .. |
|---|
| 4171 | 4372 | qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha) |
|---|
| 4172 | 4373 | { |
|---|
| 4173 | 4374 | int rval; |
|---|
| 4174 | | - uint16_t size, max_cnt, temp; |
|---|
| 4375 | + uint16_t size, max_cnt; |
|---|
| 4376 | + uint32_t temp; |
|---|
| 4175 | 4377 | struct qla_hw_data *ha = vha->hw; |
|---|
| 4176 | 4378 | |
|---|
| 4177 | 4379 | /* Return if we don't need to alloacate any extended logins */ |
|---|
| 4178 | | - if (!ql2xexlogins) |
|---|
| 4380 | + if (ql2xexlogins <= MAX_FIBRE_DEVICES_2400) |
|---|
| 4179 | 4381 | return QLA_SUCCESS; |
|---|
| 4180 | 4382 | |
|---|
| 4181 | 4383 | if (!IS_EXLOGIN_OFFLD_CAPABLE(ha)) |
|---|
| .. | .. |
|---|
| 4246 | 4448 | qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt) |
|---|
| 4247 | 4449 | { |
|---|
| 4248 | 4450 | u32 temp; |
|---|
| 4451 | + struct init_cb_81xx *icb = (struct init_cb_81xx *)&vha->hw->init_cb; |
|---|
| 4249 | 4452 | *ret_cnt = FW_DEF_EXCHANGES_CNT; |
|---|
| 4250 | 4453 | |
|---|
| 4251 | 4454 | if (max_cnt > vha->hw->max_exchg) |
|---|
| 4252 | 4455 | max_cnt = vha->hw->max_exchg; |
|---|
| 4253 | 4456 | |
|---|
| 4254 | 4457 | if (qla_ini_mode_enabled(vha)) { |
|---|
| 4255 | | - if (ql2xiniexchg > max_cnt) |
|---|
| 4256 | | - ql2xiniexchg = max_cnt; |
|---|
| 4458 | + if (vha->ql2xiniexchg > max_cnt) |
|---|
| 4459 | + vha->ql2xiniexchg = max_cnt; |
|---|
| 4257 | 4460 | |
|---|
| 4258 | | - if (ql2xiniexchg > FW_DEF_EXCHANGES_CNT) |
|---|
| 4259 | | - *ret_cnt = ql2xiniexchg; |
|---|
| 4461 | + if (vha->ql2xiniexchg > FW_DEF_EXCHANGES_CNT) |
|---|
| 4462 | + *ret_cnt = vha->ql2xiniexchg; |
|---|
| 4463 | + |
|---|
| 4260 | 4464 | } else if (qla_tgt_mode_enabled(vha)) { |
|---|
| 4261 | | - if (ql2xexchoffld > max_cnt) |
|---|
| 4262 | | - ql2xexchoffld = max_cnt; |
|---|
| 4465 | + if (vha->ql2xexchoffld > max_cnt) { |
|---|
| 4466 | + vha->ql2xexchoffld = max_cnt; |
|---|
| 4467 | + icb->exchange_count = cpu_to_le16(vha->ql2xexchoffld); |
|---|
| 4468 | + } |
|---|
| 4263 | 4469 | |
|---|
| 4264 | | - if (ql2xexchoffld > FW_DEF_EXCHANGES_CNT) |
|---|
| 4265 | | - *ret_cnt = ql2xexchoffld; |
|---|
| 4470 | + if (vha->ql2xexchoffld > FW_DEF_EXCHANGES_CNT) |
|---|
| 4471 | + *ret_cnt = vha->ql2xexchoffld; |
|---|
| 4266 | 4472 | } else if (qla_dual_mode_enabled(vha)) { |
|---|
| 4267 | | - temp = ql2xiniexchg + ql2xexchoffld; |
|---|
| 4473 | + temp = vha->ql2xiniexchg + vha->ql2xexchoffld; |
|---|
| 4268 | 4474 | if (temp > max_cnt) { |
|---|
| 4269 | | - ql2xiniexchg -= (temp - max_cnt)/2; |
|---|
| 4270 | | - ql2xexchoffld -= (((temp - max_cnt)/2) + 1); |
|---|
| 4475 | + vha->ql2xiniexchg -= (temp - max_cnt)/2; |
|---|
| 4476 | + vha->ql2xexchoffld -= (((temp - max_cnt)/2) + 1); |
|---|
| 4271 | 4477 | temp = max_cnt; |
|---|
| 4478 | + icb->exchange_count = cpu_to_le16(vha->ql2xexchoffld); |
|---|
| 4272 | 4479 | } |
|---|
| 4273 | 4480 | |
|---|
| 4274 | 4481 | if (temp > FW_DEF_EXCHANGES_CNT) |
|---|
| .. | .. |
|---|
| 4306 | 4513 | |
|---|
| 4307 | 4514 | if (totsz != ha->exchoffld_size) { |
|---|
| 4308 | 4515 | qla2x00_free_exchoffld_buffer(ha); |
|---|
| 4516 | + if (actual_cnt <= FW_DEF_EXCHANGES_CNT) { |
|---|
| 4517 | + ha->exchoffld_size = 0; |
|---|
| 4518 | + ha->flags.exchoffld_enabled = 0; |
|---|
| 4519 | + return QLA_SUCCESS; |
|---|
| 4520 | + } |
|---|
| 4521 | + |
|---|
| 4309 | 4522 | ha->exchoffld_size = totsz; |
|---|
| 4310 | 4523 | |
|---|
| 4311 | 4524 | ql_log(ql_log_info, vha, 0xd016, |
|---|
| .. | .. |
|---|
| 4338 | 4551 | |
|---|
| 4339 | 4552 | return -ENOMEM; |
|---|
| 4340 | 4553 | } |
|---|
| 4554 | + } else if (!ha->exchoffld_buf || (actual_cnt <= FW_DEF_EXCHANGES_CNT)) { |
|---|
| 4555 | + /* pathological case */ |
|---|
| 4556 | + qla2x00_free_exchoffld_buffer(ha); |
|---|
| 4557 | + ha->exchoffld_size = 0; |
|---|
| 4558 | + ha->flags.exchoffld_enabled = 0; |
|---|
| 4559 | + ql_log(ql_log_info, vha, 0xd016, |
|---|
| 4560 | + "Exchange offload not enable: offld size=%d, actual count=%d entry sz=0x%x, total sz=0x%x.\n", |
|---|
| 4561 | + ha->exchoffld_size, actual_cnt, size, totsz); |
|---|
| 4562 | + return 0; |
|---|
| 4341 | 4563 | } |
|---|
| 4342 | 4564 | |
|---|
| 4343 | 4565 | /* Now configure the dma buffer */ |
|---|
| .. | .. |
|---|
| 4353 | 4575 | if (qla_ini_mode_enabled(vha)) |
|---|
| 4354 | 4576 | icb->exchange_count = 0; |
|---|
| 4355 | 4577 | else |
|---|
| 4356 | | - icb->exchange_count = cpu_to_le16(ql2xexchoffld); |
|---|
| 4578 | + icb->exchange_count = cpu_to_le16(vha->ql2xexchoffld); |
|---|
| 4357 | 4579 | } |
|---|
| 4358 | 4580 | |
|---|
| 4359 | 4581 | return rval; |
|---|
| .. | .. |
|---|
| 4386 | 4608 | static void |
|---|
| 4387 | 4609 | qla2x00_free_fw_dump(struct qla_hw_data *ha) |
|---|
| 4388 | 4610 | { |
|---|
| 4611 | + struct fwdt *fwdt = ha->fwdt; |
|---|
| 4612 | + uint j; |
|---|
| 4613 | + |
|---|
| 4389 | 4614 | if (ha->fce) |
|---|
| 4390 | 4615 | dma_free_coherent(&ha->pdev->dev, |
|---|
| 4391 | 4616 | FCE_SIZE, ha->fce, ha->fce_dma); |
|---|
| .. | .. |
|---|
| 4396 | 4621 | |
|---|
| 4397 | 4622 | if (ha->fw_dump) |
|---|
| 4398 | 4623 | vfree(ha->fw_dump); |
|---|
| 4399 | | - if (ha->fw_dump_template) |
|---|
| 4400 | | - vfree(ha->fw_dump_template); |
|---|
| 4401 | 4624 | |
|---|
| 4402 | 4625 | ha->fce = NULL; |
|---|
| 4403 | 4626 | ha->fce_dma = 0; |
|---|
| 4627 | + ha->flags.fce_enabled = 0; |
|---|
| 4404 | 4628 | ha->eft = NULL; |
|---|
| 4405 | 4629 | ha->eft_dma = 0; |
|---|
| 4406 | | - ha->fw_dumped = 0; |
|---|
| 4630 | + ha->fw_dumped = false; |
|---|
| 4407 | 4631 | ha->fw_dump_cap_flags = 0; |
|---|
| 4408 | 4632 | ha->fw_dump_reading = 0; |
|---|
| 4409 | 4633 | ha->fw_dump = NULL; |
|---|
| 4410 | 4634 | ha->fw_dump_len = 0; |
|---|
| 4411 | | - ha->fw_dump_template = NULL; |
|---|
| 4412 | | - ha->fw_dump_template_len = 0; |
|---|
| 4635 | + |
|---|
| 4636 | + for (j = 0; j < 2; j++, fwdt++) { |
|---|
| 4637 | + if (fwdt->template) |
|---|
| 4638 | + vfree(fwdt->template); |
|---|
| 4639 | + fwdt->template = NULL; |
|---|
| 4640 | + fwdt->length = 0; |
|---|
| 4641 | + } |
|---|
| 4413 | 4642 | } |
|---|
| 4414 | 4643 | |
|---|
| 4415 | 4644 | /* |
|---|
| .. | .. |
|---|
| 4427 | 4656 | if (ha->mctp_dump) |
|---|
| 4428 | 4657 | dma_free_coherent(&ha->pdev->dev, MCTP_DUMP_SIZE, ha->mctp_dump, |
|---|
| 4429 | 4658 | ha->mctp_dump_dma); |
|---|
| 4659 | + ha->mctp_dump = NULL; |
|---|
| 4430 | 4660 | |
|---|
| 4431 | | - if (ha->srb_mempool) |
|---|
| 4432 | | - mempool_destroy(ha->srb_mempool); |
|---|
| 4661 | + mempool_destroy(ha->srb_mempool); |
|---|
| 4662 | + ha->srb_mempool = NULL; |
|---|
| 4433 | 4663 | |
|---|
| 4434 | 4664 | if (ha->dcbx_tlv) |
|---|
| 4435 | 4665 | dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE, |
|---|
| 4436 | 4666 | ha->dcbx_tlv, ha->dcbx_tlv_dma); |
|---|
| 4667 | + ha->dcbx_tlv = NULL; |
|---|
| 4437 | 4668 | |
|---|
| 4438 | 4669 | if (ha->xgmac_data) |
|---|
| 4439 | 4670 | dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE, |
|---|
| 4440 | 4671 | ha->xgmac_data, ha->xgmac_data_dma); |
|---|
| 4672 | + ha->xgmac_data = NULL; |
|---|
| 4441 | 4673 | |
|---|
| 4442 | 4674 | if (ha->sns_cmd) |
|---|
| 4443 | 4675 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
|---|
| 4444 | 4676 | ha->sns_cmd, ha->sns_cmd_dma); |
|---|
| 4677 | + ha->sns_cmd = NULL; |
|---|
| 4678 | + ha->sns_cmd_dma = 0; |
|---|
| 4445 | 4679 | |
|---|
| 4446 | 4680 | if (ha->ct_sns) |
|---|
| 4447 | 4681 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), |
|---|
| 4448 | 4682 | ha->ct_sns, ha->ct_sns_dma); |
|---|
| 4683 | + ha->ct_sns = NULL; |
|---|
| 4684 | + ha->ct_sns_dma = 0; |
|---|
| 4449 | 4685 | |
|---|
| 4450 | 4686 | if (ha->sfp_data) |
|---|
| 4451 | 4687 | dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, ha->sfp_data, |
|---|
| 4452 | 4688 | ha->sfp_data_dma); |
|---|
| 4689 | + ha->sfp_data = NULL; |
|---|
| 4690 | + |
|---|
| 4691 | + if (ha->flt) |
|---|
| 4692 | + dma_free_coherent(&ha->pdev->dev, |
|---|
| 4693 | + sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, |
|---|
| 4694 | + ha->flt, ha->flt_dma); |
|---|
| 4695 | + ha->flt = NULL; |
|---|
| 4696 | + ha->flt_dma = 0; |
|---|
| 4453 | 4697 | |
|---|
| 4454 | 4698 | if (ha->ms_iocb) |
|---|
| 4455 | 4699 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); |
|---|
| 4700 | + ha->ms_iocb = NULL; |
|---|
| 4701 | + ha->ms_iocb_dma = 0; |
|---|
| 4702 | + |
|---|
| 4703 | + if (ha->sf_init_cb) |
|---|
| 4704 | + dma_pool_free(ha->s_dma_pool, |
|---|
| 4705 | + ha->sf_init_cb, ha->sf_init_cb_dma); |
|---|
| 4456 | 4706 | |
|---|
| 4457 | 4707 | if (ha->ex_init_cb) |
|---|
| 4458 | 4708 | dma_pool_free(ha->s_dma_pool, |
|---|
| 4459 | 4709 | ha->ex_init_cb, ha->ex_init_cb_dma); |
|---|
| 4710 | + ha->ex_init_cb = NULL; |
|---|
| 4711 | + ha->ex_init_cb_dma = 0; |
|---|
| 4460 | 4712 | |
|---|
| 4461 | 4713 | if (ha->async_pd) |
|---|
| 4462 | 4714 | dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); |
|---|
| 4715 | + ha->async_pd = NULL; |
|---|
| 4716 | + ha->async_pd_dma = 0; |
|---|
| 4463 | 4717 | |
|---|
| 4464 | | - if (ha->s_dma_pool) |
|---|
| 4465 | | - dma_pool_destroy(ha->s_dma_pool); |
|---|
| 4718 | + dma_pool_destroy(ha->s_dma_pool); |
|---|
| 4719 | + ha->s_dma_pool = NULL; |
|---|
| 4466 | 4720 | |
|---|
| 4467 | 4721 | if (ha->gid_list) |
|---|
| 4468 | 4722 | dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), |
|---|
| 4469 | 4723 | ha->gid_list, ha->gid_list_dma); |
|---|
| 4724 | + ha->gid_list = NULL; |
|---|
| 4725 | + ha->gid_list_dma = 0; |
|---|
| 4470 | 4726 | |
|---|
| 4471 | 4727 | if (IS_QLA82XX(ha)) { |
|---|
| 4472 | 4728 | if (!list_empty(&ha->gbl_dsd_list)) { |
|---|
| .. | .. |
|---|
| 4483 | 4739 | } |
|---|
| 4484 | 4740 | } |
|---|
| 4485 | 4741 | |
|---|
| 4486 | | - if (ha->dl_dma_pool) |
|---|
| 4487 | | - dma_pool_destroy(ha->dl_dma_pool); |
|---|
| 4742 | + dma_pool_destroy(ha->dl_dma_pool); |
|---|
| 4743 | + ha->dl_dma_pool = NULL; |
|---|
| 4488 | 4744 | |
|---|
| 4489 | | - if (ha->fcp_cmnd_dma_pool) |
|---|
| 4490 | | - dma_pool_destroy(ha->fcp_cmnd_dma_pool); |
|---|
| 4745 | + dma_pool_destroy(ha->fcp_cmnd_dma_pool); |
|---|
| 4746 | + ha->fcp_cmnd_dma_pool = NULL; |
|---|
| 4491 | 4747 | |
|---|
| 4492 | | - if (ha->ctx_mempool) |
|---|
| 4493 | | - mempool_destroy(ha->ctx_mempool); |
|---|
| 4748 | + mempool_destroy(ha->ctx_mempool); |
|---|
| 4749 | + ha->ctx_mempool = NULL; |
|---|
| 4750 | + |
|---|
| 4751 | + if (ql2xenabledif && ha->dif_bundl_pool) { |
|---|
| 4752 | + struct dsd_dma *dsd, *nxt; |
|---|
| 4753 | + |
|---|
| 4754 | + list_for_each_entry_safe(dsd, nxt, &ha->pool.unusable.head, |
|---|
| 4755 | + list) { |
|---|
| 4756 | + list_del(&dsd->list); |
|---|
| 4757 | + dma_pool_free(ha->dif_bundl_pool, dsd->dsd_addr, |
|---|
| 4758 | + dsd->dsd_list_dma); |
|---|
| 4759 | + ha->dif_bundle_dma_allocs--; |
|---|
| 4760 | + kfree(dsd); |
|---|
| 4761 | + ha->dif_bundle_kallocs--; |
|---|
| 4762 | + ha->pool.unusable.count--; |
|---|
| 4763 | + } |
|---|
| 4764 | + list_for_each_entry_safe(dsd, nxt, &ha->pool.good.head, list) { |
|---|
| 4765 | + list_del(&dsd->list); |
|---|
| 4766 | + dma_pool_free(ha->dif_bundl_pool, dsd->dsd_addr, |
|---|
| 4767 | + dsd->dsd_list_dma); |
|---|
| 4768 | + ha->dif_bundle_dma_allocs--; |
|---|
| 4769 | + kfree(dsd); |
|---|
| 4770 | + ha->dif_bundle_kallocs--; |
|---|
| 4771 | + } |
|---|
| 4772 | + } |
|---|
| 4773 | + |
|---|
| 4774 | + dma_pool_destroy(ha->dif_bundl_pool); |
|---|
| 4775 | + ha->dif_bundl_pool = NULL; |
|---|
| 4494 | 4776 | |
|---|
| 4495 | 4777 | qlt_mem_free(ha); |
|---|
| 4496 | 4778 | |
|---|
| 4497 | 4779 | if (ha->init_cb) |
|---|
| 4498 | 4780 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, |
|---|
| 4499 | 4781 | ha->init_cb, ha->init_cb_dma); |
|---|
| 4500 | | - |
|---|
| 4501 | | - vfree(ha->optrom_buffer); |
|---|
| 4502 | | - kfree(ha->nvram); |
|---|
| 4503 | | - kfree(ha->npiv_info); |
|---|
| 4504 | | - kfree(ha->swl); |
|---|
| 4505 | | - kfree(ha->loop_id_map); |
|---|
| 4506 | | - |
|---|
| 4507 | | - ha->srb_mempool = NULL; |
|---|
| 4508 | | - ha->ctx_mempool = NULL; |
|---|
| 4509 | | - ha->sns_cmd = NULL; |
|---|
| 4510 | | - ha->sns_cmd_dma = 0; |
|---|
| 4511 | | - ha->ct_sns = NULL; |
|---|
| 4512 | | - ha->ct_sns_dma = 0; |
|---|
| 4513 | | - ha->ms_iocb = NULL; |
|---|
| 4514 | | - ha->ms_iocb_dma = 0; |
|---|
| 4515 | 4782 | ha->init_cb = NULL; |
|---|
| 4516 | 4783 | ha->init_cb_dma = 0; |
|---|
| 4517 | | - ha->ex_init_cb = NULL; |
|---|
| 4518 | | - ha->ex_init_cb_dma = 0; |
|---|
| 4519 | | - ha->async_pd = NULL; |
|---|
| 4520 | | - ha->async_pd_dma = 0; |
|---|
| 4521 | | - ha->loop_id_map = NULL; |
|---|
| 4522 | | - ha->npiv_info = NULL; |
|---|
| 4784 | + |
|---|
| 4785 | + vfree(ha->optrom_buffer); |
|---|
| 4523 | 4786 | ha->optrom_buffer = NULL; |
|---|
| 4524 | | - ha->swl = NULL; |
|---|
| 4787 | + kfree(ha->nvram); |
|---|
| 4525 | 4788 | ha->nvram = NULL; |
|---|
| 4526 | | - ha->mctp_dump = NULL; |
|---|
| 4527 | | - ha->dcbx_tlv = NULL; |
|---|
| 4528 | | - ha->xgmac_data = NULL; |
|---|
| 4529 | | - ha->sfp_data = NULL; |
|---|
| 4530 | | - |
|---|
| 4531 | | - ha->s_dma_pool = NULL; |
|---|
| 4532 | | - ha->dl_dma_pool = NULL; |
|---|
| 4533 | | - ha->fcp_cmnd_dma_pool = NULL; |
|---|
| 4534 | | - |
|---|
| 4535 | | - ha->gid_list = NULL; |
|---|
| 4536 | | - ha->gid_list_dma = 0; |
|---|
| 4537 | | - |
|---|
| 4538 | | - ha->tgt.atio_ring = NULL; |
|---|
| 4539 | | - ha->tgt.atio_dma = 0; |
|---|
| 4540 | | - ha->tgt.tgt_vp_map = NULL; |
|---|
| 4789 | + kfree(ha->npiv_info); |
|---|
| 4790 | + ha->npiv_info = NULL; |
|---|
| 4791 | + kfree(ha->swl); |
|---|
| 4792 | + ha->swl = NULL; |
|---|
| 4793 | + kfree(ha->loop_id_map); |
|---|
| 4794 | + ha->sf_init_cb = NULL; |
|---|
| 4795 | + ha->sf_init_cb_dma = 0; |
|---|
| 4796 | + ha->loop_id_map = NULL; |
|---|
| 4541 | 4797 | } |
|---|
| 4542 | 4798 | |
|---|
| 4543 | 4799 | struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, |
|---|
| .. | .. |
|---|
| 4561 | 4817 | vha->host_no = host->host_no; |
|---|
| 4562 | 4818 | vha->hw = ha; |
|---|
| 4563 | 4819 | |
|---|
| 4820 | + vha->qlini_mode = ql2x_ini_mode; |
|---|
| 4821 | + vha->ql2xexchoffld = ql2xexchoffld; |
|---|
| 4822 | + vha->ql2xiniexchg = ql2xiniexchg; |
|---|
| 4823 | + |
|---|
| 4564 | 4824 | INIT_LIST_HEAD(&vha->vp_fcports); |
|---|
| 4565 | 4825 | INIT_LIST_HEAD(&vha->work_list); |
|---|
| 4566 | 4826 | INIT_LIST_HEAD(&vha->list); |
|---|
| .. | .. |
|---|
| 4570 | 4830 | INIT_LIST_HEAD(&vha->plogi_ack_list); |
|---|
| 4571 | 4831 | INIT_LIST_HEAD(&vha->qp_list); |
|---|
| 4572 | 4832 | INIT_LIST_HEAD(&vha->gnl.fcports); |
|---|
| 4573 | | - INIT_LIST_HEAD(&vha->nvme_rport_list); |
|---|
| 4574 | 4833 | INIT_LIST_HEAD(&vha->gpnid_list); |
|---|
| 4575 | 4834 | INIT_WORK(&vha->iocb_work, qla2x00_iocb_work_fn); |
|---|
| 4835 | + |
|---|
| 4836 | + INIT_LIST_HEAD(&vha->purex_list.head); |
|---|
| 4837 | + spin_lock_init(&vha->purex_list.lock); |
|---|
| 4576 | 4838 | |
|---|
| 4577 | 4839 | spin_lock_init(&vha->work_lock); |
|---|
| 4578 | 4840 | spin_lock_init(&vha->cmd_list_lock); |
|---|
| .. | .. |
|---|
| 4586 | 4848 | if (!vha->gnl.l) { |
|---|
| 4587 | 4849 | ql_log(ql_log_fatal, vha, 0xd04a, |
|---|
| 4588 | 4850 | "Alloc failed for name list.\n"); |
|---|
| 4589 | | - scsi_remove_host(vha->host); |
|---|
| 4851 | + scsi_host_put(vha->host); |
|---|
| 4590 | 4852 | return NULL; |
|---|
| 4591 | 4853 | } |
|---|
| 4592 | 4854 | |
|---|
| .. | .. |
|---|
| 4599 | 4861 | dma_free_coherent(&ha->pdev->dev, vha->gnl.size, |
|---|
| 4600 | 4862 | vha->gnl.l, vha->gnl.ldma); |
|---|
| 4601 | 4863 | vha->gnl.l = NULL; |
|---|
| 4602 | | - scsi_remove_host(vha->host); |
|---|
| 4864 | + scsi_host_put(vha->host); |
|---|
| 4603 | 4865 | return NULL; |
|---|
| 4604 | 4866 | } |
|---|
| 4605 | 4867 | INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); |
|---|
| 4606 | 4868 | |
|---|
| 4607 | | - sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); |
|---|
| 4869 | + sprintf(vha->host_str, "%s_%lu", QLA2XXX_DRIVER_NAME, vha->host_no); |
|---|
| 4608 | 4870 | ql_dbg(ql_dbg_init, vha, 0x0041, |
|---|
| 4609 | 4871 | "Allocated the host=%p hw=%p vha=%p dev_name=%s", |
|---|
| 4610 | 4872 | vha->host, vha->hw, vha, |
|---|
| .. | .. |
|---|
| 4708 | 4970 | |
|---|
| 4709 | 4971 | qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN); |
|---|
| 4710 | 4972 | qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); |
|---|
| 4711 | | -qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); |
|---|
| 4712 | 4973 | qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC); |
|---|
| 4713 | | -qla2x00_post_async_work(adisc_done, QLA_EVT_ASYNC_ADISC_DONE); |
|---|
| 4714 | 4974 | qla2x00_post_async_work(prlo, QLA_EVT_ASYNC_PRLO); |
|---|
| 4715 | 4975 | qla2x00_post_async_work(prlo_done, QLA_EVT_ASYNC_PRLO_DONE); |
|---|
| 4716 | 4976 | |
|---|
| .. | .. |
|---|
| 4735 | 4995 | |
|---|
| 4736 | 4996 | switch (code) { |
|---|
| 4737 | 4997 | case QLA_UEVENT_CODE_FW_DUMP: |
|---|
| 4738 | | - snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", |
|---|
| 4998 | + snprintf(event_string, sizeof(event_string), "FW_DUMP=%lu", |
|---|
| 4739 | 4999 | vha->host_no); |
|---|
| 4740 | 5000 | break; |
|---|
| 4741 | 5001 | default: |
|---|
| .. | .. |
|---|
| 4776 | 5036 | fcport->jiffies_at_registration = jiffies; |
|---|
| 4777 | 5037 | fcport->sec_since_registration = 0; |
|---|
| 4778 | 5038 | fcport->next_disc_state = DSC_DELETED; |
|---|
| 4779 | | - fcport->disc_state = DSC_UPD_FCPORT; |
|---|
| 5039 | + qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); |
|---|
| 4780 | 5040 | spin_unlock_irqrestore(&fcport->vha->work_lock, flags); |
|---|
| 4781 | 5041 | |
|---|
| 4782 | 5042 | queue_work(system_unbound_wq, &fcport->reg_work); |
|---|
| .. | .. |
|---|
| 4817 | 5077 | fcport->d_id = e->u.new_sess.id; |
|---|
| 4818 | 5078 | fcport->flags |= FCF_FABRIC_DEVICE; |
|---|
| 4819 | 5079 | fcport->fw_login_state = DSC_LS_PLOGI_PEND; |
|---|
| 4820 | | - if (e->u.new_sess.fc4_type == FS_FC4TYPE_FCP) |
|---|
| 4821 | | - fcport->fc4_type = FC4_TYPE_FCP_SCSI; |
|---|
| 4822 | | - |
|---|
| 4823 | | - if (e->u.new_sess.fc4_type == FS_FC4TYPE_NVME) { |
|---|
| 4824 | | - fcport->fc4_type = FC4_TYPE_OTHER; |
|---|
| 4825 | | - fcport->fc4f_nvme = FC4_TYPE_NVME; |
|---|
| 4826 | | - } |
|---|
| 4827 | 5080 | |
|---|
| 4828 | 5081 | memcpy(fcport->port_name, e->u.new_sess.port_name, |
|---|
| 4829 | 5082 | WWN_SIZE); |
|---|
| 5083 | + |
|---|
| 5084 | + fcport->fc4_type = e->u.new_sess.fc4_type; |
|---|
| 5085 | + if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) { |
|---|
| 5086 | + fcport->dm_login_expire = jiffies + |
|---|
| 5087 | + QLA_N2N_WAIT_TIME * HZ; |
|---|
| 5088 | + fcport->fc4_type = FS_FC4TYPE_FCP; |
|---|
| 5089 | + fcport->n2n_flag = 1; |
|---|
| 5090 | + if (vha->flags.nvme_enabled) |
|---|
| 5091 | + fcport->fc4_type |= FS_FC4TYPE_NVME; |
|---|
| 5092 | + } |
|---|
| 5093 | + |
|---|
| 4830 | 5094 | } else { |
|---|
| 4831 | 5095 | ql_dbg(ql_dbg_disc, vha, 0xffff, |
|---|
| 4832 | 5096 | "%s %8phC mem alloc fail.\n", |
|---|
| 4833 | 5097 | __func__, e->u.new_sess.port_name); |
|---|
| 4834 | 5098 | |
|---|
| 4835 | | - if (pla) |
|---|
| 5099 | + if (pla) { |
|---|
| 5100 | + list_del(&pla->list); |
|---|
| 4836 | 5101 | kmem_cache_free(qla_tgt_plogi_cachep, pla); |
|---|
| 5102 | + } |
|---|
| 4837 | 5103 | return; |
|---|
| 4838 | 5104 | } |
|---|
| 4839 | 5105 | |
|---|
| .. | .. |
|---|
| 4923 | 5189 | if (dfcp) |
|---|
| 4924 | 5190 | qlt_schedule_sess_for_deletion(tfcp); |
|---|
| 4925 | 5191 | |
|---|
| 4926 | | - |
|---|
| 4927 | | - if (N2N_TOPO(vha->hw)) |
|---|
| 4928 | | - fcport->flags &= ~FCF_FABRIC_DEVICE; |
|---|
| 4929 | | - |
|---|
| 4930 | 5192 | if (N2N_TOPO(vha->hw)) { |
|---|
| 5193 | + fcport->flags &= ~FCF_FABRIC_DEVICE; |
|---|
| 5194 | + fcport->keep_nport_handle = 1; |
|---|
| 4931 | 5195 | if (vha->flags.nvme_enabled) { |
|---|
| 4932 | | - fcport->fc4f_nvme = 1; |
|---|
| 5196 | + fcport->fc4_type = |
|---|
| 5197 | + (FS_FC4TYPE_NVME | FS_FC4TYPE_FCP); |
|---|
| 4933 | 5198 | fcport->n2n_flag = 1; |
|---|
| 4934 | 5199 | } |
|---|
| 4935 | 5200 | fcport->fw_login_state = 0; |
|---|
| 4936 | | - /* |
|---|
| 4937 | | - * wait link init done before sending login |
|---|
| 4938 | | - */ |
|---|
| 5201 | + |
|---|
| 5202 | + schedule_delayed_work(&vha->scan.scan_work, 5); |
|---|
| 4939 | 5203 | } else { |
|---|
| 4940 | 5204 | qla24xx_fcport_handle_login(vha, fcport); |
|---|
| 4941 | 5205 | } |
|---|
| .. | .. |
|---|
| 4944 | 5208 | |
|---|
| 4945 | 5209 | if (free_fcport) { |
|---|
| 4946 | 5210 | qla2x00_free_fcport(fcport); |
|---|
| 4947 | | - if (pla) |
|---|
| 5211 | + if (pla) { |
|---|
| 5212 | + list_del(&pla->list); |
|---|
| 4948 | 5213 | kmem_cache_free(qla_tgt_plogi_cachep, pla); |
|---|
| 5214 | + } |
|---|
| 4949 | 5215 | } |
|---|
| 4950 | 5216 | } |
|---|
| 4951 | 5217 | |
|---|
| .. | .. |
|---|
| 4969 | 5235 | struct qla_work_evt *e, *tmp; |
|---|
| 4970 | 5236 | unsigned long flags; |
|---|
| 4971 | 5237 | LIST_HEAD(work); |
|---|
| 5238 | + int rc; |
|---|
| 4972 | 5239 | |
|---|
| 4973 | 5240 | spin_lock_irqsave(&vha->work_lock, flags); |
|---|
| 4974 | 5241 | list_splice_init(&vha->work_list, &work); |
|---|
| 4975 | 5242 | spin_unlock_irqrestore(&vha->work_lock, flags); |
|---|
| 4976 | 5243 | |
|---|
| 4977 | 5244 | list_for_each_entry_safe(e, tmp, &work, list) { |
|---|
| 4978 | | - list_del_init(&e->list); |
|---|
| 4979 | | - |
|---|
| 5245 | + rc = QLA_SUCCESS; |
|---|
| 4980 | 5246 | switch (e->type) { |
|---|
| 4981 | 5247 | case QLA_EVT_AEN: |
|---|
| 4982 | 5248 | fc_host_post_event(vha->host, fc_get_event_number(), |
|---|
| .. | .. |
|---|
| 4990 | 5256 | e->u.logio.data); |
|---|
| 4991 | 5257 | break; |
|---|
| 4992 | 5258 | case QLA_EVT_ASYNC_LOGOUT: |
|---|
| 4993 | | - qla2x00_async_logout(vha, e->u.logio.fcport); |
|---|
| 4994 | | - break; |
|---|
| 4995 | | - case QLA_EVT_ASYNC_LOGOUT_DONE: |
|---|
| 4996 | | - qla2x00_async_logout_done(vha, e->u.logio.fcport, |
|---|
| 4997 | | - e->u.logio.data); |
|---|
| 5259 | + rc = qla2x00_async_logout(vha, e->u.logio.fcport); |
|---|
| 4998 | 5260 | break; |
|---|
| 4999 | 5261 | case QLA_EVT_ASYNC_ADISC: |
|---|
| 5000 | 5262 | qla2x00_async_adisc(vha, e->u.logio.fcport, |
|---|
| 5001 | | - e->u.logio.data); |
|---|
| 5002 | | - break; |
|---|
| 5003 | | - case QLA_EVT_ASYNC_ADISC_DONE: |
|---|
| 5004 | | - qla2x00_async_adisc_done(vha, e->u.logio.fcport, |
|---|
| 5005 | 5263 | e->u.logio.data); |
|---|
| 5006 | 5264 | break; |
|---|
| 5007 | 5265 | case QLA_EVT_UEVENT: |
|---|
| .. | .. |
|---|
| 5009 | 5267 | break; |
|---|
| 5010 | 5268 | case QLA_EVT_AENFX: |
|---|
| 5011 | 5269 | qlafx00_process_aen(vha, e); |
|---|
| 5012 | | - break; |
|---|
| 5013 | | - case QLA_EVT_GIDPN: |
|---|
| 5014 | | - qla24xx_async_gidpn(vha, e->u.fcport.fcport); |
|---|
| 5015 | 5270 | break; |
|---|
| 5016 | 5271 | case QLA_EVT_GPNID: |
|---|
| 5017 | 5272 | qla24xx_async_gpnid(vha, &e->u.gpnid.id); |
|---|
| .. | .. |
|---|
| 5042 | 5297 | qla24xx_do_nack_work(vha, e); |
|---|
| 5043 | 5298 | break; |
|---|
| 5044 | 5299 | case QLA_EVT_ASYNC_PRLO: |
|---|
| 5045 | | - qla2x00_async_prlo(vha, e->u.logio.fcport); |
|---|
| 5300 | + rc = qla2x00_async_prlo(vha, e->u.logio.fcport); |
|---|
| 5046 | 5301 | break; |
|---|
| 5047 | 5302 | case QLA_EVT_ASYNC_PRLO_DONE: |
|---|
| 5048 | 5303 | qla2x00_async_prlo_done(vha, e->u.logio.fcport, |
|---|
| .. | .. |
|---|
| 5075 | 5330 | e->u.fcport.fcport, false); |
|---|
| 5076 | 5331 | break; |
|---|
| 5077 | 5332 | } |
|---|
| 5333 | + |
|---|
| 5334 | + if (rc == EAGAIN) { |
|---|
| 5335 | + /* put 'work' at head of 'vha->work_list' */ |
|---|
| 5336 | + spin_lock_irqsave(&vha->work_lock, flags); |
|---|
| 5337 | + list_splice(&work, &vha->work_list); |
|---|
| 5338 | + spin_unlock_irqrestore(&vha->work_lock, flags); |
|---|
| 5339 | + break; |
|---|
| 5340 | + } |
|---|
| 5341 | + list_del_init(&e->list); |
|---|
| 5078 | 5342 | if (e->flags & QLA_EVT_FLAG_FREE) |
|---|
| 5079 | 5343 | kfree(e); |
|---|
| 5080 | 5344 | |
|---|
| .. | .. |
|---|
| 5123 | 5387 | } else { |
|---|
| 5124 | 5388 | if (vha->hw->current_topology != ISP_CFG_NL) { |
|---|
| 5125 | 5389 | memset(&ea, 0, sizeof(ea)); |
|---|
| 5126 | | - ea.event = FCME_RELOGIN; |
|---|
| 5127 | 5390 | ea.fcport = fcport; |
|---|
| 5128 | | - qla2x00_fcport_event_handler(vha, &ea); |
|---|
| 5391 | + qla24xx_handle_relogin_event(vha, &ea); |
|---|
| 5392 | + } else if (vha->hw->current_topology == |
|---|
| 5393 | + ISP_CFG_NL && |
|---|
| 5394 | + IS_QLA2XXX_MIDTYPE(vha->hw)) { |
|---|
| 5395 | + (void)qla24xx_fcport_handle_login(vha, |
|---|
| 5396 | + fcport); |
|---|
| 5129 | 5397 | } else if (vha->hw->current_topology == |
|---|
| 5130 | 5398 | ISP_CFG_NL) { |
|---|
| 5131 | 5399 | fcport->login_retry--; |
|---|
| .. | .. |
|---|
| 5371 | 5639 | uint32_t idc_lck_rcvry_stage_mask = 0x3; |
|---|
| 5372 | 5640 | uint32_t idc_lck_rcvry_owner_mask = 0x3c; |
|---|
| 5373 | 5641 | struct qla_hw_data *ha = base_vha->hw; |
|---|
| 5642 | + |
|---|
| 5374 | 5643 | ql_dbg(ql_dbg_p3p, base_vha, 0xb086, |
|---|
| 5375 | 5644 | "Trying force recovery of the IDC lock.\n"); |
|---|
| 5376 | 5645 | |
|---|
| .. | .. |
|---|
| 5462 | 5731 | void |
|---|
| 5463 | 5732 | qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id) |
|---|
| 5464 | 5733 | { |
|---|
| 5465 | | - uint16_t options = (requester_id << 15) | BIT_6; |
|---|
| 5466 | 5734 | uint32_t data; |
|---|
| 5467 | 5735 | uint32_t lock_owner; |
|---|
| 5468 | 5736 | struct qla_hw_data *ha = base_vha->hw; |
|---|
| .. | .. |
|---|
| 5495 | 5763 | } |
|---|
| 5496 | 5764 | |
|---|
| 5497 | 5765 | return; |
|---|
| 5766 | +} |
|---|
| 5498 | 5767 | |
|---|
| 5499 | | - /* XXX: IDC-lock implementation using access-control mbx */ |
|---|
| 5500 | | -retry_lock2: |
|---|
| 5501 | | - if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) { |
|---|
| 5502 | | - ql_dbg(ql_dbg_p3p, base_vha, 0xb072, |
|---|
| 5503 | | - "Failed to acquire IDC lock. retrying...\n"); |
|---|
| 5504 | | - /* Retry/Perform IDC-Lock recovery */ |
|---|
| 5505 | | - if (qla83xx_idc_lock_recovery(base_vha) == QLA_SUCCESS) { |
|---|
| 5506 | | - qla83xx_wait_logic(); |
|---|
| 5507 | | - goto retry_lock2; |
|---|
| 5508 | | - } else |
|---|
| 5509 | | - ql_log(ql_log_warn, base_vha, 0xb076, |
|---|
| 5510 | | - "IDC Lock recovery FAILED.\n"); |
|---|
| 5768 | +static bool |
|---|
| 5769 | +qla25xx_rdp_rsp_reduce_size(struct scsi_qla_host *vha, |
|---|
| 5770 | + struct purex_entry_24xx *purex) |
|---|
| 5771 | +{ |
|---|
| 5772 | + char fwstr[16]; |
|---|
| 5773 | + u32 sid = purex->s_id[2] << 16 | purex->s_id[1] << 8 | purex->s_id[0]; |
|---|
| 5774 | + struct port_database_24xx *pdb; |
|---|
| 5775 | + |
|---|
| 5776 | + /* Domain Controller is always logged-out. */ |
|---|
| 5777 | + /* if RDP request is not from Domain Controller: */ |
|---|
| 5778 | + if (sid != 0xfffc01) |
|---|
| 5779 | + return false; |
|---|
| 5780 | + |
|---|
| 5781 | + ql_dbg(ql_dbg_init, vha, 0x0181, "%s: s_id=%#x\n", __func__, sid); |
|---|
| 5782 | + |
|---|
| 5783 | + pdb = kzalloc(sizeof(*pdb), GFP_KERNEL); |
|---|
| 5784 | + if (!pdb) { |
|---|
| 5785 | + ql_dbg(ql_dbg_init, vha, 0x0181, |
|---|
| 5786 | + "%s: Failed allocate pdb\n", __func__); |
|---|
| 5787 | + } else if (qla24xx_get_port_database(vha, |
|---|
| 5788 | + le16_to_cpu(purex->nport_handle), pdb)) { |
|---|
| 5789 | + ql_dbg(ql_dbg_init, vha, 0x0181, |
|---|
| 5790 | + "%s: Failed get pdb sid=%x\n", __func__, sid); |
|---|
| 5791 | + } else if (pdb->current_login_state != PDS_PLOGI_COMPLETE && |
|---|
| 5792 | + pdb->current_login_state != PDS_PRLI_COMPLETE) { |
|---|
| 5793 | + ql_dbg(ql_dbg_init, vha, 0x0181, |
|---|
| 5794 | + "%s: Port not logged in sid=%#x\n", __func__, sid); |
|---|
| 5795 | + } else { |
|---|
| 5796 | + /* RDP request is from logged in port */ |
|---|
| 5797 | + kfree(pdb); |
|---|
| 5798 | + return false; |
|---|
| 5799 | + } |
|---|
| 5800 | + kfree(pdb); |
|---|
| 5801 | + |
|---|
| 5802 | + vha->hw->isp_ops->fw_version_str(vha, fwstr, sizeof(fwstr)); |
|---|
| 5803 | + fwstr[strcspn(fwstr, " ")] = 0; |
|---|
| 5804 | + /* if FW version allows RDP response length upto 2048 bytes: */ |
|---|
| 5805 | + if (strcmp(fwstr, "8.09.00") > 0 || strcmp(fwstr, "8.05.65") == 0) |
|---|
| 5806 | + return false; |
|---|
| 5807 | + |
|---|
| 5808 | + ql_dbg(ql_dbg_init, vha, 0x0181, "%s: fw=%s\n", __func__, fwstr); |
|---|
| 5809 | + |
|---|
| 5810 | + /* RDP response length is to be reduced to maximum 256 bytes */ |
|---|
| 5811 | + return true; |
|---|
| 5812 | +} |
|---|
| 5813 | + |
|---|
| 5814 | +/* |
|---|
| 5815 | + * Function Name: qla24xx_process_purex_iocb |
|---|
| 5816 | + * |
|---|
| 5817 | + * Description: |
|---|
| 5818 | + * Prepare a RDP response and send to Fabric switch |
|---|
| 5819 | + * |
|---|
| 5820 | + * PARAMETERS: |
|---|
| 5821 | + * vha: SCSI qla host |
|---|
| 5822 | + * purex: RDP request received by HBA |
|---|
| 5823 | + */ |
|---|
| 5824 | +void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, |
|---|
| 5825 | + struct purex_item *item) |
|---|
| 5826 | +{ |
|---|
| 5827 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 5828 | + struct purex_entry_24xx *purex = |
|---|
| 5829 | + (struct purex_entry_24xx *)&item->iocb; |
|---|
| 5830 | + dma_addr_t rsp_els_dma; |
|---|
| 5831 | + dma_addr_t rsp_payload_dma; |
|---|
| 5832 | + dma_addr_t stat_dma; |
|---|
| 5833 | + dma_addr_t sfp_dma; |
|---|
| 5834 | + struct els_entry_24xx *rsp_els = NULL; |
|---|
| 5835 | + struct rdp_rsp_payload *rsp_payload = NULL; |
|---|
| 5836 | + struct link_statistics *stat = NULL; |
|---|
| 5837 | + uint8_t *sfp = NULL; |
|---|
| 5838 | + uint16_t sfp_flags = 0; |
|---|
| 5839 | + uint rsp_payload_length = sizeof(*rsp_payload); |
|---|
| 5840 | + int rval; |
|---|
| 5841 | + |
|---|
| 5842 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0180, |
|---|
| 5843 | + "%s: Enter\n", __func__); |
|---|
| 5844 | + |
|---|
| 5845 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0181, |
|---|
| 5846 | + "-------- ELS REQ -------\n"); |
|---|
| 5847 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0182, |
|---|
| 5848 | + purex, sizeof(*purex)); |
|---|
| 5849 | + |
|---|
| 5850 | + if (qla25xx_rdp_rsp_reduce_size(vha, purex)) { |
|---|
| 5851 | + rsp_payload_length = |
|---|
| 5852 | + offsetof(typeof(*rsp_payload), optical_elmt_desc); |
|---|
| 5853 | + ql_dbg(ql_dbg_init, vha, 0x0181, |
|---|
| 5854 | + "Reducing RSP payload length to %u bytes...\n", |
|---|
| 5855 | + rsp_payload_length); |
|---|
| 5511 | 5856 | } |
|---|
| 5512 | 5857 | |
|---|
| 5513 | | - return; |
|---|
| 5858 | + rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els), |
|---|
| 5859 | + &rsp_els_dma, GFP_KERNEL); |
|---|
| 5860 | + if (!rsp_els) { |
|---|
| 5861 | + ql_log(ql_log_warn, vha, 0x0183, |
|---|
| 5862 | + "Failed allocate dma buffer ELS RSP.\n"); |
|---|
| 5863 | + goto dealloc; |
|---|
| 5864 | + } |
|---|
| 5865 | + |
|---|
| 5866 | + rsp_payload = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_payload), |
|---|
| 5867 | + &rsp_payload_dma, GFP_KERNEL); |
|---|
| 5868 | + if (!rsp_payload) { |
|---|
| 5869 | + ql_log(ql_log_warn, vha, 0x0184, |
|---|
| 5870 | + "Failed allocate dma buffer ELS RSP payload.\n"); |
|---|
| 5871 | + goto dealloc; |
|---|
| 5872 | + } |
|---|
| 5873 | + |
|---|
| 5874 | + sfp = dma_alloc_coherent(&ha->pdev->dev, SFP_RTDI_LEN, |
|---|
| 5875 | + &sfp_dma, GFP_KERNEL); |
|---|
| 5876 | + |
|---|
| 5877 | + stat = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stat), |
|---|
| 5878 | + &stat_dma, GFP_KERNEL); |
|---|
| 5879 | + |
|---|
| 5880 | + /* Prepare Response IOCB */ |
|---|
| 5881 | + rsp_els->entry_type = ELS_IOCB_TYPE; |
|---|
| 5882 | + rsp_els->entry_count = 1; |
|---|
| 5883 | + rsp_els->sys_define = 0; |
|---|
| 5884 | + rsp_els->entry_status = 0; |
|---|
| 5885 | + rsp_els->handle = 0; |
|---|
| 5886 | + rsp_els->nport_handle = purex->nport_handle; |
|---|
| 5887 | + rsp_els->tx_dsd_count = cpu_to_le16(1); |
|---|
| 5888 | + rsp_els->vp_index = purex->vp_idx; |
|---|
| 5889 | + rsp_els->sof_type = EST_SOFI3; |
|---|
| 5890 | + rsp_els->rx_xchg_address = purex->rx_xchg_addr; |
|---|
| 5891 | + rsp_els->rx_dsd_count = 0; |
|---|
| 5892 | + rsp_els->opcode = purex->els_frame_payload[0]; |
|---|
| 5893 | + |
|---|
| 5894 | + rsp_els->d_id[0] = purex->s_id[0]; |
|---|
| 5895 | + rsp_els->d_id[1] = purex->s_id[1]; |
|---|
| 5896 | + rsp_els->d_id[2] = purex->s_id[2]; |
|---|
| 5897 | + |
|---|
| 5898 | + rsp_els->control_flags = cpu_to_le16(EPD_ELS_ACC); |
|---|
| 5899 | + rsp_els->rx_byte_count = 0; |
|---|
| 5900 | + rsp_els->tx_byte_count = cpu_to_le32(rsp_payload_length); |
|---|
| 5901 | + |
|---|
| 5902 | + put_unaligned_le64(rsp_payload_dma, &rsp_els->tx_address); |
|---|
| 5903 | + rsp_els->tx_len = rsp_els->tx_byte_count; |
|---|
| 5904 | + |
|---|
| 5905 | + rsp_els->rx_address = 0; |
|---|
| 5906 | + rsp_els->rx_len = 0; |
|---|
| 5907 | + |
|---|
| 5908 | + /* Prepare Response Payload */ |
|---|
| 5909 | + rsp_payload->hdr.cmd = cpu_to_be32(0x2 << 24); /* LS_ACC */ |
|---|
| 5910 | + rsp_payload->hdr.len = cpu_to_be32(le32_to_cpu(rsp_els->tx_byte_count) - |
|---|
| 5911 | + sizeof(rsp_payload->hdr)); |
|---|
| 5912 | + |
|---|
| 5913 | + /* Link service Request Info Descriptor */ |
|---|
| 5914 | + rsp_payload->ls_req_info_desc.desc_tag = cpu_to_be32(0x1); |
|---|
| 5915 | + rsp_payload->ls_req_info_desc.desc_len = |
|---|
| 5916 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_req_info_desc)); |
|---|
| 5917 | + rsp_payload->ls_req_info_desc.req_payload_word_0 = |
|---|
| 5918 | + cpu_to_be32p((uint32_t *)purex->els_frame_payload); |
|---|
| 5919 | + |
|---|
| 5920 | + /* Link service Request Info Descriptor 2 */ |
|---|
| 5921 | + rsp_payload->ls_req_info_desc2.desc_tag = cpu_to_be32(0x1); |
|---|
| 5922 | + rsp_payload->ls_req_info_desc2.desc_len = |
|---|
| 5923 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_req_info_desc2)); |
|---|
| 5924 | + rsp_payload->ls_req_info_desc2.req_payload_word_0 = |
|---|
| 5925 | + cpu_to_be32p((uint32_t *)purex->els_frame_payload); |
|---|
| 5926 | + |
|---|
| 5927 | + |
|---|
| 5928 | + rsp_payload->sfp_diag_desc.desc_tag = cpu_to_be32(0x10000); |
|---|
| 5929 | + rsp_payload->sfp_diag_desc.desc_len = |
|---|
| 5930 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->sfp_diag_desc)); |
|---|
| 5931 | + |
|---|
| 5932 | + if (sfp) { |
|---|
| 5933 | + /* SFP Flags */ |
|---|
| 5934 | + memset(sfp, 0, SFP_RTDI_LEN); |
|---|
| 5935 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 0x7, 2, 0); |
|---|
| 5936 | + if (!rval) { |
|---|
| 5937 | + /* SFP Flags bits 3-0: Port Tx Laser Type */ |
|---|
| 5938 | + if (sfp[0] & BIT_2 || sfp[1] & (BIT_6|BIT_5)) |
|---|
| 5939 | + sfp_flags |= BIT_0; /* short wave */ |
|---|
| 5940 | + else if (sfp[0] & BIT_1) |
|---|
| 5941 | + sfp_flags |= BIT_1; /* long wave 1310nm */ |
|---|
| 5942 | + else if (sfp[1] & BIT_4) |
|---|
| 5943 | + sfp_flags |= BIT_1|BIT_0; /* long wave 1550nm */ |
|---|
| 5944 | + } |
|---|
| 5945 | + |
|---|
| 5946 | + /* SFP Type */ |
|---|
| 5947 | + memset(sfp, 0, SFP_RTDI_LEN); |
|---|
| 5948 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 0x0, 1, 0); |
|---|
| 5949 | + if (!rval) { |
|---|
| 5950 | + sfp_flags |= BIT_4; /* optical */ |
|---|
| 5951 | + if (sfp[0] == 0x3) |
|---|
| 5952 | + sfp_flags |= BIT_6; /* sfp+ */ |
|---|
| 5953 | + } |
|---|
| 5954 | + |
|---|
| 5955 | + rsp_payload->sfp_diag_desc.sfp_flags = cpu_to_be16(sfp_flags); |
|---|
| 5956 | + |
|---|
| 5957 | + /* SFP Diagnostics */ |
|---|
| 5958 | + memset(sfp, 0, SFP_RTDI_LEN); |
|---|
| 5959 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 0x60, 10, 0); |
|---|
| 5960 | + if (!rval) { |
|---|
| 5961 | + __be16 *trx = (__force __be16 *)sfp; /* already be16 */ |
|---|
| 5962 | + rsp_payload->sfp_diag_desc.temperature = trx[0]; |
|---|
| 5963 | + rsp_payload->sfp_diag_desc.vcc = trx[1]; |
|---|
| 5964 | + rsp_payload->sfp_diag_desc.tx_bias = trx[2]; |
|---|
| 5965 | + rsp_payload->sfp_diag_desc.tx_power = trx[3]; |
|---|
| 5966 | + rsp_payload->sfp_diag_desc.rx_power = trx[4]; |
|---|
| 5967 | + } |
|---|
| 5968 | + } |
|---|
| 5969 | + |
|---|
| 5970 | + /* Port Speed Descriptor */ |
|---|
| 5971 | + rsp_payload->port_speed_desc.desc_tag = cpu_to_be32(0x10001); |
|---|
| 5972 | + rsp_payload->port_speed_desc.desc_len = |
|---|
| 5973 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_speed_desc)); |
|---|
| 5974 | + rsp_payload->port_speed_desc.speed_capab = cpu_to_be16( |
|---|
| 5975 | + qla25xx_fdmi_port_speed_capability(ha)); |
|---|
| 5976 | + rsp_payload->port_speed_desc.operating_speed = cpu_to_be16( |
|---|
| 5977 | + qla25xx_fdmi_port_speed_currently(ha)); |
|---|
| 5978 | + |
|---|
| 5979 | + /* Link Error Status Descriptor */ |
|---|
| 5980 | + rsp_payload->ls_err_desc.desc_tag = cpu_to_be32(0x10002); |
|---|
| 5981 | + rsp_payload->ls_err_desc.desc_len = |
|---|
| 5982 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_err_desc)); |
|---|
| 5983 | + |
|---|
| 5984 | + if (stat) { |
|---|
| 5985 | + rval = qla24xx_get_isp_stats(vha, stat, stat_dma, 0); |
|---|
| 5986 | + if (!rval) { |
|---|
| 5987 | + rsp_payload->ls_err_desc.link_fail_cnt = |
|---|
| 5988 | + cpu_to_be32(le32_to_cpu(stat->link_fail_cnt)); |
|---|
| 5989 | + rsp_payload->ls_err_desc.loss_sync_cnt = |
|---|
| 5990 | + cpu_to_be32(le32_to_cpu(stat->loss_sync_cnt)); |
|---|
| 5991 | + rsp_payload->ls_err_desc.loss_sig_cnt = |
|---|
| 5992 | + cpu_to_be32(le32_to_cpu(stat->loss_sig_cnt)); |
|---|
| 5993 | + rsp_payload->ls_err_desc.prim_seq_err_cnt = |
|---|
| 5994 | + cpu_to_be32(le32_to_cpu(stat->prim_seq_err_cnt)); |
|---|
| 5995 | + rsp_payload->ls_err_desc.inval_xmit_word_cnt = |
|---|
| 5996 | + cpu_to_be32(le32_to_cpu(stat->inval_xmit_word_cnt)); |
|---|
| 5997 | + rsp_payload->ls_err_desc.inval_crc_cnt = |
|---|
| 5998 | + cpu_to_be32(le32_to_cpu(stat->inval_crc_cnt)); |
|---|
| 5999 | + rsp_payload->ls_err_desc.pn_port_phy_type |= BIT_6; |
|---|
| 6000 | + } |
|---|
| 6001 | + } |
|---|
| 6002 | + |
|---|
| 6003 | + /* Portname Descriptor */ |
|---|
| 6004 | + rsp_payload->port_name_diag_desc.desc_tag = cpu_to_be32(0x10003); |
|---|
| 6005 | + rsp_payload->port_name_diag_desc.desc_len = |
|---|
| 6006 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_name_diag_desc)); |
|---|
| 6007 | + memcpy(rsp_payload->port_name_diag_desc.WWNN, |
|---|
| 6008 | + vha->node_name, |
|---|
| 6009 | + sizeof(rsp_payload->port_name_diag_desc.WWNN)); |
|---|
| 6010 | + memcpy(rsp_payload->port_name_diag_desc.WWPN, |
|---|
| 6011 | + vha->port_name, |
|---|
| 6012 | + sizeof(rsp_payload->port_name_diag_desc.WWPN)); |
|---|
| 6013 | + |
|---|
| 6014 | + /* F-Port Portname Descriptor */ |
|---|
| 6015 | + rsp_payload->port_name_direct_desc.desc_tag = cpu_to_be32(0x10003); |
|---|
| 6016 | + rsp_payload->port_name_direct_desc.desc_len = |
|---|
| 6017 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_name_direct_desc)); |
|---|
| 6018 | + memcpy(rsp_payload->port_name_direct_desc.WWNN, |
|---|
| 6019 | + vha->fabric_node_name, |
|---|
| 6020 | + sizeof(rsp_payload->port_name_direct_desc.WWNN)); |
|---|
| 6021 | + memcpy(rsp_payload->port_name_direct_desc.WWPN, |
|---|
| 6022 | + vha->fabric_port_name, |
|---|
| 6023 | + sizeof(rsp_payload->port_name_direct_desc.WWPN)); |
|---|
| 6024 | + |
|---|
| 6025 | + /* Bufer Credit Descriptor */ |
|---|
| 6026 | + rsp_payload->buffer_credit_desc.desc_tag = cpu_to_be32(0x10006); |
|---|
| 6027 | + rsp_payload->buffer_credit_desc.desc_len = |
|---|
| 6028 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->buffer_credit_desc)); |
|---|
| 6029 | + rsp_payload->buffer_credit_desc.fcport_b2b = 0; |
|---|
| 6030 | + rsp_payload->buffer_credit_desc.attached_fcport_b2b = cpu_to_be32(0); |
|---|
| 6031 | + rsp_payload->buffer_credit_desc.fcport_rtt = cpu_to_be32(0); |
|---|
| 6032 | + |
|---|
| 6033 | + if (ha->flags.plogi_template_valid) { |
|---|
| 6034 | + uint32_t tmp = |
|---|
| 6035 | + be16_to_cpu(ha->plogi_els_payld.fl_csp.sp_bb_cred); |
|---|
| 6036 | + rsp_payload->buffer_credit_desc.fcport_b2b = cpu_to_be32(tmp); |
|---|
| 6037 | + } |
|---|
| 6038 | + |
|---|
| 6039 | + if (rsp_payload_length < sizeof(*rsp_payload)) |
|---|
| 6040 | + goto send; |
|---|
| 6041 | + |
|---|
| 6042 | + /* Optical Element Descriptor, Temperature */ |
|---|
| 6043 | + rsp_payload->optical_elmt_desc[0].desc_tag = cpu_to_be32(0x10007); |
|---|
| 6044 | + rsp_payload->optical_elmt_desc[0].desc_len = |
|---|
| 6045 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
|---|
| 6046 | + /* Optical Element Descriptor, Voltage */ |
|---|
| 6047 | + rsp_payload->optical_elmt_desc[1].desc_tag = cpu_to_be32(0x10007); |
|---|
| 6048 | + rsp_payload->optical_elmt_desc[1].desc_len = |
|---|
| 6049 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
|---|
| 6050 | + /* Optical Element Descriptor, Tx Bias Current */ |
|---|
| 6051 | + rsp_payload->optical_elmt_desc[2].desc_tag = cpu_to_be32(0x10007); |
|---|
| 6052 | + rsp_payload->optical_elmt_desc[2].desc_len = |
|---|
| 6053 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
|---|
| 6054 | + /* Optical Element Descriptor, Tx Power */ |
|---|
| 6055 | + rsp_payload->optical_elmt_desc[3].desc_tag = cpu_to_be32(0x10007); |
|---|
| 6056 | + rsp_payload->optical_elmt_desc[3].desc_len = |
|---|
| 6057 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
|---|
| 6058 | + /* Optical Element Descriptor, Rx Power */ |
|---|
| 6059 | + rsp_payload->optical_elmt_desc[4].desc_tag = cpu_to_be32(0x10007); |
|---|
| 6060 | + rsp_payload->optical_elmt_desc[4].desc_len = |
|---|
| 6061 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
|---|
| 6062 | + |
|---|
| 6063 | + if (sfp) { |
|---|
| 6064 | + memset(sfp, 0, SFP_RTDI_LEN); |
|---|
| 6065 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 0, 64, 0); |
|---|
| 6066 | + if (!rval) { |
|---|
| 6067 | + __be16 *trx = (__force __be16 *)sfp; /* already be16 */ |
|---|
| 6068 | + |
|---|
| 6069 | + /* Optical Element Descriptor, Temperature */ |
|---|
| 6070 | + rsp_payload->optical_elmt_desc[0].high_alarm = trx[0]; |
|---|
| 6071 | + rsp_payload->optical_elmt_desc[0].low_alarm = trx[1]; |
|---|
| 6072 | + rsp_payload->optical_elmt_desc[0].high_warn = trx[2]; |
|---|
| 6073 | + rsp_payload->optical_elmt_desc[0].low_warn = trx[3]; |
|---|
| 6074 | + rsp_payload->optical_elmt_desc[0].element_flags = |
|---|
| 6075 | + cpu_to_be32(1 << 28); |
|---|
| 6076 | + |
|---|
| 6077 | + /* Optical Element Descriptor, Voltage */ |
|---|
| 6078 | + rsp_payload->optical_elmt_desc[1].high_alarm = trx[4]; |
|---|
| 6079 | + rsp_payload->optical_elmt_desc[1].low_alarm = trx[5]; |
|---|
| 6080 | + rsp_payload->optical_elmt_desc[1].high_warn = trx[6]; |
|---|
| 6081 | + rsp_payload->optical_elmt_desc[1].low_warn = trx[7]; |
|---|
| 6082 | + rsp_payload->optical_elmt_desc[1].element_flags = |
|---|
| 6083 | + cpu_to_be32(2 << 28); |
|---|
| 6084 | + |
|---|
| 6085 | + /* Optical Element Descriptor, Tx Bias Current */ |
|---|
| 6086 | + rsp_payload->optical_elmt_desc[2].high_alarm = trx[8]; |
|---|
| 6087 | + rsp_payload->optical_elmt_desc[2].low_alarm = trx[9]; |
|---|
| 6088 | + rsp_payload->optical_elmt_desc[2].high_warn = trx[10]; |
|---|
| 6089 | + rsp_payload->optical_elmt_desc[2].low_warn = trx[11]; |
|---|
| 6090 | + rsp_payload->optical_elmt_desc[2].element_flags = |
|---|
| 6091 | + cpu_to_be32(3 << 28); |
|---|
| 6092 | + |
|---|
| 6093 | + /* Optical Element Descriptor, Tx Power */ |
|---|
| 6094 | + rsp_payload->optical_elmt_desc[3].high_alarm = trx[12]; |
|---|
| 6095 | + rsp_payload->optical_elmt_desc[3].low_alarm = trx[13]; |
|---|
| 6096 | + rsp_payload->optical_elmt_desc[3].high_warn = trx[14]; |
|---|
| 6097 | + rsp_payload->optical_elmt_desc[3].low_warn = trx[15]; |
|---|
| 6098 | + rsp_payload->optical_elmt_desc[3].element_flags = |
|---|
| 6099 | + cpu_to_be32(4 << 28); |
|---|
| 6100 | + |
|---|
| 6101 | + /* Optical Element Descriptor, Rx Power */ |
|---|
| 6102 | + rsp_payload->optical_elmt_desc[4].high_alarm = trx[16]; |
|---|
| 6103 | + rsp_payload->optical_elmt_desc[4].low_alarm = trx[17]; |
|---|
| 6104 | + rsp_payload->optical_elmt_desc[4].high_warn = trx[18]; |
|---|
| 6105 | + rsp_payload->optical_elmt_desc[4].low_warn = trx[19]; |
|---|
| 6106 | + rsp_payload->optical_elmt_desc[4].element_flags = |
|---|
| 6107 | + cpu_to_be32(5 << 28); |
|---|
| 6108 | + } |
|---|
| 6109 | + |
|---|
| 6110 | + memset(sfp, 0, SFP_RTDI_LEN); |
|---|
| 6111 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 112, 64, 0); |
|---|
| 6112 | + if (!rval) { |
|---|
| 6113 | + /* Temperature high/low alarm/warning */ |
|---|
| 6114 | + rsp_payload->optical_elmt_desc[0].element_flags |= |
|---|
| 6115 | + cpu_to_be32( |
|---|
| 6116 | + (sfp[0] >> 7 & 1) << 3 | |
|---|
| 6117 | + (sfp[0] >> 6 & 1) << 2 | |
|---|
| 6118 | + (sfp[4] >> 7 & 1) << 1 | |
|---|
| 6119 | + (sfp[4] >> 6 & 1) << 0); |
|---|
| 6120 | + |
|---|
| 6121 | + /* Voltage high/low alarm/warning */ |
|---|
| 6122 | + rsp_payload->optical_elmt_desc[1].element_flags |= |
|---|
| 6123 | + cpu_to_be32( |
|---|
| 6124 | + (sfp[0] >> 5 & 1) << 3 | |
|---|
| 6125 | + (sfp[0] >> 4 & 1) << 2 | |
|---|
| 6126 | + (sfp[4] >> 5 & 1) << 1 | |
|---|
| 6127 | + (sfp[4] >> 4 & 1) << 0); |
|---|
| 6128 | + |
|---|
| 6129 | + /* Tx Bias Current high/low alarm/warning */ |
|---|
| 6130 | + rsp_payload->optical_elmt_desc[2].element_flags |= |
|---|
| 6131 | + cpu_to_be32( |
|---|
| 6132 | + (sfp[0] >> 3 & 1) << 3 | |
|---|
| 6133 | + (sfp[0] >> 2 & 1) << 2 | |
|---|
| 6134 | + (sfp[4] >> 3 & 1) << 1 | |
|---|
| 6135 | + (sfp[4] >> 2 & 1) << 0); |
|---|
| 6136 | + |
|---|
| 6137 | + /* Tx Power high/low alarm/warning */ |
|---|
| 6138 | + rsp_payload->optical_elmt_desc[3].element_flags |= |
|---|
| 6139 | + cpu_to_be32( |
|---|
| 6140 | + (sfp[0] >> 1 & 1) << 3 | |
|---|
| 6141 | + (sfp[0] >> 0 & 1) << 2 | |
|---|
| 6142 | + (sfp[4] >> 1 & 1) << 1 | |
|---|
| 6143 | + (sfp[4] >> 0 & 1) << 0); |
|---|
| 6144 | + |
|---|
| 6145 | + /* Rx Power high/low alarm/warning */ |
|---|
| 6146 | + rsp_payload->optical_elmt_desc[4].element_flags |= |
|---|
| 6147 | + cpu_to_be32( |
|---|
| 6148 | + (sfp[1] >> 7 & 1) << 3 | |
|---|
| 6149 | + (sfp[1] >> 6 & 1) << 2 | |
|---|
| 6150 | + (sfp[5] >> 7 & 1) << 1 | |
|---|
| 6151 | + (sfp[5] >> 6 & 1) << 0); |
|---|
| 6152 | + } |
|---|
| 6153 | + } |
|---|
| 6154 | + |
|---|
| 6155 | + /* Optical Product Data Descriptor */ |
|---|
| 6156 | + rsp_payload->optical_prod_desc.desc_tag = cpu_to_be32(0x10008); |
|---|
| 6157 | + rsp_payload->optical_prod_desc.desc_len = |
|---|
| 6158 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->optical_prod_desc)); |
|---|
| 6159 | + |
|---|
| 6160 | + if (sfp) { |
|---|
| 6161 | + memset(sfp, 0, SFP_RTDI_LEN); |
|---|
| 6162 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 20, 64, 0); |
|---|
| 6163 | + if (!rval) { |
|---|
| 6164 | + memcpy(rsp_payload->optical_prod_desc.vendor_name, |
|---|
| 6165 | + sfp + 0, |
|---|
| 6166 | + sizeof(rsp_payload->optical_prod_desc.vendor_name)); |
|---|
| 6167 | + memcpy(rsp_payload->optical_prod_desc.part_number, |
|---|
| 6168 | + sfp + 20, |
|---|
| 6169 | + sizeof(rsp_payload->optical_prod_desc.part_number)); |
|---|
| 6170 | + memcpy(rsp_payload->optical_prod_desc.revision, |
|---|
| 6171 | + sfp + 36, |
|---|
| 6172 | + sizeof(rsp_payload->optical_prod_desc.revision)); |
|---|
| 6173 | + memcpy(rsp_payload->optical_prod_desc.serial_number, |
|---|
| 6174 | + sfp + 48, |
|---|
| 6175 | + sizeof(rsp_payload->optical_prod_desc.serial_number)); |
|---|
| 6176 | + } |
|---|
| 6177 | + |
|---|
| 6178 | + memset(sfp, 0, SFP_RTDI_LEN); |
|---|
| 6179 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 84, 8, 0); |
|---|
| 6180 | + if (!rval) { |
|---|
| 6181 | + memcpy(rsp_payload->optical_prod_desc.date, |
|---|
| 6182 | + sfp + 0, |
|---|
| 6183 | + sizeof(rsp_payload->optical_prod_desc.date)); |
|---|
| 6184 | + } |
|---|
| 6185 | + } |
|---|
| 6186 | + |
|---|
| 6187 | +send: |
|---|
| 6188 | + ql_dbg(ql_dbg_init, vha, 0x0183, |
|---|
| 6189 | + "Sending ELS Response to RDP Request...\n"); |
|---|
| 6190 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0184, |
|---|
| 6191 | + "-------- ELS RSP -------\n"); |
|---|
| 6192 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0185, |
|---|
| 6193 | + rsp_els, sizeof(*rsp_els)); |
|---|
| 6194 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0186, |
|---|
| 6195 | + "-------- ELS RSP PAYLOAD -------\n"); |
|---|
| 6196 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0187, |
|---|
| 6197 | + rsp_payload, rsp_payload_length); |
|---|
| 6198 | + |
|---|
| 6199 | + rval = qla2x00_issue_iocb(vha, rsp_els, rsp_els_dma, 0); |
|---|
| 6200 | + |
|---|
| 6201 | + if (rval) { |
|---|
| 6202 | + ql_log(ql_log_warn, vha, 0x0188, |
|---|
| 6203 | + "%s: iocb failed to execute -> %x\n", __func__, rval); |
|---|
| 6204 | + } else if (rsp_els->comp_status) { |
|---|
| 6205 | + ql_log(ql_log_warn, vha, 0x0189, |
|---|
| 6206 | + "%s: iocb failed to complete -> completion=%#x subcode=(%#x,%#x)\n", |
|---|
| 6207 | + __func__, rsp_els->comp_status, |
|---|
| 6208 | + rsp_els->error_subcode_1, rsp_els->error_subcode_2); |
|---|
| 6209 | + } else { |
|---|
| 6210 | + ql_dbg(ql_dbg_init, vha, 0x018a, "%s: done.\n", __func__); |
|---|
| 6211 | + } |
|---|
| 6212 | + |
|---|
| 6213 | +dealloc: |
|---|
| 6214 | + if (stat) |
|---|
| 6215 | + dma_free_coherent(&ha->pdev->dev, sizeof(*stat), |
|---|
| 6216 | + stat, stat_dma); |
|---|
| 6217 | + if (sfp) |
|---|
| 6218 | + dma_free_coherent(&ha->pdev->dev, SFP_RTDI_LEN, |
|---|
| 6219 | + sfp, sfp_dma); |
|---|
| 6220 | + if (rsp_payload) |
|---|
| 6221 | + dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_payload), |
|---|
| 6222 | + rsp_payload, rsp_payload_dma); |
|---|
| 6223 | + if (rsp_els) |
|---|
| 6224 | + dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els), |
|---|
| 6225 | + rsp_els, rsp_els_dma); |
|---|
| 6226 | +} |
|---|
| 6227 | + |
|---|
| 6228 | +void |
|---|
| 6229 | +qla24xx_free_purex_item(struct purex_item *item) |
|---|
| 6230 | +{ |
|---|
| 6231 | + if (item == &item->vha->default_item) |
|---|
| 6232 | + memset(&item->vha->default_item, 0, sizeof(struct purex_item)); |
|---|
| 6233 | + else |
|---|
| 6234 | + kfree(item); |
|---|
| 6235 | +} |
|---|
| 6236 | + |
|---|
| 6237 | +void qla24xx_process_purex_list(struct purex_list *list) |
|---|
| 6238 | +{ |
|---|
| 6239 | + struct list_head head = LIST_HEAD_INIT(head); |
|---|
| 6240 | + struct purex_item *item, *next; |
|---|
| 6241 | + ulong flags; |
|---|
| 6242 | + |
|---|
| 6243 | + spin_lock_irqsave(&list->lock, flags); |
|---|
| 6244 | + list_splice_init(&list->head, &head); |
|---|
| 6245 | + spin_unlock_irqrestore(&list->lock, flags); |
|---|
| 6246 | + |
|---|
| 6247 | + list_for_each_entry_safe(item, next, &head, list) { |
|---|
| 6248 | + list_del(&item->list); |
|---|
| 6249 | + item->process_item(item->vha, item); |
|---|
| 6250 | + qla24xx_free_purex_item(item); |
|---|
| 6251 | + } |
|---|
| 5514 | 6252 | } |
|---|
| 5515 | 6253 | |
|---|
| 5516 | 6254 | void |
|---|
| .. | .. |
|---|
| 6034 | 6772 | } |
|---|
| 6035 | 6773 | |
|---|
| 6036 | 6774 | if (test_and_clear_bit(DETECT_SFP_CHANGE, |
|---|
| 6037 | | - &base_vha->dpc_flags) && |
|---|
| 6038 | | - !test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) { |
|---|
| 6039 | | - qla24xx_detect_sfp(base_vha); |
|---|
| 6040 | | - |
|---|
| 6041 | | - if (ha->flags.detected_lr_sfp != |
|---|
| 6042 | | - ha->flags.using_lr_setting) |
|---|
| 6043 | | - set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); |
|---|
| 6775 | + &base_vha->dpc_flags)) { |
|---|
| 6776 | + /* Semantic: |
|---|
| 6777 | + * - NO-OP -- await next ISP-ABORT. Preferred method |
|---|
| 6778 | + * to minimize disruptions that will occur |
|---|
| 6779 | + * when a forced chip-reset occurs. |
|---|
| 6780 | + * - Force -- ISP-ABORT scheduled. |
|---|
| 6781 | + */ |
|---|
| 6782 | + /* set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); */ |
|---|
| 6044 | 6783 | } |
|---|
| 6045 | 6784 | |
|---|
| 6046 | 6785 | if (test_and_clear_bit |
|---|
| .. | .. |
|---|
| 6048 | 6787 | !test_bit(UNLOADING, &base_vha->dpc_flags)) { |
|---|
| 6049 | 6788 | bool do_reset = true; |
|---|
| 6050 | 6789 | |
|---|
| 6051 | | - switch (ql2x_ini_mode) { |
|---|
| 6790 | + switch (base_vha->qlini_mode) { |
|---|
| 6052 | 6791 | case QLA2XXX_INI_MODE_ENABLED: |
|---|
| 6053 | 6792 | break; |
|---|
| 6054 | 6793 | case QLA2XXX_INI_MODE_DISABLED: |
|---|
| 6055 | | - if (!qla_tgt_mode_enabled(base_vha)) |
|---|
| 6794 | + if (!qla_tgt_mode_enabled(base_vha) && |
|---|
| 6795 | + !ha->flags.fw_started) |
|---|
| 6056 | 6796 | do_reset = false; |
|---|
| 6057 | 6797 | break; |
|---|
| 6058 | 6798 | case QLA2XXX_INI_MODE_DUAL: |
|---|
| 6059 | | - if (!qla_dual_mode_enabled(base_vha)) |
|---|
| 6799 | + if (!qla_dual_mode_enabled(base_vha) && |
|---|
| 6800 | + !ha->flags.fw_started) |
|---|
| 6060 | 6801 | do_reset = false; |
|---|
| 6061 | 6802 | break; |
|---|
| 6062 | 6803 | default: |
|---|
| .. | .. |
|---|
| 6077 | 6818 | &base_vha->dpc_flags); |
|---|
| 6078 | 6819 | ql_dbg(ql_dbg_dpc, base_vha, 0x4008, |
|---|
| 6079 | 6820 | "ISP abort end.\n"); |
|---|
| 6821 | + } |
|---|
| 6822 | + } |
|---|
| 6823 | + |
|---|
| 6824 | + if (test_bit(PROCESS_PUREX_IOCB, &base_vha->dpc_flags)) { |
|---|
| 6825 | + if (atomic_read(&base_vha->loop_state) == LOOP_READY) { |
|---|
| 6826 | + qla24xx_process_purex_list |
|---|
| 6827 | + (&base_vha->purex_list); |
|---|
| 6828 | + clear_bit(PROCESS_PUREX_IOCB, |
|---|
| 6829 | + &base_vha->dpc_flags); |
|---|
| 6080 | 6830 | } |
|---|
| 6081 | 6831 | } |
|---|
| 6082 | 6832 | |
|---|
| .. | .. |
|---|
| 6203 | 6953 | mutex_unlock(&ha->mq_lock); |
|---|
| 6204 | 6954 | } |
|---|
| 6205 | 6955 | |
|---|
| 6206 | | - if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED, &base_vha->dpc_flags)) { |
|---|
| 6956 | + if (test_and_clear_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, |
|---|
| 6957 | + &base_vha->dpc_flags)) { |
|---|
| 6207 | 6958 | ql_log(ql_log_info, base_vha, 0xffffff, |
|---|
| 6208 | 6959 | "nvme: SET ZIO Activity exchange threshold to %d.\n", |
|---|
| 6209 | 6960 | ha->nvme_last_rptd_aen); |
|---|
| 6210 | | - if (qla27xx_set_zio_threshold(base_vha, ha->nvme_last_rptd_aen)) { |
|---|
| 6961 | + if (qla27xx_set_zio_threshold(base_vha, |
|---|
| 6962 | + ha->nvme_last_rptd_aen)) { |
|---|
| 6211 | 6963 | ql_log(ql_log_info, base_vha, 0xffffff, |
|---|
| 6212 | | - "nvme: Unable to SET ZIO Activity exchange threshold to %d.\n", |
|---|
| 6213 | | - ha->nvme_last_rptd_aen); |
|---|
| 6964 | + "nvme: Unable to SET ZIO Activity exchange threshold to %d.\n", |
|---|
| 6965 | + ha->nvme_last_rptd_aen); |
|---|
| 6214 | 6966 | } |
|---|
| 6967 | + } |
|---|
| 6968 | + |
|---|
| 6969 | + if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED, |
|---|
| 6970 | + &base_vha->dpc_flags)) { |
|---|
| 6971 | + ql_log(ql_log_info, base_vha, 0xffffff, |
|---|
| 6972 | + "SET ZIO Activity exchange threshold to %d.\n", |
|---|
| 6973 | + ha->last_zio_threshold); |
|---|
| 6974 | + qla27xx_set_zio_threshold(base_vha, |
|---|
| 6975 | + ha->last_zio_threshold); |
|---|
| 6215 | 6976 | } |
|---|
| 6216 | 6977 | |
|---|
| 6217 | 6978 | if (!IS_QLAFX00(ha)) |
|---|
| .. | .. |
|---|
| 6426 | 7187 | * FC-NVME |
|---|
| 6427 | 7188 | * see if the active AEN count has changed from what was last reported. |
|---|
| 6428 | 7189 | */ |
|---|
| 7190 | + index = atomic_read(&ha->nvme_active_aen_cnt); |
|---|
| 6429 | 7191 | if (!vha->vp_idx && |
|---|
| 6430 | | - atomic_read(&ha->nvme_active_aen_cnt) != ha->nvme_last_rptd_aen && |
|---|
| 6431 | | - ha->zio_mode == QLA_ZIO_MODE_6) { |
|---|
| 7192 | + (index != ha->nvme_last_rptd_aen) && |
|---|
| 7193 | + (index >= DEFAULT_ZIO_THRESHOLD) && |
|---|
| 7194 | + ha->zio_mode == QLA_ZIO_MODE_6 && |
|---|
| 7195 | + !ha->flags.host_shutting_down) { |
|---|
| 6432 | 7196 | ql_log(ql_log_info, vha, 0x3002, |
|---|
| 6433 | | - "nvme: Sched: Set ZIO exchange threshold to %d.\n", |
|---|
| 6434 | | - ha->nvme_last_rptd_aen); |
|---|
| 7197 | + "nvme: Sched: Set ZIO exchange threshold to %d.\n", |
|---|
| 7198 | + ha->nvme_last_rptd_aen); |
|---|
| 6435 | 7199 | ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt); |
|---|
| 7200 | + set_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); |
|---|
| 7201 | + start_dpc++; |
|---|
| 7202 | + } |
|---|
| 7203 | + |
|---|
| 7204 | + if (!vha->vp_idx && |
|---|
| 7205 | + atomic_read(&ha->zio_threshold) != ha->last_zio_threshold && |
|---|
| 7206 | + IS_ZIO_THRESHOLD_CAPABLE(ha)) { |
|---|
| 7207 | + ql_log(ql_log_info, vha, 0x3002, |
|---|
| 7208 | + "Sched: Set ZIO exchange threshold to %d.\n", |
|---|
| 7209 | + ha->last_zio_threshold); |
|---|
| 7210 | + ha->last_zio_threshold = atomic_read(&ha->zio_threshold); |
|---|
| 6436 | 7211 | set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); |
|---|
| 6437 | 7212 | start_dpc++; |
|---|
| 6438 | 7213 | } |
|---|
| .. | .. |
|---|
| 6447 | 7222 | test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) || |
|---|
| 6448 | 7223 | test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) || |
|---|
| 6449 | 7224 | test_bit(VP_DPC_NEEDED, &vha->dpc_flags) || |
|---|
| 6450 | | - test_bit(RELOGIN_NEEDED, &vha->dpc_flags))) { |
|---|
| 7225 | + test_bit(RELOGIN_NEEDED, &vha->dpc_flags) || |
|---|
| 7226 | + test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags))) { |
|---|
| 6451 | 7227 | ql_dbg(ql_dbg_timer, vha, 0x600b, |
|---|
| 6452 | 7228 | "isp_abort_needed=%d loop_resync_needed=%d " |
|---|
| 6453 | 7229 | "fcport_update_needed=%d start_dpc=%d " |
|---|
| .. | .. |
|---|
| 6460 | 7236 | ql_dbg(ql_dbg_timer, vha, 0x600c, |
|---|
| 6461 | 7237 | "beacon_blink_needed=%d isp_unrecoverable=%d " |
|---|
| 6462 | 7238 | "fcoe_ctx_reset_needed=%d vp_dpc_needed=%d " |
|---|
| 6463 | | - "relogin_needed=%d.\n", |
|---|
| 7239 | + "relogin_needed=%d, Process_purex_iocb=%d.\n", |
|---|
| 6464 | 7240 | test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags), |
|---|
| 6465 | 7241 | test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags), |
|---|
| 6466 | 7242 | test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags), |
|---|
| 6467 | 7243 | test_bit(VP_DPC_NEEDED, &vha->dpc_flags), |
|---|
| 6468 | | - test_bit(RELOGIN_NEEDED, &vha->dpc_flags)); |
|---|
| 7244 | + test_bit(RELOGIN_NEEDED, &vha->dpc_flags), |
|---|
| 7245 | + test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags)); |
|---|
| 6469 | 7246 | qla2xxx_wake_dpc(vha); |
|---|
| 6470 | 7247 | } |
|---|
| 6471 | 7248 | |
|---|
| .. | .. |
|---|
| 6474 | 7251 | |
|---|
| 6475 | 7252 | /* Firmware interface routines. */ |
|---|
| 6476 | 7253 | |
|---|
| 6477 | | -#define FW_BLOBS 11 |
|---|
| 6478 | 7254 | #define FW_ISP21XX 0 |
|---|
| 6479 | 7255 | #define FW_ISP22XX 1 |
|---|
| 6480 | 7256 | #define FW_ISP2300 2 |
|---|
| .. | .. |
|---|
| 6486 | 7262 | #define FW_ISP2031 8 |
|---|
| 6487 | 7263 | #define FW_ISP8031 9 |
|---|
| 6488 | 7264 | #define FW_ISP27XX 10 |
|---|
| 7265 | +#define FW_ISP28XX 11 |
|---|
| 6489 | 7266 | |
|---|
| 6490 | 7267 | #define FW_FILE_ISP21XX "ql2100_fw.bin" |
|---|
| 6491 | 7268 | #define FW_FILE_ISP22XX "ql2200_fw.bin" |
|---|
| .. | .. |
|---|
| 6498 | 7275 | #define FW_FILE_ISP2031 "ql2600_fw.bin" |
|---|
| 6499 | 7276 | #define FW_FILE_ISP8031 "ql8300_fw.bin" |
|---|
| 6500 | 7277 | #define FW_FILE_ISP27XX "ql2700_fw.bin" |
|---|
| 7278 | +#define FW_FILE_ISP28XX "ql2800_fw.bin" |
|---|
| 6501 | 7279 | |
|---|
| 6502 | 7280 | |
|---|
| 6503 | 7281 | static DEFINE_MUTEX(qla_fw_lock); |
|---|
| 6504 | 7282 | |
|---|
| 6505 | | -static struct fw_blob qla_fw_blobs[FW_BLOBS] = { |
|---|
| 7283 | +static struct fw_blob qla_fw_blobs[] = { |
|---|
| 6506 | 7284 | { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, |
|---|
| 6507 | 7285 | { .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, }, |
|---|
| 6508 | 7286 | { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, }, |
|---|
| .. | .. |
|---|
| 6514 | 7292 | { .name = FW_FILE_ISP2031, }, |
|---|
| 6515 | 7293 | { .name = FW_FILE_ISP8031, }, |
|---|
| 6516 | 7294 | { .name = FW_FILE_ISP27XX, }, |
|---|
| 7295 | + { .name = FW_FILE_ISP28XX, }, |
|---|
| 7296 | + { .name = NULL, }, |
|---|
| 6517 | 7297 | }; |
|---|
| 6518 | 7298 | |
|---|
| 6519 | 7299 | struct fw_blob * |
|---|
| .. | .. |
|---|
| 6544 | 7324 | blob = &qla_fw_blobs[FW_ISP8031]; |
|---|
| 6545 | 7325 | } else if (IS_QLA27XX(ha)) { |
|---|
| 6546 | 7326 | blob = &qla_fw_blobs[FW_ISP27XX]; |
|---|
| 7327 | + } else if (IS_QLA28XX(ha)) { |
|---|
| 7328 | + blob = &qla_fw_blobs[FW_ISP28XX]; |
|---|
| 6547 | 7329 | } else { |
|---|
| 6548 | 7330 | return NULL; |
|---|
| 6549 | 7331 | } |
|---|
| 7332 | + |
|---|
| 7333 | + if (!blob->name) |
|---|
| 7334 | + return NULL; |
|---|
| 6550 | 7335 | |
|---|
| 6551 | 7336 | mutex_lock(&qla_fw_lock); |
|---|
| 6552 | 7337 | if (blob->fw) |
|---|
| .. | .. |
|---|
| 6557 | 7342 | "Failed to load firmware image (%s).\n", blob->name); |
|---|
| 6558 | 7343 | blob->fw = NULL; |
|---|
| 6559 | 7344 | blob = NULL; |
|---|
| 6560 | | - goto out; |
|---|
| 6561 | 7345 | } |
|---|
| 6562 | 7346 | |
|---|
| 6563 | 7347 | out: |
|---|
| .. | .. |
|---|
| 6568 | 7352 | static void |
|---|
| 6569 | 7353 | qla2x00_release_firmware(void) |
|---|
| 6570 | 7354 | { |
|---|
| 6571 | | - int idx; |
|---|
| 7355 | + struct fw_blob *blob; |
|---|
| 6572 | 7356 | |
|---|
| 6573 | 7357 | mutex_lock(&qla_fw_lock); |
|---|
| 6574 | | - for (idx = 0; idx < FW_BLOBS; idx++) |
|---|
| 6575 | | - release_firmware(qla_fw_blobs[idx].fw); |
|---|
| 7358 | + for (blob = qla_fw_blobs; blob->name; blob++) |
|---|
| 7359 | + release_firmware(blob->fw); |
|---|
| 6576 | 7360 | mutex_unlock(&qla_fw_lock); |
|---|
| 6577 | 7361 | } |
|---|
| 7362 | + |
|---|
| 7363 | +static void qla_pci_error_cleanup(scsi_qla_host_t *vha) |
|---|
| 7364 | +{ |
|---|
| 7365 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 7366 | + scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
|---|
| 7367 | + struct qla_qpair *qpair = NULL; |
|---|
| 7368 | + struct scsi_qla_host *vp; |
|---|
| 7369 | + fc_port_t *fcport; |
|---|
| 7370 | + int i; |
|---|
| 7371 | + unsigned long flags; |
|---|
| 7372 | + |
|---|
| 7373 | + ha->chip_reset++; |
|---|
| 7374 | + |
|---|
| 7375 | + ha->base_qpair->chip_reset = ha->chip_reset; |
|---|
| 7376 | + for (i = 0; i < ha->max_qpairs; i++) { |
|---|
| 7377 | + if (ha->queue_pair_map[i]) |
|---|
| 7378 | + ha->queue_pair_map[i]->chip_reset = |
|---|
| 7379 | + ha->base_qpair->chip_reset; |
|---|
| 7380 | + } |
|---|
| 7381 | + |
|---|
| 7382 | + /* purge MBox commands */ |
|---|
| 7383 | + if (atomic_read(&ha->num_pend_mbx_stage3)) { |
|---|
| 7384 | + clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
|---|
| 7385 | + complete(&ha->mbx_intr_comp); |
|---|
| 7386 | + } |
|---|
| 7387 | + |
|---|
| 7388 | + i = 0; |
|---|
| 7389 | + |
|---|
| 7390 | + while (atomic_read(&ha->num_pend_mbx_stage3) || |
|---|
| 7391 | + atomic_read(&ha->num_pend_mbx_stage2) || |
|---|
| 7392 | + atomic_read(&ha->num_pend_mbx_stage1)) { |
|---|
| 7393 | + msleep(20); |
|---|
| 7394 | + i++; |
|---|
| 7395 | + if (i > 50) |
|---|
| 7396 | + break; |
|---|
| 7397 | + } |
|---|
| 7398 | + |
|---|
| 7399 | + ha->flags.purge_mbox = 0; |
|---|
| 7400 | + |
|---|
| 7401 | + mutex_lock(&ha->mq_lock); |
|---|
| 7402 | + list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
|---|
| 7403 | + qpair->online = 0; |
|---|
| 7404 | + mutex_unlock(&ha->mq_lock); |
|---|
| 7405 | + |
|---|
| 7406 | + qla2x00_mark_all_devices_lost(vha); |
|---|
| 7407 | + |
|---|
| 7408 | + spin_lock_irqsave(&ha->vport_slock, flags); |
|---|
| 7409 | + list_for_each_entry(vp, &ha->vp_list, list) { |
|---|
| 7410 | + atomic_inc(&vp->vref_count); |
|---|
| 7411 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
|---|
| 7412 | + qla2x00_mark_all_devices_lost(vp); |
|---|
| 7413 | + spin_lock_irqsave(&ha->vport_slock, flags); |
|---|
| 7414 | + atomic_dec(&vp->vref_count); |
|---|
| 7415 | + } |
|---|
| 7416 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
|---|
| 7417 | + |
|---|
| 7418 | + /* Clear all async request states across all VPs. */ |
|---|
| 7419 | + list_for_each_entry(fcport, &vha->vp_fcports, list) |
|---|
| 7420 | + fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); |
|---|
| 7421 | + |
|---|
| 7422 | + spin_lock_irqsave(&ha->vport_slock, flags); |
|---|
| 7423 | + list_for_each_entry(vp, &ha->vp_list, list) { |
|---|
| 7424 | + atomic_inc(&vp->vref_count); |
|---|
| 7425 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
|---|
| 7426 | + list_for_each_entry(fcport, &vp->vp_fcports, list) |
|---|
| 7427 | + fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); |
|---|
| 7428 | + spin_lock_irqsave(&ha->vport_slock, flags); |
|---|
| 7429 | + atomic_dec(&vp->vref_count); |
|---|
| 7430 | + } |
|---|
| 7431 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
|---|
| 7432 | +} |
|---|
| 7433 | + |
|---|
| 6578 | 7434 | |
|---|
| 6579 | 7435 | static pci_ers_result_t |
|---|
| 6580 | 7436 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) |
|---|
| .. | .. |
|---|
| 6601 | 7457 | return PCI_ERS_RESULT_CAN_RECOVER; |
|---|
| 6602 | 7458 | case pci_channel_io_frozen: |
|---|
| 6603 | 7459 | ha->flags.eeh_busy = 1; |
|---|
| 6604 | | - /* For ISP82XX complete any pending mailbox cmd */ |
|---|
| 6605 | | - if (IS_QLA82XX(ha)) { |
|---|
| 6606 | | - ha->flags.isp82xx_fw_hung = 1; |
|---|
| 6607 | | - ql_dbg(ql_dbg_aer, vha, 0x9001, "Pci channel io frozen\n"); |
|---|
| 6608 | | - qla82xx_clear_pending_mbx(vha); |
|---|
| 6609 | | - } |
|---|
| 6610 | | - qla2x00_free_irqs(vha); |
|---|
| 6611 | | - pci_disable_device(pdev); |
|---|
| 6612 | | - /* Return back all IOs */ |
|---|
| 6613 | | - qla2x00_abort_all_cmds(vha, DID_RESET << 16); |
|---|
| 6614 | | - if (ql2xmqsupport || ql2xnvmeenable) { |
|---|
| 6615 | | - set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); |
|---|
| 6616 | | - qla2xxx_wake_dpc(vha); |
|---|
| 6617 | | - } |
|---|
| 7460 | + qla_pci_error_cleanup(vha); |
|---|
| 6618 | 7461 | return PCI_ERS_RESULT_NEED_RESET; |
|---|
| 6619 | 7462 | case pci_channel_io_perm_failure: |
|---|
| 6620 | 7463 | ha->flags.pci_channel_io_perm_failure = 1; |
|---|
| .. | .. |
|---|
| 6644 | 7487 | |
|---|
| 6645 | 7488 | spin_lock_irqsave(&ha->hardware_lock, flags); |
|---|
| 6646 | 7489 | if (IS_QLA2100(ha) || IS_QLA2200(ha)){ |
|---|
| 6647 | | - stat = RD_REG_DWORD(®->hccr); |
|---|
| 7490 | + stat = rd_reg_word(®->hccr); |
|---|
| 6648 | 7491 | if (stat & HCCR_RISC_PAUSE) |
|---|
| 6649 | 7492 | risc_paused = 1; |
|---|
| 6650 | 7493 | } else if (IS_QLA23XX(ha)) { |
|---|
| 6651 | | - stat = RD_REG_DWORD(®->u.isp2300.host_status); |
|---|
| 7494 | + stat = rd_reg_dword(®->u.isp2300.host_status); |
|---|
| 6652 | 7495 | if (stat & HSR_RISC_PAUSED) |
|---|
| 6653 | 7496 | risc_paused = 1; |
|---|
| 6654 | 7497 | } else if (IS_FWI2_CAPABLE(ha)) { |
|---|
| 6655 | | - stat = RD_REG_DWORD(®24->host_status); |
|---|
| 7498 | + stat = rd_reg_dword(®24->host_status); |
|---|
| 6656 | 7499 | if (stat & HSRX_RISC_PAUSED) |
|---|
| 6657 | 7500 | risc_paused = 1; |
|---|
| 6658 | 7501 | } |
|---|
| .. | .. |
|---|
| 6661 | 7504 | if (risc_paused) { |
|---|
| 6662 | 7505 | ql_log(ql_log_info, base_vha, 0x9003, |
|---|
| 6663 | 7506 | "RISC paused -- mmio_enabled, Dumping firmware.\n"); |
|---|
| 6664 | | - ha->isp_ops->fw_dump(base_vha, 0); |
|---|
| 7507 | + qla2xxx_dump_fw(base_vha); |
|---|
| 6665 | 7508 | |
|---|
| 6666 | 7509 | return PCI_ERS_RESULT_NEED_RESET; |
|---|
| 6667 | 7510 | } else |
|---|
| 6668 | 7511 | return PCI_ERS_RESULT_RECOVERED; |
|---|
| 6669 | | -} |
|---|
| 6670 | | - |
|---|
| 6671 | | -static uint32_t |
|---|
| 6672 | | -qla82xx_error_recovery(scsi_qla_host_t *base_vha) |
|---|
| 6673 | | -{ |
|---|
| 6674 | | - uint32_t rval = QLA_FUNCTION_FAILED; |
|---|
| 6675 | | - uint32_t drv_active = 0; |
|---|
| 6676 | | - struct qla_hw_data *ha = base_vha->hw; |
|---|
| 6677 | | - int fn; |
|---|
| 6678 | | - struct pci_dev *other_pdev = NULL; |
|---|
| 6679 | | - |
|---|
| 6680 | | - ql_dbg(ql_dbg_aer, base_vha, 0x9006, |
|---|
| 6681 | | - "Entered %s.\n", __func__); |
|---|
| 6682 | | - |
|---|
| 6683 | | - set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
|---|
| 6684 | | - |
|---|
| 6685 | | - if (base_vha->flags.online) { |
|---|
| 6686 | | - /* Abort all outstanding commands, |
|---|
| 6687 | | - * so as to be requeued later */ |
|---|
| 6688 | | - qla2x00_abort_isp_cleanup(base_vha); |
|---|
| 6689 | | - } |
|---|
| 6690 | | - |
|---|
| 6691 | | - |
|---|
| 6692 | | - fn = PCI_FUNC(ha->pdev->devfn); |
|---|
| 6693 | | - while (fn > 0) { |
|---|
| 6694 | | - fn--; |
|---|
| 6695 | | - ql_dbg(ql_dbg_aer, base_vha, 0x9007, |
|---|
| 6696 | | - "Finding pci device at function = 0x%x.\n", fn); |
|---|
| 6697 | | - other_pdev = |
|---|
| 6698 | | - pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus), |
|---|
| 6699 | | - ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn), |
|---|
| 6700 | | - fn)); |
|---|
| 6701 | | - |
|---|
| 6702 | | - if (!other_pdev) |
|---|
| 6703 | | - continue; |
|---|
| 6704 | | - if (atomic_read(&other_pdev->enable_cnt)) { |
|---|
| 6705 | | - ql_dbg(ql_dbg_aer, base_vha, 0x9008, |
|---|
| 6706 | | - "Found PCI func available and enable at 0x%x.\n", |
|---|
| 6707 | | - fn); |
|---|
| 6708 | | - pci_dev_put(other_pdev); |
|---|
| 6709 | | - break; |
|---|
| 6710 | | - } |
|---|
| 6711 | | - pci_dev_put(other_pdev); |
|---|
| 6712 | | - } |
|---|
| 6713 | | - |
|---|
| 6714 | | - if (!fn) { |
|---|
| 6715 | | - /* Reset owner */ |
|---|
| 6716 | | - ql_dbg(ql_dbg_aer, base_vha, 0x9009, |
|---|
| 6717 | | - "This devfn is reset owner = 0x%x.\n", |
|---|
| 6718 | | - ha->pdev->devfn); |
|---|
| 6719 | | - qla82xx_idc_lock(ha); |
|---|
| 6720 | | - |
|---|
| 6721 | | - qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, |
|---|
| 6722 | | - QLA8XXX_DEV_INITIALIZING); |
|---|
| 6723 | | - |
|---|
| 6724 | | - qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, |
|---|
| 6725 | | - QLA82XX_IDC_VERSION); |
|---|
| 6726 | | - |
|---|
| 6727 | | - drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); |
|---|
| 6728 | | - ql_dbg(ql_dbg_aer, base_vha, 0x900a, |
|---|
| 6729 | | - "drv_active = 0x%x.\n", drv_active); |
|---|
| 6730 | | - |
|---|
| 6731 | | - qla82xx_idc_unlock(ha); |
|---|
| 6732 | | - /* Reset if device is not already reset |
|---|
| 6733 | | - * drv_active would be 0 if a reset has already been done |
|---|
| 6734 | | - */ |
|---|
| 6735 | | - if (drv_active) |
|---|
| 6736 | | - rval = qla82xx_start_firmware(base_vha); |
|---|
| 6737 | | - else |
|---|
| 6738 | | - rval = QLA_SUCCESS; |
|---|
| 6739 | | - qla82xx_idc_lock(ha); |
|---|
| 6740 | | - |
|---|
| 6741 | | - if (rval != QLA_SUCCESS) { |
|---|
| 6742 | | - ql_log(ql_log_info, base_vha, 0x900b, |
|---|
| 6743 | | - "HW State: FAILED.\n"); |
|---|
| 6744 | | - qla82xx_clear_drv_active(ha); |
|---|
| 6745 | | - qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, |
|---|
| 6746 | | - QLA8XXX_DEV_FAILED); |
|---|
| 6747 | | - } else { |
|---|
| 6748 | | - ql_log(ql_log_info, base_vha, 0x900c, |
|---|
| 6749 | | - "HW State: READY.\n"); |
|---|
| 6750 | | - qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, |
|---|
| 6751 | | - QLA8XXX_DEV_READY); |
|---|
| 6752 | | - qla82xx_idc_unlock(ha); |
|---|
| 6753 | | - ha->flags.isp82xx_fw_hung = 0; |
|---|
| 6754 | | - rval = qla82xx_restart_isp(base_vha); |
|---|
| 6755 | | - qla82xx_idc_lock(ha); |
|---|
| 6756 | | - /* Clear driver state register */ |
|---|
| 6757 | | - qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0); |
|---|
| 6758 | | - qla82xx_set_drv_active(base_vha); |
|---|
| 6759 | | - } |
|---|
| 6760 | | - qla82xx_idc_unlock(ha); |
|---|
| 6761 | | - } else { |
|---|
| 6762 | | - ql_dbg(ql_dbg_aer, base_vha, 0x900d, |
|---|
| 6763 | | - "This devfn is not reset owner = 0x%x.\n", |
|---|
| 6764 | | - ha->pdev->devfn); |
|---|
| 6765 | | - if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == |
|---|
| 6766 | | - QLA8XXX_DEV_READY)) { |
|---|
| 6767 | | - ha->flags.isp82xx_fw_hung = 0; |
|---|
| 6768 | | - rval = qla82xx_restart_isp(base_vha); |
|---|
| 6769 | | - qla82xx_idc_lock(ha); |
|---|
| 6770 | | - qla82xx_set_drv_active(base_vha); |
|---|
| 6771 | | - qla82xx_idc_unlock(ha); |
|---|
| 6772 | | - } |
|---|
| 6773 | | - } |
|---|
| 6774 | | - clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
|---|
| 6775 | | - |
|---|
| 6776 | | - return rval; |
|---|
| 6777 | 7512 | } |
|---|
| 6778 | 7513 | |
|---|
| 6779 | 7514 | static pci_ers_result_t |
|---|
| .. | .. |
|---|
| 6782 | 7517 | pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; |
|---|
| 6783 | 7518 | scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); |
|---|
| 6784 | 7519 | struct qla_hw_data *ha = base_vha->hw; |
|---|
| 6785 | | - struct rsp_que *rsp; |
|---|
| 6786 | | - int rc, retries = 10; |
|---|
| 7520 | + int rc; |
|---|
| 7521 | + struct qla_qpair *qpair = NULL; |
|---|
| 6787 | 7522 | |
|---|
| 6788 | 7523 | ql_dbg(ql_dbg_aer, base_vha, 0x9004, |
|---|
| 6789 | 7524 | "Slot Reset.\n"); |
|---|
| .. | .. |
|---|
| 6812 | 7547 | goto exit_slot_reset; |
|---|
| 6813 | 7548 | } |
|---|
| 6814 | 7549 | |
|---|
| 6815 | | - rsp = ha->rsp_q_map[0]; |
|---|
| 6816 | | - if (qla2x00_request_irqs(ha, rsp)) |
|---|
| 6817 | | - goto exit_slot_reset; |
|---|
| 6818 | 7550 | |
|---|
| 6819 | 7551 | if (ha->isp_ops->pci_config(base_vha)) |
|---|
| 6820 | 7552 | goto exit_slot_reset; |
|---|
| 6821 | 7553 | |
|---|
| 6822 | | - if (IS_QLA82XX(ha)) { |
|---|
| 6823 | | - if (qla82xx_error_recovery(base_vha) == QLA_SUCCESS) { |
|---|
| 6824 | | - ret = PCI_ERS_RESULT_RECOVERED; |
|---|
| 6825 | | - goto exit_slot_reset; |
|---|
| 6826 | | - } else |
|---|
| 6827 | | - goto exit_slot_reset; |
|---|
| 6828 | | - } |
|---|
| 7554 | + mutex_lock(&ha->mq_lock); |
|---|
| 7555 | + list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
|---|
| 7556 | + qpair->online = 1; |
|---|
| 7557 | + mutex_unlock(&ha->mq_lock); |
|---|
| 6829 | 7558 | |
|---|
| 6830 | | - while (ha->flags.mbox_busy && retries--) |
|---|
| 6831 | | - msleep(1000); |
|---|
| 6832 | | - |
|---|
| 7559 | + base_vha->flags.online = 1; |
|---|
| 6833 | 7560 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
|---|
| 6834 | 7561 | if (ha->isp_ops->abort_isp(base_vha) == QLA_SUCCESS) |
|---|
| 6835 | 7562 | ret = PCI_ERS_RESULT_RECOVERED; |
|---|
| .. | .. |
|---|
| 6853 | 7580 | ql_dbg(ql_dbg_aer, base_vha, 0x900f, |
|---|
| 6854 | 7581 | "pci_resume.\n"); |
|---|
| 6855 | 7582 | |
|---|
| 7583 | + ha->flags.eeh_busy = 0; |
|---|
| 7584 | + |
|---|
| 6856 | 7585 | ret = qla2x00_wait_for_hba_online(base_vha); |
|---|
| 6857 | 7586 | if (ret != QLA_SUCCESS) { |
|---|
| 6858 | 7587 | ql_log(ql_log_fatal, base_vha, 0x9002, |
|---|
| 6859 | 7588 | "The device failed to resume I/O from slot/link_reset.\n"); |
|---|
| 6860 | 7589 | } |
|---|
| 7590 | +} |
|---|
| 6861 | 7591 | |
|---|
| 6862 | | - pci_cleanup_aer_uncorrect_error_status(pdev); |
|---|
| 7592 | +static void |
|---|
| 7593 | +qla_pci_reset_prepare(struct pci_dev *pdev) |
|---|
| 7594 | +{ |
|---|
| 7595 | + scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); |
|---|
| 7596 | + struct qla_hw_data *ha = base_vha->hw; |
|---|
| 7597 | + struct qla_qpair *qpair; |
|---|
| 6863 | 7598 | |
|---|
| 7599 | + ql_log(ql_log_warn, base_vha, 0xffff, |
|---|
| 7600 | + "%s.\n", __func__); |
|---|
| 7601 | + |
|---|
| 7602 | + /* |
|---|
| 7603 | + * PCI FLR/function reset is about to reset the |
|---|
| 7604 | + * slot. Stop the chip to stop all DMA access. |
|---|
| 7605 | + * It is assumed that pci_reset_done will be called |
|---|
| 7606 | + * after FLR to resume Chip operation. |
|---|
| 7607 | + */ |
|---|
| 7608 | + ha->flags.eeh_busy = 1; |
|---|
| 7609 | + mutex_lock(&ha->mq_lock); |
|---|
| 7610 | + list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
|---|
| 7611 | + qpair->online = 0; |
|---|
| 7612 | + mutex_unlock(&ha->mq_lock); |
|---|
| 7613 | + |
|---|
| 7614 | + set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
|---|
| 7615 | + qla2x00_abort_isp_cleanup(base_vha); |
|---|
| 7616 | + qla2x00_abort_all_cmds(base_vha, DID_RESET << 16); |
|---|
| 7617 | +} |
|---|
| 7618 | + |
|---|
| 7619 | +static void |
|---|
| 7620 | +qla_pci_reset_done(struct pci_dev *pdev) |
|---|
| 7621 | +{ |
|---|
| 7622 | + scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); |
|---|
| 7623 | + struct qla_hw_data *ha = base_vha->hw; |
|---|
| 7624 | + struct qla_qpair *qpair; |
|---|
| 7625 | + |
|---|
| 7626 | + ql_log(ql_log_warn, base_vha, 0xffff, |
|---|
| 7627 | + "%s.\n", __func__); |
|---|
| 7628 | + |
|---|
| 7629 | + /* |
|---|
| 7630 | + * FLR just completed by PCI layer. Resume adapter |
|---|
| 7631 | + */ |
|---|
| 6864 | 7632 | ha->flags.eeh_busy = 0; |
|---|
| 7633 | + mutex_lock(&ha->mq_lock); |
|---|
| 7634 | + list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
|---|
| 7635 | + qpair->online = 1; |
|---|
| 7636 | + mutex_unlock(&ha->mq_lock); |
|---|
| 7637 | + |
|---|
| 7638 | + base_vha->flags.online = 1; |
|---|
| 7639 | + ha->isp_ops->abort_isp(base_vha); |
|---|
| 7640 | + clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
|---|
| 6865 | 7641 | } |
|---|
| 6866 | 7642 | |
|---|
| 6867 | 7643 | static int qla2xxx_map_queues(struct Scsi_Host *shost) |
|---|
| 6868 | 7644 | { |
|---|
| 6869 | 7645 | int rc; |
|---|
| 6870 | 7646 | scsi_qla_host_t *vha = (scsi_qla_host_t *)shost->hostdata; |
|---|
| 7647 | + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; |
|---|
| 6871 | 7648 | |
|---|
| 6872 | | - if (USER_CTRL_IRQ(vha->hw)) |
|---|
| 6873 | | - rc = blk_mq_map_queues(&shost->tag_set); |
|---|
| 7649 | + if (USER_CTRL_IRQ(vha->hw) || !vha->hw->mqiobase) |
|---|
| 7650 | + rc = blk_mq_map_queues(qmap); |
|---|
| 6874 | 7651 | else |
|---|
| 6875 | | - rc = blk_mq_pci_map_queues(&shost->tag_set, vha->hw->pdev, 0); |
|---|
| 7652 | + rc = blk_mq_pci_map_queues(qmap, vha->hw->pdev, vha->irq_offset); |
|---|
| 6876 | 7653 | return rc; |
|---|
| 6877 | 7654 | } |
|---|
| 7655 | + |
|---|
| 7656 | +struct scsi_host_template qla2xxx_driver_template = { |
|---|
| 7657 | + .module = THIS_MODULE, |
|---|
| 7658 | + .name = QLA2XXX_DRIVER_NAME, |
|---|
| 7659 | + .queuecommand = qla2xxx_queuecommand, |
|---|
| 7660 | + |
|---|
| 7661 | + .eh_timed_out = fc_eh_timed_out, |
|---|
| 7662 | + .eh_abort_handler = qla2xxx_eh_abort, |
|---|
| 7663 | + .eh_device_reset_handler = qla2xxx_eh_device_reset, |
|---|
| 7664 | + .eh_target_reset_handler = qla2xxx_eh_target_reset, |
|---|
| 7665 | + .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
|---|
| 7666 | + .eh_host_reset_handler = qla2xxx_eh_host_reset, |
|---|
| 7667 | + |
|---|
| 7668 | + .slave_configure = qla2xxx_slave_configure, |
|---|
| 7669 | + |
|---|
| 7670 | + .slave_alloc = qla2xxx_slave_alloc, |
|---|
| 7671 | + .slave_destroy = qla2xxx_slave_destroy, |
|---|
| 7672 | + .scan_finished = qla2xxx_scan_finished, |
|---|
| 7673 | + .scan_start = qla2xxx_scan_start, |
|---|
| 7674 | + .change_queue_depth = scsi_change_queue_depth, |
|---|
| 7675 | + .map_queues = qla2xxx_map_queues, |
|---|
| 7676 | + .this_id = -1, |
|---|
| 7677 | + .cmd_per_lun = 3, |
|---|
| 7678 | + .sg_tablesize = SG_ALL, |
|---|
| 7679 | + |
|---|
| 7680 | + .max_sectors = 0xFFFF, |
|---|
| 7681 | + .shost_attrs = qla2x00_host_attrs, |
|---|
| 7682 | + |
|---|
| 7683 | + .supported_mode = MODE_INITIATOR, |
|---|
| 7684 | + .track_queue_depth = 1, |
|---|
| 7685 | + .cmd_size = sizeof(srb_t), |
|---|
| 7686 | +}; |
|---|
| 6878 | 7687 | |
|---|
| 6879 | 7688 | static const struct pci_error_handlers qla2xxx_err_handler = { |
|---|
| 6880 | 7689 | .error_detected = qla2xxx_pci_error_detected, |
|---|
| 6881 | 7690 | .mmio_enabled = qla2xxx_pci_mmio_enabled, |
|---|
| 6882 | 7691 | .slot_reset = qla2xxx_pci_slot_reset, |
|---|
| 6883 | 7692 | .resume = qla2xxx_pci_resume, |
|---|
| 7693 | + .reset_prepare = qla_pci_reset_prepare, |
|---|
| 7694 | + .reset_done = qla_pci_reset_done, |
|---|
| 6884 | 7695 | }; |
|---|
| 6885 | 7696 | |
|---|
| 6886 | 7697 | static struct pci_device_id qla2xxx_pci_tbl[] = { |
|---|
| .. | .. |
|---|
| 6906 | 7717 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) }, |
|---|
| 6907 | 7718 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) }, |
|---|
| 6908 | 7719 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2261) }, |
|---|
| 7720 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2061) }, |
|---|
| 7721 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2081) }, |
|---|
| 7722 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2281) }, |
|---|
| 7723 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2089) }, |
|---|
| 7724 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2289) }, |
|---|
| 6909 | 7725 | { 0 }, |
|---|
| 6910 | 7726 | }; |
|---|
| 6911 | 7727 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
|---|
| .. | .. |
|---|
| 6934 | 7750 | qla2x00_module_init(void) |
|---|
| 6935 | 7751 | { |
|---|
| 6936 | 7752 | int ret = 0; |
|---|
| 7753 | + |
|---|
| 7754 | + BUILD_BUG_ON(sizeof(cmd_a64_entry_t) != 64); |
|---|
| 7755 | + BUILD_BUG_ON(sizeof(cmd_entry_t) != 64); |
|---|
| 7756 | + BUILD_BUG_ON(sizeof(cont_a64_entry_t) != 64); |
|---|
| 7757 | + BUILD_BUG_ON(sizeof(cont_entry_t) != 64); |
|---|
| 7758 | + BUILD_BUG_ON(sizeof(init_cb_t) != 96); |
|---|
| 7759 | + BUILD_BUG_ON(sizeof(mrk_entry_t) != 64); |
|---|
| 7760 | + BUILD_BUG_ON(sizeof(ms_iocb_entry_t) != 64); |
|---|
| 7761 | + BUILD_BUG_ON(sizeof(request_t) != 64); |
|---|
| 7762 | + BUILD_BUG_ON(sizeof(struct abort_entry_24xx) != 64); |
|---|
| 7763 | + BUILD_BUG_ON(sizeof(struct abort_iocb_entry_fx00) != 64); |
|---|
| 7764 | + BUILD_BUG_ON(sizeof(struct abts_entry_24xx) != 64); |
|---|
| 7765 | + BUILD_BUG_ON(sizeof(struct access_chip_84xx) != 64); |
|---|
| 7766 | + BUILD_BUG_ON(sizeof(struct access_chip_rsp_84xx) != 64); |
|---|
| 7767 | + BUILD_BUG_ON(sizeof(struct cmd_bidir) != 64); |
|---|
| 7768 | + BUILD_BUG_ON(sizeof(struct cmd_nvme) != 64); |
|---|
| 7769 | + BUILD_BUG_ON(sizeof(struct cmd_type_6) != 64); |
|---|
| 7770 | + BUILD_BUG_ON(sizeof(struct cmd_type_7) != 64); |
|---|
| 7771 | + BUILD_BUG_ON(sizeof(struct cmd_type_7_fx00) != 64); |
|---|
| 7772 | + BUILD_BUG_ON(sizeof(struct cmd_type_crc_2) != 64); |
|---|
| 7773 | + BUILD_BUG_ON(sizeof(struct ct_entry_24xx) != 64); |
|---|
| 7774 | + BUILD_BUG_ON(sizeof(struct ct_fdmi1_hba_attributes) != 2344); |
|---|
| 7775 | + BUILD_BUG_ON(sizeof(struct ct_fdmi2_hba_attributes) != 4424); |
|---|
| 7776 | + BUILD_BUG_ON(sizeof(struct ct_fdmi2_port_attributes) != 4164); |
|---|
| 7777 | + BUILD_BUG_ON(sizeof(struct ct_fdmi_hba_attr) != 260); |
|---|
| 7778 | + BUILD_BUG_ON(sizeof(struct ct_fdmi_port_attr) != 260); |
|---|
| 7779 | + BUILD_BUG_ON(sizeof(struct ct_rsp_hdr) != 16); |
|---|
| 7780 | + BUILD_BUG_ON(sizeof(struct ctio_crc2_to_fw) != 64); |
|---|
| 7781 | + BUILD_BUG_ON(sizeof(struct device_reg_24xx) != 256); |
|---|
| 7782 | + BUILD_BUG_ON(sizeof(struct device_reg_25xxmq) != 24); |
|---|
| 7783 | + BUILD_BUG_ON(sizeof(struct device_reg_2xxx) != 256); |
|---|
| 7784 | + BUILD_BUG_ON(sizeof(struct device_reg_82xx) != 1288); |
|---|
| 7785 | + BUILD_BUG_ON(sizeof(struct device_reg_fx00) != 216); |
|---|
| 7786 | + BUILD_BUG_ON(sizeof(struct els_entry_24xx) != 64); |
|---|
| 7787 | + BUILD_BUG_ON(sizeof(struct els_sts_entry_24xx) != 64); |
|---|
| 7788 | + BUILD_BUG_ON(sizeof(struct fxdisc_entry_fx00) != 64); |
|---|
| 7789 | + BUILD_BUG_ON(sizeof(struct imm_ntfy_from_isp) != 64); |
|---|
| 7790 | + BUILD_BUG_ON(sizeof(struct init_cb_24xx) != 128); |
|---|
| 7791 | + BUILD_BUG_ON(sizeof(struct init_cb_81xx) != 128); |
|---|
| 7792 | + BUILD_BUG_ON(sizeof(struct logio_entry_24xx) != 64); |
|---|
| 7793 | + BUILD_BUG_ON(sizeof(struct mbx_entry) != 64); |
|---|
| 7794 | + BUILD_BUG_ON(sizeof(struct mid_init_cb_24xx) != 5252); |
|---|
| 7795 | + BUILD_BUG_ON(sizeof(struct mrk_entry_24xx) != 64); |
|---|
| 7796 | + BUILD_BUG_ON(sizeof(struct nvram_24xx) != 512); |
|---|
| 7797 | + BUILD_BUG_ON(sizeof(struct nvram_81xx) != 512); |
|---|
| 7798 | + BUILD_BUG_ON(sizeof(struct pt_ls4_request) != 64); |
|---|
| 7799 | + BUILD_BUG_ON(sizeof(struct pt_ls4_rx_unsol) != 64); |
|---|
| 7800 | + BUILD_BUG_ON(sizeof(struct purex_entry_24xx) != 64); |
|---|
| 7801 | + BUILD_BUG_ON(sizeof(struct qla2100_fw_dump) != 123634); |
|---|
| 7802 | + BUILD_BUG_ON(sizeof(struct qla2300_fw_dump) != 136100); |
|---|
| 7803 | + BUILD_BUG_ON(sizeof(struct qla24xx_fw_dump) != 37976); |
|---|
| 7804 | + BUILD_BUG_ON(sizeof(struct qla25xx_fw_dump) != 39228); |
|---|
| 7805 | + BUILD_BUG_ON(sizeof(struct qla2xxx_fce_chain) != 52); |
|---|
| 7806 | + BUILD_BUG_ON(sizeof(struct qla2xxx_fw_dump) != 136172); |
|---|
| 7807 | + BUILD_BUG_ON(sizeof(struct qla2xxx_mq_chain) != 524); |
|---|
| 7808 | + BUILD_BUG_ON(sizeof(struct qla2xxx_mqueue_chain) != 8); |
|---|
| 7809 | + BUILD_BUG_ON(sizeof(struct qla2xxx_mqueue_header) != 12); |
|---|
| 7810 | + BUILD_BUG_ON(sizeof(struct qla2xxx_offld_chain) != 24); |
|---|
| 7811 | + BUILD_BUG_ON(sizeof(struct qla81xx_fw_dump) != 39420); |
|---|
| 7812 | + BUILD_BUG_ON(sizeof(struct qla82xx_uri_data_desc) != 28); |
|---|
| 7813 | + BUILD_BUG_ON(sizeof(struct qla82xx_uri_table_desc) != 32); |
|---|
| 7814 | + BUILD_BUG_ON(sizeof(struct qla83xx_fw_dump) != 51196); |
|---|
| 7815 | + BUILD_BUG_ON(sizeof(struct qla_fcp_prio_cfg) != FCP_PRIO_CFG_SIZE); |
|---|
| 7816 | + BUILD_BUG_ON(sizeof(struct qla_fdt_layout) != 128); |
|---|
| 7817 | + BUILD_BUG_ON(sizeof(struct qla_flt_header) != 8); |
|---|
| 7818 | + BUILD_BUG_ON(sizeof(struct qla_flt_region) != 16); |
|---|
| 7819 | + BUILD_BUG_ON(sizeof(struct qla_npiv_entry) != 24); |
|---|
| 7820 | + BUILD_BUG_ON(sizeof(struct qla_npiv_header) != 16); |
|---|
| 7821 | + BUILD_BUG_ON(sizeof(struct rdp_rsp_payload) != 336); |
|---|
| 7822 | + BUILD_BUG_ON(sizeof(struct sns_cmd_pkt) != 2064); |
|---|
| 7823 | + BUILD_BUG_ON(sizeof(struct sts_entry_24xx) != 64); |
|---|
| 7824 | + BUILD_BUG_ON(sizeof(struct tsk_mgmt_entry) != 64); |
|---|
| 7825 | + BUILD_BUG_ON(sizeof(struct tsk_mgmt_entry_fx00) != 64); |
|---|
| 7826 | + BUILD_BUG_ON(sizeof(struct verify_chip_entry_84xx) != 64); |
|---|
| 7827 | + BUILD_BUG_ON(sizeof(struct verify_chip_rsp_84xx) != 52); |
|---|
| 7828 | + BUILD_BUG_ON(sizeof(struct vf_evfp_entry_24xx) != 56); |
|---|
| 7829 | + BUILD_BUG_ON(sizeof(struct vp_config_entry_24xx) != 64); |
|---|
| 7830 | + BUILD_BUG_ON(sizeof(struct vp_ctrl_entry_24xx) != 64); |
|---|
| 7831 | + BUILD_BUG_ON(sizeof(struct vp_rpt_id_entry_24xx) != 64); |
|---|
| 7832 | + BUILD_BUG_ON(sizeof(sts21_entry_t) != 64); |
|---|
| 7833 | + BUILD_BUG_ON(sizeof(sts22_entry_t) != 64); |
|---|
| 7834 | + BUILD_BUG_ON(sizeof(sts_cont_entry_t) != 64); |
|---|
| 7835 | + BUILD_BUG_ON(sizeof(sts_entry_t) != 64); |
|---|
| 7836 | + BUILD_BUG_ON(sizeof(sw_info_t) != 32); |
|---|
| 7837 | + BUILD_BUG_ON(sizeof(target_id_t) != 2); |
|---|
| 6937 | 7838 | |
|---|
| 6938 | 7839 | /* Allocate cache for SRBs. */ |
|---|
| 6939 | 7840 | srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, |
|---|
| .. | .. |
|---|
| 6964 | 7865 | strcat(qla2x00_version_str, "-debug"); |
|---|
| 6965 | 7866 | if (ql2xextended_error_logging == 1) |
|---|
| 6966 | 7867 | ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK; |
|---|
| 7868 | + |
|---|
| 7869 | + if (ql2x_ini_mode == QLA2XXX_INI_MODE_DUAL) |
|---|
| 7870 | + qla_insert_tgt_attrs(); |
|---|
| 6967 | 7871 | |
|---|
| 6968 | 7872 | qla2xxx_transport_template = |
|---|
| 6969 | 7873 | fc_attach_transport(&qla2xxx_transport_functions); |
|---|
| .. | .. |
|---|
| 7022 | 7926 | static void __exit |
|---|
| 7023 | 7927 | qla2x00_module_exit(void) |
|---|
| 7024 | 7928 | { |
|---|
| 7025 | | - unregister_chrdev(apidev_major, QLA2XXX_APIDEV); |
|---|
| 7026 | 7929 | pci_unregister_driver(&qla2xxx_pci_driver); |
|---|
| 7027 | 7930 | qla2x00_release_firmware(); |
|---|
| 7028 | | - kmem_cache_destroy(srb_cachep); |
|---|
| 7029 | | - qlt_exit(); |
|---|
| 7030 | | - if (ctx_cachep) |
|---|
| 7031 | | - kmem_cache_destroy(ctx_cachep); |
|---|
| 7032 | | - fc_release_transport(qla2xxx_transport_template); |
|---|
| 7931 | + kmem_cache_destroy(ctx_cachep); |
|---|
| 7033 | 7932 | fc_release_transport(qla2xxx_transport_vport_template); |
|---|
| 7933 | + if (apidev_major >= 0) |
|---|
| 7934 | + unregister_chrdev(apidev_major, QLA2XXX_APIDEV); |
|---|
| 7935 | + fc_release_transport(qla2xxx_transport_template); |
|---|
| 7936 | + qlt_exit(); |
|---|
| 7937 | + kmem_cache_destroy(srb_cachep); |
|---|
| 7034 | 7938 | } |
|---|
| 7035 | 7939 | |
|---|
| 7036 | 7940 | module_init(qla2x00_module_init); |
|---|
| .. | .. |
|---|
| 7039 | 7943 | MODULE_AUTHOR("QLogic Corporation"); |
|---|
| 7040 | 7944 | MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver"); |
|---|
| 7041 | 7945 | MODULE_LICENSE("GPL"); |
|---|
| 7042 | | -MODULE_VERSION(QLA2XXX_VERSION); |
|---|
| 7043 | 7946 | MODULE_FIRMWARE(FW_FILE_ISP21XX); |
|---|
| 7044 | 7947 | MODULE_FIRMWARE(FW_FILE_ISP22XX); |
|---|
| 7045 | 7948 | MODULE_FIRMWARE(FW_FILE_ISP2300); |
|---|