.. | .. |
---|
| 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); |
---|
.. | .. |
---|
891 | 879 | goto qc24_fail_command; |
---|
892 | 880 | } |
---|
893 | 881 | |
---|
894 | | - if (!fcport) { |
---|
895 | | - cmd->result = DID_NO_CONNECT << 16; |
---|
| 882 | + if (!fcport || fcport->deleted) { |
---|
| 883 | + cmd->result = DID_IMM_RETRY << 16; |
---|
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, |
---|
.. | .. |
---|
977 | 961 | goto qc24_fail_command; |
---|
978 | 962 | } |
---|
979 | 963 | |
---|
980 | | - if (!fcport) { |
---|
| 964 | + if (!qpair->online) { |
---|
| 965 | + ql_dbg(ql_dbg_io, vha, 0x3077, |
---|
| 966 | + "qpair not online. eeh_busy=%d.\n", ha->flags.eeh_busy); |
---|
981 | 967 | cmd->result = DID_NO_CONNECT << 16; |
---|
982 | 968 | goto qc24_fail_command; |
---|
983 | 969 | } |
---|
984 | 970 | |
---|
985 | | - if (atomic_read(&fcport->state) != FCS_ONLINE) { |
---|
| 971 | + if (!fcport || fcport->deleted) { |
---|
| 972 | + cmd->result = DID_IMM_RETRY << 16; |
---|
| 973 | + goto qc24_fail_command; |
---|
| 974 | + } |
---|
| 975 | + |
---|
| 976 | + if (atomic_read(&fcport->state) != FCS_ONLINE || fcport->deleted) { |
---|
986 | 977 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
---|
987 | 978 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
---|
988 | 979 | ql_dbg(ql_dbg_io, vha, 0x3077, |
---|
.. | .. |
---|
1006 | 997 | else |
---|
1007 | 998 | goto qc24_target_busy; |
---|
1008 | 999 | |
---|
1009 | | - sp = qla2xxx_get_qpair_sp(qpair, fcport, GFP_ATOMIC); |
---|
1010 | | - if (!sp) |
---|
1011 | | - goto qc24_host_busy; |
---|
| 1000 | + sp = scsi_cmd_priv(cmd); |
---|
| 1001 | + qla2xxx_init_sp(sp, vha, qpair, fcport); |
---|
1012 | 1002 | |
---|
1013 | 1003 | sp->u.scmd.cmd = cmd; |
---|
1014 | 1004 | sp->type = SRB_SCSI_CMD; |
---|
1015 | | - atomic_set(&sp->ref_count, 1); |
---|
1016 | 1005 | CMD_SP(cmd) = (void *)sp; |
---|
1017 | 1006 | sp->free = qla2xxx_qpair_sp_free_dma; |
---|
1018 | 1007 | sp->done = qla2xxx_qpair_sp_compl; |
---|
1019 | | - sp->qpair = qpair; |
---|
1020 | 1008 | |
---|
1021 | 1009 | rval = ha->isp_ops->start_scsi_mq(sp); |
---|
1022 | 1010 | if (rval != QLA_SUCCESS) { |
---|
.. | .. |
---|
1029 | 1017 | |
---|
1030 | 1018 | qc24_host_busy_free_sp: |
---|
1031 | 1019 | sp->free(sp); |
---|
1032 | | - |
---|
1033 | | -qc24_host_busy: |
---|
1034 | | - return SCSI_MLQUEUE_HOST_BUSY; |
---|
1035 | 1020 | |
---|
1036 | 1021 | qc24_target_busy: |
---|
1037 | 1022 | return SCSI_MLQUEUE_TARGET_BUSY; |
---|
.. | .. |
---|
1051 | 1036 | * cmd = Scsi Command to wait on. |
---|
1052 | 1037 | * |
---|
1053 | 1038 | * Return: |
---|
1054 | | - * Not Found : 0 |
---|
1055 | | - * Found : 1 |
---|
| 1039 | + * Completed in time : QLA_SUCCESS |
---|
| 1040 | + * Did not complete in time : QLA_FUNCTION_FAILED |
---|
1056 | 1041 | */ |
---|
1057 | 1042 | static int |
---|
1058 | 1043 | qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) |
---|
.. | .. |
---|
1143 | 1128 | void |
---|
1144 | 1129 | qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha) |
---|
1145 | 1130 | { |
---|
1146 | | - qla2x00_mark_all_devices_lost(vha, 0); |
---|
| 1131 | + u8 i; |
---|
1147 | 1132 | |
---|
1148 | | - wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha), 10*HZ); |
---|
| 1133 | + qla2x00_mark_all_devices_lost(vha); |
---|
| 1134 | + |
---|
| 1135 | + for (i = 0; i < 10; i++) { |
---|
| 1136 | + if (wait_event_timeout(vha->fcport_waitQ, |
---|
| 1137 | + test_fcport_count(vha), HZ) > 0) |
---|
| 1138 | + break; |
---|
| 1139 | + } |
---|
| 1140 | + |
---|
| 1141 | + flush_workqueue(vha->hw->wq); |
---|
1149 | 1142 | } |
---|
1150 | 1143 | |
---|
1151 | 1144 | /* |
---|
.. | .. |
---|
1204 | 1197 | return return_status; |
---|
1205 | 1198 | } |
---|
1206 | 1199 | |
---|
1207 | | -static void |
---|
1208 | | -sp_get(struct srb *sp) |
---|
1209 | | -{ |
---|
1210 | | - atomic_inc(&sp->ref_count); |
---|
1211 | | -} |
---|
1212 | | - |
---|
1213 | | -#define ISP_REG_DISCONNECT 0xffffffffU |
---|
1214 | | -/************************************************************************** |
---|
1215 | | -* qla2x00_isp_reg_stat |
---|
1216 | | -* |
---|
1217 | | -* Description: |
---|
1218 | | -* Read the host status register of ISP before aborting the command. |
---|
1219 | | -* |
---|
1220 | | -* Input: |
---|
1221 | | -* ha = pointer to host adapter structure. |
---|
1222 | | -* |
---|
1223 | | -* |
---|
1224 | | -* Returns: |
---|
1225 | | -* Either true or false. |
---|
1226 | | -* |
---|
1227 | | -* Note: Return true if there is register disconnect. |
---|
1228 | | -**************************************************************************/ |
---|
1229 | | -static inline |
---|
1230 | | -uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha) |
---|
1231 | | -{ |
---|
1232 | | - struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
---|
1233 | | - struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; |
---|
1234 | | - |
---|
1235 | | - if (IS_P3P_TYPE(ha)) |
---|
1236 | | - return ((RD_REG_DWORD(®82->host_int)) == ISP_REG_DISCONNECT); |
---|
1237 | | - else |
---|
1238 | | - return ((RD_REG_DWORD(®->host_status)) == |
---|
1239 | | - ISP_REG_DISCONNECT); |
---|
1240 | | -} |
---|
1241 | | - |
---|
1242 | 1200 | /************************************************************************** |
---|
1243 | 1201 | * qla2xxx_eh_abort |
---|
1244 | 1202 | * |
---|
.. | .. |
---|
1258 | 1216 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) |
---|
1259 | 1217 | { |
---|
1260 | 1218 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
---|
| 1219 | + DECLARE_COMPLETION_ONSTACK(comp); |
---|
1261 | 1220 | srb_t *sp; |
---|
1262 | 1221 | int ret; |
---|
1263 | 1222 | unsigned int id; |
---|
1264 | 1223 | uint64_t lun; |
---|
1265 | | - unsigned long flags; |
---|
1266 | | - int rval, wait = 0; |
---|
| 1224 | + int rval; |
---|
1267 | 1225 | struct qla_hw_data *ha = vha->hw; |
---|
| 1226 | + uint32_t ratov_j; |
---|
| 1227 | + struct qla_qpair *qpair; |
---|
| 1228 | + unsigned long flags; |
---|
| 1229 | + int fast_fail_status = SUCCESS; |
---|
1268 | 1230 | |
---|
1269 | 1231 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1270 | 1232 | ql_log(ql_log_info, vha, 0x8042, |
---|
1271 | 1233 | "PCI/Register disconnect, exiting.\n"); |
---|
| 1234 | + qla_pci_set_eeh_busy(vha); |
---|
1272 | 1235 | return FAILED; |
---|
1273 | 1236 | } |
---|
1274 | | - if (!CMD_SP(cmd)) |
---|
1275 | | - return SUCCESS; |
---|
1276 | 1237 | |
---|
| 1238 | + /* Save any FAST_IO_FAIL value to return later if abort succeeds */ |
---|
1277 | 1239 | ret = fc_block_scsi_eh(cmd); |
---|
1278 | 1240 | if (ret != 0) |
---|
1279 | | - return ret; |
---|
1280 | | - ret = SUCCESS; |
---|
| 1241 | + fast_fail_status = ret; |
---|
| 1242 | + |
---|
| 1243 | + sp = scsi_cmd_priv(cmd); |
---|
| 1244 | + qpair = sp->qpair; |
---|
| 1245 | + |
---|
| 1246 | + if ((sp->fcport && sp->fcport->deleted) || !qpair) |
---|
| 1247 | + return fast_fail_status != SUCCESS ? fast_fail_status : FAILED; |
---|
| 1248 | + |
---|
| 1249 | + spin_lock_irqsave(qpair->qp_lock_ptr, flags); |
---|
| 1250 | + sp->comp = ∁ |
---|
| 1251 | + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); |
---|
| 1252 | + |
---|
1281 | 1253 | |
---|
1282 | 1254 | id = cmd->device->id; |
---|
1283 | 1255 | 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 | 1256 | |
---|
1292 | 1257 | ql_dbg(ql_dbg_taskm, vha, 0x8002, |
---|
1293 | 1258 | "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n", |
---|
1294 | 1259 | vha->host_no, id, lun, sp, cmd, sp->handle); |
---|
1295 | 1260 | |
---|
1296 | | - /* Get a reference to the sp and drop the lock.*/ |
---|
1297 | | - sp_get(sp); |
---|
1298 | | - |
---|
1299 | | - spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
| 1261 | + /* |
---|
| 1262 | + * Abort will release the original Command/sp from FW. Let the |
---|
| 1263 | + * original command call scsi_done. In return, he will wakeup |
---|
| 1264 | + * this sleeping thread. |
---|
| 1265 | + */ |
---|
1300 | 1266 | rval = ha->isp_ops->abort_command(sp); |
---|
1301 | | - if (rval) { |
---|
1302 | | - if (rval == QLA_FUNCTION_PARAMETER_ERROR) |
---|
1303 | | - ret = SUCCESS; |
---|
1304 | | - else |
---|
| 1267 | + |
---|
| 1268 | + ql_dbg(ql_dbg_taskm, vha, 0x8003, |
---|
| 1269 | + "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval); |
---|
| 1270 | + |
---|
| 1271 | + /* Wait for the command completion. */ |
---|
| 1272 | + ratov_j = ha->r_a_tov/10 * 4 * 1000; |
---|
| 1273 | + ratov_j = msecs_to_jiffies(ratov_j); |
---|
| 1274 | + switch (rval) { |
---|
| 1275 | + case QLA_SUCCESS: |
---|
| 1276 | + if (!wait_for_completion_timeout(&comp, ratov_j)) { |
---|
| 1277 | + ql_dbg(ql_dbg_taskm, vha, 0xffff, |
---|
| 1278 | + "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", |
---|
| 1279 | + __func__, ha->r_a_tov/10); |
---|
1305 | 1280 | 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; |
---|
| 1281 | + } else { |
---|
| 1282 | + ret = fast_fail_status; |
---|
1329 | 1283 | } |
---|
| 1284 | + break; |
---|
| 1285 | + default: |
---|
| 1286 | + ret = FAILED; |
---|
| 1287 | + break; |
---|
1330 | 1288 | } |
---|
| 1289 | + |
---|
| 1290 | + sp->comp = NULL; |
---|
1331 | 1291 | |
---|
1332 | 1292 | 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); |
---|
| 1293 | + "Abort command issued nexus=%ld:%d:%llu -- %x.\n", |
---|
| 1294 | + vha->host_no, id, lun, ret); |
---|
1335 | 1295 | |
---|
1336 | 1296 | return ret; |
---|
1337 | 1297 | } |
---|
1338 | 1298 | |
---|
| 1299 | +/* |
---|
| 1300 | + * Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED. |
---|
| 1301 | + */ |
---|
1339 | 1302 | int |
---|
1340 | 1303 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, |
---|
1341 | 1304 | uint64_t l, enum nexus_wait_type type) |
---|
.. | .. |
---|
1409 | 1372 | if (err != 0) |
---|
1410 | 1373 | return err; |
---|
1411 | 1374 | |
---|
| 1375 | + if (fcport->deleted) |
---|
| 1376 | + return SUCCESS; |
---|
| 1377 | + |
---|
1412 | 1378 | ql_log(ql_log_info, vha, 0x8009, |
---|
1413 | 1379 | "%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no, |
---|
1414 | 1380 | cmd->device->id, cmd->device->lun, cmd); |
---|
.. | .. |
---|
1420 | 1386 | goto eh_reset_failed; |
---|
1421 | 1387 | } |
---|
1422 | 1388 | err = 2; |
---|
1423 | | - if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1) |
---|
| 1389 | + if (do_reset(fcport, cmd->device->lun, 1) |
---|
1424 | 1390 | != QLA_SUCCESS) { |
---|
1425 | 1391 | ql_log(ql_log_warn, vha, 0x800c, |
---|
1426 | 1392 | "do_reset failed for cmd=%p.\n", cmd); |
---|
.. | .. |
---|
1457 | 1423 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1458 | 1424 | ql_log(ql_log_info, vha, 0x803e, |
---|
1459 | 1425 | "PCI/Register disconnect, exiting.\n"); |
---|
| 1426 | + qla_pci_set_eeh_busy(vha); |
---|
1460 | 1427 | return FAILED; |
---|
1461 | 1428 | } |
---|
1462 | 1429 | |
---|
.. | .. |
---|
1473 | 1440 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1474 | 1441 | ql_log(ql_log_info, vha, 0x803f, |
---|
1475 | 1442 | "PCI/Register disconnect, exiting.\n"); |
---|
| 1443 | + qla_pci_set_eeh_busy(vha); |
---|
1476 | 1444 | return FAILED; |
---|
1477 | 1445 | } |
---|
1478 | 1446 | |
---|
.. | .. |
---|
1508 | 1476 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1509 | 1477 | ql_log(ql_log_info, vha, 0x8040, |
---|
1510 | 1478 | "PCI/Register disconnect, exiting.\n"); |
---|
| 1479 | + qla_pci_set_eeh_busy(vha); |
---|
1511 | 1480 | return FAILED; |
---|
1512 | 1481 | } |
---|
1513 | 1482 | |
---|
.. | .. |
---|
1522 | 1491 | if (ret != 0) |
---|
1523 | 1492 | return ret; |
---|
1524 | 1493 | ret = FAILED; |
---|
| 1494 | + |
---|
| 1495 | + if (qla2x00_chip_is_down(vha)) |
---|
| 1496 | + return ret; |
---|
1525 | 1497 | |
---|
1526 | 1498 | ql_log(ql_log_info, vha, 0x8012, |
---|
1527 | 1499 | "BUS RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun); |
---|
.. | .. |
---|
1582 | 1554 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1583 | 1555 | ql_log(ql_log_info, vha, 0x8041, |
---|
1584 | 1556 | "PCI/Register disconnect, exiting.\n"); |
---|
1585 | | - schedule_work(&ha->board_disable); |
---|
| 1557 | + qla_pci_set_eeh_busy(vha); |
---|
1586 | 1558 | return SUCCESS; |
---|
1587 | 1559 | } |
---|
1588 | 1560 | |
---|
.. | .. |
---|
1664 | 1636 | if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) { |
---|
1665 | 1637 | atomic_set(&vha->loop_state, LOOP_DOWN); |
---|
1666 | 1638 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
---|
1667 | | - qla2x00_mark_all_devices_lost(vha, 0); |
---|
| 1639 | + qla2x00_mark_all_devices_lost(vha); |
---|
1668 | 1640 | ret = qla2x00_full_login_lip(vha); |
---|
1669 | 1641 | if (ret != QLA_SUCCESS) { |
---|
1670 | 1642 | ql_dbg(ql_dbg_taskm, vha, 0x802d, |
---|
.. | .. |
---|
1685 | 1657 | return QLA_SUCCESS; |
---|
1686 | 1658 | } |
---|
1687 | 1659 | |
---|
| 1660 | +/* |
---|
| 1661 | + * The caller must ensure that no completion interrupts will happen |
---|
| 1662 | + * while this function is in progress. |
---|
| 1663 | + */ |
---|
| 1664 | +static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, |
---|
| 1665 | + unsigned long *flags) |
---|
| 1666 | + __releases(qp->qp_lock_ptr) |
---|
| 1667 | + __acquires(qp->qp_lock_ptr) |
---|
| 1668 | +{ |
---|
| 1669 | + DECLARE_COMPLETION_ONSTACK(comp); |
---|
| 1670 | + scsi_qla_host_t *vha = qp->vha; |
---|
| 1671 | + struct qla_hw_data *ha = vha->hw; |
---|
| 1672 | + struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
---|
| 1673 | + int rval; |
---|
| 1674 | + bool ret_cmd; |
---|
| 1675 | + uint32_t ratov_j; |
---|
| 1676 | + |
---|
| 1677 | + lockdep_assert_held(qp->qp_lock_ptr); |
---|
| 1678 | + |
---|
| 1679 | + if (qla2x00_chip_is_down(vha)) { |
---|
| 1680 | + sp->done(sp, res); |
---|
| 1681 | + return; |
---|
| 1682 | + } |
---|
| 1683 | + |
---|
| 1684 | + if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS || |
---|
| 1685 | + (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy && |
---|
| 1686 | + !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && |
---|
| 1687 | + !qla2x00_isp_reg_stat(ha))) { |
---|
| 1688 | + if (sp->comp) { |
---|
| 1689 | + sp->done(sp, res); |
---|
| 1690 | + return; |
---|
| 1691 | + } |
---|
| 1692 | + |
---|
| 1693 | + sp->comp = ∁ |
---|
| 1694 | + spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); |
---|
| 1695 | + |
---|
| 1696 | + rval = ha->isp_ops->abort_command(sp); |
---|
| 1697 | + /* Wait for command completion. */ |
---|
| 1698 | + ret_cmd = false; |
---|
| 1699 | + ratov_j = ha->r_a_tov/10 * 4 * 1000; |
---|
| 1700 | + ratov_j = msecs_to_jiffies(ratov_j); |
---|
| 1701 | + switch (rval) { |
---|
| 1702 | + case QLA_SUCCESS: |
---|
| 1703 | + if (wait_for_completion_timeout(&comp, ratov_j)) { |
---|
| 1704 | + ql_dbg(ql_dbg_taskm, vha, 0xffff, |
---|
| 1705 | + "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", |
---|
| 1706 | + __func__, ha->r_a_tov/10); |
---|
| 1707 | + ret_cmd = true; |
---|
| 1708 | + } |
---|
| 1709 | + /* else FW return SP to driver */ |
---|
| 1710 | + break; |
---|
| 1711 | + default: |
---|
| 1712 | + ret_cmd = true; |
---|
| 1713 | + break; |
---|
| 1714 | + } |
---|
| 1715 | + |
---|
| 1716 | + spin_lock_irqsave(qp->qp_lock_ptr, *flags); |
---|
| 1717 | + if (ret_cmd && blk_mq_request_started(cmd->request)) |
---|
| 1718 | + sp->done(sp, res); |
---|
| 1719 | + } else { |
---|
| 1720 | + sp->done(sp, res); |
---|
| 1721 | + } |
---|
| 1722 | +} |
---|
| 1723 | + |
---|
| 1724 | +/* |
---|
| 1725 | + * The caller must ensure that no completion interrupts will happen |
---|
| 1726 | + * while this function is in progress. |
---|
| 1727 | + */ |
---|
1688 | 1728 | static void |
---|
1689 | 1729 | __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) |
---|
1690 | 1730 | { |
---|
1691 | | - int cnt, status; |
---|
| 1731 | + int cnt; |
---|
1692 | 1732 | unsigned long flags; |
---|
1693 | 1733 | srb_t *sp; |
---|
1694 | 1734 | scsi_qla_host_t *vha = qp->vha; |
---|
.. | .. |
---|
1696 | 1736 | struct req_que *req; |
---|
1697 | 1737 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
---|
1698 | 1738 | struct qla_tgt_cmd *cmd; |
---|
1699 | | - uint8_t trace = 0; |
---|
1700 | 1739 | |
---|
1701 | 1740 | if (!ha->req_q_map) |
---|
1702 | 1741 | return; |
---|
.. | .. |
---|
1705 | 1744 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { |
---|
1706 | 1745 | sp = req->outstanding_cmds[cnt]; |
---|
1707 | 1746 | 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 | | - } |
---|
| 1747 | + /* |
---|
| 1748 | + * perform lockless completion during driver unload |
---|
| 1749 | + */ |
---|
| 1750 | + if (qla2x00_chip_is_down(vha)) { |
---|
| 1751 | + req->outstanding_cmds[cnt] = NULL; |
---|
| 1752 | + spin_unlock_irqrestore(qp->qp_lock_ptr, flags); |
---|
1755 | 1753 | sp->done(sp, res); |
---|
1756 | | - } else { |
---|
| 1754 | + spin_lock_irqsave(qp->qp_lock_ptr, flags); |
---|
| 1755 | + continue; |
---|
| 1756 | + } |
---|
| 1757 | + |
---|
| 1758 | + switch (sp->cmd_type) { |
---|
| 1759 | + case TYPE_SRB: |
---|
| 1760 | + qla2x00_abort_srb(qp, sp, res, &flags); |
---|
| 1761 | + break; |
---|
| 1762 | + case TYPE_TGT_CMD: |
---|
1757 | 1763 | if (!vha->hw->tgt.tgt_ops || !tgt || |
---|
1758 | 1764 | 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); |
---|
| 1765 | + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003, |
---|
| 1766 | + "HOST-ABORT-HNDLR: dpc_flags=%lx. Target mode disabled\n", |
---|
| 1767 | + vha->dpc_flags); |
---|
1764 | 1768 | continue; |
---|
1765 | 1769 | } |
---|
1766 | 1770 | cmd = (struct qla_tgt_cmd *)sp; |
---|
1767 | | - qlt_abort_cmd_on_host_reset(cmd->vha, cmd); |
---|
| 1771 | + cmd->aborted = 1; |
---|
| 1772 | + break; |
---|
| 1773 | + case TYPE_TGT_TMCMD: |
---|
| 1774 | + /* Skip task management functions. */ |
---|
| 1775 | + break; |
---|
| 1776 | + default: |
---|
| 1777 | + break; |
---|
1768 | 1778 | } |
---|
| 1779 | + req->outstanding_cmds[cnt] = NULL; |
---|
1769 | 1780 | } |
---|
1770 | 1781 | } |
---|
1771 | 1782 | spin_unlock_irqrestore(qp->qp_lock_ptr, flags); |
---|
1772 | 1783 | } |
---|
1773 | 1784 | |
---|
| 1785 | +/* |
---|
| 1786 | + * The caller must ensure that no completion interrupts will happen |
---|
| 1787 | + * while this function is in progress. |
---|
| 1788 | + */ |
---|
1774 | 1789 | void |
---|
1775 | 1790 | qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) |
---|
1776 | 1791 | { |
---|
1777 | 1792 | int que; |
---|
1778 | 1793 | struct qla_hw_data *ha = vha->hw; |
---|
1779 | 1794 | |
---|
| 1795 | + /* Continue only if initialization complete. */ |
---|
| 1796 | + if (!ha->base_qpair) |
---|
| 1797 | + return; |
---|
1780 | 1798 | __qla2x00_abort_all_cmds(ha->base_qpair, res); |
---|
1781 | 1799 | |
---|
| 1800 | + if (!ha->queue_pair_map) |
---|
| 1801 | + return; |
---|
1782 | 1802 | for (que = 0; que < ha->max_qpairs; que++) { |
---|
1783 | 1803 | if (!ha->queue_pair_map[que]) |
---|
1784 | 1804 | continue; |
---|
.. | .. |
---|
1835 | 1855 | if (!dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(64))) { |
---|
1836 | 1856 | /* Any upper-dword bits set? */ |
---|
1837 | 1857 | if (MSD(dma_get_required_mask(&ha->pdev->dev)) && |
---|
1838 | | - !pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(64))) { |
---|
| 1858 | + !dma_set_coherent_mask(&ha->pdev->dev, DMA_BIT_MASK(64))) { |
---|
1839 | 1859 | /* Ok, a 64bit DMA mask is applicable. */ |
---|
1840 | 1860 | ha->flags.enable_64bit_addressing = 1; |
---|
1841 | 1861 | ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64; |
---|
.. | .. |
---|
1845 | 1865 | } |
---|
1846 | 1866 | |
---|
1847 | 1867 | dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(32)); |
---|
1848 | | - pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(32)); |
---|
| 1868 | + dma_set_coherent_mask(&ha->pdev->dev, DMA_BIT_MASK(32)); |
---|
1849 | 1869 | } |
---|
1850 | 1870 | |
---|
1851 | 1871 | static void |
---|
.. | .. |
---|
1857 | 1877 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
1858 | 1878 | ha->interrupts_on = 1; |
---|
1859 | 1879 | /* enable risc and host interrupts */ |
---|
1860 | | - WRT_REG_WORD(®->ictrl, ICR_EN_INT | ICR_EN_RISC); |
---|
1861 | | - RD_REG_WORD(®->ictrl); |
---|
| 1880 | + wrt_reg_word(®->ictrl, ICR_EN_INT | ICR_EN_RISC); |
---|
| 1881 | + rd_reg_word(®->ictrl); |
---|
1862 | 1882 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
1863 | 1883 | |
---|
1864 | 1884 | } |
---|
.. | .. |
---|
1872 | 1892 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
1873 | 1893 | ha->interrupts_on = 0; |
---|
1874 | 1894 | /* disable risc and host interrupts */ |
---|
1875 | | - WRT_REG_WORD(®->ictrl, 0); |
---|
1876 | | - RD_REG_WORD(®->ictrl); |
---|
| 1895 | + wrt_reg_word(®->ictrl, 0); |
---|
| 1896 | + rd_reg_word(®->ictrl); |
---|
1877 | 1897 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
1878 | 1898 | } |
---|
1879 | 1899 | |
---|
.. | .. |
---|
1885 | 1905 | |
---|
1886 | 1906 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
1887 | 1907 | ha->interrupts_on = 1; |
---|
1888 | | - WRT_REG_DWORD(®->ictrl, ICRX_EN_RISC_INT); |
---|
1889 | | - RD_REG_DWORD(®->ictrl); |
---|
| 1908 | + wrt_reg_dword(®->ictrl, ICRX_EN_RISC_INT); |
---|
| 1909 | + rd_reg_dword(®->ictrl); |
---|
1890 | 1910 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
1891 | 1911 | } |
---|
1892 | 1912 | |
---|
.. | .. |
---|
1900 | 1920 | return; |
---|
1901 | 1921 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
1902 | 1922 | ha->interrupts_on = 0; |
---|
1903 | | - WRT_REG_DWORD(®->ictrl, 0); |
---|
1904 | | - RD_REG_DWORD(®->ictrl); |
---|
| 1923 | + wrt_reg_dword(®->ictrl, 0); |
---|
| 1924 | + rd_reg_dword(®->ictrl); |
---|
1905 | 1925 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
1906 | 1926 | } |
---|
1907 | 1927 | |
---|
.. | .. |
---|
2264 | 2284 | .config_rings = qla24xx_config_rings, |
---|
2265 | 2285 | .reset_adapter = qla24xx_reset_adapter, |
---|
2266 | 2286 | .nvram_config = qla81xx_nvram_config, |
---|
2267 | | - .update_fw_options = qla81xx_update_fw_options, |
---|
| 2287 | + .update_fw_options = qla24xx_update_fw_options, |
---|
2268 | 2288 | .load_risc = qla81xx_load_risc, |
---|
2269 | 2289 | .pci_info_str = qla24xx_pci_info_str, |
---|
2270 | 2290 | .fw_version_str = qla24xx_fw_version_str, |
---|
.. | .. |
---|
2381 | 2401 | .config_rings = qla24xx_config_rings, |
---|
2382 | 2402 | .reset_adapter = qla24xx_reset_adapter, |
---|
2383 | 2403 | .nvram_config = qla81xx_nvram_config, |
---|
2384 | | - .update_fw_options = qla81xx_update_fw_options, |
---|
| 2404 | + .update_fw_options = qla24xx_update_fw_options, |
---|
2385 | 2405 | .load_risc = qla81xx_load_risc, |
---|
2386 | 2406 | .pci_info_str = qla24xx_pci_info_str, |
---|
2387 | 2407 | .fw_version_str = qla24xx_fw_version_str, |
---|
.. | .. |
---|
2459 | 2479 | .config_rings = qla24xx_config_rings, |
---|
2460 | 2480 | .reset_adapter = qla24xx_reset_adapter, |
---|
2461 | 2481 | .nvram_config = qla81xx_nvram_config, |
---|
2462 | | - .update_fw_options = qla81xx_update_fw_options, |
---|
| 2482 | + .update_fw_options = qla24xx_update_fw_options, |
---|
2463 | 2483 | .load_risc = qla81xx_load_risc, |
---|
2464 | 2484 | .pci_info_str = qla24xx_pci_info_str, |
---|
2465 | 2485 | .fw_version_str = qla24xx_fw_version_str, |
---|
.. | .. |
---|
2478 | 2498 | .read_nvram = NULL, |
---|
2479 | 2499 | .write_nvram = NULL, |
---|
2480 | 2500 | .fw_dump = qla27xx_fwdump, |
---|
| 2501 | + .mpi_fw_dump = qla27xx_mpi_fwdump, |
---|
2481 | 2502 | .beacon_on = qla24xx_beacon_on, |
---|
2482 | 2503 | .beacon_off = qla24xx_beacon_off, |
---|
2483 | 2504 | .beacon_blink = qla83xx_beacon_blink, |
---|
.. | .. |
---|
2636 | 2657 | ha->device_type |= DT_T10_PI; |
---|
2637 | 2658 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
---|
2638 | 2659 | break; |
---|
| 2660 | + case PCI_DEVICE_ID_QLOGIC_ISP2081: |
---|
| 2661 | + case PCI_DEVICE_ID_QLOGIC_ISP2089: |
---|
| 2662 | + ha->isp_type |= DT_ISP2081; |
---|
| 2663 | + ha->device_type |= DT_ZIO_SUPPORTED; |
---|
| 2664 | + ha->device_type |= DT_FWI2; |
---|
| 2665 | + ha->device_type |= DT_IIDMA; |
---|
| 2666 | + ha->device_type |= DT_T10_PI; |
---|
| 2667 | + ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
---|
| 2668 | + break; |
---|
| 2669 | + case PCI_DEVICE_ID_QLOGIC_ISP2281: |
---|
| 2670 | + case PCI_DEVICE_ID_QLOGIC_ISP2289: |
---|
| 2671 | + ha->isp_type |= DT_ISP2281; |
---|
| 2672 | + ha->device_type |= DT_ZIO_SUPPORTED; |
---|
| 2673 | + ha->device_type |= DT_FWI2; |
---|
| 2674 | + ha->device_type |= DT_IIDMA; |
---|
| 2675 | + ha->device_type |= DT_T10_PI; |
---|
| 2676 | + ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
---|
| 2677 | + break; |
---|
2639 | 2678 | } |
---|
2640 | 2679 | |
---|
2641 | 2680 | if (IS_QLA82XX(ha)) |
---|
.. | .. |
---|
2643 | 2682 | else { |
---|
2644 | 2683 | /* Get adapter physical port no from interrupt pin register. */ |
---|
2645 | 2684 | pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no); |
---|
2646 | | - if (IS_QLA27XX(ha)) |
---|
| 2685 | + if (IS_QLA25XX(ha) || IS_QLA2031(ha) || |
---|
| 2686 | + IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
---|
2647 | 2687 | ha->port_no--; |
---|
2648 | 2688 | else |
---|
2649 | 2689 | ha->port_no = !(ha->port_no & 1); |
---|
.. | .. |
---|
2740 | 2780 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 || |
---|
2741 | 2781 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071 || |
---|
2742 | 2782 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2271 || |
---|
2743 | | - pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2261) { |
---|
| 2783 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2261 || |
---|
| 2784 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2081 || |
---|
| 2785 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2281 || |
---|
| 2786 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2089 || |
---|
| 2787 | + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2289) { |
---|
2744 | 2788 | bars = pci_select_bars(pdev, IORESOURCE_MEM); |
---|
2745 | 2789 | mem_only = 1; |
---|
2746 | 2790 | ql_dbg_pci(ql_dbg_init, pdev, 0x0007, |
---|
.. | .. |
---|
2755 | 2799 | } else { |
---|
2756 | 2800 | if (pci_enable_device(pdev)) |
---|
2757 | 2801 | return ret; |
---|
| 2802 | + } |
---|
| 2803 | + |
---|
| 2804 | + if (is_kdump_kernel()) { |
---|
| 2805 | + ql2xmqsupport = 0; |
---|
| 2806 | + ql2xallocfwdump = 0; |
---|
2758 | 2807 | } |
---|
2759 | 2808 | |
---|
2760 | 2809 | /* This may fail but that's ok */ |
---|
.. | .. |
---|
2789 | 2838 | |
---|
2790 | 2839 | /* Set EEH reset type to fundamental if required by hba */ |
---|
2791 | 2840 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) || |
---|
2792 | | - IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
---|
| 2841 | + IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
---|
2793 | 2842 | pdev->needs_freset = 1; |
---|
2794 | 2843 | |
---|
2795 | 2844 | ha->prev_topology = 0; |
---|
.. | .. |
---|
2799 | 2848 | ha->max_exchg = FW_MAX_EXCHANGES_CNT; |
---|
2800 | 2849 | atomic_set(&ha->num_pend_mbx_stage1, 0); |
---|
2801 | 2850 | atomic_set(&ha->num_pend_mbx_stage2, 0); |
---|
2802 | | - atomic_set(&ha->num_pend_mbx_stage3, 0); |
---|
| 2851 | + atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD); |
---|
| 2852 | + ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD; |
---|
2803 | 2853 | |
---|
2804 | 2854 | /* Assign ISP specific operations. */ |
---|
2805 | 2855 | if (IS_QLA2100(ha)) { |
---|
.. | .. |
---|
2966 | 3016 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX; |
---|
2967 | 3017 | ha->nvram_conf_off = ~0; |
---|
2968 | 3018 | ha->nvram_data_off = ~0; |
---|
| 3019 | + } else if (IS_QLA28XX(ha)) { |
---|
| 3020 | + ha->portnum = PCI_FUNC(ha->pdev->devfn); |
---|
| 3021 | + ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400; |
---|
| 3022 | + ha->mbx_count = MAILBOX_REGISTER_COUNT; |
---|
| 3023 | + req_length = REQUEST_ENTRY_CNT_24XX; |
---|
| 3024 | + rsp_length = RESPONSE_ENTRY_CNT_2300; |
---|
| 3025 | + ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; |
---|
| 3026 | + ha->max_loop_id = SNS_LAST_LOOP_ID_2300; |
---|
| 3027 | + ha->init_cb_size = sizeof(struct mid_init_cb_81xx); |
---|
| 3028 | + ha->gid_list_info_size = 8; |
---|
| 3029 | + ha->optrom_size = OPTROM_SIZE_28XX; |
---|
| 3030 | + ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; |
---|
| 3031 | + ha->isp_ops = &qla27xx_isp_ops; |
---|
| 3032 | + ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_28XX; |
---|
| 3033 | + ha->flash_data_off = FARX_ACCESS_FLASH_DATA_28XX; |
---|
| 3034 | + ha->nvram_conf_off = ~0; |
---|
| 3035 | + ha->nvram_data_off = ~0; |
---|
2969 | 3036 | } |
---|
2970 | 3037 | |
---|
2971 | 3038 | ql_dbg_pci(ql_dbg_init, pdev, 0x001e, |
---|
.. | .. |
---|
3055 | 3122 | host->max_id = ha->max_fibre_devices; |
---|
3056 | 3123 | host->cmd_per_lun = 3; |
---|
3057 | 3124 | host->unique_id = host->host_no; |
---|
| 3125 | + |
---|
| 3126 | + if (ql2xenabledif && ql2xenabledif != 2) { |
---|
| 3127 | + ql_log(ql_log_warn, base_vha, 0x302d, |
---|
| 3128 | + "Invalid value for ql2xenabledif, resetting it to default (2)\n"); |
---|
| 3129 | + ql2xenabledif = 2; |
---|
| 3130 | + } |
---|
| 3131 | + |
---|
3058 | 3132 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) |
---|
3059 | 3133 | host->max_cmd_len = 32; |
---|
3060 | 3134 | else |
---|
.. | .. |
---|
3090 | 3164 | ql_log(ql_log_fatal, base_vha, 0x003d, |
---|
3091 | 3165 | "Failed to allocate memory for queue pointers..." |
---|
3092 | 3166 | "aborting.\n"); |
---|
| 3167 | + ret = -ENODEV; |
---|
3093 | 3168 | goto probe_failed; |
---|
3094 | 3169 | } |
---|
3095 | 3170 | |
---|
3096 | | - if (ha->mqenable && shost_use_blk_mq(host)) { |
---|
| 3171 | + if (ha->mqenable) { |
---|
3097 | 3172 | /* number of hardware queues supported by blk/scsi-mq*/ |
---|
3098 | 3173 | host->nr_hw_queues = ha->max_qpairs; |
---|
3099 | 3174 | |
---|
.. | .. |
---|
3131 | 3206 | req->req_q_out = &ha->iobase->isp24.req_q_out; |
---|
3132 | 3207 | rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in; |
---|
3133 | 3208 | rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out; |
---|
3134 | | - if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
---|
| 3209 | + if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
---|
| 3210 | + IS_QLA28XX(ha)) { |
---|
3135 | 3211 | req->req_q_in = &ha->mqiobase->isp25mq.req_q_in; |
---|
3136 | 3212 | req->req_q_out = &ha->mqiobase->isp25mq.req_q_out; |
---|
3137 | 3213 | rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in; |
---|
.. | .. |
---|
3209 | 3285 | base_vha->mgmt_svr_loop_id, host->sg_tablesize); |
---|
3210 | 3286 | |
---|
3211 | 3287 | if (ha->mqenable) { |
---|
3212 | | - bool mq = false; |
---|
3213 | 3288 | bool startit = false; |
---|
3214 | 3289 | |
---|
3215 | | - if (QLA_TGT_MODE_ENABLED()) { |
---|
3216 | | - mq = true; |
---|
| 3290 | + if (QLA_TGT_MODE_ENABLED()) |
---|
3217 | 3291 | startit = false; |
---|
3218 | | - } |
---|
3219 | 3292 | |
---|
3220 | | - if ((ql2x_ini_mode == QLA2XXX_INI_MODE_ENABLED) && |
---|
3221 | | - shost_use_blk_mq(host)) { |
---|
3222 | | - mq = true; |
---|
| 3293 | + if (ql2x_ini_mode == QLA2XXX_INI_MODE_ENABLED) |
---|
3223 | 3294 | startit = true; |
---|
3224 | | - } |
---|
3225 | 3295 | |
---|
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 | | - } |
---|
| 3296 | + /* Create start of day qpairs for Block MQ */ |
---|
| 3297 | + for (i = 0; i < ha->max_qpairs; i++) |
---|
| 3298 | + qla2xxx_create_qpair(base_vha, 5, 0, startit); |
---|
3231 | 3299 | } |
---|
| 3300 | + qla_init_iocb_limit(base_vha); |
---|
3232 | 3301 | |
---|
3233 | 3302 | if (ha->flags.running_gold_fw) |
---|
3234 | 3303 | goto skip_dpc; |
---|
.. | .. |
---|
3288 | 3357 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { |
---|
3289 | 3358 | if (ha->fw_attributes & BIT_4) { |
---|
3290 | 3359 | int prot = 0, guard; |
---|
| 3360 | + |
---|
3291 | 3361 | base_vha->flags.difdix_supported = 1; |
---|
3292 | 3362 | ql_dbg(ql_dbg_init, base_vha, 0x00f1, |
---|
3293 | 3363 | "Registering for DIF/DIX type 1 and 3 protection.\n"); |
---|
3294 | | - if (ql2xenabledif == 1) |
---|
3295 | | - 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); |
---|
| 3364 | + if (ql2xprotmask) |
---|
| 3365 | + scsi_host_set_prot(host, ql2xprotmask); |
---|
| 3366 | + else |
---|
| 3367 | + scsi_host_set_prot(host, |
---|
| 3368 | + prot | SHOST_DIF_TYPE1_PROTECTION |
---|
| 3369 | + | SHOST_DIF_TYPE2_PROTECTION |
---|
| 3370 | + | SHOST_DIF_TYPE3_PROTECTION |
---|
| 3371 | + | SHOST_DIX_TYPE1_PROTECTION |
---|
| 3372 | + | SHOST_DIX_TYPE2_PROTECTION |
---|
| 3373 | + | SHOST_DIX_TYPE3_PROTECTION); |
---|
3303 | 3374 | |
---|
3304 | 3375 | guard = SHOST_DIX_GUARD_CRC; |
---|
3305 | 3376 | |
---|
.. | .. |
---|
3307 | 3378 | (ql2xenabledif > 1 || IS_PI_DIFB_DIX0_CAPABLE(ha))) |
---|
3308 | 3379 | guard |= SHOST_DIX_GUARD_IP; |
---|
3309 | 3380 | |
---|
3310 | | - scsi_host_set_guard(host, guard); |
---|
| 3381 | + if (ql2xprotguard) |
---|
| 3382 | + scsi_host_set_guard(host, ql2xprotguard); |
---|
| 3383 | + else |
---|
| 3384 | + scsi_host_set_guard(host, guard); |
---|
3311 | 3385 | } else |
---|
3312 | 3386 | base_vha->flags.difdix_supported = 0; |
---|
3313 | 3387 | } |
---|
.. | .. |
---|
3358 | 3432 | "QLogic %s - %s.\n", ha->model_number, ha->model_desc); |
---|
3359 | 3433 | ql_log(ql_log_info, base_vha, 0x00fc, |
---|
3360 | 3434 | "ISP%04X: %s @ %s hdma%c host#=%ld fw=%s.\n", |
---|
3361 | | - pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info), |
---|
| 3435 | + pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info, |
---|
| 3436 | + sizeof(pci_info)), |
---|
3362 | 3437 | pci_name(pdev), ha->flags.enable_64bit_addressing ? '+' : '-', |
---|
3363 | 3438 | base_vha->host_no, |
---|
3364 | 3439 | ha->isp_ops->fw_version_str(base_vha, fw_str, sizeof(fw_str))); |
---|
.. | .. |
---|
3369 | 3444 | |
---|
3370 | 3445 | if (test_bit(UNLOADING, &base_vha->dpc_flags)) |
---|
3371 | 3446 | 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 | 3447 | |
---|
3380 | 3448 | return 0; |
---|
3381 | 3449 | |
---|
.. | .. |
---|
3433 | 3501 | return ret; |
---|
3434 | 3502 | } |
---|
3435 | 3503 | |
---|
| 3504 | +static void __qla_set_remove_flag(scsi_qla_host_t *base_vha) |
---|
| 3505 | +{ |
---|
| 3506 | + scsi_qla_host_t *vp; |
---|
| 3507 | + unsigned long flags; |
---|
| 3508 | + struct qla_hw_data *ha; |
---|
| 3509 | + |
---|
| 3510 | + if (!base_vha) |
---|
| 3511 | + return; |
---|
| 3512 | + |
---|
| 3513 | + ha = base_vha->hw; |
---|
| 3514 | + |
---|
| 3515 | + spin_lock_irqsave(&ha->vport_slock, flags); |
---|
| 3516 | + list_for_each_entry(vp, &ha->vp_list, list) |
---|
| 3517 | + set_bit(PFLG_DRIVER_REMOVING, &vp->pci_flags); |
---|
| 3518 | + |
---|
| 3519 | + /* |
---|
| 3520 | + * Indicate device removal to prevent future board_disable |
---|
| 3521 | + * and wait until any pending board_disable has completed. |
---|
| 3522 | + */ |
---|
| 3523 | + set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags); |
---|
| 3524 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
---|
| 3525 | +} |
---|
| 3526 | + |
---|
3436 | 3527 | static void |
---|
3437 | 3528 | qla2x00_shutdown(struct pci_dev *pdev) |
---|
3438 | 3529 | { |
---|
.. | .. |
---|
3449 | 3540 | * Prevent future board_disable and wait |
---|
3450 | 3541 | * until any pending board_disable has completed. |
---|
3451 | 3542 | */ |
---|
3452 | | - set_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags); |
---|
| 3543 | + __qla_set_remove_flag(vha); |
---|
3453 | 3544 | cancel_work_sync(&ha->board_disable); |
---|
3454 | 3545 | |
---|
3455 | 3546 | if (!atomic_read(&pdev->enable_cnt)) |
---|
.. | .. |
---|
3469 | 3560 | if (ha->eft) |
---|
3470 | 3561 | qla2x00_disable_eft_trace(vha); |
---|
3471 | 3562 | |
---|
3472 | | - if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { |
---|
| 3563 | + if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
---|
| 3564 | + IS_QLA28XX(ha)) { |
---|
3473 | 3565 | if (ha->flags.fw_started) |
---|
3474 | 3566 | qla2x00_abort_isp_cleanup(vha); |
---|
3475 | 3567 | } else { |
---|
.. | .. |
---|
3578 | 3670 | if (ha->mqiobase) |
---|
3579 | 3671 | iounmap(ha->mqiobase); |
---|
3580 | 3672 | |
---|
3581 | | - if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) && ha->msixbase) |
---|
| 3673 | + if (ha->msixbase) |
---|
3582 | 3674 | iounmap(ha->msixbase); |
---|
3583 | 3675 | } |
---|
3584 | 3676 | } |
---|
.. | .. |
---|
3607 | 3699 | ha = base_vha->hw; |
---|
3608 | 3700 | ql_log(ql_log_info, base_vha, 0xb079, |
---|
3609 | 3701 | "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); |
---|
| 3702 | + __qla_set_remove_flag(base_vha); |
---|
3614 | 3703 | cancel_work_sync(&ha->board_disable); |
---|
3615 | 3704 | |
---|
3616 | 3705 | /* |
---|
.. | .. |
---|
3636 | 3725 | if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) |
---|
3637 | 3726 | return; |
---|
3638 | 3727 | |
---|
3639 | | - if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { |
---|
| 3728 | + if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
---|
| 3729 | + IS_QLA28XX(ha)) { |
---|
3640 | 3730 | if (ha->flags.fw_started) |
---|
3641 | 3731 | qla2x00_abort_isp_cleanup(base_vha); |
---|
3642 | 3732 | } else if (!IS_QLAFX00(ha)) { |
---|
.. | .. |
---|
3666 | 3756 | qlafx00_driver_shutdown(base_vha, 20); |
---|
3667 | 3757 | |
---|
3668 | 3758 | qla2x00_delete_all_vps(ha, base_vha); |
---|
3669 | | - |
---|
3670 | | - qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); |
---|
3671 | 3759 | |
---|
3672 | 3760 | qla2x00_dfs_remove(base_vha); |
---|
3673 | 3761 | |
---|
.. | .. |
---|
3714 | 3802 | pci_disable_device(pdev); |
---|
3715 | 3803 | } |
---|
3716 | 3804 | |
---|
| 3805 | +static inline void |
---|
| 3806 | +qla24xx_free_purex_list(struct purex_list *list) |
---|
| 3807 | +{ |
---|
| 3808 | + struct list_head *item, *next; |
---|
| 3809 | + ulong flags; |
---|
| 3810 | + |
---|
| 3811 | + spin_lock_irqsave(&list->lock, flags); |
---|
| 3812 | + list_for_each_safe(item, next, &list->head) { |
---|
| 3813 | + list_del(item); |
---|
| 3814 | + kfree(list_entry(item, struct purex_item, list)); |
---|
| 3815 | + } |
---|
| 3816 | + spin_unlock_irqrestore(&list->lock, flags); |
---|
| 3817 | +} |
---|
| 3818 | + |
---|
3717 | 3819 | static void |
---|
3718 | 3820 | qla2x00_free_device(scsi_qla_host_t *vha) |
---|
3719 | 3821 | { |
---|
.. | .. |
---|
3746 | 3848 | } |
---|
3747 | 3849 | |
---|
3748 | 3850 | |
---|
| 3851 | + qla24xx_free_purex_list(&vha->purex_list); |
---|
| 3852 | + |
---|
3749 | 3853 | qla2x00_mem_free(ha); |
---|
3750 | 3854 | |
---|
3751 | 3855 | qla82xx_md_free(vha); |
---|
.. | .. |
---|
3757 | 3861 | { |
---|
3758 | 3862 | fc_port_t *fcport, *tfcport; |
---|
3759 | 3863 | |
---|
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 | | - } |
---|
| 3864 | + list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) |
---|
| 3865 | + qla2x00_free_fcport(fcport); |
---|
3765 | 3866 | } |
---|
3766 | 3867 | |
---|
3767 | 3868 | static inline void |
---|
3768 | | -qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, |
---|
3769 | | - int defer) |
---|
| 3869 | +qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport) |
---|
3770 | 3870 | { |
---|
3771 | | - struct fc_rport *rport; |
---|
3772 | | - scsi_qla_host_t *base_vha; |
---|
3773 | | - unsigned long flags; |
---|
| 3871 | + int now; |
---|
3774 | 3872 | |
---|
3775 | 3873 | if (!fcport->rport) |
---|
3776 | 3874 | return; |
---|
3777 | 3875 | |
---|
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); |
---|
| 3876 | + if (fcport->rport) { |
---|
| 3877 | + ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, |
---|
| 3878 | + "%s %8phN. rport %p roles %x\n", |
---|
| 3879 | + __func__, fcport->port_name, fcport->rport, |
---|
| 3880 | + fcport->rport->roles); |
---|
| 3881 | + fc_remote_port_delete(fcport->rport); |
---|
3797 | 3882 | } |
---|
| 3883 | + qlt_do_generation_tick(vha, &now); |
---|
3798 | 3884 | } |
---|
3799 | 3885 | |
---|
3800 | 3886 | /* |
---|
.. | .. |
---|
3807 | 3893 | * Context: |
---|
3808 | 3894 | */ |
---|
3809 | 3895 | void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, |
---|
3810 | | - int do_login, int defer) |
---|
| 3896 | + int do_login) |
---|
3811 | 3897 | { |
---|
3812 | 3898 | if (IS_QLAFX00(vha->hw)) { |
---|
3813 | 3899 | qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); |
---|
3814 | | - qla2x00_schedule_rport_del(vha, fcport, defer); |
---|
| 3900 | + qla2x00_schedule_rport_del(vha, fcport); |
---|
3815 | 3901 | return; |
---|
3816 | 3902 | } |
---|
3817 | 3903 | |
---|
3818 | 3904 | if (atomic_read(&fcport->state) == FCS_ONLINE && |
---|
3819 | 3905 | vha->vp_idx == fcport->vha->vp_idx) { |
---|
3820 | 3906 | qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); |
---|
3821 | | - qla2x00_schedule_rport_del(vha, fcport, defer); |
---|
| 3907 | + qla2x00_schedule_rport_del(vha, fcport); |
---|
3822 | 3908 | } |
---|
3823 | 3909 | /* |
---|
3824 | 3910 | * We may need to retry the login, so don't change the state of the |
---|
.. | .. |
---|
3833 | 3919 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); |
---|
3834 | 3920 | } |
---|
3835 | 3921 | |
---|
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 | 3922 | void |
---|
3850 | | -qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) |
---|
| 3923 | +qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha) |
---|
3851 | 3924 | { |
---|
3852 | 3925 | fc_port_t *fcport; |
---|
3853 | 3926 | |
---|
.. | .. |
---|
3855 | 3928 | "Mark all dev lost\n"); |
---|
3856 | 3929 | |
---|
3857 | 3930 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
---|
| 3931 | + if (fcport->loop_id != FC_NO_LOOP_ID && |
---|
| 3932 | + (fcport->flags & FCF_FCP2_DEVICE) && |
---|
| 3933 | + fcport->port_type == FCT_TARGET && |
---|
| 3934 | + !qla2x00_reset_active(vha)) { |
---|
| 3935 | + ql_dbg(ql_dbg_disc, vha, 0x211a, |
---|
| 3936 | + "Delaying session delete for FCP2 flags 0x%x port_type = 0x%x port_id=%06x %phC", |
---|
| 3937 | + fcport->flags, fcport->port_type, |
---|
| 3938 | + fcport->d_id.b24, fcport->port_name); |
---|
| 3939 | + continue; |
---|
| 3940 | + } |
---|
3858 | 3941 | fcport->scan_state = 0; |
---|
3859 | 3942 | 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 | 3943 | } |
---|
| 3944 | +} |
---|
| 3945 | + |
---|
| 3946 | +static void qla2x00_set_reserved_loop_ids(struct qla_hw_data *ha) |
---|
| 3947 | +{ |
---|
| 3948 | + int i; |
---|
| 3949 | + |
---|
| 3950 | + if (IS_FWI2_CAPABLE(ha)) |
---|
| 3951 | + return; |
---|
| 3952 | + |
---|
| 3953 | + for (i = 0; i < SNS_FIRST_LOOP_ID; i++) |
---|
| 3954 | + set_bit(i, ha->loop_id_map); |
---|
| 3955 | + set_bit(MANAGEMENT_SERVER, ha->loop_id_map); |
---|
| 3956 | + set_bit(BROADCAST, ha->loop_id_map); |
---|
3878 | 3957 | } |
---|
3879 | 3958 | |
---|
3880 | 3959 | /* |
---|
.. | .. |
---|
3958 | 4037 | "Failed to allocate memory for fcp_cmnd_dma_pool.\n"); |
---|
3959 | 4038 | goto fail_dl_dma_pool; |
---|
3960 | 4039 | } |
---|
| 4040 | + |
---|
| 4041 | + if (ql2xenabledif) { |
---|
| 4042 | + u64 bufsize = DIF_BUNDLING_DMA_POOL_SIZE; |
---|
| 4043 | + struct dsd_dma *dsd, *nxt; |
---|
| 4044 | + uint i; |
---|
| 4045 | + /* Creata a DMA pool of buffers for DIF bundling */ |
---|
| 4046 | + ha->dif_bundl_pool = dma_pool_create(name, |
---|
| 4047 | + &ha->pdev->dev, DIF_BUNDLING_DMA_POOL_SIZE, 8, 0); |
---|
| 4048 | + if (!ha->dif_bundl_pool) { |
---|
| 4049 | + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0024, |
---|
| 4050 | + "%s: failed create dif_bundl_pool\n", |
---|
| 4051 | + __func__); |
---|
| 4052 | + goto fail_dif_bundl_dma_pool; |
---|
| 4053 | + } |
---|
| 4054 | + |
---|
| 4055 | + INIT_LIST_HEAD(&ha->pool.good.head); |
---|
| 4056 | + INIT_LIST_HEAD(&ha->pool.unusable.head); |
---|
| 4057 | + ha->pool.good.count = 0; |
---|
| 4058 | + ha->pool.unusable.count = 0; |
---|
| 4059 | + for (i = 0; i < 128; i++) { |
---|
| 4060 | + dsd = kzalloc(sizeof(*dsd), GFP_ATOMIC); |
---|
| 4061 | + if (!dsd) { |
---|
| 4062 | + ql_dbg_pci(ql_dbg_init, ha->pdev, |
---|
| 4063 | + 0xe0ee, "%s: failed alloc dsd\n", |
---|
| 4064 | + __func__); |
---|
| 4065 | + return -ENOMEM; |
---|
| 4066 | + } |
---|
| 4067 | + ha->dif_bundle_kallocs++; |
---|
| 4068 | + |
---|
| 4069 | + dsd->dsd_addr = dma_pool_alloc( |
---|
| 4070 | + ha->dif_bundl_pool, GFP_ATOMIC, |
---|
| 4071 | + &dsd->dsd_list_dma); |
---|
| 4072 | + if (!dsd->dsd_addr) { |
---|
| 4073 | + ql_dbg_pci(ql_dbg_init, ha->pdev, |
---|
| 4074 | + 0xe0ee, |
---|
| 4075 | + "%s: failed alloc ->dsd_addr\n", |
---|
| 4076 | + __func__); |
---|
| 4077 | + kfree(dsd); |
---|
| 4078 | + ha->dif_bundle_kallocs--; |
---|
| 4079 | + continue; |
---|
| 4080 | + } |
---|
| 4081 | + ha->dif_bundle_dma_allocs++; |
---|
| 4082 | + |
---|
| 4083 | + /* |
---|
| 4084 | + * if DMA buffer crosses 4G boundary, |
---|
| 4085 | + * put it on bad list |
---|
| 4086 | + */ |
---|
| 4087 | + if (MSD(dsd->dsd_list_dma) ^ |
---|
| 4088 | + MSD(dsd->dsd_list_dma + bufsize)) { |
---|
| 4089 | + list_add_tail(&dsd->list, |
---|
| 4090 | + &ha->pool.unusable.head); |
---|
| 4091 | + ha->pool.unusable.count++; |
---|
| 4092 | + } else { |
---|
| 4093 | + list_add_tail(&dsd->list, |
---|
| 4094 | + &ha->pool.good.head); |
---|
| 4095 | + ha->pool.good.count++; |
---|
| 4096 | + } |
---|
| 4097 | + } |
---|
| 4098 | + |
---|
| 4099 | + /* return the good ones back to the pool */ |
---|
| 4100 | + list_for_each_entry_safe(dsd, nxt, |
---|
| 4101 | + &ha->pool.good.head, list) { |
---|
| 4102 | + list_del(&dsd->list); |
---|
| 4103 | + dma_pool_free(ha->dif_bundl_pool, |
---|
| 4104 | + dsd->dsd_addr, dsd->dsd_list_dma); |
---|
| 4105 | + ha->dif_bundle_dma_allocs--; |
---|
| 4106 | + kfree(dsd); |
---|
| 4107 | + ha->dif_bundle_kallocs--; |
---|
| 4108 | + } |
---|
| 4109 | + |
---|
| 4110 | + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0024, |
---|
| 4111 | + "%s: dif dma pool (good=%u unusable=%u)\n", |
---|
| 4112 | + __func__, ha->pool.good.count, |
---|
| 4113 | + ha->pool.unusable.count); |
---|
| 4114 | + } |
---|
| 4115 | + |
---|
3961 | 4116 | 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); |
---|
| 4117 | + "dl_dma_pool=%p fcp_cmnd_dma_pool=%p dif_bundl_pool=%p.\n", |
---|
| 4118 | + ha->dl_dma_pool, ha->fcp_cmnd_dma_pool, |
---|
| 4119 | + ha->dif_bundl_pool); |
---|
3964 | 4120 | } |
---|
3965 | 4121 | |
---|
3966 | 4122 | /* Allocate memory for SNS commands */ |
---|
.. | .. |
---|
4042 | 4198 | ha->npiv_info = NULL; |
---|
4043 | 4199 | |
---|
4044 | 4200 | /* Get consistent memory allocated for EX-INIT-CB. */ |
---|
4045 | | - if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { |
---|
| 4201 | + if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
---|
| 4202 | + IS_QLA28XX(ha)) { |
---|
4046 | 4203 | ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, |
---|
4047 | 4204 | &ha->ex_init_cb_dma); |
---|
4048 | 4205 | if (!ha->ex_init_cb) |
---|
4049 | 4206 | goto fail_ex_init_cb; |
---|
4050 | 4207 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x002e, |
---|
4051 | 4208 | "ex_init_cb=%p.\n", ha->ex_init_cb); |
---|
| 4209 | + } |
---|
| 4210 | + |
---|
| 4211 | + /* Get consistent memory allocated for Special Features-CB. */ |
---|
| 4212 | + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
---|
| 4213 | + ha->sf_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, |
---|
| 4214 | + &ha->sf_init_cb_dma); |
---|
| 4215 | + if (!ha->sf_init_cb) |
---|
| 4216 | + goto fail_sf_init_cb; |
---|
| 4217 | + memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb)); |
---|
| 4218 | + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199, |
---|
| 4219 | + "sf_init_cb=%p.\n", ha->sf_init_cb); |
---|
4052 | 4220 | } |
---|
4053 | 4221 | |
---|
4054 | 4222 | INIT_LIST_HEAD(&ha->gbl_dsd_list); |
---|
.. | .. |
---|
4085 | 4253 | goto fail_sfp_data; |
---|
4086 | 4254 | } |
---|
4087 | 4255 | |
---|
| 4256 | + ha->flt = dma_alloc_coherent(&ha->pdev->dev, |
---|
| 4257 | + sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, &ha->flt_dma, |
---|
| 4258 | + GFP_KERNEL); |
---|
| 4259 | + if (!ha->flt) { |
---|
| 4260 | + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011b, |
---|
| 4261 | + "Unable to allocate memory for FLT.\n"); |
---|
| 4262 | + goto fail_flt_buffer; |
---|
| 4263 | + } |
---|
| 4264 | + |
---|
4088 | 4265 | return 0; |
---|
4089 | 4266 | |
---|
| 4267 | +fail_flt_buffer: |
---|
| 4268 | + dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, |
---|
| 4269 | + ha->sfp_data, ha->sfp_data_dma); |
---|
4090 | 4270 | fail_sfp_data: |
---|
4091 | 4271 | kfree(ha->loop_id_map); |
---|
4092 | 4272 | fail_loop_id_map: |
---|
4093 | 4273 | dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); |
---|
4094 | 4274 | fail_async_pd: |
---|
| 4275 | + dma_pool_free(ha->s_dma_pool, ha->sf_init_cb, ha->sf_init_cb_dma); |
---|
| 4276 | +fail_sf_init_cb: |
---|
4095 | 4277 | dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); |
---|
4096 | 4278 | fail_ex_init_cb: |
---|
4097 | 4279 | kfree(ha->npiv_info); |
---|
.. | .. |
---|
4125 | 4307 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
---|
4126 | 4308 | ha->sns_cmd, ha->sns_cmd_dma); |
---|
4127 | 4309 | fail_dma_pool: |
---|
| 4310 | + if (ql2xenabledif) { |
---|
| 4311 | + struct dsd_dma *dsd, *nxt; |
---|
| 4312 | + |
---|
| 4313 | + list_for_each_entry_safe(dsd, nxt, &ha->pool.unusable.head, |
---|
| 4314 | + list) { |
---|
| 4315 | + list_del(&dsd->list); |
---|
| 4316 | + dma_pool_free(ha->dif_bundl_pool, dsd->dsd_addr, |
---|
| 4317 | + dsd->dsd_list_dma); |
---|
| 4318 | + ha->dif_bundle_dma_allocs--; |
---|
| 4319 | + kfree(dsd); |
---|
| 4320 | + ha->dif_bundle_kallocs--; |
---|
| 4321 | + ha->pool.unusable.count--; |
---|
| 4322 | + } |
---|
| 4323 | + dma_pool_destroy(ha->dif_bundl_pool); |
---|
| 4324 | + ha->dif_bundl_pool = NULL; |
---|
| 4325 | + } |
---|
| 4326 | + |
---|
| 4327 | +fail_dif_bundl_dma_pool: |
---|
4128 | 4328 | if (IS_QLA82XX(ha) || ql2xenabledif) { |
---|
4129 | 4329 | dma_pool_destroy(ha->fcp_cmnd_dma_pool); |
---|
4130 | 4330 | ha->fcp_cmnd_dma_pool = NULL; |
---|
.. | .. |
---|
4141 | 4341 | kfree(ha->nvram); |
---|
4142 | 4342 | ha->nvram = NULL; |
---|
4143 | 4343 | fail_free_ctx_mempool: |
---|
4144 | | - if (ha->ctx_mempool) |
---|
4145 | | - mempool_destroy(ha->ctx_mempool); |
---|
| 4344 | + mempool_destroy(ha->ctx_mempool); |
---|
4146 | 4345 | ha->ctx_mempool = NULL; |
---|
4147 | 4346 | fail_free_srb_mempool: |
---|
4148 | | - if (ha->srb_mempool) |
---|
4149 | | - mempool_destroy(ha->srb_mempool); |
---|
| 4347 | + mempool_destroy(ha->srb_mempool); |
---|
4150 | 4348 | ha->srb_mempool = NULL; |
---|
4151 | 4349 | fail_free_gid_list: |
---|
4152 | 4350 | dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), |
---|
.. | .. |
---|
4171 | 4369 | qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha) |
---|
4172 | 4370 | { |
---|
4173 | 4371 | int rval; |
---|
4174 | | - uint16_t size, max_cnt, temp; |
---|
| 4372 | + uint16_t size, max_cnt; |
---|
| 4373 | + uint32_t temp; |
---|
4175 | 4374 | struct qla_hw_data *ha = vha->hw; |
---|
4176 | 4375 | |
---|
4177 | 4376 | /* Return if we don't need to alloacate any extended logins */ |
---|
4178 | | - if (!ql2xexlogins) |
---|
| 4377 | + if (ql2xexlogins <= MAX_FIBRE_DEVICES_2400) |
---|
4179 | 4378 | return QLA_SUCCESS; |
---|
4180 | 4379 | |
---|
4181 | 4380 | if (!IS_EXLOGIN_OFFLD_CAPABLE(ha)) |
---|
.. | .. |
---|
4246 | 4445 | qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt) |
---|
4247 | 4446 | { |
---|
4248 | 4447 | u32 temp; |
---|
| 4448 | + struct init_cb_81xx *icb = (struct init_cb_81xx *)&vha->hw->init_cb; |
---|
4249 | 4449 | *ret_cnt = FW_DEF_EXCHANGES_CNT; |
---|
4250 | 4450 | |
---|
4251 | 4451 | if (max_cnt > vha->hw->max_exchg) |
---|
4252 | 4452 | max_cnt = vha->hw->max_exchg; |
---|
4253 | 4453 | |
---|
4254 | 4454 | if (qla_ini_mode_enabled(vha)) { |
---|
4255 | | - if (ql2xiniexchg > max_cnt) |
---|
4256 | | - ql2xiniexchg = max_cnt; |
---|
| 4455 | + if (vha->ql2xiniexchg > max_cnt) |
---|
| 4456 | + vha->ql2xiniexchg = max_cnt; |
---|
4257 | 4457 | |
---|
4258 | | - if (ql2xiniexchg > FW_DEF_EXCHANGES_CNT) |
---|
4259 | | - *ret_cnt = ql2xiniexchg; |
---|
| 4458 | + if (vha->ql2xiniexchg > FW_DEF_EXCHANGES_CNT) |
---|
| 4459 | + *ret_cnt = vha->ql2xiniexchg; |
---|
| 4460 | + |
---|
4260 | 4461 | } else if (qla_tgt_mode_enabled(vha)) { |
---|
4261 | | - if (ql2xexchoffld > max_cnt) |
---|
4262 | | - ql2xexchoffld = max_cnt; |
---|
| 4462 | + if (vha->ql2xexchoffld > max_cnt) { |
---|
| 4463 | + vha->ql2xexchoffld = max_cnt; |
---|
| 4464 | + icb->exchange_count = cpu_to_le16(vha->ql2xexchoffld); |
---|
| 4465 | + } |
---|
4263 | 4466 | |
---|
4264 | | - if (ql2xexchoffld > FW_DEF_EXCHANGES_CNT) |
---|
4265 | | - *ret_cnt = ql2xexchoffld; |
---|
| 4467 | + if (vha->ql2xexchoffld > FW_DEF_EXCHANGES_CNT) |
---|
| 4468 | + *ret_cnt = vha->ql2xexchoffld; |
---|
4266 | 4469 | } else if (qla_dual_mode_enabled(vha)) { |
---|
4267 | | - temp = ql2xiniexchg + ql2xexchoffld; |
---|
| 4470 | + temp = vha->ql2xiniexchg + vha->ql2xexchoffld; |
---|
4268 | 4471 | if (temp > max_cnt) { |
---|
4269 | | - ql2xiniexchg -= (temp - max_cnt)/2; |
---|
4270 | | - ql2xexchoffld -= (((temp - max_cnt)/2) + 1); |
---|
| 4472 | + vha->ql2xiniexchg -= (temp - max_cnt)/2; |
---|
| 4473 | + vha->ql2xexchoffld -= (((temp - max_cnt)/2) + 1); |
---|
4271 | 4474 | temp = max_cnt; |
---|
| 4475 | + icb->exchange_count = cpu_to_le16(vha->ql2xexchoffld); |
---|
4272 | 4476 | } |
---|
4273 | 4477 | |
---|
4274 | 4478 | if (temp > FW_DEF_EXCHANGES_CNT) |
---|
.. | .. |
---|
4306 | 4510 | |
---|
4307 | 4511 | if (totsz != ha->exchoffld_size) { |
---|
4308 | 4512 | qla2x00_free_exchoffld_buffer(ha); |
---|
| 4513 | + if (actual_cnt <= FW_DEF_EXCHANGES_CNT) { |
---|
| 4514 | + ha->exchoffld_size = 0; |
---|
| 4515 | + ha->flags.exchoffld_enabled = 0; |
---|
| 4516 | + return QLA_SUCCESS; |
---|
| 4517 | + } |
---|
| 4518 | + |
---|
4309 | 4519 | ha->exchoffld_size = totsz; |
---|
4310 | 4520 | |
---|
4311 | 4521 | ql_log(ql_log_info, vha, 0xd016, |
---|
.. | .. |
---|
4338 | 4548 | |
---|
4339 | 4549 | return -ENOMEM; |
---|
4340 | 4550 | } |
---|
| 4551 | + } else if (!ha->exchoffld_buf || (actual_cnt <= FW_DEF_EXCHANGES_CNT)) { |
---|
| 4552 | + /* pathological case */ |
---|
| 4553 | + qla2x00_free_exchoffld_buffer(ha); |
---|
| 4554 | + ha->exchoffld_size = 0; |
---|
| 4555 | + ha->flags.exchoffld_enabled = 0; |
---|
| 4556 | + ql_log(ql_log_info, vha, 0xd016, |
---|
| 4557 | + "Exchange offload not enable: offld size=%d, actual count=%d entry sz=0x%x, total sz=0x%x.\n", |
---|
| 4558 | + ha->exchoffld_size, actual_cnt, size, totsz); |
---|
| 4559 | + return 0; |
---|
4341 | 4560 | } |
---|
4342 | 4561 | |
---|
4343 | 4562 | /* Now configure the dma buffer */ |
---|
.. | .. |
---|
4353 | 4572 | if (qla_ini_mode_enabled(vha)) |
---|
4354 | 4573 | icb->exchange_count = 0; |
---|
4355 | 4574 | else |
---|
4356 | | - icb->exchange_count = cpu_to_le16(ql2xexchoffld); |
---|
| 4575 | + icb->exchange_count = cpu_to_le16(vha->ql2xexchoffld); |
---|
4357 | 4576 | } |
---|
4358 | 4577 | |
---|
4359 | 4578 | return rval; |
---|
.. | .. |
---|
4386 | 4605 | static void |
---|
4387 | 4606 | qla2x00_free_fw_dump(struct qla_hw_data *ha) |
---|
4388 | 4607 | { |
---|
| 4608 | + struct fwdt *fwdt = ha->fwdt; |
---|
| 4609 | + uint j; |
---|
| 4610 | + |
---|
4389 | 4611 | if (ha->fce) |
---|
4390 | 4612 | dma_free_coherent(&ha->pdev->dev, |
---|
4391 | 4613 | FCE_SIZE, ha->fce, ha->fce_dma); |
---|
.. | .. |
---|
4396 | 4618 | |
---|
4397 | 4619 | if (ha->fw_dump) |
---|
4398 | 4620 | vfree(ha->fw_dump); |
---|
4399 | | - if (ha->fw_dump_template) |
---|
4400 | | - vfree(ha->fw_dump_template); |
---|
4401 | 4621 | |
---|
4402 | 4622 | ha->fce = NULL; |
---|
4403 | 4623 | ha->fce_dma = 0; |
---|
| 4624 | + ha->flags.fce_enabled = 0; |
---|
4404 | 4625 | ha->eft = NULL; |
---|
4405 | 4626 | ha->eft_dma = 0; |
---|
4406 | | - ha->fw_dumped = 0; |
---|
| 4627 | + ha->fw_dumped = false; |
---|
4407 | 4628 | ha->fw_dump_cap_flags = 0; |
---|
4408 | 4629 | ha->fw_dump_reading = 0; |
---|
4409 | 4630 | ha->fw_dump = NULL; |
---|
4410 | 4631 | ha->fw_dump_len = 0; |
---|
4411 | | - ha->fw_dump_template = NULL; |
---|
4412 | | - ha->fw_dump_template_len = 0; |
---|
| 4632 | + |
---|
| 4633 | + for (j = 0; j < 2; j++, fwdt++) { |
---|
| 4634 | + if (fwdt->template) |
---|
| 4635 | + vfree(fwdt->template); |
---|
| 4636 | + fwdt->template = NULL; |
---|
| 4637 | + fwdt->length = 0; |
---|
| 4638 | + } |
---|
4413 | 4639 | } |
---|
4414 | 4640 | |
---|
4415 | 4641 | /* |
---|
.. | .. |
---|
4427 | 4653 | if (ha->mctp_dump) |
---|
4428 | 4654 | dma_free_coherent(&ha->pdev->dev, MCTP_DUMP_SIZE, ha->mctp_dump, |
---|
4429 | 4655 | ha->mctp_dump_dma); |
---|
| 4656 | + ha->mctp_dump = NULL; |
---|
4430 | 4657 | |
---|
4431 | | - if (ha->srb_mempool) |
---|
4432 | | - mempool_destroy(ha->srb_mempool); |
---|
| 4658 | + mempool_destroy(ha->srb_mempool); |
---|
| 4659 | + ha->srb_mempool = NULL; |
---|
4433 | 4660 | |
---|
4434 | 4661 | if (ha->dcbx_tlv) |
---|
4435 | 4662 | dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE, |
---|
4436 | 4663 | ha->dcbx_tlv, ha->dcbx_tlv_dma); |
---|
| 4664 | + ha->dcbx_tlv = NULL; |
---|
4437 | 4665 | |
---|
4438 | 4666 | if (ha->xgmac_data) |
---|
4439 | 4667 | dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE, |
---|
4440 | 4668 | ha->xgmac_data, ha->xgmac_data_dma); |
---|
| 4669 | + ha->xgmac_data = NULL; |
---|
4441 | 4670 | |
---|
4442 | 4671 | if (ha->sns_cmd) |
---|
4443 | 4672 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
---|
4444 | 4673 | ha->sns_cmd, ha->sns_cmd_dma); |
---|
| 4674 | + ha->sns_cmd = NULL; |
---|
| 4675 | + ha->sns_cmd_dma = 0; |
---|
4445 | 4676 | |
---|
4446 | 4677 | if (ha->ct_sns) |
---|
4447 | 4678 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), |
---|
4448 | 4679 | ha->ct_sns, ha->ct_sns_dma); |
---|
| 4680 | + ha->ct_sns = NULL; |
---|
| 4681 | + ha->ct_sns_dma = 0; |
---|
4449 | 4682 | |
---|
4450 | 4683 | if (ha->sfp_data) |
---|
4451 | 4684 | dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, ha->sfp_data, |
---|
4452 | 4685 | ha->sfp_data_dma); |
---|
| 4686 | + ha->sfp_data = NULL; |
---|
| 4687 | + |
---|
| 4688 | + if (ha->flt) |
---|
| 4689 | + dma_free_coherent(&ha->pdev->dev, |
---|
| 4690 | + sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, |
---|
| 4691 | + ha->flt, ha->flt_dma); |
---|
| 4692 | + ha->flt = NULL; |
---|
| 4693 | + ha->flt_dma = 0; |
---|
4453 | 4694 | |
---|
4454 | 4695 | if (ha->ms_iocb) |
---|
4455 | 4696 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); |
---|
| 4697 | + ha->ms_iocb = NULL; |
---|
| 4698 | + ha->ms_iocb_dma = 0; |
---|
| 4699 | + |
---|
| 4700 | + if (ha->sf_init_cb) |
---|
| 4701 | + dma_pool_free(ha->s_dma_pool, |
---|
| 4702 | + ha->sf_init_cb, ha->sf_init_cb_dma); |
---|
4456 | 4703 | |
---|
4457 | 4704 | if (ha->ex_init_cb) |
---|
4458 | 4705 | dma_pool_free(ha->s_dma_pool, |
---|
4459 | 4706 | ha->ex_init_cb, ha->ex_init_cb_dma); |
---|
| 4707 | + ha->ex_init_cb = NULL; |
---|
| 4708 | + ha->ex_init_cb_dma = 0; |
---|
4460 | 4709 | |
---|
4461 | 4710 | if (ha->async_pd) |
---|
4462 | 4711 | dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); |
---|
| 4712 | + ha->async_pd = NULL; |
---|
| 4713 | + ha->async_pd_dma = 0; |
---|
4463 | 4714 | |
---|
4464 | | - if (ha->s_dma_pool) |
---|
4465 | | - dma_pool_destroy(ha->s_dma_pool); |
---|
| 4715 | + dma_pool_destroy(ha->s_dma_pool); |
---|
| 4716 | + ha->s_dma_pool = NULL; |
---|
4466 | 4717 | |
---|
4467 | 4718 | if (ha->gid_list) |
---|
4468 | 4719 | dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), |
---|
4469 | 4720 | ha->gid_list, ha->gid_list_dma); |
---|
| 4721 | + ha->gid_list = NULL; |
---|
| 4722 | + ha->gid_list_dma = 0; |
---|
4470 | 4723 | |
---|
4471 | 4724 | if (IS_QLA82XX(ha)) { |
---|
4472 | 4725 | if (!list_empty(&ha->gbl_dsd_list)) { |
---|
.. | .. |
---|
4483 | 4736 | } |
---|
4484 | 4737 | } |
---|
4485 | 4738 | |
---|
4486 | | - if (ha->dl_dma_pool) |
---|
4487 | | - dma_pool_destroy(ha->dl_dma_pool); |
---|
| 4739 | + dma_pool_destroy(ha->dl_dma_pool); |
---|
| 4740 | + ha->dl_dma_pool = NULL; |
---|
4488 | 4741 | |
---|
4489 | | - if (ha->fcp_cmnd_dma_pool) |
---|
4490 | | - dma_pool_destroy(ha->fcp_cmnd_dma_pool); |
---|
| 4742 | + dma_pool_destroy(ha->fcp_cmnd_dma_pool); |
---|
| 4743 | + ha->fcp_cmnd_dma_pool = NULL; |
---|
4491 | 4744 | |
---|
4492 | | - if (ha->ctx_mempool) |
---|
4493 | | - mempool_destroy(ha->ctx_mempool); |
---|
| 4745 | + mempool_destroy(ha->ctx_mempool); |
---|
| 4746 | + ha->ctx_mempool = NULL; |
---|
| 4747 | + |
---|
| 4748 | + if (ql2xenabledif && ha->dif_bundl_pool) { |
---|
| 4749 | + struct dsd_dma *dsd, *nxt; |
---|
| 4750 | + |
---|
| 4751 | + list_for_each_entry_safe(dsd, nxt, &ha->pool.unusable.head, |
---|
| 4752 | + list) { |
---|
| 4753 | + list_del(&dsd->list); |
---|
| 4754 | + dma_pool_free(ha->dif_bundl_pool, dsd->dsd_addr, |
---|
| 4755 | + dsd->dsd_list_dma); |
---|
| 4756 | + ha->dif_bundle_dma_allocs--; |
---|
| 4757 | + kfree(dsd); |
---|
| 4758 | + ha->dif_bundle_kallocs--; |
---|
| 4759 | + ha->pool.unusable.count--; |
---|
| 4760 | + } |
---|
| 4761 | + list_for_each_entry_safe(dsd, nxt, &ha->pool.good.head, list) { |
---|
| 4762 | + list_del(&dsd->list); |
---|
| 4763 | + dma_pool_free(ha->dif_bundl_pool, dsd->dsd_addr, |
---|
| 4764 | + dsd->dsd_list_dma); |
---|
| 4765 | + ha->dif_bundle_dma_allocs--; |
---|
| 4766 | + kfree(dsd); |
---|
| 4767 | + ha->dif_bundle_kallocs--; |
---|
| 4768 | + } |
---|
| 4769 | + } |
---|
| 4770 | + |
---|
| 4771 | + dma_pool_destroy(ha->dif_bundl_pool); |
---|
| 4772 | + ha->dif_bundl_pool = NULL; |
---|
4494 | 4773 | |
---|
4495 | 4774 | qlt_mem_free(ha); |
---|
4496 | 4775 | |
---|
4497 | 4776 | if (ha->init_cb) |
---|
4498 | 4777 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, |
---|
4499 | 4778 | 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 | 4779 | ha->init_cb = NULL; |
---|
4516 | 4780 | 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; |
---|
| 4781 | + |
---|
| 4782 | + vfree(ha->optrom_buffer); |
---|
4523 | 4783 | ha->optrom_buffer = NULL; |
---|
4524 | | - ha->swl = NULL; |
---|
| 4784 | + kfree(ha->nvram); |
---|
4525 | 4785 | 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; |
---|
| 4786 | + kfree(ha->npiv_info); |
---|
| 4787 | + ha->npiv_info = NULL; |
---|
| 4788 | + kfree(ha->swl); |
---|
| 4789 | + ha->swl = NULL; |
---|
| 4790 | + kfree(ha->loop_id_map); |
---|
| 4791 | + ha->sf_init_cb = NULL; |
---|
| 4792 | + ha->sf_init_cb_dma = 0; |
---|
| 4793 | + ha->loop_id_map = NULL; |
---|
4541 | 4794 | } |
---|
4542 | 4795 | |
---|
4543 | 4796 | struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, |
---|
.. | .. |
---|
4561 | 4814 | vha->host_no = host->host_no; |
---|
4562 | 4815 | vha->hw = ha; |
---|
4563 | 4816 | |
---|
| 4817 | + vha->qlini_mode = ql2x_ini_mode; |
---|
| 4818 | + vha->ql2xexchoffld = ql2xexchoffld; |
---|
| 4819 | + vha->ql2xiniexchg = ql2xiniexchg; |
---|
| 4820 | + |
---|
4564 | 4821 | INIT_LIST_HEAD(&vha->vp_fcports); |
---|
4565 | 4822 | INIT_LIST_HEAD(&vha->work_list); |
---|
4566 | 4823 | INIT_LIST_HEAD(&vha->list); |
---|
.. | .. |
---|
4570 | 4827 | INIT_LIST_HEAD(&vha->plogi_ack_list); |
---|
4571 | 4828 | INIT_LIST_HEAD(&vha->qp_list); |
---|
4572 | 4829 | INIT_LIST_HEAD(&vha->gnl.fcports); |
---|
4573 | | - INIT_LIST_HEAD(&vha->nvme_rport_list); |
---|
4574 | 4830 | INIT_LIST_HEAD(&vha->gpnid_list); |
---|
4575 | 4831 | INIT_WORK(&vha->iocb_work, qla2x00_iocb_work_fn); |
---|
| 4832 | + |
---|
| 4833 | + INIT_LIST_HEAD(&vha->purex_list.head); |
---|
| 4834 | + spin_lock_init(&vha->purex_list.lock); |
---|
4576 | 4835 | |
---|
4577 | 4836 | spin_lock_init(&vha->work_lock); |
---|
4578 | 4837 | spin_lock_init(&vha->cmd_list_lock); |
---|
.. | .. |
---|
4586 | 4845 | if (!vha->gnl.l) { |
---|
4587 | 4846 | ql_log(ql_log_fatal, vha, 0xd04a, |
---|
4588 | 4847 | "Alloc failed for name list.\n"); |
---|
4589 | | - scsi_remove_host(vha->host); |
---|
| 4848 | + scsi_host_put(vha->host); |
---|
4590 | 4849 | return NULL; |
---|
4591 | 4850 | } |
---|
4592 | 4851 | |
---|
.. | .. |
---|
4599 | 4858 | dma_free_coherent(&ha->pdev->dev, vha->gnl.size, |
---|
4600 | 4859 | vha->gnl.l, vha->gnl.ldma); |
---|
4601 | 4860 | vha->gnl.l = NULL; |
---|
4602 | | - scsi_remove_host(vha->host); |
---|
| 4861 | + scsi_host_put(vha->host); |
---|
4603 | 4862 | return NULL; |
---|
4604 | 4863 | } |
---|
4605 | 4864 | INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); |
---|
4606 | 4865 | |
---|
4607 | | - sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); |
---|
| 4866 | + snprintf(vha->host_str, sizeof(vha->host_str), "%s_%lu", |
---|
| 4867 | + QLA2XXX_DRIVER_NAME, vha->host_no); |
---|
4608 | 4868 | ql_dbg(ql_dbg_init, vha, 0x0041, |
---|
4609 | 4869 | "Allocated the host=%p hw=%p vha=%p dev_name=%s", |
---|
4610 | 4870 | vha->host, vha->hw, vha, |
---|
.. | .. |
---|
4708 | 4968 | |
---|
4709 | 4969 | qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN); |
---|
4710 | 4970 | qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); |
---|
4711 | | -qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); |
---|
4712 | 4971 | qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC); |
---|
4713 | | -qla2x00_post_async_work(adisc_done, QLA_EVT_ASYNC_ADISC_DONE); |
---|
4714 | 4972 | qla2x00_post_async_work(prlo, QLA_EVT_ASYNC_PRLO); |
---|
4715 | 4973 | qla2x00_post_async_work(prlo_done, QLA_EVT_ASYNC_PRLO_DONE); |
---|
4716 | 4974 | |
---|
.. | .. |
---|
4735 | 4993 | |
---|
4736 | 4994 | switch (code) { |
---|
4737 | 4995 | case QLA_UEVENT_CODE_FW_DUMP: |
---|
4738 | | - snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", |
---|
| 4996 | + snprintf(event_string, sizeof(event_string), "FW_DUMP=%lu", |
---|
4739 | 4997 | vha->host_no); |
---|
4740 | 4998 | break; |
---|
4741 | 4999 | default: |
---|
.. | .. |
---|
4776 | 5034 | fcport->jiffies_at_registration = jiffies; |
---|
4777 | 5035 | fcport->sec_since_registration = 0; |
---|
4778 | 5036 | fcport->next_disc_state = DSC_DELETED; |
---|
4779 | | - fcport->disc_state = DSC_UPD_FCPORT; |
---|
| 5037 | + qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); |
---|
4780 | 5038 | spin_unlock_irqrestore(&fcport->vha->work_lock, flags); |
---|
4781 | 5039 | |
---|
4782 | 5040 | queue_work(system_unbound_wq, &fcport->reg_work); |
---|
.. | .. |
---|
4817 | 5075 | fcport->d_id = e->u.new_sess.id; |
---|
4818 | 5076 | fcport->flags |= FCF_FABRIC_DEVICE; |
---|
4819 | 5077 | 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 | 5078 | |
---|
4828 | 5079 | memcpy(fcport->port_name, e->u.new_sess.port_name, |
---|
4829 | 5080 | WWN_SIZE); |
---|
| 5081 | + |
---|
| 5082 | + fcport->fc4_type = e->u.new_sess.fc4_type; |
---|
| 5083 | + if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) { |
---|
| 5084 | + fcport->dm_login_expire = jiffies + |
---|
| 5085 | + QLA_N2N_WAIT_TIME * HZ; |
---|
| 5086 | + fcport->fc4_type = FS_FC4TYPE_FCP; |
---|
| 5087 | + fcport->n2n_flag = 1; |
---|
| 5088 | + if (vha->flags.nvme_enabled) |
---|
| 5089 | + fcport->fc4_type |= FS_FC4TYPE_NVME; |
---|
| 5090 | + } |
---|
| 5091 | + |
---|
4830 | 5092 | } else { |
---|
4831 | 5093 | ql_dbg(ql_dbg_disc, vha, 0xffff, |
---|
4832 | 5094 | "%s %8phC mem alloc fail.\n", |
---|
4833 | 5095 | __func__, e->u.new_sess.port_name); |
---|
4834 | 5096 | |
---|
4835 | | - if (pla) |
---|
| 5097 | + if (pla) { |
---|
| 5098 | + list_del(&pla->list); |
---|
4836 | 5099 | kmem_cache_free(qla_tgt_plogi_cachep, pla); |
---|
| 5100 | + } |
---|
4837 | 5101 | return; |
---|
4838 | 5102 | } |
---|
4839 | 5103 | |
---|
.. | .. |
---|
4923 | 5187 | if (dfcp) |
---|
4924 | 5188 | qlt_schedule_sess_for_deletion(tfcp); |
---|
4925 | 5189 | |
---|
4926 | | - |
---|
4927 | | - if (N2N_TOPO(vha->hw)) |
---|
4928 | | - fcport->flags &= ~FCF_FABRIC_DEVICE; |
---|
4929 | | - |
---|
4930 | 5190 | if (N2N_TOPO(vha->hw)) { |
---|
| 5191 | + fcport->flags &= ~FCF_FABRIC_DEVICE; |
---|
| 5192 | + fcport->keep_nport_handle = 1; |
---|
4931 | 5193 | if (vha->flags.nvme_enabled) { |
---|
4932 | | - fcport->fc4f_nvme = 1; |
---|
| 5194 | + fcport->fc4_type = |
---|
| 5195 | + (FS_FC4TYPE_NVME | FS_FC4TYPE_FCP); |
---|
4933 | 5196 | fcport->n2n_flag = 1; |
---|
4934 | 5197 | } |
---|
4935 | 5198 | fcport->fw_login_state = 0; |
---|
4936 | | - /* |
---|
4937 | | - * wait link init done before sending login |
---|
4938 | | - */ |
---|
| 5199 | + |
---|
| 5200 | + schedule_delayed_work(&vha->scan.scan_work, 5); |
---|
4939 | 5201 | } else { |
---|
4940 | 5202 | qla24xx_fcport_handle_login(vha, fcport); |
---|
4941 | 5203 | } |
---|
.. | .. |
---|
4944 | 5206 | |
---|
4945 | 5207 | if (free_fcport) { |
---|
4946 | 5208 | qla2x00_free_fcport(fcport); |
---|
4947 | | - if (pla) |
---|
| 5209 | + if (pla) { |
---|
| 5210 | + list_del(&pla->list); |
---|
4948 | 5211 | kmem_cache_free(qla_tgt_plogi_cachep, pla); |
---|
| 5212 | + } |
---|
4949 | 5213 | } |
---|
4950 | 5214 | } |
---|
4951 | 5215 | |
---|
.. | .. |
---|
4969 | 5233 | struct qla_work_evt *e, *tmp; |
---|
4970 | 5234 | unsigned long flags; |
---|
4971 | 5235 | LIST_HEAD(work); |
---|
| 5236 | + int rc; |
---|
4972 | 5237 | |
---|
4973 | 5238 | spin_lock_irqsave(&vha->work_lock, flags); |
---|
4974 | 5239 | list_splice_init(&vha->work_list, &work); |
---|
4975 | 5240 | spin_unlock_irqrestore(&vha->work_lock, flags); |
---|
4976 | 5241 | |
---|
4977 | 5242 | list_for_each_entry_safe(e, tmp, &work, list) { |
---|
4978 | | - list_del_init(&e->list); |
---|
4979 | | - |
---|
| 5243 | + rc = QLA_SUCCESS; |
---|
4980 | 5244 | switch (e->type) { |
---|
4981 | 5245 | case QLA_EVT_AEN: |
---|
4982 | 5246 | fc_host_post_event(vha->host, fc_get_event_number(), |
---|
.. | .. |
---|
4990 | 5254 | e->u.logio.data); |
---|
4991 | 5255 | break; |
---|
4992 | 5256 | 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); |
---|
| 5257 | + rc = qla2x00_async_logout(vha, e->u.logio.fcport); |
---|
4998 | 5258 | break; |
---|
4999 | 5259 | case QLA_EVT_ASYNC_ADISC: |
---|
5000 | 5260 | 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 | 5261 | e->u.logio.data); |
---|
5006 | 5262 | break; |
---|
5007 | 5263 | case QLA_EVT_UEVENT: |
---|
.. | .. |
---|
5009 | 5265 | break; |
---|
5010 | 5266 | case QLA_EVT_AENFX: |
---|
5011 | 5267 | qlafx00_process_aen(vha, e); |
---|
5012 | | - break; |
---|
5013 | | - case QLA_EVT_GIDPN: |
---|
5014 | | - qla24xx_async_gidpn(vha, e->u.fcport.fcport); |
---|
5015 | 5268 | break; |
---|
5016 | 5269 | case QLA_EVT_GPNID: |
---|
5017 | 5270 | qla24xx_async_gpnid(vha, &e->u.gpnid.id); |
---|
.. | .. |
---|
5042 | 5295 | qla24xx_do_nack_work(vha, e); |
---|
5043 | 5296 | break; |
---|
5044 | 5297 | case QLA_EVT_ASYNC_PRLO: |
---|
5045 | | - qla2x00_async_prlo(vha, e->u.logio.fcport); |
---|
| 5298 | + rc = qla2x00_async_prlo(vha, e->u.logio.fcport); |
---|
5046 | 5299 | break; |
---|
5047 | 5300 | case QLA_EVT_ASYNC_PRLO_DONE: |
---|
5048 | 5301 | qla2x00_async_prlo_done(vha, e->u.logio.fcport, |
---|
.. | .. |
---|
5075 | 5328 | e->u.fcport.fcport, false); |
---|
5076 | 5329 | break; |
---|
5077 | 5330 | } |
---|
| 5331 | + |
---|
| 5332 | + if (rc == EAGAIN) { |
---|
| 5333 | + /* put 'work' at head of 'vha->work_list' */ |
---|
| 5334 | + spin_lock_irqsave(&vha->work_lock, flags); |
---|
| 5335 | + list_splice(&work, &vha->work_list); |
---|
| 5336 | + spin_unlock_irqrestore(&vha->work_lock, flags); |
---|
| 5337 | + break; |
---|
| 5338 | + } |
---|
| 5339 | + list_del_init(&e->list); |
---|
5078 | 5340 | if (e->flags & QLA_EVT_FLAG_FREE) |
---|
5079 | 5341 | kfree(e); |
---|
5080 | 5342 | |
---|
.. | .. |
---|
5123 | 5385 | } else { |
---|
5124 | 5386 | if (vha->hw->current_topology != ISP_CFG_NL) { |
---|
5125 | 5387 | memset(&ea, 0, sizeof(ea)); |
---|
5126 | | - ea.event = FCME_RELOGIN; |
---|
5127 | 5388 | ea.fcport = fcport; |
---|
5128 | | - qla2x00_fcport_event_handler(vha, &ea); |
---|
| 5389 | + qla24xx_handle_relogin_event(vha, &ea); |
---|
| 5390 | + } else if (vha->hw->current_topology == |
---|
| 5391 | + ISP_CFG_NL && |
---|
| 5392 | + IS_QLA2XXX_MIDTYPE(vha->hw)) { |
---|
| 5393 | + (void)qla24xx_fcport_handle_login(vha, |
---|
| 5394 | + fcport); |
---|
5129 | 5395 | } else if (vha->hw->current_topology == |
---|
5130 | 5396 | ISP_CFG_NL) { |
---|
5131 | 5397 | fcport->login_retry--; |
---|
.. | .. |
---|
5371 | 5637 | uint32_t idc_lck_rcvry_stage_mask = 0x3; |
---|
5372 | 5638 | uint32_t idc_lck_rcvry_owner_mask = 0x3c; |
---|
5373 | 5639 | struct qla_hw_data *ha = base_vha->hw; |
---|
| 5640 | + |
---|
5374 | 5641 | ql_dbg(ql_dbg_p3p, base_vha, 0xb086, |
---|
5375 | 5642 | "Trying force recovery of the IDC lock.\n"); |
---|
5376 | 5643 | |
---|
.. | .. |
---|
5462 | 5729 | void |
---|
5463 | 5730 | qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id) |
---|
5464 | 5731 | { |
---|
5465 | | - uint16_t options = (requester_id << 15) | BIT_6; |
---|
5466 | 5732 | uint32_t data; |
---|
5467 | 5733 | uint32_t lock_owner; |
---|
5468 | 5734 | struct qla_hw_data *ha = base_vha->hw; |
---|
.. | .. |
---|
5495 | 5761 | } |
---|
5496 | 5762 | |
---|
5497 | 5763 | return; |
---|
| 5764 | +} |
---|
5498 | 5765 | |
---|
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"); |
---|
| 5766 | +static bool |
---|
| 5767 | +qla25xx_rdp_rsp_reduce_size(struct scsi_qla_host *vha, |
---|
| 5768 | + struct purex_entry_24xx *purex) |
---|
| 5769 | +{ |
---|
| 5770 | + char fwstr[16]; |
---|
| 5771 | + u32 sid = purex->s_id[2] << 16 | purex->s_id[1] << 8 | purex->s_id[0]; |
---|
| 5772 | + struct port_database_24xx *pdb; |
---|
| 5773 | + |
---|
| 5774 | + /* Domain Controller is always logged-out. */ |
---|
| 5775 | + /* if RDP request is not from Domain Controller: */ |
---|
| 5776 | + if (sid != 0xfffc01) |
---|
| 5777 | + return false; |
---|
| 5778 | + |
---|
| 5779 | + ql_dbg(ql_dbg_init, vha, 0x0181, "%s: s_id=%#x\n", __func__, sid); |
---|
| 5780 | + |
---|
| 5781 | + pdb = kzalloc(sizeof(*pdb), GFP_KERNEL); |
---|
| 5782 | + if (!pdb) { |
---|
| 5783 | + ql_dbg(ql_dbg_init, vha, 0x0181, |
---|
| 5784 | + "%s: Failed allocate pdb\n", __func__); |
---|
| 5785 | + } else if (qla24xx_get_port_database(vha, |
---|
| 5786 | + le16_to_cpu(purex->nport_handle), pdb)) { |
---|
| 5787 | + ql_dbg(ql_dbg_init, vha, 0x0181, |
---|
| 5788 | + "%s: Failed get pdb sid=%x\n", __func__, sid); |
---|
| 5789 | + } else if (pdb->current_login_state != PDS_PLOGI_COMPLETE && |
---|
| 5790 | + pdb->current_login_state != PDS_PRLI_COMPLETE) { |
---|
| 5791 | + ql_dbg(ql_dbg_init, vha, 0x0181, |
---|
| 5792 | + "%s: Port not logged in sid=%#x\n", __func__, sid); |
---|
| 5793 | + } else { |
---|
| 5794 | + /* RDP request is from logged in port */ |
---|
| 5795 | + kfree(pdb); |
---|
| 5796 | + return false; |
---|
| 5797 | + } |
---|
| 5798 | + kfree(pdb); |
---|
| 5799 | + |
---|
| 5800 | + vha->hw->isp_ops->fw_version_str(vha, fwstr, sizeof(fwstr)); |
---|
| 5801 | + fwstr[strcspn(fwstr, " ")] = 0; |
---|
| 5802 | + /* if FW version allows RDP response length upto 2048 bytes: */ |
---|
| 5803 | + if (strcmp(fwstr, "8.09.00") > 0 || strcmp(fwstr, "8.05.65") == 0) |
---|
| 5804 | + return false; |
---|
| 5805 | + |
---|
| 5806 | + ql_dbg(ql_dbg_init, vha, 0x0181, "%s: fw=%s\n", __func__, fwstr); |
---|
| 5807 | + |
---|
| 5808 | + /* RDP response length is to be reduced to maximum 256 bytes */ |
---|
| 5809 | + return true; |
---|
| 5810 | +} |
---|
| 5811 | + |
---|
| 5812 | +/* |
---|
| 5813 | + * Function Name: qla24xx_process_purex_iocb |
---|
| 5814 | + * |
---|
| 5815 | + * Description: |
---|
| 5816 | + * Prepare a RDP response and send to Fabric switch |
---|
| 5817 | + * |
---|
| 5818 | + * PARAMETERS: |
---|
| 5819 | + * vha: SCSI qla host |
---|
| 5820 | + * purex: RDP request received by HBA |
---|
| 5821 | + */ |
---|
| 5822 | +void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, |
---|
| 5823 | + struct purex_item *item) |
---|
| 5824 | +{ |
---|
| 5825 | + struct qla_hw_data *ha = vha->hw; |
---|
| 5826 | + struct purex_entry_24xx *purex = |
---|
| 5827 | + (struct purex_entry_24xx *)&item->iocb; |
---|
| 5828 | + dma_addr_t rsp_els_dma; |
---|
| 5829 | + dma_addr_t rsp_payload_dma; |
---|
| 5830 | + dma_addr_t stat_dma; |
---|
| 5831 | + dma_addr_t sfp_dma; |
---|
| 5832 | + struct els_entry_24xx *rsp_els = NULL; |
---|
| 5833 | + struct rdp_rsp_payload *rsp_payload = NULL; |
---|
| 5834 | + struct link_statistics *stat = NULL; |
---|
| 5835 | + uint8_t *sfp = NULL; |
---|
| 5836 | + uint16_t sfp_flags = 0; |
---|
| 5837 | + uint rsp_payload_length = sizeof(*rsp_payload); |
---|
| 5838 | + int rval; |
---|
| 5839 | + |
---|
| 5840 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0180, |
---|
| 5841 | + "%s: Enter\n", __func__); |
---|
| 5842 | + |
---|
| 5843 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0181, |
---|
| 5844 | + "-------- ELS REQ -------\n"); |
---|
| 5845 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0182, |
---|
| 5846 | + purex, sizeof(*purex)); |
---|
| 5847 | + |
---|
| 5848 | + if (qla25xx_rdp_rsp_reduce_size(vha, purex)) { |
---|
| 5849 | + rsp_payload_length = |
---|
| 5850 | + offsetof(typeof(*rsp_payload), optical_elmt_desc); |
---|
| 5851 | + ql_dbg(ql_dbg_init, vha, 0x0181, |
---|
| 5852 | + "Reducing RSP payload length to %u bytes...\n", |
---|
| 5853 | + rsp_payload_length); |
---|
5511 | 5854 | } |
---|
5512 | 5855 | |
---|
5513 | | - return; |
---|
| 5856 | + rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els), |
---|
| 5857 | + &rsp_els_dma, GFP_KERNEL); |
---|
| 5858 | + if (!rsp_els) { |
---|
| 5859 | + ql_log(ql_log_warn, vha, 0x0183, |
---|
| 5860 | + "Failed allocate dma buffer ELS RSP.\n"); |
---|
| 5861 | + goto dealloc; |
---|
| 5862 | + } |
---|
| 5863 | + |
---|
| 5864 | + rsp_payload = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_payload), |
---|
| 5865 | + &rsp_payload_dma, GFP_KERNEL); |
---|
| 5866 | + if (!rsp_payload) { |
---|
| 5867 | + ql_log(ql_log_warn, vha, 0x0184, |
---|
| 5868 | + "Failed allocate dma buffer ELS RSP payload.\n"); |
---|
| 5869 | + goto dealloc; |
---|
| 5870 | + } |
---|
| 5871 | + |
---|
| 5872 | + sfp = dma_alloc_coherent(&ha->pdev->dev, SFP_RTDI_LEN, |
---|
| 5873 | + &sfp_dma, GFP_KERNEL); |
---|
| 5874 | + |
---|
| 5875 | + stat = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stat), |
---|
| 5876 | + &stat_dma, GFP_KERNEL); |
---|
| 5877 | + |
---|
| 5878 | + /* Prepare Response IOCB */ |
---|
| 5879 | + rsp_els->entry_type = ELS_IOCB_TYPE; |
---|
| 5880 | + rsp_els->entry_count = 1; |
---|
| 5881 | + rsp_els->sys_define = 0; |
---|
| 5882 | + rsp_els->entry_status = 0; |
---|
| 5883 | + rsp_els->handle = 0; |
---|
| 5884 | + rsp_els->nport_handle = purex->nport_handle; |
---|
| 5885 | + rsp_els->tx_dsd_count = cpu_to_le16(1); |
---|
| 5886 | + rsp_els->vp_index = purex->vp_idx; |
---|
| 5887 | + rsp_els->sof_type = EST_SOFI3; |
---|
| 5888 | + rsp_els->rx_xchg_address = purex->rx_xchg_addr; |
---|
| 5889 | + rsp_els->rx_dsd_count = 0; |
---|
| 5890 | + rsp_els->opcode = purex->els_frame_payload[0]; |
---|
| 5891 | + |
---|
| 5892 | + rsp_els->d_id[0] = purex->s_id[0]; |
---|
| 5893 | + rsp_els->d_id[1] = purex->s_id[1]; |
---|
| 5894 | + rsp_els->d_id[2] = purex->s_id[2]; |
---|
| 5895 | + |
---|
| 5896 | + rsp_els->control_flags = cpu_to_le16(EPD_ELS_ACC); |
---|
| 5897 | + rsp_els->rx_byte_count = 0; |
---|
| 5898 | + rsp_els->tx_byte_count = cpu_to_le32(rsp_payload_length); |
---|
| 5899 | + |
---|
| 5900 | + put_unaligned_le64(rsp_payload_dma, &rsp_els->tx_address); |
---|
| 5901 | + rsp_els->tx_len = rsp_els->tx_byte_count; |
---|
| 5902 | + |
---|
| 5903 | + rsp_els->rx_address = 0; |
---|
| 5904 | + rsp_els->rx_len = 0; |
---|
| 5905 | + |
---|
| 5906 | + /* Prepare Response Payload */ |
---|
| 5907 | + rsp_payload->hdr.cmd = cpu_to_be32(0x2 << 24); /* LS_ACC */ |
---|
| 5908 | + rsp_payload->hdr.len = cpu_to_be32(le32_to_cpu(rsp_els->tx_byte_count) - |
---|
| 5909 | + sizeof(rsp_payload->hdr)); |
---|
| 5910 | + |
---|
| 5911 | + /* Link service Request Info Descriptor */ |
---|
| 5912 | + rsp_payload->ls_req_info_desc.desc_tag = cpu_to_be32(0x1); |
---|
| 5913 | + rsp_payload->ls_req_info_desc.desc_len = |
---|
| 5914 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_req_info_desc)); |
---|
| 5915 | + rsp_payload->ls_req_info_desc.req_payload_word_0 = |
---|
| 5916 | + cpu_to_be32p((uint32_t *)purex->els_frame_payload); |
---|
| 5917 | + |
---|
| 5918 | + /* Link service Request Info Descriptor 2 */ |
---|
| 5919 | + rsp_payload->ls_req_info_desc2.desc_tag = cpu_to_be32(0x1); |
---|
| 5920 | + rsp_payload->ls_req_info_desc2.desc_len = |
---|
| 5921 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_req_info_desc2)); |
---|
| 5922 | + rsp_payload->ls_req_info_desc2.req_payload_word_0 = |
---|
| 5923 | + cpu_to_be32p((uint32_t *)purex->els_frame_payload); |
---|
| 5924 | + |
---|
| 5925 | + |
---|
| 5926 | + rsp_payload->sfp_diag_desc.desc_tag = cpu_to_be32(0x10000); |
---|
| 5927 | + rsp_payload->sfp_diag_desc.desc_len = |
---|
| 5928 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->sfp_diag_desc)); |
---|
| 5929 | + |
---|
| 5930 | + if (sfp) { |
---|
| 5931 | + /* SFP Flags */ |
---|
| 5932 | + memset(sfp, 0, SFP_RTDI_LEN); |
---|
| 5933 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 0x7, 2, 0); |
---|
| 5934 | + if (!rval) { |
---|
| 5935 | + /* SFP Flags bits 3-0: Port Tx Laser Type */ |
---|
| 5936 | + if (sfp[0] & BIT_2 || sfp[1] & (BIT_6|BIT_5)) |
---|
| 5937 | + sfp_flags |= BIT_0; /* short wave */ |
---|
| 5938 | + else if (sfp[0] & BIT_1) |
---|
| 5939 | + sfp_flags |= BIT_1; /* long wave 1310nm */ |
---|
| 5940 | + else if (sfp[1] & BIT_4) |
---|
| 5941 | + sfp_flags |= BIT_1|BIT_0; /* long wave 1550nm */ |
---|
| 5942 | + } |
---|
| 5943 | + |
---|
| 5944 | + /* SFP Type */ |
---|
| 5945 | + memset(sfp, 0, SFP_RTDI_LEN); |
---|
| 5946 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 0x0, 1, 0); |
---|
| 5947 | + if (!rval) { |
---|
| 5948 | + sfp_flags |= BIT_4; /* optical */ |
---|
| 5949 | + if (sfp[0] == 0x3) |
---|
| 5950 | + sfp_flags |= BIT_6; /* sfp+ */ |
---|
| 5951 | + } |
---|
| 5952 | + |
---|
| 5953 | + rsp_payload->sfp_diag_desc.sfp_flags = cpu_to_be16(sfp_flags); |
---|
| 5954 | + |
---|
| 5955 | + /* SFP Diagnostics */ |
---|
| 5956 | + memset(sfp, 0, SFP_RTDI_LEN); |
---|
| 5957 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 0x60, 10, 0); |
---|
| 5958 | + if (!rval) { |
---|
| 5959 | + __be16 *trx = (__force __be16 *)sfp; /* already be16 */ |
---|
| 5960 | + rsp_payload->sfp_diag_desc.temperature = trx[0]; |
---|
| 5961 | + rsp_payload->sfp_diag_desc.vcc = trx[1]; |
---|
| 5962 | + rsp_payload->sfp_diag_desc.tx_bias = trx[2]; |
---|
| 5963 | + rsp_payload->sfp_diag_desc.tx_power = trx[3]; |
---|
| 5964 | + rsp_payload->sfp_diag_desc.rx_power = trx[4]; |
---|
| 5965 | + } |
---|
| 5966 | + } |
---|
| 5967 | + |
---|
| 5968 | + /* Port Speed Descriptor */ |
---|
| 5969 | + rsp_payload->port_speed_desc.desc_tag = cpu_to_be32(0x10001); |
---|
| 5970 | + rsp_payload->port_speed_desc.desc_len = |
---|
| 5971 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_speed_desc)); |
---|
| 5972 | + rsp_payload->port_speed_desc.speed_capab = cpu_to_be16( |
---|
| 5973 | + qla25xx_fdmi_port_speed_capability(ha)); |
---|
| 5974 | + rsp_payload->port_speed_desc.operating_speed = cpu_to_be16( |
---|
| 5975 | + qla25xx_fdmi_port_speed_currently(ha)); |
---|
| 5976 | + |
---|
| 5977 | + /* Link Error Status Descriptor */ |
---|
| 5978 | + rsp_payload->ls_err_desc.desc_tag = cpu_to_be32(0x10002); |
---|
| 5979 | + rsp_payload->ls_err_desc.desc_len = |
---|
| 5980 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_err_desc)); |
---|
| 5981 | + |
---|
| 5982 | + if (stat) { |
---|
| 5983 | + rval = qla24xx_get_isp_stats(vha, stat, stat_dma, 0); |
---|
| 5984 | + if (!rval) { |
---|
| 5985 | + rsp_payload->ls_err_desc.link_fail_cnt = |
---|
| 5986 | + cpu_to_be32(le32_to_cpu(stat->link_fail_cnt)); |
---|
| 5987 | + rsp_payload->ls_err_desc.loss_sync_cnt = |
---|
| 5988 | + cpu_to_be32(le32_to_cpu(stat->loss_sync_cnt)); |
---|
| 5989 | + rsp_payload->ls_err_desc.loss_sig_cnt = |
---|
| 5990 | + cpu_to_be32(le32_to_cpu(stat->loss_sig_cnt)); |
---|
| 5991 | + rsp_payload->ls_err_desc.prim_seq_err_cnt = |
---|
| 5992 | + cpu_to_be32(le32_to_cpu(stat->prim_seq_err_cnt)); |
---|
| 5993 | + rsp_payload->ls_err_desc.inval_xmit_word_cnt = |
---|
| 5994 | + cpu_to_be32(le32_to_cpu(stat->inval_xmit_word_cnt)); |
---|
| 5995 | + rsp_payload->ls_err_desc.inval_crc_cnt = |
---|
| 5996 | + cpu_to_be32(le32_to_cpu(stat->inval_crc_cnt)); |
---|
| 5997 | + rsp_payload->ls_err_desc.pn_port_phy_type |= BIT_6; |
---|
| 5998 | + } |
---|
| 5999 | + } |
---|
| 6000 | + |
---|
| 6001 | + /* Portname Descriptor */ |
---|
| 6002 | + rsp_payload->port_name_diag_desc.desc_tag = cpu_to_be32(0x10003); |
---|
| 6003 | + rsp_payload->port_name_diag_desc.desc_len = |
---|
| 6004 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_name_diag_desc)); |
---|
| 6005 | + memcpy(rsp_payload->port_name_diag_desc.WWNN, |
---|
| 6006 | + vha->node_name, |
---|
| 6007 | + sizeof(rsp_payload->port_name_diag_desc.WWNN)); |
---|
| 6008 | + memcpy(rsp_payload->port_name_diag_desc.WWPN, |
---|
| 6009 | + vha->port_name, |
---|
| 6010 | + sizeof(rsp_payload->port_name_diag_desc.WWPN)); |
---|
| 6011 | + |
---|
| 6012 | + /* F-Port Portname Descriptor */ |
---|
| 6013 | + rsp_payload->port_name_direct_desc.desc_tag = cpu_to_be32(0x10003); |
---|
| 6014 | + rsp_payload->port_name_direct_desc.desc_len = |
---|
| 6015 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_name_direct_desc)); |
---|
| 6016 | + memcpy(rsp_payload->port_name_direct_desc.WWNN, |
---|
| 6017 | + vha->fabric_node_name, |
---|
| 6018 | + sizeof(rsp_payload->port_name_direct_desc.WWNN)); |
---|
| 6019 | + memcpy(rsp_payload->port_name_direct_desc.WWPN, |
---|
| 6020 | + vha->fabric_port_name, |
---|
| 6021 | + sizeof(rsp_payload->port_name_direct_desc.WWPN)); |
---|
| 6022 | + |
---|
| 6023 | + /* Bufer Credit Descriptor */ |
---|
| 6024 | + rsp_payload->buffer_credit_desc.desc_tag = cpu_to_be32(0x10006); |
---|
| 6025 | + rsp_payload->buffer_credit_desc.desc_len = |
---|
| 6026 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->buffer_credit_desc)); |
---|
| 6027 | + rsp_payload->buffer_credit_desc.fcport_b2b = 0; |
---|
| 6028 | + rsp_payload->buffer_credit_desc.attached_fcport_b2b = cpu_to_be32(0); |
---|
| 6029 | + rsp_payload->buffer_credit_desc.fcport_rtt = cpu_to_be32(0); |
---|
| 6030 | + |
---|
| 6031 | + if (ha->flags.plogi_template_valid) { |
---|
| 6032 | + uint32_t tmp = |
---|
| 6033 | + be16_to_cpu(ha->plogi_els_payld.fl_csp.sp_bb_cred); |
---|
| 6034 | + rsp_payload->buffer_credit_desc.fcport_b2b = cpu_to_be32(tmp); |
---|
| 6035 | + } |
---|
| 6036 | + |
---|
| 6037 | + if (rsp_payload_length < sizeof(*rsp_payload)) |
---|
| 6038 | + goto send; |
---|
| 6039 | + |
---|
| 6040 | + /* Optical Element Descriptor, Temperature */ |
---|
| 6041 | + rsp_payload->optical_elmt_desc[0].desc_tag = cpu_to_be32(0x10007); |
---|
| 6042 | + rsp_payload->optical_elmt_desc[0].desc_len = |
---|
| 6043 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
---|
| 6044 | + /* Optical Element Descriptor, Voltage */ |
---|
| 6045 | + rsp_payload->optical_elmt_desc[1].desc_tag = cpu_to_be32(0x10007); |
---|
| 6046 | + rsp_payload->optical_elmt_desc[1].desc_len = |
---|
| 6047 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
---|
| 6048 | + /* Optical Element Descriptor, Tx Bias Current */ |
---|
| 6049 | + rsp_payload->optical_elmt_desc[2].desc_tag = cpu_to_be32(0x10007); |
---|
| 6050 | + rsp_payload->optical_elmt_desc[2].desc_len = |
---|
| 6051 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
---|
| 6052 | + /* Optical Element Descriptor, Tx Power */ |
---|
| 6053 | + rsp_payload->optical_elmt_desc[3].desc_tag = cpu_to_be32(0x10007); |
---|
| 6054 | + rsp_payload->optical_elmt_desc[3].desc_len = |
---|
| 6055 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
---|
| 6056 | + /* Optical Element Descriptor, Rx Power */ |
---|
| 6057 | + rsp_payload->optical_elmt_desc[4].desc_tag = cpu_to_be32(0x10007); |
---|
| 6058 | + rsp_payload->optical_elmt_desc[4].desc_len = |
---|
| 6059 | + cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc)); |
---|
| 6060 | + |
---|
| 6061 | + if (sfp) { |
---|
| 6062 | + memset(sfp, 0, SFP_RTDI_LEN); |
---|
| 6063 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 0, 64, 0); |
---|
| 6064 | + if (!rval) { |
---|
| 6065 | + __be16 *trx = (__force __be16 *)sfp; /* already be16 */ |
---|
| 6066 | + |
---|
| 6067 | + /* Optical Element Descriptor, Temperature */ |
---|
| 6068 | + rsp_payload->optical_elmt_desc[0].high_alarm = trx[0]; |
---|
| 6069 | + rsp_payload->optical_elmt_desc[0].low_alarm = trx[1]; |
---|
| 6070 | + rsp_payload->optical_elmt_desc[0].high_warn = trx[2]; |
---|
| 6071 | + rsp_payload->optical_elmt_desc[0].low_warn = trx[3]; |
---|
| 6072 | + rsp_payload->optical_elmt_desc[0].element_flags = |
---|
| 6073 | + cpu_to_be32(1 << 28); |
---|
| 6074 | + |
---|
| 6075 | + /* Optical Element Descriptor, Voltage */ |
---|
| 6076 | + rsp_payload->optical_elmt_desc[1].high_alarm = trx[4]; |
---|
| 6077 | + rsp_payload->optical_elmt_desc[1].low_alarm = trx[5]; |
---|
| 6078 | + rsp_payload->optical_elmt_desc[1].high_warn = trx[6]; |
---|
| 6079 | + rsp_payload->optical_elmt_desc[1].low_warn = trx[7]; |
---|
| 6080 | + rsp_payload->optical_elmt_desc[1].element_flags = |
---|
| 6081 | + cpu_to_be32(2 << 28); |
---|
| 6082 | + |
---|
| 6083 | + /* Optical Element Descriptor, Tx Bias Current */ |
---|
| 6084 | + rsp_payload->optical_elmt_desc[2].high_alarm = trx[8]; |
---|
| 6085 | + rsp_payload->optical_elmt_desc[2].low_alarm = trx[9]; |
---|
| 6086 | + rsp_payload->optical_elmt_desc[2].high_warn = trx[10]; |
---|
| 6087 | + rsp_payload->optical_elmt_desc[2].low_warn = trx[11]; |
---|
| 6088 | + rsp_payload->optical_elmt_desc[2].element_flags = |
---|
| 6089 | + cpu_to_be32(3 << 28); |
---|
| 6090 | + |
---|
| 6091 | + /* Optical Element Descriptor, Tx Power */ |
---|
| 6092 | + rsp_payload->optical_elmt_desc[3].high_alarm = trx[12]; |
---|
| 6093 | + rsp_payload->optical_elmt_desc[3].low_alarm = trx[13]; |
---|
| 6094 | + rsp_payload->optical_elmt_desc[3].high_warn = trx[14]; |
---|
| 6095 | + rsp_payload->optical_elmt_desc[3].low_warn = trx[15]; |
---|
| 6096 | + rsp_payload->optical_elmt_desc[3].element_flags = |
---|
| 6097 | + cpu_to_be32(4 << 28); |
---|
| 6098 | + |
---|
| 6099 | + /* Optical Element Descriptor, Rx Power */ |
---|
| 6100 | + rsp_payload->optical_elmt_desc[4].high_alarm = trx[16]; |
---|
| 6101 | + rsp_payload->optical_elmt_desc[4].low_alarm = trx[17]; |
---|
| 6102 | + rsp_payload->optical_elmt_desc[4].high_warn = trx[18]; |
---|
| 6103 | + rsp_payload->optical_elmt_desc[4].low_warn = trx[19]; |
---|
| 6104 | + rsp_payload->optical_elmt_desc[4].element_flags = |
---|
| 6105 | + cpu_to_be32(5 << 28); |
---|
| 6106 | + } |
---|
| 6107 | + |
---|
| 6108 | + memset(sfp, 0, SFP_RTDI_LEN); |
---|
| 6109 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 112, 64, 0); |
---|
| 6110 | + if (!rval) { |
---|
| 6111 | + /* Temperature high/low alarm/warning */ |
---|
| 6112 | + rsp_payload->optical_elmt_desc[0].element_flags |= |
---|
| 6113 | + cpu_to_be32( |
---|
| 6114 | + (sfp[0] >> 7 & 1) << 3 | |
---|
| 6115 | + (sfp[0] >> 6 & 1) << 2 | |
---|
| 6116 | + (sfp[4] >> 7 & 1) << 1 | |
---|
| 6117 | + (sfp[4] >> 6 & 1) << 0); |
---|
| 6118 | + |
---|
| 6119 | + /* Voltage high/low alarm/warning */ |
---|
| 6120 | + rsp_payload->optical_elmt_desc[1].element_flags |= |
---|
| 6121 | + cpu_to_be32( |
---|
| 6122 | + (sfp[0] >> 5 & 1) << 3 | |
---|
| 6123 | + (sfp[0] >> 4 & 1) << 2 | |
---|
| 6124 | + (sfp[4] >> 5 & 1) << 1 | |
---|
| 6125 | + (sfp[4] >> 4 & 1) << 0); |
---|
| 6126 | + |
---|
| 6127 | + /* Tx Bias Current high/low alarm/warning */ |
---|
| 6128 | + rsp_payload->optical_elmt_desc[2].element_flags |= |
---|
| 6129 | + cpu_to_be32( |
---|
| 6130 | + (sfp[0] >> 3 & 1) << 3 | |
---|
| 6131 | + (sfp[0] >> 2 & 1) << 2 | |
---|
| 6132 | + (sfp[4] >> 3 & 1) << 1 | |
---|
| 6133 | + (sfp[4] >> 2 & 1) << 0); |
---|
| 6134 | + |
---|
| 6135 | + /* Tx Power high/low alarm/warning */ |
---|
| 6136 | + rsp_payload->optical_elmt_desc[3].element_flags |= |
---|
| 6137 | + cpu_to_be32( |
---|
| 6138 | + (sfp[0] >> 1 & 1) << 3 | |
---|
| 6139 | + (sfp[0] >> 0 & 1) << 2 | |
---|
| 6140 | + (sfp[4] >> 1 & 1) << 1 | |
---|
| 6141 | + (sfp[4] >> 0 & 1) << 0); |
---|
| 6142 | + |
---|
| 6143 | + /* Rx Power high/low alarm/warning */ |
---|
| 6144 | + rsp_payload->optical_elmt_desc[4].element_flags |= |
---|
| 6145 | + cpu_to_be32( |
---|
| 6146 | + (sfp[1] >> 7 & 1) << 3 | |
---|
| 6147 | + (sfp[1] >> 6 & 1) << 2 | |
---|
| 6148 | + (sfp[5] >> 7 & 1) << 1 | |
---|
| 6149 | + (sfp[5] >> 6 & 1) << 0); |
---|
| 6150 | + } |
---|
| 6151 | + } |
---|
| 6152 | + |
---|
| 6153 | + /* Optical Product Data Descriptor */ |
---|
| 6154 | + rsp_payload->optical_prod_desc.desc_tag = cpu_to_be32(0x10008); |
---|
| 6155 | + rsp_payload->optical_prod_desc.desc_len = |
---|
| 6156 | + cpu_to_be32(RDP_DESC_LEN(rsp_payload->optical_prod_desc)); |
---|
| 6157 | + |
---|
| 6158 | + if (sfp) { |
---|
| 6159 | + memset(sfp, 0, SFP_RTDI_LEN); |
---|
| 6160 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 20, 64, 0); |
---|
| 6161 | + if (!rval) { |
---|
| 6162 | + memcpy(rsp_payload->optical_prod_desc.vendor_name, |
---|
| 6163 | + sfp + 0, |
---|
| 6164 | + sizeof(rsp_payload->optical_prod_desc.vendor_name)); |
---|
| 6165 | + memcpy(rsp_payload->optical_prod_desc.part_number, |
---|
| 6166 | + sfp + 20, |
---|
| 6167 | + sizeof(rsp_payload->optical_prod_desc.part_number)); |
---|
| 6168 | + memcpy(rsp_payload->optical_prod_desc.revision, |
---|
| 6169 | + sfp + 36, |
---|
| 6170 | + sizeof(rsp_payload->optical_prod_desc.revision)); |
---|
| 6171 | + memcpy(rsp_payload->optical_prod_desc.serial_number, |
---|
| 6172 | + sfp + 48, |
---|
| 6173 | + sizeof(rsp_payload->optical_prod_desc.serial_number)); |
---|
| 6174 | + } |
---|
| 6175 | + |
---|
| 6176 | + memset(sfp, 0, SFP_RTDI_LEN); |
---|
| 6177 | + rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 84, 8, 0); |
---|
| 6178 | + if (!rval) { |
---|
| 6179 | + memcpy(rsp_payload->optical_prod_desc.date, |
---|
| 6180 | + sfp + 0, |
---|
| 6181 | + sizeof(rsp_payload->optical_prod_desc.date)); |
---|
| 6182 | + } |
---|
| 6183 | + } |
---|
| 6184 | + |
---|
| 6185 | +send: |
---|
| 6186 | + ql_dbg(ql_dbg_init, vha, 0x0183, |
---|
| 6187 | + "Sending ELS Response to RDP Request...\n"); |
---|
| 6188 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0184, |
---|
| 6189 | + "-------- ELS RSP -------\n"); |
---|
| 6190 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0185, |
---|
| 6191 | + rsp_els, sizeof(*rsp_els)); |
---|
| 6192 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0186, |
---|
| 6193 | + "-------- ELS RSP PAYLOAD -------\n"); |
---|
| 6194 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0187, |
---|
| 6195 | + rsp_payload, rsp_payload_length); |
---|
| 6196 | + |
---|
| 6197 | + rval = qla2x00_issue_iocb(vha, rsp_els, rsp_els_dma, 0); |
---|
| 6198 | + |
---|
| 6199 | + if (rval) { |
---|
| 6200 | + ql_log(ql_log_warn, vha, 0x0188, |
---|
| 6201 | + "%s: iocb failed to execute -> %x\n", __func__, rval); |
---|
| 6202 | + } else if (rsp_els->comp_status) { |
---|
| 6203 | + ql_log(ql_log_warn, vha, 0x0189, |
---|
| 6204 | + "%s: iocb failed to complete -> completion=%#x subcode=(%#x,%#x)\n", |
---|
| 6205 | + __func__, rsp_els->comp_status, |
---|
| 6206 | + rsp_els->error_subcode_1, rsp_els->error_subcode_2); |
---|
| 6207 | + } else { |
---|
| 6208 | + ql_dbg(ql_dbg_init, vha, 0x018a, "%s: done.\n", __func__); |
---|
| 6209 | + } |
---|
| 6210 | + |
---|
| 6211 | +dealloc: |
---|
| 6212 | + if (stat) |
---|
| 6213 | + dma_free_coherent(&ha->pdev->dev, sizeof(*stat), |
---|
| 6214 | + stat, stat_dma); |
---|
| 6215 | + if (sfp) |
---|
| 6216 | + dma_free_coherent(&ha->pdev->dev, SFP_RTDI_LEN, |
---|
| 6217 | + sfp, sfp_dma); |
---|
| 6218 | + if (rsp_payload) |
---|
| 6219 | + dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_payload), |
---|
| 6220 | + rsp_payload, rsp_payload_dma); |
---|
| 6221 | + if (rsp_els) |
---|
| 6222 | + dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els), |
---|
| 6223 | + rsp_els, rsp_els_dma); |
---|
| 6224 | +} |
---|
| 6225 | + |
---|
| 6226 | +void |
---|
| 6227 | +qla24xx_free_purex_item(struct purex_item *item) |
---|
| 6228 | +{ |
---|
| 6229 | + if (item == &item->vha->default_item) |
---|
| 6230 | + memset(&item->vha->default_item, 0, sizeof(struct purex_item)); |
---|
| 6231 | + else |
---|
| 6232 | + kfree(item); |
---|
| 6233 | +} |
---|
| 6234 | + |
---|
| 6235 | +void qla24xx_process_purex_list(struct purex_list *list) |
---|
| 6236 | +{ |
---|
| 6237 | + struct list_head head = LIST_HEAD_INIT(head); |
---|
| 6238 | + struct purex_item *item, *next; |
---|
| 6239 | + ulong flags; |
---|
| 6240 | + |
---|
| 6241 | + spin_lock_irqsave(&list->lock, flags); |
---|
| 6242 | + list_splice_init(&list->head, &head); |
---|
| 6243 | + spin_unlock_irqrestore(&list->lock, flags); |
---|
| 6244 | + |
---|
| 6245 | + list_for_each_entry_safe(item, next, &head, list) { |
---|
| 6246 | + list_del(&item->list); |
---|
| 6247 | + item->process_item(item->vha, item); |
---|
| 6248 | + qla24xx_free_purex_item(item); |
---|
| 6249 | + } |
---|
5514 | 6250 | } |
---|
5515 | 6251 | |
---|
5516 | 6252 | void |
---|
.. | .. |
---|
5922 | 6658 | |
---|
5923 | 6659 | schedule(); |
---|
5924 | 6660 | |
---|
| 6661 | + if (test_and_clear_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags)) |
---|
| 6662 | + qla_pci_set_eeh_busy(base_vha); |
---|
| 6663 | + |
---|
5925 | 6664 | if (!base_vha->flags.init_done || ha->flags.mbox_busy) |
---|
5926 | 6665 | goto end_loop; |
---|
5927 | 6666 | |
---|
.. | .. |
---|
6034 | 6773 | } |
---|
6035 | 6774 | |
---|
6036 | 6775 | 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); |
---|
| 6776 | + &base_vha->dpc_flags)) { |
---|
| 6777 | + /* Semantic: |
---|
| 6778 | + * - NO-OP -- await next ISP-ABORT. Preferred method |
---|
| 6779 | + * to minimize disruptions that will occur |
---|
| 6780 | + * when a forced chip-reset occurs. |
---|
| 6781 | + * - Force -- ISP-ABORT scheduled. |
---|
| 6782 | + */ |
---|
| 6783 | + /* set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); */ |
---|
6044 | 6784 | } |
---|
6045 | 6785 | |
---|
6046 | 6786 | if (test_and_clear_bit |
---|
.. | .. |
---|
6048 | 6788 | !test_bit(UNLOADING, &base_vha->dpc_flags)) { |
---|
6049 | 6789 | bool do_reset = true; |
---|
6050 | 6790 | |
---|
6051 | | - switch (ql2x_ini_mode) { |
---|
| 6791 | + switch (base_vha->qlini_mode) { |
---|
6052 | 6792 | case QLA2XXX_INI_MODE_ENABLED: |
---|
6053 | 6793 | break; |
---|
6054 | 6794 | case QLA2XXX_INI_MODE_DISABLED: |
---|
6055 | | - if (!qla_tgt_mode_enabled(base_vha)) |
---|
| 6795 | + if (!qla_tgt_mode_enabled(base_vha) && |
---|
| 6796 | + !ha->flags.fw_started) |
---|
6056 | 6797 | do_reset = false; |
---|
6057 | 6798 | break; |
---|
6058 | 6799 | case QLA2XXX_INI_MODE_DUAL: |
---|
6059 | | - if (!qla_dual_mode_enabled(base_vha)) |
---|
| 6800 | + if (!qla_dual_mode_enabled(base_vha) && |
---|
| 6801 | + !ha->flags.fw_started) |
---|
6060 | 6802 | do_reset = false; |
---|
6061 | 6803 | break; |
---|
6062 | 6804 | default: |
---|
.. | .. |
---|
6077 | 6819 | &base_vha->dpc_flags); |
---|
6078 | 6820 | ql_dbg(ql_dbg_dpc, base_vha, 0x4008, |
---|
6079 | 6821 | "ISP abort end.\n"); |
---|
| 6822 | + } |
---|
| 6823 | + } |
---|
| 6824 | + |
---|
| 6825 | + if (test_bit(PROCESS_PUREX_IOCB, &base_vha->dpc_flags)) { |
---|
| 6826 | + if (atomic_read(&base_vha->loop_state) == LOOP_READY) { |
---|
| 6827 | + qla24xx_process_purex_list |
---|
| 6828 | + (&base_vha->purex_list); |
---|
| 6829 | + clear_bit(PROCESS_PUREX_IOCB, |
---|
| 6830 | + &base_vha->dpc_flags); |
---|
6080 | 6831 | } |
---|
6081 | 6832 | } |
---|
6082 | 6833 | |
---|
.. | .. |
---|
6149 | 6900 | } |
---|
6150 | 6901 | } |
---|
6151 | 6902 | loop_resync_check: |
---|
6152 | | - if (test_and_clear_bit(LOOP_RESYNC_NEEDED, |
---|
| 6903 | + if (!qla2x00_reset_active(base_vha) && |
---|
| 6904 | + test_and_clear_bit(LOOP_RESYNC_NEEDED, |
---|
6153 | 6905 | &base_vha->dpc_flags)) { |
---|
6154 | | - |
---|
| 6906 | + /* |
---|
| 6907 | + * Allow abort_isp to complete before moving on to scanning. |
---|
| 6908 | + */ |
---|
6155 | 6909 | ql_dbg(ql_dbg_dpc, base_vha, 0x400f, |
---|
6156 | 6910 | "Loop resync scheduled.\n"); |
---|
6157 | 6911 | |
---|
.. | .. |
---|
6203 | 6957 | mutex_unlock(&ha->mq_lock); |
---|
6204 | 6958 | } |
---|
6205 | 6959 | |
---|
6206 | | - if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED, &base_vha->dpc_flags)) { |
---|
| 6960 | + if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED, |
---|
| 6961 | + &base_vha->dpc_flags)) { |
---|
| 6962 | + u16 threshold = ha->nvme_last_rptd_aen + ha->last_zio_threshold; |
---|
| 6963 | + |
---|
| 6964 | + if (threshold > ha->orig_fw_xcb_count) |
---|
| 6965 | + threshold = ha->orig_fw_xcb_count; |
---|
| 6966 | + |
---|
6207 | 6967 | ql_log(ql_log_info, base_vha, 0xffffff, |
---|
6208 | | - "nvme: SET ZIO Activity exchange threshold to %d.\n", |
---|
6209 | | - ha->nvme_last_rptd_aen); |
---|
6210 | | - if (qla27xx_set_zio_threshold(base_vha, ha->nvme_last_rptd_aen)) { |
---|
| 6968 | + "SET ZIO Activity exchange threshold to %d.\n", |
---|
| 6969 | + threshold); |
---|
| 6970 | + if (qla27xx_set_zio_threshold(base_vha, threshold)) { |
---|
6211 | 6971 | 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); |
---|
| 6972 | + "Unable to SET ZIO Activity exchange threshold to %d.\n", |
---|
| 6973 | + threshold); |
---|
6214 | 6974 | } |
---|
6215 | 6975 | } |
---|
6216 | 6976 | |
---|
.. | .. |
---|
6384 | 7144 | |
---|
6385 | 7145 | /* if the loop has been down for 4 minutes, reinit adapter */ |
---|
6386 | 7146 | if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { |
---|
6387 | | - if (!(vha->device_flags & DFLG_NO_CABLE)) { |
---|
| 7147 | + if (!(vha->device_flags & DFLG_NO_CABLE) && !vha->vp_idx) { |
---|
6388 | 7148 | ql_log(ql_log_warn, vha, 0x6009, |
---|
6389 | 7149 | "Loop down - aborting ISP.\n"); |
---|
6390 | 7150 | |
---|
.. | .. |
---|
6426 | 7186 | * FC-NVME |
---|
6427 | 7187 | * see if the active AEN count has changed from what was last reported. |
---|
6428 | 7188 | */ |
---|
| 7189 | + index = atomic_read(&ha->nvme_active_aen_cnt); |
---|
6429 | 7190 | 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) { |
---|
6432 | | - ql_log(ql_log_info, vha, 0x3002, |
---|
6433 | | - "nvme: Sched: Set ZIO exchange threshold to %d.\n", |
---|
6434 | | - ha->nvme_last_rptd_aen); |
---|
| 7191 | + (index != ha->nvme_last_rptd_aen) && |
---|
| 7192 | + ha->zio_mode == QLA_ZIO_MODE_6 && |
---|
| 7193 | + !ha->flags.host_shutting_down) { |
---|
6435 | 7194 | ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt); |
---|
| 7195 | + ql_log(ql_log_info, vha, 0x3002, |
---|
| 7196 | + "nvme: Sched: Set ZIO exchange threshold to %d.\n", |
---|
| 7197 | + ha->nvme_last_rptd_aen); |
---|
| 7198 | + set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); |
---|
| 7199 | + start_dpc++; |
---|
| 7200 | + } |
---|
| 7201 | + |
---|
| 7202 | + if (!vha->vp_idx && |
---|
| 7203 | + atomic_read(&ha->zio_threshold) != ha->last_zio_threshold && |
---|
| 7204 | + IS_ZIO_THRESHOLD_CAPABLE(ha)) { |
---|
| 7205 | + ql_log(ql_log_info, vha, 0x3002, |
---|
| 7206 | + "Sched: Set ZIO exchange threshold to %d.\n", |
---|
| 7207 | + ha->last_zio_threshold); |
---|
| 7208 | + ha->last_zio_threshold = atomic_read(&ha->zio_threshold); |
---|
6436 | 7209 | set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); |
---|
6437 | 7210 | start_dpc++; |
---|
6438 | 7211 | } |
---|
.. | .. |
---|
6447 | 7220 | test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) || |
---|
6448 | 7221 | test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) || |
---|
6449 | 7222 | test_bit(VP_DPC_NEEDED, &vha->dpc_flags) || |
---|
6450 | | - test_bit(RELOGIN_NEEDED, &vha->dpc_flags))) { |
---|
| 7223 | + test_bit(RELOGIN_NEEDED, &vha->dpc_flags) || |
---|
| 7224 | + test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags))) { |
---|
6451 | 7225 | ql_dbg(ql_dbg_timer, vha, 0x600b, |
---|
6452 | 7226 | "isp_abort_needed=%d loop_resync_needed=%d " |
---|
6453 | 7227 | "fcport_update_needed=%d start_dpc=%d " |
---|
.. | .. |
---|
6460 | 7234 | ql_dbg(ql_dbg_timer, vha, 0x600c, |
---|
6461 | 7235 | "beacon_blink_needed=%d isp_unrecoverable=%d " |
---|
6462 | 7236 | "fcoe_ctx_reset_needed=%d vp_dpc_needed=%d " |
---|
6463 | | - "relogin_needed=%d.\n", |
---|
| 7237 | + "relogin_needed=%d, Process_purex_iocb=%d.\n", |
---|
6464 | 7238 | test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags), |
---|
6465 | 7239 | test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags), |
---|
6466 | 7240 | test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags), |
---|
6467 | 7241 | test_bit(VP_DPC_NEEDED, &vha->dpc_flags), |
---|
6468 | | - test_bit(RELOGIN_NEEDED, &vha->dpc_flags)); |
---|
| 7242 | + test_bit(RELOGIN_NEEDED, &vha->dpc_flags), |
---|
| 7243 | + test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags)); |
---|
6469 | 7244 | qla2xxx_wake_dpc(vha); |
---|
6470 | 7245 | } |
---|
6471 | 7246 | |
---|
.. | .. |
---|
6474 | 7249 | |
---|
6475 | 7250 | /* Firmware interface routines. */ |
---|
6476 | 7251 | |
---|
6477 | | -#define FW_BLOBS 11 |
---|
6478 | 7252 | #define FW_ISP21XX 0 |
---|
6479 | 7253 | #define FW_ISP22XX 1 |
---|
6480 | 7254 | #define FW_ISP2300 2 |
---|
.. | .. |
---|
6486 | 7260 | #define FW_ISP2031 8 |
---|
6487 | 7261 | #define FW_ISP8031 9 |
---|
6488 | 7262 | #define FW_ISP27XX 10 |
---|
| 7263 | +#define FW_ISP28XX 11 |
---|
6489 | 7264 | |
---|
6490 | 7265 | #define FW_FILE_ISP21XX "ql2100_fw.bin" |
---|
6491 | 7266 | #define FW_FILE_ISP22XX "ql2200_fw.bin" |
---|
.. | .. |
---|
6498 | 7273 | #define FW_FILE_ISP2031 "ql2600_fw.bin" |
---|
6499 | 7274 | #define FW_FILE_ISP8031 "ql8300_fw.bin" |
---|
6500 | 7275 | #define FW_FILE_ISP27XX "ql2700_fw.bin" |
---|
| 7276 | +#define FW_FILE_ISP28XX "ql2800_fw.bin" |
---|
6501 | 7277 | |
---|
6502 | 7278 | |
---|
6503 | 7279 | static DEFINE_MUTEX(qla_fw_lock); |
---|
6504 | 7280 | |
---|
6505 | | -static struct fw_blob qla_fw_blobs[FW_BLOBS] = { |
---|
| 7281 | +static struct fw_blob qla_fw_blobs[] = { |
---|
6506 | 7282 | { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, |
---|
6507 | 7283 | { .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, }, |
---|
6508 | 7284 | { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, }, |
---|
.. | .. |
---|
6514 | 7290 | { .name = FW_FILE_ISP2031, }, |
---|
6515 | 7291 | { .name = FW_FILE_ISP8031, }, |
---|
6516 | 7292 | { .name = FW_FILE_ISP27XX, }, |
---|
| 7293 | + { .name = FW_FILE_ISP28XX, }, |
---|
| 7294 | + { .name = NULL, }, |
---|
6517 | 7295 | }; |
---|
6518 | 7296 | |
---|
6519 | 7297 | struct fw_blob * |
---|
.. | .. |
---|
6544 | 7322 | blob = &qla_fw_blobs[FW_ISP8031]; |
---|
6545 | 7323 | } else if (IS_QLA27XX(ha)) { |
---|
6546 | 7324 | blob = &qla_fw_blobs[FW_ISP27XX]; |
---|
| 7325 | + } else if (IS_QLA28XX(ha)) { |
---|
| 7326 | + blob = &qla_fw_blobs[FW_ISP28XX]; |
---|
6547 | 7327 | } else { |
---|
6548 | 7328 | return NULL; |
---|
6549 | 7329 | } |
---|
| 7330 | + |
---|
| 7331 | + if (!blob->name) |
---|
| 7332 | + return NULL; |
---|
6550 | 7333 | |
---|
6551 | 7334 | mutex_lock(&qla_fw_lock); |
---|
6552 | 7335 | if (blob->fw) |
---|
.. | .. |
---|
6557 | 7340 | "Failed to load firmware image (%s).\n", blob->name); |
---|
6558 | 7341 | blob->fw = NULL; |
---|
6559 | 7342 | blob = NULL; |
---|
6560 | | - goto out; |
---|
6561 | 7343 | } |
---|
6562 | 7344 | |
---|
6563 | 7345 | out: |
---|
.. | .. |
---|
6568 | 7350 | static void |
---|
6569 | 7351 | qla2x00_release_firmware(void) |
---|
6570 | 7352 | { |
---|
6571 | | - int idx; |
---|
| 7353 | + struct fw_blob *blob; |
---|
6572 | 7354 | |
---|
6573 | 7355 | mutex_lock(&qla_fw_lock); |
---|
6574 | | - for (idx = 0; idx < FW_BLOBS; idx++) |
---|
6575 | | - release_firmware(qla_fw_blobs[idx].fw); |
---|
| 7356 | + for (blob = qla_fw_blobs; blob->name; blob++) |
---|
| 7357 | + release_firmware(blob->fw); |
---|
6576 | 7358 | mutex_unlock(&qla_fw_lock); |
---|
6577 | 7359 | } |
---|
| 7360 | + |
---|
| 7361 | +static void qla_pci_error_cleanup(scsi_qla_host_t *vha) |
---|
| 7362 | +{ |
---|
| 7363 | + struct qla_hw_data *ha = vha->hw; |
---|
| 7364 | + scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
---|
| 7365 | + struct qla_qpair *qpair = NULL; |
---|
| 7366 | + struct scsi_qla_host *vp; |
---|
| 7367 | + fc_port_t *fcport; |
---|
| 7368 | + int i; |
---|
| 7369 | + unsigned long flags; |
---|
| 7370 | + |
---|
| 7371 | + ql_dbg(ql_dbg_aer, vha, 0x9000, |
---|
| 7372 | + "%s\n", __func__); |
---|
| 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 | + /* |
---|
| 7383 | + * purge mailbox might take a while. Slot Reset/chip reset |
---|
| 7384 | + * will take care of the purge |
---|
| 7385 | + */ |
---|
| 7386 | + |
---|
| 7387 | + mutex_lock(&ha->mq_lock); |
---|
| 7388 | + ha->base_qpair->online = 0; |
---|
| 7389 | + list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
---|
| 7390 | + qpair->online = 0; |
---|
| 7391 | + wmb(); |
---|
| 7392 | + mutex_unlock(&ha->mq_lock); |
---|
| 7393 | + |
---|
| 7394 | + qla2x00_mark_all_devices_lost(vha); |
---|
| 7395 | + |
---|
| 7396 | + spin_lock_irqsave(&ha->vport_slock, flags); |
---|
| 7397 | + list_for_each_entry(vp, &ha->vp_list, list) { |
---|
| 7398 | + atomic_inc(&vp->vref_count); |
---|
| 7399 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
---|
| 7400 | + qla2x00_mark_all_devices_lost(vp); |
---|
| 7401 | + spin_lock_irqsave(&ha->vport_slock, flags); |
---|
| 7402 | + atomic_dec(&vp->vref_count); |
---|
| 7403 | + } |
---|
| 7404 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
---|
| 7405 | + |
---|
| 7406 | + /* Clear all async request states across all VPs. */ |
---|
| 7407 | + list_for_each_entry(fcport, &vha->vp_fcports, list) |
---|
| 7408 | + fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); |
---|
| 7409 | + |
---|
| 7410 | + spin_lock_irqsave(&ha->vport_slock, flags); |
---|
| 7411 | + list_for_each_entry(vp, &ha->vp_list, list) { |
---|
| 7412 | + atomic_inc(&vp->vref_count); |
---|
| 7413 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
---|
| 7414 | + list_for_each_entry(fcport, &vp->vp_fcports, list) |
---|
| 7415 | + fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); |
---|
| 7416 | + spin_lock_irqsave(&ha->vport_slock, flags); |
---|
| 7417 | + atomic_dec(&vp->vref_count); |
---|
| 7418 | + } |
---|
| 7419 | + spin_unlock_irqrestore(&ha->vport_slock, flags); |
---|
| 7420 | +} |
---|
| 7421 | + |
---|
6578 | 7422 | |
---|
6579 | 7423 | static pci_ers_result_t |
---|
6580 | 7424 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) |
---|
6581 | 7425 | { |
---|
6582 | 7426 | scsi_qla_host_t *vha = pci_get_drvdata(pdev); |
---|
6583 | 7427 | struct qla_hw_data *ha = vha->hw; |
---|
| 7428 | + pci_ers_result_t ret = PCI_ERS_RESULT_NEED_RESET; |
---|
6584 | 7429 | |
---|
6585 | | - ql_dbg(ql_dbg_aer, vha, 0x9000, |
---|
6586 | | - "PCI error detected, state %x.\n", state); |
---|
| 7430 | + ql_log(ql_log_warn, vha, 0x9000, |
---|
| 7431 | + "PCI error detected, state %x.\n", state); |
---|
| 7432 | + ha->pci_error_state = QLA_PCI_ERR_DETECTED; |
---|
6587 | 7433 | |
---|
6588 | 7434 | if (!atomic_read(&pdev->enable_cnt)) { |
---|
6589 | 7435 | ql_log(ql_log_info, vha, 0xffff, |
---|
6590 | 7436 | "PCI device is disabled,state %x\n", state); |
---|
6591 | | - return PCI_ERS_RESULT_NEED_RESET; |
---|
| 7437 | + ret = PCI_ERS_RESULT_NEED_RESET; |
---|
| 7438 | + goto out; |
---|
6592 | 7439 | } |
---|
6593 | 7440 | |
---|
6594 | 7441 | switch (state) { |
---|
.. | .. |
---|
6598 | 7445 | set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); |
---|
6599 | 7446 | qla2xxx_wake_dpc(vha); |
---|
6600 | 7447 | } |
---|
6601 | | - return PCI_ERS_RESULT_CAN_RECOVER; |
---|
| 7448 | + ret = PCI_ERS_RESULT_CAN_RECOVER; |
---|
| 7449 | + break; |
---|
6602 | 7450 | case pci_channel_io_frozen: |
---|
6603 | | - 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 | | - } |
---|
6618 | | - return PCI_ERS_RESULT_NEED_RESET; |
---|
| 7451 | + qla_pci_set_eeh_busy(vha); |
---|
| 7452 | + ret = PCI_ERS_RESULT_NEED_RESET; |
---|
| 7453 | + break; |
---|
6619 | 7454 | case pci_channel_io_perm_failure: |
---|
6620 | 7455 | ha->flags.pci_channel_io_perm_failure = 1; |
---|
6621 | 7456 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); |
---|
.. | .. |
---|
6623 | 7458 | set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); |
---|
6624 | 7459 | qla2xxx_wake_dpc(vha); |
---|
6625 | 7460 | } |
---|
6626 | | - return PCI_ERS_RESULT_DISCONNECT; |
---|
| 7461 | + ret = PCI_ERS_RESULT_DISCONNECT; |
---|
6627 | 7462 | } |
---|
6628 | | - return PCI_ERS_RESULT_NEED_RESET; |
---|
| 7463 | +out: |
---|
| 7464 | + ql_dbg(ql_dbg_aer, vha, 0x600d, |
---|
| 7465 | + "PCI error detected returning [%x].\n", ret); |
---|
| 7466 | + return ret; |
---|
6629 | 7467 | } |
---|
6630 | 7468 | |
---|
6631 | 7469 | static pci_ers_result_t |
---|
.. | .. |
---|
6639 | 7477 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
---|
6640 | 7478 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; |
---|
6641 | 7479 | |
---|
| 7480 | + ql_log(ql_log_warn, base_vha, 0x9000, |
---|
| 7481 | + "mmio enabled\n"); |
---|
| 7482 | + |
---|
| 7483 | + ha->pci_error_state = QLA_PCI_MMIO_ENABLED; |
---|
6642 | 7484 | if (IS_QLA82XX(ha)) |
---|
6643 | 7485 | return PCI_ERS_RESULT_RECOVERED; |
---|
6644 | 7486 | |
---|
6645 | 7487 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
6646 | 7488 | if (IS_QLA2100(ha) || IS_QLA2200(ha)){ |
---|
6647 | | - stat = RD_REG_DWORD(®->hccr); |
---|
| 7489 | + stat = rd_reg_word(®->hccr); |
---|
6648 | 7490 | if (stat & HCCR_RISC_PAUSE) |
---|
6649 | 7491 | risc_paused = 1; |
---|
6650 | 7492 | } else if (IS_QLA23XX(ha)) { |
---|
6651 | | - stat = RD_REG_DWORD(®->u.isp2300.host_status); |
---|
| 7493 | + stat = rd_reg_dword(®->u.isp2300.host_status); |
---|
6652 | 7494 | if (stat & HSR_RISC_PAUSED) |
---|
6653 | 7495 | risc_paused = 1; |
---|
6654 | 7496 | } else if (IS_FWI2_CAPABLE(ha)) { |
---|
6655 | | - stat = RD_REG_DWORD(®24->host_status); |
---|
| 7497 | + stat = rd_reg_dword(®24->host_status); |
---|
6656 | 7498 | if (stat & HSRX_RISC_PAUSED) |
---|
6657 | 7499 | risc_paused = 1; |
---|
6658 | 7500 | } |
---|
.. | .. |
---|
6661 | 7503 | if (risc_paused) { |
---|
6662 | 7504 | ql_log(ql_log_info, base_vha, 0x9003, |
---|
6663 | 7505 | "RISC paused -- mmio_enabled, Dumping firmware.\n"); |
---|
6664 | | - ha->isp_ops->fw_dump(base_vha, 0); |
---|
6665 | | - |
---|
6666 | | - return PCI_ERS_RESULT_NEED_RESET; |
---|
6667 | | - } else |
---|
6668 | | - 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); |
---|
| 7506 | + qla2xxx_dump_fw(base_vha); |
---|
6689 | 7507 | } |
---|
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; |
---|
| 7508 | + /* set PCI_ERS_RESULT_NEED_RESET to trigger call to qla2xxx_pci_slot_reset */ |
---|
| 7509 | + ql_dbg(ql_dbg_aer, base_vha, 0x600d, |
---|
| 7510 | + "mmio enabled returning.\n"); |
---|
| 7511 | + return PCI_ERS_RESULT_NEED_RESET; |
---|
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 | | - ql_dbg(ql_dbg_aer, base_vha, 0x9004, |
---|
6789 | | - "Slot Reset.\n"); |
---|
| 7523 | + ql_log(ql_log_warn, base_vha, 0x9004, |
---|
| 7524 | + "Slot Reset.\n"); |
---|
6790 | 7525 | |
---|
| 7526 | + ha->pci_error_state = QLA_PCI_SLOT_RESET; |
---|
6791 | 7527 | /* Workaround: qla2xxx driver which access hardware earlier |
---|
6792 | 7528 | * needs error state to be pci_channel_io_online. |
---|
6793 | 7529 | * Otherwise mailbox command timesout. |
---|
.. | .. |
---|
6812 | 7548 | goto exit_slot_reset; |
---|
6813 | 7549 | } |
---|
6814 | 7550 | |
---|
6815 | | - rsp = ha->rsp_q_map[0]; |
---|
6816 | | - if (qla2x00_request_irqs(ha, rsp)) |
---|
6817 | | - goto exit_slot_reset; |
---|
6818 | 7551 | |
---|
6819 | 7552 | if (ha->isp_ops->pci_config(base_vha)) |
---|
6820 | 7553 | goto exit_slot_reset; |
---|
6821 | 7554 | |
---|
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 | | - } |
---|
| 7555 | + mutex_lock(&ha->mq_lock); |
---|
| 7556 | + list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
---|
| 7557 | + qpair->online = 1; |
---|
| 7558 | + mutex_unlock(&ha->mq_lock); |
---|
6829 | 7559 | |
---|
6830 | | - while (ha->flags.mbox_busy && retries--) |
---|
6831 | | - msleep(1000); |
---|
6832 | | - |
---|
| 7560 | + ha->flags.eeh_busy = 0; |
---|
| 7561 | + base_vha->flags.online = 1; |
---|
6833 | 7562 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
---|
6834 | | - if (ha->isp_ops->abort_isp(base_vha) == QLA_SUCCESS) |
---|
6835 | | - ret = PCI_ERS_RESULT_RECOVERED; |
---|
| 7563 | + ha->isp_ops->abort_isp(base_vha); |
---|
6836 | 7564 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
---|
6837 | 7565 | |
---|
| 7566 | + if (qla2x00_isp_reg_stat(ha)) { |
---|
| 7567 | + ha->flags.eeh_busy = 1; |
---|
| 7568 | + qla_pci_error_cleanup(base_vha); |
---|
| 7569 | + ql_log(ql_log_warn, base_vha, 0x9005, |
---|
| 7570 | + "Device unable to recover from PCI error.\n"); |
---|
| 7571 | + } else { |
---|
| 7572 | + ret = PCI_ERS_RESULT_RECOVERED; |
---|
| 7573 | + } |
---|
6838 | 7574 | |
---|
6839 | 7575 | exit_slot_reset: |
---|
6840 | 7576 | ql_dbg(ql_dbg_aer, base_vha, 0x900e, |
---|
6841 | | - "slot_reset return %x.\n", ret); |
---|
| 7577 | + "Slot Reset returning %x.\n", ret); |
---|
6842 | 7578 | |
---|
6843 | 7579 | return ret; |
---|
6844 | 7580 | } |
---|
.. | .. |
---|
6850 | 7586 | struct qla_hw_data *ha = base_vha->hw; |
---|
6851 | 7587 | int ret; |
---|
6852 | 7588 | |
---|
6853 | | - ql_dbg(ql_dbg_aer, base_vha, 0x900f, |
---|
6854 | | - "pci_resume.\n"); |
---|
| 7589 | + ql_log(ql_log_warn, base_vha, 0x900f, |
---|
| 7590 | + "Pci Resume.\n"); |
---|
| 7591 | + |
---|
6855 | 7592 | |
---|
6856 | 7593 | ret = qla2x00_wait_for_hba_online(base_vha); |
---|
6857 | 7594 | if (ret != QLA_SUCCESS) { |
---|
6858 | 7595 | ql_log(ql_log_fatal, base_vha, 0x9002, |
---|
6859 | 7596 | "The device failed to resume I/O from slot/link_reset.\n"); |
---|
6860 | 7597 | } |
---|
| 7598 | + ha->pci_error_state = QLA_PCI_RESUME; |
---|
| 7599 | + ql_dbg(ql_dbg_aer, base_vha, 0x600d, |
---|
| 7600 | + "Pci Resume returning.\n"); |
---|
| 7601 | +} |
---|
6861 | 7602 | |
---|
6862 | | - pci_cleanup_aer_uncorrect_error_status(pdev); |
---|
| 7603 | +void qla_pci_set_eeh_busy(struct scsi_qla_host *vha) |
---|
| 7604 | +{ |
---|
| 7605 | + struct qla_hw_data *ha = vha->hw; |
---|
| 7606 | + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
---|
| 7607 | + bool do_cleanup = false; |
---|
| 7608 | + unsigned long flags; |
---|
6863 | 7609 | |
---|
| 7610 | + if (ha->flags.eeh_busy) |
---|
| 7611 | + return; |
---|
| 7612 | + |
---|
| 7613 | + spin_lock_irqsave(&base_vha->work_lock, flags); |
---|
| 7614 | + if (!ha->flags.eeh_busy) { |
---|
| 7615 | + ha->flags.eeh_busy = 1; |
---|
| 7616 | + do_cleanup = true; |
---|
| 7617 | + } |
---|
| 7618 | + spin_unlock_irqrestore(&base_vha->work_lock, flags); |
---|
| 7619 | + |
---|
| 7620 | + if (do_cleanup) |
---|
| 7621 | + qla_pci_error_cleanup(base_vha); |
---|
| 7622 | +} |
---|
| 7623 | + |
---|
| 7624 | +/* |
---|
| 7625 | + * this routine will schedule a task to pause IO from interrupt context |
---|
| 7626 | + * if caller sees a PCIE error event (register read = 0xf's) |
---|
| 7627 | + */ |
---|
| 7628 | +void qla_schedule_eeh_work(struct scsi_qla_host *vha) |
---|
| 7629 | +{ |
---|
| 7630 | + struct qla_hw_data *ha = vha->hw; |
---|
| 7631 | + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
---|
| 7632 | + |
---|
| 7633 | + if (ha->flags.eeh_busy) |
---|
| 7634 | + return; |
---|
| 7635 | + |
---|
| 7636 | + set_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags); |
---|
| 7637 | + qla2xxx_wake_dpc(base_vha); |
---|
| 7638 | +} |
---|
| 7639 | + |
---|
| 7640 | +static void |
---|
| 7641 | +qla_pci_reset_prepare(struct pci_dev *pdev) |
---|
| 7642 | +{ |
---|
| 7643 | + scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); |
---|
| 7644 | + struct qla_hw_data *ha = base_vha->hw; |
---|
| 7645 | + struct qla_qpair *qpair; |
---|
| 7646 | + |
---|
| 7647 | + ql_log(ql_log_warn, base_vha, 0xffff, |
---|
| 7648 | + "%s.\n", __func__); |
---|
| 7649 | + |
---|
| 7650 | + /* |
---|
| 7651 | + * PCI FLR/function reset is about to reset the |
---|
| 7652 | + * slot. Stop the chip to stop all DMA access. |
---|
| 7653 | + * It is assumed that pci_reset_done will be called |
---|
| 7654 | + * after FLR to resume Chip operation. |
---|
| 7655 | + */ |
---|
| 7656 | + ha->flags.eeh_busy = 1; |
---|
| 7657 | + mutex_lock(&ha->mq_lock); |
---|
| 7658 | + list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
---|
| 7659 | + qpair->online = 0; |
---|
| 7660 | + mutex_unlock(&ha->mq_lock); |
---|
| 7661 | + |
---|
| 7662 | + set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
---|
| 7663 | + qla2x00_abort_isp_cleanup(base_vha); |
---|
| 7664 | + qla2x00_abort_all_cmds(base_vha, DID_RESET << 16); |
---|
| 7665 | +} |
---|
| 7666 | + |
---|
| 7667 | +static void |
---|
| 7668 | +qla_pci_reset_done(struct pci_dev *pdev) |
---|
| 7669 | +{ |
---|
| 7670 | + scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); |
---|
| 7671 | + struct qla_hw_data *ha = base_vha->hw; |
---|
| 7672 | + struct qla_qpair *qpair; |
---|
| 7673 | + |
---|
| 7674 | + ql_log(ql_log_warn, base_vha, 0xffff, |
---|
| 7675 | + "%s.\n", __func__); |
---|
| 7676 | + |
---|
| 7677 | + /* |
---|
| 7678 | + * FLR just completed by PCI layer. Resume adapter |
---|
| 7679 | + */ |
---|
6864 | 7680 | ha->flags.eeh_busy = 0; |
---|
| 7681 | + mutex_lock(&ha->mq_lock); |
---|
| 7682 | + list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
---|
| 7683 | + qpair->online = 1; |
---|
| 7684 | + mutex_unlock(&ha->mq_lock); |
---|
| 7685 | + |
---|
| 7686 | + base_vha->flags.online = 1; |
---|
| 7687 | + ha->isp_ops->abort_isp(base_vha); |
---|
| 7688 | + clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
---|
6865 | 7689 | } |
---|
6866 | 7690 | |
---|
6867 | 7691 | static int qla2xxx_map_queues(struct Scsi_Host *shost) |
---|
6868 | 7692 | { |
---|
6869 | 7693 | int rc; |
---|
6870 | 7694 | scsi_qla_host_t *vha = (scsi_qla_host_t *)shost->hostdata; |
---|
| 7695 | + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; |
---|
6871 | 7696 | |
---|
6872 | | - if (USER_CTRL_IRQ(vha->hw)) |
---|
6873 | | - rc = blk_mq_map_queues(&shost->tag_set); |
---|
| 7697 | + if (USER_CTRL_IRQ(vha->hw) || !vha->hw->mqiobase) |
---|
| 7698 | + rc = blk_mq_map_queues(qmap); |
---|
6874 | 7699 | else |
---|
6875 | | - rc = blk_mq_pci_map_queues(&shost->tag_set, vha->hw->pdev, 0); |
---|
| 7700 | + rc = blk_mq_pci_map_queues(qmap, vha->hw->pdev, vha->irq_offset); |
---|
6876 | 7701 | return rc; |
---|
6877 | 7702 | } |
---|
| 7703 | + |
---|
| 7704 | +struct scsi_host_template qla2xxx_driver_template = { |
---|
| 7705 | + .module = THIS_MODULE, |
---|
| 7706 | + .name = QLA2XXX_DRIVER_NAME, |
---|
| 7707 | + .queuecommand = qla2xxx_queuecommand, |
---|
| 7708 | + |
---|
| 7709 | + .eh_timed_out = fc_eh_timed_out, |
---|
| 7710 | + .eh_abort_handler = qla2xxx_eh_abort, |
---|
| 7711 | + .eh_device_reset_handler = qla2xxx_eh_device_reset, |
---|
| 7712 | + .eh_target_reset_handler = qla2xxx_eh_target_reset, |
---|
| 7713 | + .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
---|
| 7714 | + .eh_host_reset_handler = qla2xxx_eh_host_reset, |
---|
| 7715 | + |
---|
| 7716 | + .slave_configure = qla2xxx_slave_configure, |
---|
| 7717 | + |
---|
| 7718 | + .slave_alloc = qla2xxx_slave_alloc, |
---|
| 7719 | + .slave_destroy = qla2xxx_slave_destroy, |
---|
| 7720 | + .scan_finished = qla2xxx_scan_finished, |
---|
| 7721 | + .scan_start = qla2xxx_scan_start, |
---|
| 7722 | + .change_queue_depth = scsi_change_queue_depth, |
---|
| 7723 | + .map_queues = qla2xxx_map_queues, |
---|
| 7724 | + .this_id = -1, |
---|
| 7725 | + .cmd_per_lun = 3, |
---|
| 7726 | + .sg_tablesize = SG_ALL, |
---|
| 7727 | + |
---|
| 7728 | + .max_sectors = 0xFFFF, |
---|
| 7729 | + .shost_attrs = qla2x00_host_attrs, |
---|
| 7730 | + |
---|
| 7731 | + .supported_mode = MODE_INITIATOR, |
---|
| 7732 | + .track_queue_depth = 1, |
---|
| 7733 | + .cmd_size = sizeof(srb_t), |
---|
| 7734 | +}; |
---|
6878 | 7735 | |
---|
6879 | 7736 | static const struct pci_error_handlers qla2xxx_err_handler = { |
---|
6880 | 7737 | .error_detected = qla2xxx_pci_error_detected, |
---|
6881 | 7738 | .mmio_enabled = qla2xxx_pci_mmio_enabled, |
---|
6882 | 7739 | .slot_reset = qla2xxx_pci_slot_reset, |
---|
6883 | 7740 | .resume = qla2xxx_pci_resume, |
---|
| 7741 | + .reset_prepare = qla_pci_reset_prepare, |
---|
| 7742 | + .reset_done = qla_pci_reset_done, |
---|
6884 | 7743 | }; |
---|
6885 | 7744 | |
---|
6886 | 7745 | static struct pci_device_id qla2xxx_pci_tbl[] = { |
---|
.. | .. |
---|
6906 | 7765 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) }, |
---|
6907 | 7766 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) }, |
---|
6908 | 7767 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2261) }, |
---|
| 7768 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2061) }, |
---|
| 7769 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2081) }, |
---|
| 7770 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2281) }, |
---|
| 7771 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2089) }, |
---|
| 7772 | + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2289) }, |
---|
6909 | 7773 | { 0 }, |
---|
6910 | 7774 | }; |
---|
6911 | 7775 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
---|
.. | .. |
---|
6934 | 7798 | qla2x00_module_init(void) |
---|
6935 | 7799 | { |
---|
6936 | 7800 | int ret = 0; |
---|
| 7801 | + |
---|
| 7802 | + BUILD_BUG_ON(sizeof(cmd_a64_entry_t) != 64); |
---|
| 7803 | + BUILD_BUG_ON(sizeof(cmd_entry_t) != 64); |
---|
| 7804 | + BUILD_BUG_ON(sizeof(cont_a64_entry_t) != 64); |
---|
| 7805 | + BUILD_BUG_ON(sizeof(cont_entry_t) != 64); |
---|
| 7806 | + BUILD_BUG_ON(sizeof(init_cb_t) != 96); |
---|
| 7807 | + BUILD_BUG_ON(sizeof(mrk_entry_t) != 64); |
---|
| 7808 | + BUILD_BUG_ON(sizeof(ms_iocb_entry_t) != 64); |
---|
| 7809 | + BUILD_BUG_ON(sizeof(request_t) != 64); |
---|
| 7810 | + BUILD_BUG_ON(sizeof(struct abort_entry_24xx) != 64); |
---|
| 7811 | + BUILD_BUG_ON(sizeof(struct abort_iocb_entry_fx00) != 64); |
---|
| 7812 | + BUILD_BUG_ON(sizeof(struct abts_entry_24xx) != 64); |
---|
| 7813 | + BUILD_BUG_ON(sizeof(struct access_chip_84xx) != 64); |
---|
| 7814 | + BUILD_BUG_ON(sizeof(struct access_chip_rsp_84xx) != 64); |
---|
| 7815 | + BUILD_BUG_ON(sizeof(struct cmd_bidir) != 64); |
---|
| 7816 | + BUILD_BUG_ON(sizeof(struct cmd_nvme) != 64); |
---|
| 7817 | + BUILD_BUG_ON(sizeof(struct cmd_type_6) != 64); |
---|
| 7818 | + BUILD_BUG_ON(sizeof(struct cmd_type_7) != 64); |
---|
| 7819 | + BUILD_BUG_ON(sizeof(struct cmd_type_7_fx00) != 64); |
---|
| 7820 | + BUILD_BUG_ON(sizeof(struct cmd_type_crc_2) != 64); |
---|
| 7821 | + BUILD_BUG_ON(sizeof(struct ct_entry_24xx) != 64); |
---|
| 7822 | + BUILD_BUG_ON(sizeof(struct ct_fdmi1_hba_attributes) != 2344); |
---|
| 7823 | + BUILD_BUG_ON(sizeof(struct ct_fdmi2_hba_attributes) != 4424); |
---|
| 7824 | + BUILD_BUG_ON(sizeof(struct ct_fdmi2_port_attributes) != 4164); |
---|
| 7825 | + BUILD_BUG_ON(sizeof(struct ct_fdmi_hba_attr) != 260); |
---|
| 7826 | + BUILD_BUG_ON(sizeof(struct ct_fdmi_port_attr) != 260); |
---|
| 7827 | + BUILD_BUG_ON(sizeof(struct ct_rsp_hdr) != 16); |
---|
| 7828 | + BUILD_BUG_ON(sizeof(struct ctio_crc2_to_fw) != 64); |
---|
| 7829 | + BUILD_BUG_ON(sizeof(struct device_reg_24xx) != 256); |
---|
| 7830 | + BUILD_BUG_ON(sizeof(struct device_reg_25xxmq) != 24); |
---|
| 7831 | + BUILD_BUG_ON(sizeof(struct device_reg_2xxx) != 256); |
---|
| 7832 | + BUILD_BUG_ON(sizeof(struct device_reg_82xx) != 1288); |
---|
| 7833 | + BUILD_BUG_ON(sizeof(struct device_reg_fx00) != 216); |
---|
| 7834 | + BUILD_BUG_ON(sizeof(struct els_entry_24xx) != 64); |
---|
| 7835 | + BUILD_BUG_ON(sizeof(struct els_sts_entry_24xx) != 64); |
---|
| 7836 | + BUILD_BUG_ON(sizeof(struct fxdisc_entry_fx00) != 64); |
---|
| 7837 | + BUILD_BUG_ON(sizeof(struct imm_ntfy_from_isp) != 64); |
---|
| 7838 | + BUILD_BUG_ON(sizeof(struct init_cb_24xx) != 128); |
---|
| 7839 | + BUILD_BUG_ON(sizeof(struct init_cb_81xx) != 128); |
---|
| 7840 | + BUILD_BUG_ON(sizeof(struct logio_entry_24xx) != 64); |
---|
| 7841 | + BUILD_BUG_ON(sizeof(struct mbx_entry) != 64); |
---|
| 7842 | + BUILD_BUG_ON(sizeof(struct mid_init_cb_24xx) != 5252); |
---|
| 7843 | + BUILD_BUG_ON(sizeof(struct mrk_entry_24xx) != 64); |
---|
| 7844 | + BUILD_BUG_ON(sizeof(struct nvram_24xx) != 512); |
---|
| 7845 | + BUILD_BUG_ON(sizeof(struct nvram_81xx) != 512); |
---|
| 7846 | + BUILD_BUG_ON(sizeof(struct pt_ls4_request) != 64); |
---|
| 7847 | + BUILD_BUG_ON(sizeof(struct pt_ls4_rx_unsol) != 64); |
---|
| 7848 | + BUILD_BUG_ON(sizeof(struct purex_entry_24xx) != 64); |
---|
| 7849 | + BUILD_BUG_ON(sizeof(struct qla2100_fw_dump) != 123634); |
---|
| 7850 | + BUILD_BUG_ON(sizeof(struct qla2300_fw_dump) != 136100); |
---|
| 7851 | + BUILD_BUG_ON(sizeof(struct qla24xx_fw_dump) != 37976); |
---|
| 7852 | + BUILD_BUG_ON(sizeof(struct qla25xx_fw_dump) != 39228); |
---|
| 7853 | + BUILD_BUG_ON(sizeof(struct qla2xxx_fce_chain) != 52); |
---|
| 7854 | + BUILD_BUG_ON(sizeof(struct qla2xxx_fw_dump) != 136172); |
---|
| 7855 | + BUILD_BUG_ON(sizeof(struct qla2xxx_mq_chain) != 524); |
---|
| 7856 | + BUILD_BUG_ON(sizeof(struct qla2xxx_mqueue_chain) != 8); |
---|
| 7857 | + BUILD_BUG_ON(sizeof(struct qla2xxx_mqueue_header) != 12); |
---|
| 7858 | + BUILD_BUG_ON(sizeof(struct qla2xxx_offld_chain) != 24); |
---|
| 7859 | + BUILD_BUG_ON(sizeof(struct qla81xx_fw_dump) != 39420); |
---|
| 7860 | + BUILD_BUG_ON(sizeof(struct qla82xx_uri_data_desc) != 28); |
---|
| 7861 | + BUILD_BUG_ON(sizeof(struct qla82xx_uri_table_desc) != 32); |
---|
| 7862 | + BUILD_BUG_ON(sizeof(struct qla83xx_fw_dump) != 51196); |
---|
| 7863 | + BUILD_BUG_ON(sizeof(struct qla_fcp_prio_cfg) != FCP_PRIO_CFG_SIZE); |
---|
| 7864 | + BUILD_BUG_ON(sizeof(struct qla_fdt_layout) != 128); |
---|
| 7865 | + BUILD_BUG_ON(sizeof(struct qla_flt_header) != 8); |
---|
| 7866 | + BUILD_BUG_ON(sizeof(struct qla_flt_region) != 16); |
---|
| 7867 | + BUILD_BUG_ON(sizeof(struct qla_npiv_entry) != 24); |
---|
| 7868 | + BUILD_BUG_ON(sizeof(struct qla_npiv_header) != 16); |
---|
| 7869 | + BUILD_BUG_ON(sizeof(struct rdp_rsp_payload) != 336); |
---|
| 7870 | + BUILD_BUG_ON(sizeof(struct sns_cmd_pkt) != 2064); |
---|
| 7871 | + BUILD_BUG_ON(sizeof(struct sts_entry_24xx) != 64); |
---|
| 7872 | + BUILD_BUG_ON(sizeof(struct tsk_mgmt_entry) != 64); |
---|
| 7873 | + BUILD_BUG_ON(sizeof(struct tsk_mgmt_entry_fx00) != 64); |
---|
| 7874 | + BUILD_BUG_ON(sizeof(struct verify_chip_entry_84xx) != 64); |
---|
| 7875 | + BUILD_BUG_ON(sizeof(struct verify_chip_rsp_84xx) != 52); |
---|
| 7876 | + BUILD_BUG_ON(sizeof(struct vf_evfp_entry_24xx) != 56); |
---|
| 7877 | + BUILD_BUG_ON(sizeof(struct vp_config_entry_24xx) != 64); |
---|
| 7878 | + BUILD_BUG_ON(sizeof(struct vp_ctrl_entry_24xx) != 64); |
---|
| 7879 | + BUILD_BUG_ON(sizeof(struct vp_rpt_id_entry_24xx) != 64); |
---|
| 7880 | + BUILD_BUG_ON(sizeof(sts21_entry_t) != 64); |
---|
| 7881 | + BUILD_BUG_ON(sizeof(sts22_entry_t) != 64); |
---|
| 7882 | + BUILD_BUG_ON(sizeof(sts_cont_entry_t) != 64); |
---|
| 7883 | + BUILD_BUG_ON(sizeof(sts_entry_t) != 64); |
---|
| 7884 | + BUILD_BUG_ON(sizeof(sw_info_t) != 32); |
---|
| 7885 | + BUILD_BUG_ON(sizeof(target_id_t) != 2); |
---|
6937 | 7886 | |
---|
6938 | 7887 | /* Allocate cache for SRBs. */ |
---|
6939 | 7888 | srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, |
---|
.. | .. |
---|
6964 | 7913 | strcat(qla2x00_version_str, "-debug"); |
---|
6965 | 7914 | if (ql2xextended_error_logging == 1) |
---|
6966 | 7915 | ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK; |
---|
| 7916 | + |
---|
| 7917 | + if (ql2x_ini_mode == QLA2XXX_INI_MODE_DUAL) |
---|
| 7918 | + qla_insert_tgt_attrs(); |
---|
6967 | 7919 | |
---|
6968 | 7920 | qla2xxx_transport_template = |
---|
6969 | 7921 | fc_attach_transport(&qla2xxx_transport_functions); |
---|
.. | .. |
---|
7022 | 7974 | static void __exit |
---|
7023 | 7975 | qla2x00_module_exit(void) |
---|
7024 | 7976 | { |
---|
7025 | | - unregister_chrdev(apidev_major, QLA2XXX_APIDEV); |
---|
7026 | 7977 | pci_unregister_driver(&qla2xxx_pci_driver); |
---|
7027 | 7978 | 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); |
---|
| 7979 | + kmem_cache_destroy(ctx_cachep); |
---|
7033 | 7980 | fc_release_transport(qla2xxx_transport_vport_template); |
---|
| 7981 | + if (apidev_major >= 0) |
---|
| 7982 | + unregister_chrdev(apidev_major, QLA2XXX_APIDEV); |
---|
| 7983 | + fc_release_transport(qla2xxx_transport_template); |
---|
| 7984 | + qlt_exit(); |
---|
| 7985 | + kmem_cache_destroy(srb_cachep); |
---|
7034 | 7986 | } |
---|
7035 | 7987 | |
---|
7036 | 7988 | module_init(qla2x00_module_init); |
---|
.. | .. |
---|
7039 | 7991 | MODULE_AUTHOR("QLogic Corporation"); |
---|
7040 | 7992 | MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver"); |
---|
7041 | 7993 | MODULE_LICENSE("GPL"); |
---|
7042 | | -MODULE_VERSION(QLA2XXX_VERSION); |
---|
7043 | 7994 | MODULE_FIRMWARE(FW_FILE_ISP21XX); |
---|
7044 | 7995 | MODULE_FIRMWARE(FW_FILE_ISP22XX); |
---|
7045 | 7996 | MODULE_FIRMWARE(FW_FILE_ISP2300); |
---|