.. | .. |
---|
| 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 | #include "qla_target.h" |
---|
.. | .. |
---|
22 | 21 | static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *); |
---|
23 | 22 | static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, |
---|
24 | 23 | sts_entry_t *); |
---|
| 24 | +static void qla27xx_process_purex_fpin(struct scsi_qla_host *vha, |
---|
| 25 | + struct purex_item *item); |
---|
| 26 | +static struct purex_item *qla24xx_alloc_purex_item(scsi_qla_host_t *vha, |
---|
| 27 | + uint16_t size); |
---|
| 28 | +static struct purex_item *qla24xx_copy_std_pkt(struct scsi_qla_host *vha, |
---|
| 29 | + void *pkt); |
---|
| 30 | +static struct purex_item *qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, |
---|
| 31 | + void **pkt, struct rsp_que **rsp); |
---|
| 32 | + |
---|
| 33 | +static void |
---|
| 34 | +qla27xx_process_purex_fpin(struct scsi_qla_host *vha, struct purex_item *item) |
---|
| 35 | +{ |
---|
| 36 | + void *pkt = &item->iocb; |
---|
| 37 | + uint16_t pkt_size = item->size; |
---|
| 38 | + |
---|
| 39 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x508d, |
---|
| 40 | + "%s: Enter\n", __func__); |
---|
| 41 | + |
---|
| 42 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x508e, |
---|
| 43 | + "-------- ELS REQ -------\n"); |
---|
| 44 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x508f, |
---|
| 45 | + pkt, pkt_size); |
---|
| 46 | + |
---|
| 47 | + fc_host_fpin_rcv(vha->host, pkt_size, (char *)pkt); |
---|
| 48 | +} |
---|
| 49 | + |
---|
| 50 | +const char *const port_state_str[] = { |
---|
| 51 | + "Unknown", |
---|
| 52 | + "UNCONFIGURED", |
---|
| 53 | + "DEAD", |
---|
| 54 | + "LOST", |
---|
| 55 | + "ONLINE" |
---|
| 56 | +}; |
---|
| 57 | + |
---|
| 58 | +static void |
---|
| 59 | +qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt) |
---|
| 60 | +{ |
---|
| 61 | + struct abts_entry_24xx *abts = |
---|
| 62 | + (struct abts_entry_24xx *)&pkt->iocb; |
---|
| 63 | + struct qla_hw_data *ha = vha->hw; |
---|
| 64 | + struct els_entry_24xx *rsp_els; |
---|
| 65 | + struct abts_entry_24xx *abts_rsp; |
---|
| 66 | + dma_addr_t dma; |
---|
| 67 | + uint32_t fctl; |
---|
| 68 | + int rval; |
---|
| 69 | + |
---|
| 70 | + ql_dbg(ql_dbg_init, vha, 0x0286, "%s: entered.\n", __func__); |
---|
| 71 | + |
---|
| 72 | + ql_log(ql_log_warn, vha, 0x0287, |
---|
| 73 | + "Processing ABTS xchg=%#x oxid=%#x rxid=%#x seqid=%#x seqcnt=%#x\n", |
---|
| 74 | + abts->rx_xch_addr_to_abort, abts->ox_id, abts->rx_id, |
---|
| 75 | + abts->seq_id, abts->seq_cnt); |
---|
| 76 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0287, |
---|
| 77 | + "-------- ABTS RCV -------\n"); |
---|
| 78 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0287, |
---|
| 79 | + (uint8_t *)abts, sizeof(*abts)); |
---|
| 80 | + |
---|
| 81 | + rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els), &dma, |
---|
| 82 | + GFP_KERNEL); |
---|
| 83 | + if (!rsp_els) { |
---|
| 84 | + ql_log(ql_log_warn, vha, 0x0287, |
---|
| 85 | + "Failed allocate dma buffer ABTS/ELS RSP.\n"); |
---|
| 86 | + return; |
---|
| 87 | + } |
---|
| 88 | + |
---|
| 89 | + /* terminate exchange */ |
---|
| 90 | + rsp_els->entry_type = ELS_IOCB_TYPE; |
---|
| 91 | + rsp_els->entry_count = 1; |
---|
| 92 | + rsp_els->nport_handle = cpu_to_le16(~0); |
---|
| 93 | + rsp_els->rx_xchg_address = abts->rx_xch_addr_to_abort; |
---|
| 94 | + rsp_els->control_flags = cpu_to_le16(EPD_RX_XCHG); |
---|
| 95 | + ql_dbg(ql_dbg_init, vha, 0x0283, |
---|
| 96 | + "Sending ELS Response to terminate exchange %#x...\n", |
---|
| 97 | + abts->rx_xch_addr_to_abort); |
---|
| 98 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0283, |
---|
| 99 | + "-------- ELS RSP -------\n"); |
---|
| 100 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0283, |
---|
| 101 | + (uint8_t *)rsp_els, sizeof(*rsp_els)); |
---|
| 102 | + rval = qla2x00_issue_iocb(vha, rsp_els, dma, 0); |
---|
| 103 | + if (rval) { |
---|
| 104 | + ql_log(ql_log_warn, vha, 0x0288, |
---|
| 105 | + "%s: iocb failed to execute -> %x\n", __func__, rval); |
---|
| 106 | + } else if (rsp_els->comp_status) { |
---|
| 107 | + ql_log(ql_log_warn, vha, 0x0289, |
---|
| 108 | + "%s: iocb failed to complete -> completion=%#x subcode=(%#x,%#x)\n", |
---|
| 109 | + __func__, rsp_els->comp_status, |
---|
| 110 | + rsp_els->error_subcode_1, rsp_els->error_subcode_2); |
---|
| 111 | + } else { |
---|
| 112 | + ql_dbg(ql_dbg_init, vha, 0x028a, |
---|
| 113 | + "%s: abort exchange done.\n", __func__); |
---|
| 114 | + } |
---|
| 115 | + |
---|
| 116 | + /* send ABTS response */ |
---|
| 117 | + abts_rsp = (void *)rsp_els; |
---|
| 118 | + memset(abts_rsp, 0, sizeof(*abts_rsp)); |
---|
| 119 | + abts_rsp->entry_type = ABTS_RSP_TYPE; |
---|
| 120 | + abts_rsp->entry_count = 1; |
---|
| 121 | + abts_rsp->nport_handle = abts->nport_handle; |
---|
| 122 | + abts_rsp->vp_idx = abts->vp_idx; |
---|
| 123 | + abts_rsp->sof_type = abts->sof_type & 0xf0; |
---|
| 124 | + abts_rsp->rx_xch_addr = abts->rx_xch_addr; |
---|
| 125 | + abts_rsp->d_id[0] = abts->s_id[0]; |
---|
| 126 | + abts_rsp->d_id[1] = abts->s_id[1]; |
---|
| 127 | + abts_rsp->d_id[2] = abts->s_id[2]; |
---|
| 128 | + abts_rsp->r_ctl = FC_ROUTING_BLD | FC_R_CTL_BLD_BA_ACC; |
---|
| 129 | + abts_rsp->s_id[0] = abts->d_id[0]; |
---|
| 130 | + abts_rsp->s_id[1] = abts->d_id[1]; |
---|
| 131 | + abts_rsp->s_id[2] = abts->d_id[2]; |
---|
| 132 | + abts_rsp->cs_ctl = abts->cs_ctl; |
---|
| 133 | + /* include flipping bit23 in fctl */ |
---|
| 134 | + fctl = ~(abts->f_ctl[2] | 0x7F) << 16 | |
---|
| 135 | + FC_F_CTL_LAST_SEQ | FC_F_CTL_END_SEQ | FC_F_CTL_SEQ_INIT; |
---|
| 136 | + abts_rsp->f_ctl[0] = fctl >> 0 & 0xff; |
---|
| 137 | + abts_rsp->f_ctl[1] = fctl >> 8 & 0xff; |
---|
| 138 | + abts_rsp->f_ctl[2] = fctl >> 16 & 0xff; |
---|
| 139 | + abts_rsp->type = FC_TYPE_BLD; |
---|
| 140 | + abts_rsp->rx_id = abts->rx_id; |
---|
| 141 | + abts_rsp->ox_id = abts->ox_id; |
---|
| 142 | + abts_rsp->payload.ba_acc.aborted_rx_id = abts->rx_id; |
---|
| 143 | + abts_rsp->payload.ba_acc.aborted_ox_id = abts->ox_id; |
---|
| 144 | + abts_rsp->payload.ba_acc.high_seq_cnt = cpu_to_le16(~0); |
---|
| 145 | + abts_rsp->rx_xch_addr_to_abort = abts->rx_xch_addr_to_abort; |
---|
| 146 | + ql_dbg(ql_dbg_init, vha, 0x028b, |
---|
| 147 | + "Sending BA ACC response to ABTS %#x...\n", |
---|
| 148 | + abts->rx_xch_addr_to_abort); |
---|
| 149 | + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x028b, |
---|
| 150 | + "-------- ELS RSP -------\n"); |
---|
| 151 | + ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x028b, |
---|
| 152 | + (uint8_t *)abts_rsp, sizeof(*abts_rsp)); |
---|
| 153 | + rval = qla2x00_issue_iocb(vha, abts_rsp, dma, 0); |
---|
| 154 | + if (rval) { |
---|
| 155 | + ql_log(ql_log_warn, vha, 0x028c, |
---|
| 156 | + "%s: iocb failed to execute -> %x\n", __func__, rval); |
---|
| 157 | + } else if (abts_rsp->comp_status) { |
---|
| 158 | + ql_log(ql_log_warn, vha, 0x028d, |
---|
| 159 | + "%s: iocb failed to complete -> completion=%#x subcode=(%#x,%#x)\n", |
---|
| 160 | + __func__, abts_rsp->comp_status, |
---|
| 161 | + abts_rsp->payload.error.subcode1, |
---|
| 162 | + abts_rsp->payload.error.subcode2); |
---|
| 163 | + } else { |
---|
| 164 | + ql_dbg(ql_dbg_init, vha, 0x028ea, |
---|
| 165 | + "%s: done.\n", __func__); |
---|
| 166 | + } |
---|
| 167 | + |
---|
| 168 | + dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els), rsp_els, dma); |
---|
| 169 | +} |
---|
25 | 170 | |
---|
26 | 171 | /** |
---|
27 | 172 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. |
---|
28 | | - * @irq: |
---|
| 173 | + * @irq: interrupt number |
---|
29 | 174 | * @dev_id: SCSI driver HA context |
---|
30 | 175 | * |
---|
31 | 176 | * Called by system whenever the host adapter generates an interrupt. |
---|
.. | .. |
---|
41 | 186 | int status; |
---|
42 | 187 | unsigned long iter; |
---|
43 | 188 | uint16_t hccr; |
---|
44 | | - uint16_t mb[4]; |
---|
| 189 | + uint16_t mb[8]; |
---|
45 | 190 | struct rsp_que *rsp; |
---|
46 | 191 | unsigned long flags; |
---|
47 | 192 | |
---|
.. | .. |
---|
59 | 204 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
60 | 205 | vha = pci_get_drvdata(ha->pdev); |
---|
61 | 206 | for (iter = 50; iter--; ) { |
---|
62 | | - hccr = RD_REG_WORD(®->hccr); |
---|
| 207 | + hccr = rd_reg_word(®->hccr); |
---|
63 | 208 | if (qla2x00_check_reg16_for_disconnect(vha, hccr)) |
---|
64 | 209 | break; |
---|
65 | 210 | if (hccr & HCCR_RISC_PAUSE) { |
---|
.. | .. |
---|
71 | 216 | * bit to be cleared. Schedule a big hammer to get |
---|
72 | 217 | * out of the RISC PAUSED state. |
---|
73 | 218 | */ |
---|
74 | | - WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); |
---|
75 | | - RD_REG_WORD(®->hccr); |
---|
| 219 | + wrt_reg_word(®->hccr, HCCR_RESET_RISC); |
---|
| 220 | + rd_reg_word(®->hccr); |
---|
76 | 221 | |
---|
77 | | - ha->isp_ops->fw_dump(vha, 1); |
---|
| 222 | + ha->isp_ops->fw_dump(vha); |
---|
78 | 223 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
79 | 224 | break; |
---|
80 | | - } else if ((RD_REG_WORD(®->istatus) & ISR_RISC_INT) == 0) |
---|
| 225 | + } else if ((rd_reg_word(®->istatus) & ISR_RISC_INT) == 0) |
---|
81 | 226 | break; |
---|
82 | 227 | |
---|
83 | | - if (RD_REG_WORD(®->semaphore) & BIT_0) { |
---|
84 | | - WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
---|
85 | | - RD_REG_WORD(®->hccr); |
---|
| 228 | + if (rd_reg_word(®->semaphore) & BIT_0) { |
---|
| 229 | + wrt_reg_word(®->hccr, HCCR_CLR_RISC_INT); |
---|
| 230 | + rd_reg_word(®->hccr); |
---|
86 | 231 | |
---|
87 | 232 | /* Get mailbox data. */ |
---|
88 | 233 | mb[0] = RD_MAILBOX_REG(ha, reg, 0); |
---|
.. | .. |
---|
101 | 246 | mb[0]); |
---|
102 | 247 | } |
---|
103 | 248 | /* Release mailbox registers. */ |
---|
104 | | - WRT_REG_WORD(®->semaphore, 0); |
---|
105 | | - RD_REG_WORD(®->semaphore); |
---|
| 249 | + wrt_reg_word(®->semaphore, 0); |
---|
| 250 | + rd_reg_word(®->semaphore); |
---|
106 | 251 | } else { |
---|
107 | 252 | qla2x00_process_response_queue(rsp); |
---|
108 | 253 | |
---|
109 | | - WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
---|
110 | | - RD_REG_WORD(®->hccr); |
---|
| 254 | + wrt_reg_word(®->hccr, HCCR_CLR_RISC_INT); |
---|
| 255 | + rd_reg_word(®->hccr); |
---|
111 | 256 | } |
---|
112 | 257 | } |
---|
113 | 258 | qla2x00_handle_mbx_completion(ha, status); |
---|
.. | .. |
---|
124 | 269 | if (!test_and_set_bit(PFLG_DISCONNECTED, &vha->pci_flags) && |
---|
125 | 270 | !test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags) && |
---|
126 | 271 | !test_bit(PFLG_DRIVER_PROBING, &vha->pci_flags)) { |
---|
127 | | - /* |
---|
128 | | - * Schedule this (only once) on the default system |
---|
129 | | - * workqueue so that all the adapter workqueues and the |
---|
130 | | - * DPC thread can be shutdown cleanly. |
---|
131 | | - */ |
---|
132 | | - schedule_work(&vha->hw->board_disable); |
---|
| 272 | + qla_schedule_eeh_work(vha); |
---|
133 | 273 | } |
---|
134 | 274 | return true; |
---|
135 | 275 | } else |
---|
.. | .. |
---|
144 | 284 | |
---|
145 | 285 | /** |
---|
146 | 286 | * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. |
---|
147 | | - * @irq: |
---|
| 287 | + * @irq: interrupt number |
---|
148 | 288 | * @dev_id: SCSI driver HA context |
---|
149 | 289 | * |
---|
150 | 290 | * Called by system whenever the host adapter generates an interrupt. |
---|
.. | .. |
---|
160 | 300 | unsigned long iter; |
---|
161 | 301 | uint32_t stat; |
---|
162 | 302 | uint16_t hccr; |
---|
163 | | - uint16_t mb[4]; |
---|
| 303 | + uint16_t mb[8]; |
---|
164 | 304 | struct rsp_que *rsp; |
---|
165 | 305 | struct qla_hw_data *ha; |
---|
166 | 306 | unsigned long flags; |
---|
.. | .. |
---|
179 | 319 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
180 | 320 | vha = pci_get_drvdata(ha->pdev); |
---|
181 | 321 | for (iter = 50; iter--; ) { |
---|
182 | | - stat = RD_REG_DWORD(®->u.isp2300.host_status); |
---|
| 322 | + stat = rd_reg_dword(®->u.isp2300.host_status); |
---|
183 | 323 | if (qla2x00_check_reg32_for_disconnect(vha, stat)) |
---|
184 | 324 | break; |
---|
185 | 325 | if (stat & HSR_RISC_PAUSED) { |
---|
186 | 326 | if (unlikely(pci_channel_offline(ha->pdev))) |
---|
187 | 327 | break; |
---|
188 | 328 | |
---|
189 | | - hccr = RD_REG_WORD(®->hccr); |
---|
| 329 | + hccr = rd_reg_word(®->hccr); |
---|
190 | 330 | |
---|
191 | 331 | if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8)) |
---|
192 | 332 | ql_log(ql_log_warn, vha, 0x5026, |
---|
.. | .. |
---|
202 | 342 | * interrupt bit to be cleared. Schedule a big |
---|
203 | 343 | * hammer to get out of the RISC PAUSED state. |
---|
204 | 344 | */ |
---|
205 | | - WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); |
---|
206 | | - RD_REG_WORD(®->hccr); |
---|
| 345 | + wrt_reg_word(®->hccr, HCCR_RESET_RISC); |
---|
| 346 | + rd_reg_word(®->hccr); |
---|
207 | 347 | |
---|
208 | | - ha->isp_ops->fw_dump(vha, 1); |
---|
| 348 | + ha->isp_ops->fw_dump(vha); |
---|
209 | 349 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
210 | 350 | break; |
---|
211 | 351 | } else if ((stat & HSR_RISC_INT) == 0) |
---|
.. | .. |
---|
220 | 360 | status |= MBX_INTERRUPT; |
---|
221 | 361 | |
---|
222 | 362 | /* Release mailbox registers. */ |
---|
223 | | - WRT_REG_WORD(®->semaphore, 0); |
---|
| 363 | + wrt_reg_word(®->semaphore, 0); |
---|
224 | 364 | break; |
---|
225 | 365 | case 0x12: |
---|
226 | 366 | mb[0] = MSW(stat); |
---|
.. | .. |
---|
248 | 388 | "Unrecognized interrupt type (%d).\n", stat & 0xff); |
---|
249 | 389 | break; |
---|
250 | 390 | } |
---|
251 | | - WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
---|
252 | | - RD_REG_WORD_RELAXED(®->hccr); |
---|
| 391 | + wrt_reg_word(®->hccr, HCCR_CLR_RISC_INT); |
---|
| 392 | + rd_reg_word_relaxed(®->hccr); |
---|
253 | 393 | } |
---|
254 | 394 | qla2x00_handle_mbx_completion(ha, status); |
---|
255 | 395 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
.. | .. |
---|
267 | 407 | { |
---|
268 | 408 | uint16_t cnt; |
---|
269 | 409 | uint32_t mboxes; |
---|
270 | | - uint16_t __iomem *wptr; |
---|
| 410 | + __le16 __iomem *wptr; |
---|
271 | 411 | struct qla_hw_data *ha = vha->hw; |
---|
272 | 412 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
---|
273 | 413 | |
---|
.. | .. |
---|
283 | 423 | ha->flags.mbox_int = 1; |
---|
284 | 424 | ha->mailbox_out[0] = mb0; |
---|
285 | 425 | mboxes >>= 1; |
---|
286 | | - wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1); |
---|
| 426 | + wptr = MAILBOX_REG(ha, reg, 1); |
---|
287 | 427 | |
---|
288 | 428 | for (cnt = 1; cnt < ha->mbx_count; cnt++) { |
---|
289 | 429 | if (IS_QLA2200(ha) && cnt == 8) |
---|
290 | | - wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8); |
---|
| 430 | + wptr = MAILBOX_REG(ha, reg, 8); |
---|
291 | 431 | if ((cnt == 4 || cnt == 5) && (mboxes & BIT_0)) |
---|
292 | 432 | ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr); |
---|
293 | 433 | else if (mboxes & BIT_0) |
---|
294 | | - ha->mailbox_out[cnt] = RD_REG_WORD(wptr); |
---|
| 434 | + ha->mailbox_out[cnt] = rd_reg_word(wptr); |
---|
295 | 435 | |
---|
296 | 436 | wptr++; |
---|
297 | 437 | mboxes >>= 1; |
---|
.. | .. |
---|
306 | 446 | int rval; |
---|
307 | 447 | struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24; |
---|
308 | 448 | struct device_reg_82xx __iomem *reg82 = &vha->hw->iobase->isp82; |
---|
309 | | - uint16_t __iomem *wptr; |
---|
| 449 | + __le16 __iomem *wptr; |
---|
310 | 450 | uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS]; |
---|
311 | 451 | |
---|
312 | 452 | /* Seed data -- mailbox1 -> mailbox7. */ |
---|
313 | 453 | if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) |
---|
314 | | - wptr = (uint16_t __iomem *)®24->mailbox1; |
---|
| 454 | + wptr = ®24->mailbox1; |
---|
315 | 455 | else if (IS_QLA8044(vha->hw)) |
---|
316 | | - wptr = (uint16_t __iomem *)®82->mailbox_out[1]; |
---|
| 456 | + wptr = ®82->mailbox_out[1]; |
---|
317 | 457 | else |
---|
318 | 458 | return; |
---|
319 | 459 | |
---|
320 | 460 | for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++) |
---|
321 | | - mb[cnt] = RD_REG_WORD(wptr); |
---|
| 461 | + mb[cnt] = rd_reg_word(wptr); |
---|
322 | 462 | |
---|
323 | 463 | ql_dbg(ql_dbg_async, vha, 0x5021, |
---|
324 | 464 | "Inter-Driver Communication %s -- " |
---|
.. | .. |
---|
366 | 506 | static const char *const link_speeds[] = { |
---|
367 | 507 | "1", "2", "?", "4", "8", "16", "32", "10" |
---|
368 | 508 | }; |
---|
369 | | -#define QLA_LAST_SPEED 7 |
---|
| 509 | +#define QLA_LAST_SPEED (ARRAY_SIZE(link_speeds) - 1) |
---|
370 | 510 | |
---|
371 | 511 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
---|
372 | 512 | return link_speeds[0]; |
---|
.. | .. |
---|
611 | 751 | return NULL; |
---|
612 | 752 | } |
---|
613 | 753 | |
---|
| 754 | +/* Shall be called only on supported adapters. */ |
---|
| 755 | +static void |
---|
| 756 | +qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb) |
---|
| 757 | +{ |
---|
| 758 | + struct qla_hw_data *ha = vha->hw; |
---|
| 759 | + bool reset_isp_needed = 0; |
---|
| 760 | + |
---|
| 761 | + ql_log(ql_log_warn, vha, 0x02f0, |
---|
| 762 | + "MPI Heartbeat stop. MPI reset is%s needed. " |
---|
| 763 | + "MB0[%xh] MB1[%xh] MB2[%xh] MB3[%xh]\n", |
---|
| 764 | + mb[1] & BIT_8 ? "" : " not", |
---|
| 765 | + mb[0], mb[1], mb[2], mb[3]); |
---|
| 766 | + |
---|
| 767 | + if ((mb[1] & BIT_8) == 0) |
---|
| 768 | + return; |
---|
| 769 | + |
---|
| 770 | + ql_log(ql_log_warn, vha, 0x02f1, |
---|
| 771 | + "MPI Heartbeat stop. FW dump needed\n"); |
---|
| 772 | + |
---|
| 773 | + if (ql2xfulldump_on_mpifail) { |
---|
| 774 | + ha->isp_ops->fw_dump(vha); |
---|
| 775 | + reset_isp_needed = 1; |
---|
| 776 | + } |
---|
| 777 | + |
---|
| 778 | + ha->isp_ops->mpi_fw_dump(vha, 1); |
---|
| 779 | + |
---|
| 780 | + if (reset_isp_needed) { |
---|
| 781 | + vha->hw->flags.fw_init_done = 0; |
---|
| 782 | + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
| 783 | + qla2xxx_wake_dpc(vha); |
---|
| 784 | + } |
---|
| 785 | +} |
---|
| 786 | + |
---|
| 787 | +static struct purex_item * |
---|
| 788 | +qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size) |
---|
| 789 | +{ |
---|
| 790 | + struct purex_item *item = NULL; |
---|
| 791 | + uint8_t item_hdr_size = sizeof(*item); |
---|
| 792 | + |
---|
| 793 | + if (size > QLA_DEFAULT_PAYLOAD_SIZE) { |
---|
| 794 | + item = kzalloc(item_hdr_size + |
---|
| 795 | + (size - QLA_DEFAULT_PAYLOAD_SIZE), GFP_ATOMIC); |
---|
| 796 | + } else { |
---|
| 797 | + if (atomic_inc_return(&vha->default_item.in_use) == 1) { |
---|
| 798 | + item = &vha->default_item; |
---|
| 799 | + goto initialize_purex_header; |
---|
| 800 | + } else { |
---|
| 801 | + item = kzalloc(item_hdr_size, GFP_ATOMIC); |
---|
| 802 | + } |
---|
| 803 | + } |
---|
| 804 | + if (!item) { |
---|
| 805 | + ql_log(ql_log_warn, vha, 0x5092, |
---|
| 806 | + ">> Failed allocate purex list item.\n"); |
---|
| 807 | + |
---|
| 808 | + return NULL; |
---|
| 809 | + } |
---|
| 810 | + |
---|
| 811 | +initialize_purex_header: |
---|
| 812 | + item->vha = vha; |
---|
| 813 | + item->size = size; |
---|
| 814 | + return item; |
---|
| 815 | +} |
---|
| 816 | + |
---|
| 817 | +static void |
---|
| 818 | +qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt, |
---|
| 819 | + void (*process_item)(struct scsi_qla_host *vha, |
---|
| 820 | + struct purex_item *pkt)) |
---|
| 821 | +{ |
---|
| 822 | + struct purex_list *list = &vha->purex_list; |
---|
| 823 | + ulong flags; |
---|
| 824 | + |
---|
| 825 | + pkt->process_item = process_item; |
---|
| 826 | + |
---|
| 827 | + spin_lock_irqsave(&list->lock, flags); |
---|
| 828 | + list_add_tail(&pkt->list, &list->head); |
---|
| 829 | + spin_unlock_irqrestore(&list->lock, flags); |
---|
| 830 | + |
---|
| 831 | + set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags); |
---|
| 832 | +} |
---|
| 833 | + |
---|
| 834 | +/** |
---|
| 835 | + * qla24xx_copy_std_pkt() - Copy over purex ELS which is |
---|
| 836 | + * contained in a single IOCB. |
---|
| 837 | + * purex packet. |
---|
| 838 | + * @vha: SCSI driver HA context |
---|
| 839 | + * @pkt: ELS packet |
---|
| 840 | + */ |
---|
| 841 | +static struct purex_item |
---|
| 842 | +*qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt) |
---|
| 843 | +{ |
---|
| 844 | + struct purex_item *item; |
---|
| 845 | + |
---|
| 846 | + item = qla24xx_alloc_purex_item(vha, |
---|
| 847 | + QLA_DEFAULT_PAYLOAD_SIZE); |
---|
| 848 | + if (!item) |
---|
| 849 | + return item; |
---|
| 850 | + |
---|
| 851 | + memcpy(&item->iocb, pkt, sizeof(item->iocb)); |
---|
| 852 | + return item; |
---|
| 853 | +} |
---|
| 854 | + |
---|
| 855 | +/** |
---|
| 856 | + * qla27xx_copy_fpin_pkt() - Copy over fpin packets that can |
---|
| 857 | + * span over multiple IOCBs. |
---|
| 858 | + * @vha: SCSI driver HA context |
---|
| 859 | + * @pkt: ELS packet |
---|
| 860 | + * @rsp: Response queue |
---|
| 861 | + */ |
---|
| 862 | +static struct purex_item * |
---|
| 863 | +qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt, |
---|
| 864 | + struct rsp_que **rsp) |
---|
| 865 | +{ |
---|
| 866 | + struct purex_entry_24xx *purex = *pkt; |
---|
| 867 | + struct rsp_que *rsp_q = *rsp; |
---|
| 868 | + sts_cont_entry_t *new_pkt; |
---|
| 869 | + uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0; |
---|
| 870 | + uint16_t buffer_copy_offset = 0; |
---|
| 871 | + uint16_t entry_count, entry_count_remaining; |
---|
| 872 | + struct purex_item *item; |
---|
| 873 | + void *fpin_pkt = NULL; |
---|
| 874 | + |
---|
| 875 | + total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF) |
---|
| 876 | + - PURX_ELS_HEADER_SIZE; |
---|
| 877 | + pending_bytes = total_bytes; |
---|
| 878 | + entry_count = entry_count_remaining = purex->entry_count; |
---|
| 879 | + no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ? |
---|
| 880 | + sizeof(purex->els_frame_payload) : pending_bytes; |
---|
| 881 | + ql_log(ql_log_info, vha, 0x509a, |
---|
| 882 | + "FPIN ELS, frame_size 0x%x, entry count %d\n", |
---|
| 883 | + total_bytes, entry_count); |
---|
| 884 | + |
---|
| 885 | + item = qla24xx_alloc_purex_item(vha, total_bytes); |
---|
| 886 | + if (!item) |
---|
| 887 | + return item; |
---|
| 888 | + |
---|
| 889 | + fpin_pkt = &item->iocb; |
---|
| 890 | + |
---|
| 891 | + memcpy(fpin_pkt, &purex->els_frame_payload[0], no_bytes); |
---|
| 892 | + buffer_copy_offset += no_bytes; |
---|
| 893 | + pending_bytes -= no_bytes; |
---|
| 894 | + --entry_count_remaining; |
---|
| 895 | + |
---|
| 896 | + ((response_t *)purex)->signature = RESPONSE_PROCESSED; |
---|
| 897 | + wmb(); |
---|
| 898 | + |
---|
| 899 | + do { |
---|
| 900 | + while ((total_bytes > 0) && (entry_count_remaining > 0)) { |
---|
| 901 | + if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) { |
---|
| 902 | + ql_dbg(ql_dbg_async, vha, 0x5084, |
---|
| 903 | + "Ran out of IOCBs, partial data 0x%x\n", |
---|
| 904 | + buffer_copy_offset); |
---|
| 905 | + cpu_relax(); |
---|
| 906 | + continue; |
---|
| 907 | + } |
---|
| 908 | + |
---|
| 909 | + new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr; |
---|
| 910 | + *pkt = new_pkt; |
---|
| 911 | + |
---|
| 912 | + if (new_pkt->entry_type != STATUS_CONT_TYPE) { |
---|
| 913 | + ql_log(ql_log_warn, vha, 0x507a, |
---|
| 914 | + "Unexpected IOCB type, partial data 0x%x\n", |
---|
| 915 | + buffer_copy_offset); |
---|
| 916 | + break; |
---|
| 917 | + } |
---|
| 918 | + |
---|
| 919 | + rsp_q->ring_index++; |
---|
| 920 | + if (rsp_q->ring_index == rsp_q->length) { |
---|
| 921 | + rsp_q->ring_index = 0; |
---|
| 922 | + rsp_q->ring_ptr = rsp_q->ring; |
---|
| 923 | + } else { |
---|
| 924 | + rsp_q->ring_ptr++; |
---|
| 925 | + } |
---|
| 926 | + no_bytes = (pending_bytes > sizeof(new_pkt->data)) ? |
---|
| 927 | + sizeof(new_pkt->data) : pending_bytes; |
---|
| 928 | + if ((buffer_copy_offset + no_bytes) <= total_bytes) { |
---|
| 929 | + memcpy(((uint8_t *)fpin_pkt + |
---|
| 930 | + buffer_copy_offset), new_pkt->data, |
---|
| 931 | + no_bytes); |
---|
| 932 | + buffer_copy_offset += no_bytes; |
---|
| 933 | + pending_bytes -= no_bytes; |
---|
| 934 | + --entry_count_remaining; |
---|
| 935 | + } else { |
---|
| 936 | + ql_log(ql_log_warn, vha, 0x5044, |
---|
| 937 | + "Attempt to copy more that we got, optimizing..%x\n", |
---|
| 938 | + buffer_copy_offset); |
---|
| 939 | + memcpy(((uint8_t *)fpin_pkt + |
---|
| 940 | + buffer_copy_offset), new_pkt->data, |
---|
| 941 | + total_bytes - buffer_copy_offset); |
---|
| 942 | + } |
---|
| 943 | + |
---|
| 944 | + ((response_t *)new_pkt)->signature = RESPONSE_PROCESSED; |
---|
| 945 | + wmb(); |
---|
| 946 | + } |
---|
| 947 | + |
---|
| 948 | + if (pending_bytes != 0 || entry_count_remaining != 0) { |
---|
| 949 | + ql_log(ql_log_fatal, vha, 0x508b, |
---|
| 950 | + "Dropping partial FPIN, underrun bytes = 0x%x, entry cnts 0x%x\n", |
---|
| 951 | + total_bytes, entry_count_remaining); |
---|
| 952 | + qla24xx_free_purex_item(item); |
---|
| 953 | + return NULL; |
---|
| 954 | + } |
---|
| 955 | + } while (entry_count_remaining > 0); |
---|
| 956 | + host_to_fcp_swap((uint8_t *)&item->iocb, total_bytes); |
---|
| 957 | + return item; |
---|
| 958 | +} |
---|
| 959 | + |
---|
614 | 960 | /** |
---|
615 | 961 | * qla2x00_async_event() - Process aynchronous events. |
---|
616 | 962 | * @vha: SCSI driver HA context |
---|
.. | .. |
---|
631 | 977 | unsigned long flags; |
---|
632 | 978 | fc_port_t *fcport = NULL; |
---|
633 | 979 | |
---|
634 | | - if (!vha->hw->flags.fw_started) |
---|
| 980 | + if (!vha->hw->flags.fw_started) { |
---|
| 981 | + ql_log(ql_log_warn, vha, 0x50ff, |
---|
| 982 | + "Dropping AEN - %04x %04x %04x %04x.\n", |
---|
| 983 | + mb[0], mb[1], mb[2], mb[3]); |
---|
635 | 984 | return; |
---|
| 985 | + } |
---|
636 | 986 | |
---|
637 | 987 | /* Setup to process RIO completion. */ |
---|
638 | 988 | handle_cnt = 0; |
---|
.. | .. |
---|
640 | 990 | goto skip_rio; |
---|
641 | 991 | switch (mb[0]) { |
---|
642 | 992 | case MBA_SCSI_COMPLETION: |
---|
643 | | - handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1])); |
---|
| 993 | + handles[0] = make_handle(mb[2], mb[1]); |
---|
644 | 994 | handle_cnt = 1; |
---|
645 | 995 | break; |
---|
646 | 996 | case MBA_CMPLT_1_16BIT: |
---|
.. | .. |
---|
679 | 1029 | mb[0] = MBA_SCSI_COMPLETION; |
---|
680 | 1030 | break; |
---|
681 | 1031 | case MBA_CMPLT_2_32BIT: |
---|
682 | | - handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1])); |
---|
683 | | - handles[1] = le32_to_cpu( |
---|
684 | | - ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) | |
---|
685 | | - RD_MAILBOX_REG(ha, reg, 6)); |
---|
| 1032 | + handles[0] = make_handle(mb[2], mb[1]); |
---|
| 1033 | + handles[1] = make_handle(RD_MAILBOX_REG(ha, reg, 7), |
---|
| 1034 | + RD_MAILBOX_REG(ha, reg, 6)); |
---|
686 | 1035 | handle_cnt = 2; |
---|
687 | 1036 | mb[0] = MBA_SCSI_COMPLETION; |
---|
688 | 1037 | break; |
---|
.. | .. |
---|
708 | 1057 | break; |
---|
709 | 1058 | |
---|
710 | 1059 | case MBA_SYSTEM_ERR: /* System Error */ |
---|
711 | | - mbx = (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) ? |
---|
712 | | - RD_REG_WORD(®24->mailbox7) : 0; |
---|
713 | | - ql_log(ql_log_warn, vha, 0x5003, |
---|
714 | | - "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh " |
---|
715 | | - "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx); |
---|
| 1060 | + mbx = 0; |
---|
| 1061 | + if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || |
---|
| 1062 | + IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
---|
| 1063 | + u16 m[4]; |
---|
716 | 1064 | |
---|
717 | | - ha->isp_ops->fw_dump(vha, 1); |
---|
| 1065 | + m[0] = rd_reg_word(®24->mailbox4); |
---|
| 1066 | + m[1] = rd_reg_word(®24->mailbox5); |
---|
| 1067 | + m[2] = rd_reg_word(®24->mailbox6); |
---|
| 1068 | + mbx = m[3] = rd_reg_word(®24->mailbox7); |
---|
| 1069 | + |
---|
| 1070 | + ql_log(ql_log_warn, vha, 0x5003, |
---|
| 1071 | + "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh mbx4=%xh mbx5=%xh mbx6=%xh mbx7=%xh.\n", |
---|
| 1072 | + mb[1], mb[2], mb[3], m[0], m[1], m[2], m[3]); |
---|
| 1073 | + } else |
---|
| 1074 | + ql_log(ql_log_warn, vha, 0x5003, |
---|
| 1075 | + "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n ", |
---|
| 1076 | + mb[1], mb[2], mb[3]); |
---|
| 1077 | + |
---|
| 1078 | + if ((IS_QLA27XX(ha) || IS_QLA28XX(ha)) && |
---|
| 1079 | + rd_reg_word(®24->mailbox7) & BIT_8) |
---|
| 1080 | + ha->isp_ops->mpi_fw_dump(vha, 1); |
---|
| 1081 | + ha->isp_ops->fw_dump(vha); |
---|
718 | 1082 | ha->flags.fw_init_done = 0; |
---|
719 | 1083 | QLA_FW_STOPPED(ha); |
---|
720 | 1084 | |
---|
.. | .. |
---|
765 | 1129 | case MBA_LOOP_INIT_ERR: |
---|
766 | 1130 | ql_log(ql_log_warn, vha, 0x5090, |
---|
767 | 1131 | "LOOP INIT ERROR (%x).\n", mb[1]); |
---|
768 | | - ha->isp_ops->fw_dump(vha, 1); |
---|
769 | 1132 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
770 | 1133 | break; |
---|
771 | 1134 | |
---|
.. | .. |
---|
778 | 1141 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
---|
779 | 1142 | atomic_set(&vha->loop_state, LOOP_DOWN); |
---|
780 | 1143 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
---|
781 | | - qla2x00_mark_all_devices_lost(vha, 1); |
---|
| 1144 | + qla2x00_mark_all_devices_lost(vha); |
---|
782 | 1145 | } |
---|
783 | 1146 | |
---|
784 | 1147 | if (vha->vp_idx) { |
---|
.. | .. |
---|
803 | 1166 | "LOOP UP detected (%s Gbps).\n", |
---|
804 | 1167 | qla2x00_get_link_speed_str(ha, ha->link_data_rate)); |
---|
805 | 1168 | |
---|
| 1169 | + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
---|
| 1170 | + if (mb[2] & BIT_0) |
---|
| 1171 | + ql_log(ql_log_info, vha, 0x11a0, |
---|
| 1172 | + "FEC=enabled (link up).\n"); |
---|
| 1173 | + } |
---|
| 1174 | + |
---|
806 | 1175 | vha->flags.management_server_logged_in = 0; |
---|
807 | 1176 | qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, ha->link_data_rate); |
---|
808 | 1177 | |
---|
809 | | - if (AUTO_DETECT_SFP_SUPPORT(vha)) { |
---|
810 | | - set_bit(DETECT_SFP_CHANGE, &vha->dpc_flags); |
---|
811 | | - qla2xxx_wake_dpc(vha); |
---|
812 | | - } |
---|
813 | 1178 | break; |
---|
814 | 1179 | |
---|
815 | 1180 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
---|
.. | .. |
---|
818 | 1183 | ha->current_topology = 0; |
---|
819 | 1184 | |
---|
820 | 1185 | mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha)) |
---|
821 | | - ? RD_REG_WORD(®24->mailbox4) : 0; |
---|
822 | | - mbx = (IS_P3P_TYPE(ha)) ? RD_REG_WORD(®82->mailbox_out[4]) |
---|
| 1186 | + ? rd_reg_word(®24->mailbox4) : 0; |
---|
| 1187 | + mbx = (IS_P3P_TYPE(ha)) ? rd_reg_word(®82->mailbox_out[4]) |
---|
823 | 1188 | : mbx; |
---|
824 | 1189 | ql_log(ql_log_info, vha, 0x500b, |
---|
825 | 1190 | "LOOP DOWN detected (%x %x %x %x).\n", |
---|
.. | .. |
---|
834 | 1199 | * Restore for Physical Port only |
---|
835 | 1200 | */ |
---|
836 | 1201 | if (!vha->vp_idx) { |
---|
837 | | - if (ha->flags.fawwpn_enabled) { |
---|
838 | | - void *wwpn = ha->init_cb->port_name; |
---|
839 | | - memcpy(vha->port_name, wwpn, WWN_SIZE); |
---|
| 1202 | + if (ha->flags.fawwpn_enabled && |
---|
| 1203 | + (ha->current_topology == ISP_CFG_F)) { |
---|
| 1204 | + memcpy(vha->port_name, ha->port_name, WWN_SIZE); |
---|
840 | 1205 | fc_host_port_name(vha->host) = |
---|
841 | 1206 | wwn_to_u64(vha->port_name); |
---|
842 | 1207 | ql_dbg(ql_dbg_init + ql_dbg_verbose, |
---|
.. | .. |
---|
849 | 1214 | } |
---|
850 | 1215 | |
---|
851 | 1216 | vha->device_flags |= DFLG_NO_CABLE; |
---|
852 | | - qla2x00_mark_all_devices_lost(vha, 1); |
---|
| 1217 | + qla2x00_mark_all_devices_lost(vha); |
---|
853 | 1218 | } |
---|
854 | 1219 | |
---|
855 | 1220 | if (vha->vp_idx) { |
---|
.. | .. |
---|
869 | 1234 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
---|
870 | 1235 | atomic_set(&vha->loop_state, LOOP_DOWN); |
---|
871 | 1236 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
---|
872 | | - qla2x00_mark_all_devices_lost(vha, 1); |
---|
| 1237 | + qla2x00_mark_all_devices_lost(vha); |
---|
873 | 1238 | } |
---|
874 | 1239 | |
---|
875 | 1240 | if (vha->vp_idx) { |
---|
.. | .. |
---|
912 | 1277 | atomic_set(&vha->loop_down_timer, |
---|
913 | 1278 | LOOP_DOWN_TIME); |
---|
914 | 1279 | if (!N2N_TOPO(ha)) |
---|
915 | | - qla2x00_mark_all_devices_lost(vha, 1); |
---|
| 1280 | + qla2x00_mark_all_devices_lost(vha); |
---|
916 | 1281 | } |
---|
917 | 1282 | |
---|
918 | 1283 | if (vha->vp_idx) { |
---|
.. | .. |
---|
941 | 1306 | if (!atomic_read(&vha->loop_down_timer)) |
---|
942 | 1307 | atomic_set(&vha->loop_down_timer, |
---|
943 | 1308 | LOOP_DOWN_TIME); |
---|
944 | | - qla2x00_mark_all_devices_lost(vha, 1); |
---|
| 1309 | + qla2x00_mark_all_devices_lost(vha); |
---|
945 | 1310 | } |
---|
946 | 1311 | |
---|
947 | 1312 | if (vha->vp_idx) { |
---|
.. | .. |
---|
1010 | 1375 | "Marking port lost loopid=%04x portid=%06x.\n", |
---|
1011 | 1376 | fcport->loop_id, fcport->d_id.b24); |
---|
1012 | 1377 | if (qla_ini_mode_enabled(vha)) { |
---|
1013 | | - qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); |
---|
1014 | 1378 | fcport->logout_on_delete = 0; |
---|
1015 | 1379 | qlt_schedule_sess_for_deletion(fcport); |
---|
1016 | 1380 | } |
---|
.. | .. |
---|
1022 | 1386 | atomic_set(&vha->loop_down_timer, |
---|
1023 | 1387 | LOOP_DOWN_TIME); |
---|
1024 | 1388 | vha->device_flags |= DFLG_NO_CABLE; |
---|
1025 | | - qla2x00_mark_all_devices_lost(vha, 1); |
---|
| 1389 | + qla2x00_mark_all_devices_lost(vha); |
---|
1026 | 1390 | } |
---|
1027 | 1391 | |
---|
1028 | 1392 | if (vha->vp_idx) { |
---|
1029 | 1393 | atomic_set(&vha->vp_state, VP_FAILED); |
---|
1030 | 1394 | fc_vport_set_state(vha->fc_vport, |
---|
1031 | 1395 | FC_VPORT_FAILED); |
---|
1032 | | - qla2x00_mark_all_devices_lost(vha, 1); |
---|
| 1396 | + qla2x00_mark_all_devices_lost(vha); |
---|
1033 | 1397 | } |
---|
1034 | 1398 | |
---|
1035 | 1399 | vha->flags.management_server_logged_in = 0; |
---|
.. | .. |
---|
1102 | 1466 | struct event_arg ea; |
---|
1103 | 1467 | |
---|
1104 | 1468 | memset(&ea, 0, sizeof(ea)); |
---|
1105 | | - ea.event = FCME_RSCN; |
---|
1106 | 1469 | ea.id.b24 = rscn_entry; |
---|
1107 | 1470 | ea.id.b.rsvd_1 = rscn_entry >> 24; |
---|
1108 | | - qla2x00_fcport_event_handler(vha, &ea); |
---|
| 1471 | + qla2x00_handle_rscn(vha, &ea); |
---|
1109 | 1472 | qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry); |
---|
| 1473 | + } |
---|
| 1474 | + break; |
---|
| 1475 | + case MBA_CONGN_NOTI_RECV: |
---|
| 1476 | + if (!ha->flags.scm_enabled || |
---|
| 1477 | + mb[1] != QLA_CON_PRIMITIVE_RECEIVED) |
---|
| 1478 | + break; |
---|
| 1479 | + |
---|
| 1480 | + if (mb[2] == QLA_CONGESTION_ARB_WARNING) { |
---|
| 1481 | + ql_dbg(ql_dbg_async, vha, 0x509b, |
---|
| 1482 | + "Congestion Warning %04x %04x.\n", mb[1], mb[2]); |
---|
| 1483 | + } else if (mb[2] == QLA_CONGESTION_ARB_ALARM) { |
---|
| 1484 | + ql_log(ql_log_warn, vha, 0x509b, |
---|
| 1485 | + "Congestion Alarm %04x %04x.\n", mb[1], mb[2]); |
---|
1110 | 1486 | } |
---|
1111 | 1487 | break; |
---|
1112 | 1488 | /* case MBA_RIO_RESPONSE: */ |
---|
.. | .. |
---|
1186 | 1562 | break; |
---|
1187 | 1563 | case MBA_IDC_NOTIFY: |
---|
1188 | 1564 | if (IS_QLA8031(vha->hw) || IS_QLA8044(ha)) { |
---|
1189 | | - mb[4] = RD_REG_WORD(®24->mailbox4); |
---|
| 1565 | + mb[4] = rd_reg_word(®24->mailbox4); |
---|
1190 | 1566 | if (((mb[2] & 0x7fff) == MBC_PORT_RESET || |
---|
1191 | 1567 | (mb[2] & 0x7fff) == MBC_SET_PORT_CONFIG) && |
---|
1192 | 1568 | (mb[4] & INTERNAL_LOOPBACK_MASK) != 0) { |
---|
.. | .. |
---|
1200 | 1576 | qla2xxx_wake_dpc(vha); |
---|
1201 | 1577 | } |
---|
1202 | 1578 | } |
---|
1203 | | - /* fall through */ |
---|
| 1579 | + fallthrough; |
---|
1204 | 1580 | case MBA_IDC_COMPLETE: |
---|
1205 | 1581 | if (ha->notify_lb_portup_comp && !vha->vp_idx) |
---|
1206 | 1582 | complete(&ha->lb_portup_comp); |
---|
1207 | | - /* Fallthru */ |
---|
| 1583 | + fallthrough; |
---|
1208 | 1584 | case MBA_IDC_TIME_EXT: |
---|
1209 | 1585 | if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || |
---|
1210 | 1586 | IS_QLA8044(ha)) |
---|
.. | .. |
---|
1212 | 1588 | break; |
---|
1213 | 1589 | |
---|
1214 | 1590 | case MBA_IDC_AEN: |
---|
1215 | | - mb[4] = RD_REG_WORD(®24->mailbox4); |
---|
1216 | | - mb[5] = RD_REG_WORD(®24->mailbox5); |
---|
1217 | | - mb[6] = RD_REG_WORD(®24->mailbox6); |
---|
1218 | | - mb[7] = RD_REG_WORD(®24->mailbox7); |
---|
1219 | | - qla83xx_handle_8200_aen(vha, mb); |
---|
| 1591 | + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
---|
| 1592 | + qla27xx_handle_8200_aen(vha, mb); |
---|
| 1593 | + } else if (IS_QLA83XX(ha)) { |
---|
| 1594 | + mb[4] = rd_reg_word(®24->mailbox4); |
---|
| 1595 | + mb[5] = rd_reg_word(®24->mailbox5); |
---|
| 1596 | + mb[6] = rd_reg_word(®24->mailbox6); |
---|
| 1597 | + mb[7] = rd_reg_word(®24->mailbox7); |
---|
| 1598 | + qla83xx_handle_8200_aen(vha, mb); |
---|
| 1599 | + } else { |
---|
| 1600 | + ql_dbg(ql_dbg_async, vha, 0x5052, |
---|
| 1601 | + "skip Heartbeat processing mb0-3=[0x%04x] [0x%04x] [0x%04x] [0x%04x]\n", |
---|
| 1602 | + mb[0], mb[1], mb[2], mb[3]); |
---|
| 1603 | + } |
---|
1220 | 1604 | break; |
---|
1221 | 1605 | |
---|
1222 | 1606 | case MBA_DPORT_DIAGNOSTICS: |
---|
1223 | 1607 | ql_dbg(ql_dbg_async, vha, 0x5052, |
---|
1224 | | - "D-Port Diagnostics: %04x result=%s\n", |
---|
1225 | | - mb[0], |
---|
1226 | | - mb[1] == 0 ? "start" : |
---|
1227 | | - mb[1] == 1 ? "done (pass)" : |
---|
1228 | | - mb[1] == 2 ? "done (error)" : "other"); |
---|
| 1608 | + "D-Port Diagnostics: %04x %04x %04x %04x\n", |
---|
| 1609 | + mb[0], mb[1], mb[2], mb[3]); |
---|
| 1610 | + memcpy(vha->dport_data, mb, sizeof(vha->dport_data)); |
---|
| 1611 | + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
---|
| 1612 | + static char *results[] = { |
---|
| 1613 | + "start", "done(pass)", "done(error)", "undefined" }; |
---|
| 1614 | + static char *types[] = { |
---|
| 1615 | + "none", "dynamic", "static", "other" }; |
---|
| 1616 | + uint result = mb[1] >> 0 & 0x3; |
---|
| 1617 | + uint type = mb[1] >> 6 & 0x3; |
---|
| 1618 | + uint sw = mb[1] >> 15 & 0x1; |
---|
| 1619 | + ql_dbg(ql_dbg_async, vha, 0x5052, |
---|
| 1620 | + "D-Port Diagnostics: result=%s type=%s [sw=%u]\n", |
---|
| 1621 | + results[result], types[type], sw); |
---|
| 1622 | + if (result == 2) { |
---|
| 1623 | + static char *reasons[] = { |
---|
| 1624 | + "reserved", "unexpected reject", |
---|
| 1625 | + "unexpected phase", "retry exceeded", |
---|
| 1626 | + "timed out", "not supported", |
---|
| 1627 | + "user stopped" }; |
---|
| 1628 | + uint reason = mb[2] >> 0 & 0xf; |
---|
| 1629 | + uint phase = mb[2] >> 12 & 0xf; |
---|
| 1630 | + ql_dbg(ql_dbg_async, vha, 0x5052, |
---|
| 1631 | + "D-Port Diagnostics: reason=%s phase=%u \n", |
---|
| 1632 | + reason < 7 ? reasons[reason] : "other", |
---|
| 1633 | + phase >> 1); |
---|
| 1634 | + } |
---|
| 1635 | + } |
---|
1229 | 1636 | break; |
---|
1230 | 1637 | |
---|
1231 | 1638 | case MBA_TEMPERATURE_ALERT: |
---|
1232 | 1639 | ql_dbg(ql_dbg_async, vha, 0x505e, |
---|
1233 | 1640 | "TEMPERATURE ALERT: %04x %04x %04x\n", mb[1], mb[2], mb[3]); |
---|
1234 | | - if (mb[1] == 0x12) |
---|
1235 | | - schedule_work(&ha->board_disable); |
---|
1236 | 1641 | break; |
---|
1237 | 1642 | |
---|
1238 | 1643 | case MBA_TRANS_INSERT: |
---|
1239 | 1644 | ql_dbg(ql_dbg_async, vha, 0x5091, |
---|
1240 | 1645 | "Transceiver Insertion: %04x\n", mb[1]); |
---|
| 1646 | + set_bit(DETECT_SFP_CHANGE, &vha->dpc_flags); |
---|
| 1647 | + break; |
---|
| 1648 | + |
---|
| 1649 | + case MBA_TRANS_REMOVE: |
---|
| 1650 | + ql_dbg(ql_dbg_async, vha, 0x5091, "Transceiver Removal\n"); |
---|
1241 | 1651 | break; |
---|
1242 | 1652 | |
---|
1243 | 1653 | default: |
---|
.. | .. |
---|
1300 | 1710 | { |
---|
1301 | 1711 | struct qla_hw_data *ha = vha->hw; |
---|
1302 | 1712 | sts_entry_t *pkt = iocb; |
---|
1303 | | - srb_t *sp = NULL; |
---|
| 1713 | + srb_t *sp; |
---|
1304 | 1714 | uint16_t index; |
---|
1305 | 1715 | |
---|
1306 | 1716 | index = LSW(pkt->handle); |
---|
1307 | 1717 | if (index >= req->num_outstanding_cmds) { |
---|
1308 | 1718 | ql_log(ql_log_warn, vha, 0x5031, |
---|
1309 | | - "Invalid command index (%x) type %8ph.\n", |
---|
1310 | | - index, iocb); |
---|
| 1719 | + "%s: Invalid command index (%x) type %8ph.\n", |
---|
| 1720 | + func, index, iocb); |
---|
1311 | 1721 | if (IS_P3P_TYPE(ha)) |
---|
1312 | 1722 | set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); |
---|
1313 | 1723 | else |
---|
1314 | 1724 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
1315 | | - goto done; |
---|
| 1725 | + return NULL; |
---|
1316 | 1726 | } |
---|
1317 | 1727 | sp = req->outstanding_cmds[index]; |
---|
1318 | 1728 | if (!sp) { |
---|
1319 | 1729 | ql_log(ql_log_warn, vha, 0x5032, |
---|
1320 | | - "Invalid completion handle (%x) -- timed-out.\n", index); |
---|
1321 | | - return sp; |
---|
| 1730 | + "%s: Invalid completion handle (%x) -- timed-out.\n", |
---|
| 1731 | + func, index); |
---|
| 1732 | + return NULL; |
---|
1322 | 1733 | } |
---|
1323 | 1734 | if (sp->handle != index) { |
---|
1324 | 1735 | ql_log(ql_log_warn, vha, 0x5033, |
---|
1325 | | - "SRB handle (%x) mismatch %x.\n", sp->handle, index); |
---|
| 1736 | + "%s: SRB handle (%x) mismatch %x.\n", func, |
---|
| 1737 | + sp->handle, index); |
---|
1326 | 1738 | return NULL; |
---|
1327 | 1739 | } |
---|
1328 | 1740 | |
---|
1329 | 1741 | req->outstanding_cmds[index] = NULL; |
---|
1330 | | - |
---|
1331 | | -done: |
---|
1332 | 1742 | return sp; |
---|
1333 | 1743 | } |
---|
1334 | 1744 | |
---|
.. | .. |
---|
1367 | 1777 | le16_to_cpu(mbx->status_flags)); |
---|
1368 | 1778 | |
---|
1369 | 1779 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5029, |
---|
1370 | | - (uint8_t *)mbx, sizeof(*mbx)); |
---|
| 1780 | + mbx, sizeof(*mbx)); |
---|
1371 | 1781 | |
---|
1372 | 1782 | goto logio_done; |
---|
1373 | 1783 | } |
---|
.. | .. |
---|
1423 | 1833 | struct mbx_24xx_entry *pkt) |
---|
1424 | 1834 | { |
---|
1425 | 1835 | const char func[] = "MBX-IOCB2"; |
---|
| 1836 | + struct qla_hw_data *ha = vha->hw; |
---|
1426 | 1837 | srb_t *sp; |
---|
1427 | 1838 | struct srb_iocb *si; |
---|
1428 | 1839 | u16 sz, i; |
---|
.. | .. |
---|
1432 | 1843 | if (!sp) |
---|
1433 | 1844 | return; |
---|
1434 | 1845 | |
---|
| 1846 | + if (sp->type == SRB_SCSI_CMD || |
---|
| 1847 | + sp->type == SRB_NVME_CMD || |
---|
| 1848 | + sp->type == SRB_TM_CMD) { |
---|
| 1849 | + ql_log(ql_log_warn, vha, 0x509d, |
---|
| 1850 | + "Inconsistent event entry type %d\n", sp->type); |
---|
| 1851 | + if (IS_P3P_TYPE(ha)) |
---|
| 1852 | + set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); |
---|
| 1853 | + else |
---|
| 1854 | + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
| 1855 | + return; |
---|
| 1856 | + } |
---|
| 1857 | + |
---|
1435 | 1858 | si = &sp->u.iocb_cmd; |
---|
1436 | 1859 | sz = min(ARRAY_SIZE(pkt->mb), ARRAY_SIZE(sp->u.iocb_cmd.u.mbx.in_mb)); |
---|
1437 | 1860 | |
---|
1438 | 1861 | for (i = 0; i < sz; i++) |
---|
1439 | | - si->u.mbx.in_mb[i] = le16_to_cpu(pkt->mb[i]); |
---|
| 1862 | + si->u.mbx.in_mb[i] = pkt->mb[i]; |
---|
1440 | 1863 | |
---|
1441 | 1864 | res = (si->u.mbx.in_mb[0] & MBS_MASK); |
---|
1442 | 1865 | |
---|
.. | .. |
---|
1497 | 1920 | if (comp_status == CS_DATA_UNDERRUN) { |
---|
1498 | 1921 | res = DID_OK << 16; |
---|
1499 | 1922 | bsg_reply->reply_payload_rcv_len = |
---|
1500 | | - le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len); |
---|
| 1923 | + le16_to_cpu(pkt->rsp_info_len); |
---|
1501 | 1924 | |
---|
1502 | 1925 | ql_log(ql_log_warn, vha, 0x5048, |
---|
1503 | 1926 | "CT pass-through-%s error comp_status=0x%x total_byte=0x%x.\n", |
---|
.. | .. |
---|
1511 | 1934 | bsg_reply->reply_payload_rcv_len = 0; |
---|
1512 | 1935 | } |
---|
1513 | 1936 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035, |
---|
1514 | | - (uint8_t *)pkt, sizeof(*pkt)); |
---|
| 1937 | + pkt, sizeof(*pkt)); |
---|
1515 | 1938 | } else { |
---|
1516 | 1939 | res = DID_OK << 16; |
---|
1517 | 1940 | bsg_reply->reply_payload_rcv_len = |
---|
.. | .. |
---|
1537 | 1960 | qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, |
---|
1538 | 1961 | struct sts_entry_24xx *pkt, int iocb_type) |
---|
1539 | 1962 | { |
---|
| 1963 | + struct els_sts_entry_24xx *ese = (struct els_sts_entry_24xx *)pkt; |
---|
1540 | 1964 | const char func[] = "ELS_CT_IOCB"; |
---|
1541 | 1965 | const char *type; |
---|
1542 | 1966 | srb_t *sp; |
---|
.. | .. |
---|
1586 | 2010 | } |
---|
1587 | 2011 | |
---|
1588 | 2012 | comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status); |
---|
1589 | | - fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1); |
---|
1590 | | - fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2); |
---|
| 2013 | + fw_status[1] = le32_to_cpu(ese->error_subcode_1); |
---|
| 2014 | + fw_status[2] = le32_to_cpu(ese->error_subcode_2); |
---|
1591 | 2015 | |
---|
1592 | 2016 | if (iocb_type == ELS_IOCB_TYPE) { |
---|
1593 | 2017 | els = &sp->u.iocb_cmd; |
---|
1594 | | - els->u.els_plogi.fw_status[0] = fw_status[0]; |
---|
1595 | | - els->u.els_plogi.fw_status[1] = fw_status[1]; |
---|
1596 | | - els->u.els_plogi.fw_status[2] = fw_status[2]; |
---|
1597 | | - els->u.els_plogi.comp_status = fw_status[0]; |
---|
| 2018 | + els->u.els_plogi.fw_status[0] = cpu_to_le32(fw_status[0]); |
---|
| 2019 | + els->u.els_plogi.fw_status[1] = cpu_to_le32(fw_status[1]); |
---|
| 2020 | + els->u.els_plogi.fw_status[2] = cpu_to_le32(fw_status[2]); |
---|
| 2021 | + els->u.els_plogi.comp_status = cpu_to_le16(fw_status[0]); |
---|
1598 | 2022 | if (comp_status == CS_COMPLETE) { |
---|
1599 | 2023 | res = DID_OK << 16; |
---|
1600 | 2024 | } else { |
---|
1601 | 2025 | if (comp_status == CS_DATA_UNDERRUN) { |
---|
1602 | 2026 | res = DID_OK << 16; |
---|
1603 | | - els->u.els_plogi.len = |
---|
1604 | | - le16_to_cpu(((struct els_sts_entry_24xx *) |
---|
1605 | | - pkt)->total_byte_count); |
---|
| 2027 | + els->u.els_plogi.len = cpu_to_le16(le32_to_cpu( |
---|
| 2028 | + ese->total_byte_count)); |
---|
1606 | 2029 | } else { |
---|
1607 | 2030 | els->u.els_plogi.len = 0; |
---|
1608 | 2031 | res = DID_ERROR << 16; |
---|
1609 | 2032 | } |
---|
1610 | 2033 | } |
---|
1611 | | - ql_log(ql_log_info, vha, 0x503f, |
---|
1612 | | - "ELS IOCB Done -%s error hdl=%x comp_status=0x%x error subcode 1=0x%x error subcode 2=0x%x total_byte=0x%x\n", |
---|
| 2034 | + ql_dbg(ql_dbg_disc, vha, 0x503f, |
---|
| 2035 | + "ELS IOCB Done -%s hdl=%x comp_status=0x%x error subcode 1=0x%x error subcode 2=0x%x total_byte=0x%x\n", |
---|
1613 | 2036 | type, sp->handle, comp_status, fw_status[1], fw_status[2], |
---|
1614 | | - le16_to_cpu(((struct els_sts_entry_24xx *) |
---|
1615 | | - pkt)->total_byte_count)); |
---|
| 2037 | + le32_to_cpu(ese->total_byte_count)); |
---|
1616 | 2038 | goto els_ct_done; |
---|
1617 | 2039 | } |
---|
1618 | 2040 | |
---|
.. | .. |
---|
1628 | 2050 | if (comp_status == CS_DATA_UNDERRUN) { |
---|
1629 | 2051 | res = DID_OK << 16; |
---|
1630 | 2052 | bsg_reply->reply_payload_rcv_len = |
---|
1631 | | - le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->total_byte_count); |
---|
| 2053 | + le32_to_cpu(ese->total_byte_count); |
---|
1632 | 2054 | |
---|
1633 | 2055 | ql_dbg(ql_dbg_user, vha, 0x503f, |
---|
1634 | 2056 | "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x " |
---|
1635 | 2057 | "error subcode 1=0x%x error subcode 2=0x%x total_byte = 0x%x.\n", |
---|
1636 | 2058 | type, sp->handle, comp_status, fw_status[1], fw_status[2], |
---|
1637 | | - le16_to_cpu(((struct els_sts_entry_24xx *) |
---|
1638 | | - pkt)->total_byte_count)); |
---|
| 2059 | + le32_to_cpu(ese->total_byte_count)); |
---|
1639 | 2060 | } else { |
---|
1640 | 2061 | ql_dbg(ql_dbg_user, vha, 0x5040, |
---|
1641 | 2062 | "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x " |
---|
1642 | 2063 | "error subcode 1=0x%x error subcode 2=0x%x.\n", |
---|
1643 | 2064 | type, sp->handle, comp_status, |
---|
1644 | | - le16_to_cpu(((struct els_sts_entry_24xx *) |
---|
1645 | | - pkt)->error_subcode_1), |
---|
1646 | | - le16_to_cpu(((struct els_sts_entry_24xx *) |
---|
1647 | | - pkt)->error_subcode_2)); |
---|
| 2065 | + le32_to_cpu(ese->error_subcode_1), |
---|
| 2066 | + le32_to_cpu(ese->error_subcode_2)); |
---|
1648 | 2067 | res = DID_ERROR << 16; |
---|
1649 | 2068 | bsg_reply->reply_payload_rcv_len = 0; |
---|
1650 | 2069 | } |
---|
1651 | 2070 | memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), |
---|
1652 | 2071 | fw_status, sizeof(fw_status)); |
---|
1653 | 2072 | ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056, |
---|
1654 | | - (uint8_t *)pkt, sizeof(*pkt)); |
---|
| 2073 | + pkt, sizeof(*pkt)); |
---|
1655 | 2074 | } |
---|
1656 | 2075 | else { |
---|
1657 | 2076 | res = DID_OK << 16; |
---|
.. | .. |
---|
1695 | 2114 | fcport->d_id.b.area, fcport->d_id.b.al_pa, |
---|
1696 | 2115 | logio->entry_status); |
---|
1697 | 2116 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, |
---|
1698 | | - (uint8_t *)logio, sizeof(*logio)); |
---|
| 2117 | + logio, sizeof(*logio)); |
---|
1699 | 2118 | |
---|
1700 | 2119 | goto logio_done; |
---|
1701 | 2120 | } |
---|
1702 | 2121 | |
---|
1703 | 2122 | if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) { |
---|
1704 | | - ql_dbg(ql_dbg_async, fcport->vha, 0x5036, |
---|
1705 | | - "Async-%s complete - %8phC hdl=%x portid=%02x%02x%02x " |
---|
1706 | | - "iop0=%x.\n", type, fcport->port_name, sp->handle, |
---|
1707 | | - fcport->d_id.b.domain, |
---|
1708 | | - fcport->d_id.b.area, fcport->d_id.b.al_pa, |
---|
| 2123 | + ql_dbg(ql_dbg_async, sp->vha, 0x5036, |
---|
| 2124 | + "Async-%s complete: handle=%x pid=%06x wwpn=%8phC iop0=%x\n", |
---|
| 2125 | + type, sp->handle, fcport->d_id.b24, fcport->port_name, |
---|
1709 | 2126 | le32_to_cpu(logio->io_parameter[0])); |
---|
1710 | 2127 | |
---|
1711 | 2128 | vha->hw->exch_starvation = 0; |
---|
1712 | 2129 | data[0] = MBS_COMMAND_COMPLETE; |
---|
| 2130 | + |
---|
| 2131 | + if (sp->type == SRB_PRLI_CMD) { |
---|
| 2132 | + lio->u.logio.iop[0] = |
---|
| 2133 | + le32_to_cpu(logio->io_parameter[0]); |
---|
| 2134 | + lio->u.logio.iop[1] = |
---|
| 2135 | + le32_to_cpu(logio->io_parameter[1]); |
---|
| 2136 | + goto logio_done; |
---|
| 2137 | + } |
---|
| 2138 | + |
---|
1713 | 2139 | if (sp->type != SRB_LOGIN_CMD) |
---|
1714 | 2140 | goto logio_done; |
---|
1715 | 2141 | |
---|
.. | .. |
---|
1769 | 2195 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
1770 | 2196 | qla2xxx_wake_dpc(vha); |
---|
1771 | 2197 | } |
---|
1772 | | - /* fall through */ |
---|
| 2198 | + fallthrough; |
---|
1773 | 2199 | default: |
---|
1774 | 2200 | data[0] = MBS_COMMAND_ERROR; |
---|
1775 | 2201 | break; |
---|
1776 | 2202 | } |
---|
1777 | 2203 | |
---|
1778 | | - ql_dbg(ql_dbg_async, fcport->vha, 0x5037, |
---|
1779 | | - "Async-%s failed - %8phC hdl=%x portid=%02x%02x%02x comp=%x " |
---|
1780 | | - "iop0=%x iop1=%x.\n", type, fcport->port_name, |
---|
1781 | | - sp->handle, fcport->d_id.b.domain, |
---|
1782 | | - fcport->d_id.b.area, fcport->d_id.b.al_pa, |
---|
| 2204 | + ql_dbg(ql_dbg_async, sp->vha, 0x5037, |
---|
| 2205 | + "Async-%s failed: handle=%x pid=%06x wwpn=%8phC comp_status=%x iop0=%x iop1=%x\n", |
---|
| 2206 | + type, sp->handle, fcport->d_id.b24, fcport->port_name, |
---|
1783 | 2207 | le16_to_cpu(logio->comp_status), |
---|
1784 | 2208 | le32_to_cpu(logio->io_parameter[0]), |
---|
1785 | 2209 | le32_to_cpu(logio->io_parameter[1])); |
---|
.. | .. |
---|
1819 | 2243 | iocb->u.tmf.data = QLA_FUNCTION_FAILED; |
---|
1820 | 2244 | } else if ((le16_to_cpu(sts->scsi_status) & |
---|
1821 | 2245 | SS_RESPONSE_INFO_LEN_VALID)) { |
---|
| 2246 | + host_to_fcp_swap(sts->data, sizeof(sts->data)); |
---|
1822 | 2247 | if (le32_to_cpu(sts->rsp_data_len) < 4) { |
---|
1823 | 2248 | ql_log(ql_log_warn, fcport->vha, 0x503b, |
---|
1824 | 2249 | "Async-%s error - hdl=%x not enough response(%d).\n", |
---|
.. | .. |
---|
1832 | 2257 | } |
---|
1833 | 2258 | |
---|
1834 | 2259 | if (iocb->u.tmf.data != QLA_SUCCESS) |
---|
1835 | | - ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5055, |
---|
1836 | | - (uint8_t *)sts, sizeof(*sts)); |
---|
| 2260 | + ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, sp->vha, 0x5055, |
---|
| 2261 | + sts, sizeof(*sts)); |
---|
1837 | 2262 | |
---|
1838 | 2263 | sp->done(sp, 0); |
---|
1839 | 2264 | } |
---|
.. | .. |
---|
1846 | 2271 | struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; |
---|
1847 | 2272 | uint16_t state_flags; |
---|
1848 | 2273 | struct nvmefc_fcp_req *fd; |
---|
1849 | | - uint16_t ret = 0; |
---|
| 2274 | + uint16_t ret = QLA_SUCCESS; |
---|
| 2275 | + __le16 comp_status = sts->comp_status; |
---|
| 2276 | + int logit = 0; |
---|
1850 | 2277 | |
---|
1851 | 2278 | iocb = &sp->u.iocb_cmd; |
---|
1852 | 2279 | fcport = sp->fcport; |
---|
1853 | | - iocb->u.nvme.comp_status = le16_to_cpu(sts->comp_status); |
---|
| 2280 | + iocb->u.nvme.comp_status = comp_status; |
---|
1854 | 2281 | state_flags = le16_to_cpu(sts->state_flags); |
---|
1855 | 2282 | fd = iocb->u.nvme.desc; |
---|
1856 | 2283 | |
---|
1857 | 2284 | if (unlikely(iocb->u.nvme.aen_op)) |
---|
1858 | 2285 | atomic_dec(&sp->vha->hw->nvme_active_aen_cnt); |
---|
| 2286 | + |
---|
| 2287 | + if (unlikely(comp_status != CS_COMPLETE)) |
---|
| 2288 | + logit = 1; |
---|
| 2289 | + |
---|
| 2290 | + fd->transferred_length = fd->payload_length - |
---|
| 2291 | + le32_to_cpu(sts->residual_len); |
---|
1859 | 2292 | |
---|
1860 | 2293 | /* |
---|
1861 | 2294 | * State flags: Bit 6 and 0. |
---|
.. | .. |
---|
1867 | 2300 | */ |
---|
1868 | 2301 | if (!(state_flags & (SF_FCP_RSP_DMA | SF_NVME_ERSP))) { |
---|
1869 | 2302 | iocb->u.nvme.rsp_pyld_len = 0; |
---|
| 2303 | + } else if ((state_flags & (SF_FCP_RSP_DMA | SF_NVME_ERSP)) == |
---|
| 2304 | + (SF_FCP_RSP_DMA | SF_NVME_ERSP)) { |
---|
| 2305 | + /* Response already DMA'd to fd->rspaddr. */ |
---|
| 2306 | + iocb->u.nvme.rsp_pyld_len = sts->nvme_rsp_pyld_len; |
---|
1870 | 2307 | } else if ((state_flags & SF_FCP_RSP_DMA)) { |
---|
1871 | | - iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len); |
---|
| 2308 | + /* |
---|
| 2309 | + * Non-zero value in first 12 bytes of NVMe_RSP IU, treat this |
---|
| 2310 | + * as an error. |
---|
| 2311 | + */ |
---|
| 2312 | + iocb->u.nvme.rsp_pyld_len = 0; |
---|
| 2313 | + fd->transferred_length = 0; |
---|
| 2314 | + ql_dbg(ql_dbg_io, fcport->vha, 0x307a, |
---|
| 2315 | + "Unexpected values in NVMe_RSP IU.\n"); |
---|
| 2316 | + logit = 1; |
---|
1872 | 2317 | } else if (state_flags & SF_NVME_ERSP) { |
---|
1873 | 2318 | uint32_t *inbuf, *outbuf; |
---|
1874 | 2319 | uint16_t iter; |
---|
1875 | 2320 | |
---|
1876 | 2321 | inbuf = (uint32_t *)&sts->nvme_ersp_data; |
---|
1877 | 2322 | outbuf = (uint32_t *)fd->rspaddr; |
---|
1878 | | - iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len); |
---|
1879 | | - if (unlikely(iocb->u.nvme.rsp_pyld_len > |
---|
| 2323 | + iocb->u.nvme.rsp_pyld_len = sts->nvme_rsp_pyld_len; |
---|
| 2324 | + if (unlikely(le16_to_cpu(iocb->u.nvme.rsp_pyld_len) > |
---|
1880 | 2325 | sizeof(struct nvme_fc_ersp_iu))) { |
---|
1881 | 2326 | if (ql_mask_match(ql_dbg_io)) { |
---|
1882 | 2327 | WARN_ONCE(1, "Unexpected response payload length %u.\n", |
---|
.. | .. |
---|
1886 | 2331 | iocb->u.nvme.rsp_pyld_len); |
---|
1887 | 2332 | } |
---|
1888 | 2333 | iocb->u.nvme.rsp_pyld_len = |
---|
1889 | | - sizeof(struct nvme_fc_ersp_iu); |
---|
| 2334 | + cpu_to_le16(sizeof(struct nvme_fc_ersp_iu)); |
---|
1890 | 2335 | } |
---|
1891 | | - iter = iocb->u.nvme.rsp_pyld_len >> 2; |
---|
| 2336 | + iter = le16_to_cpu(iocb->u.nvme.rsp_pyld_len) >> 2; |
---|
1892 | 2337 | for (; iter; iter--) |
---|
1893 | 2338 | *outbuf++ = swab32(*inbuf++); |
---|
1894 | | - } else { /* unhandled case */ |
---|
1895 | | - ql_log(ql_log_warn, fcport->vha, 0x503a, |
---|
1896 | | - "NVME-%s error. Unhandled state_flags of %x\n", |
---|
1897 | | - sp->name, state_flags); |
---|
1898 | 2339 | } |
---|
1899 | 2340 | |
---|
1900 | | - fd->transferred_length = fd->payload_length - |
---|
1901 | | - le32_to_cpu(sts->residual_len); |
---|
| 2341 | + if (state_flags & SF_NVME_ERSP) { |
---|
| 2342 | + struct nvme_fc_ersp_iu *rsp_iu = fd->rspaddr; |
---|
| 2343 | + u32 tgt_xfer_len; |
---|
1902 | 2344 | |
---|
1903 | | - switch (le16_to_cpu(sts->comp_status)) { |
---|
| 2345 | + tgt_xfer_len = be32_to_cpu(rsp_iu->xfrd_len); |
---|
| 2346 | + if (fd->transferred_length != tgt_xfer_len) { |
---|
| 2347 | + ql_dbg(ql_dbg_io, fcport->vha, 0x3079, |
---|
| 2348 | + "Dropped frame(s) detected (sent/rcvd=%u/%u).\n", |
---|
| 2349 | + tgt_xfer_len, fd->transferred_length); |
---|
| 2350 | + logit = 1; |
---|
| 2351 | + } else if (le16_to_cpu(comp_status) == CS_DATA_UNDERRUN) { |
---|
| 2352 | + /* |
---|
| 2353 | + * Do not log if this is just an underflow and there |
---|
| 2354 | + * is no data loss. |
---|
| 2355 | + */ |
---|
| 2356 | + logit = 0; |
---|
| 2357 | + } |
---|
| 2358 | + } |
---|
| 2359 | + |
---|
| 2360 | + if (unlikely(logit)) |
---|
| 2361 | + ql_log(ql_log_warn, fcport->vha, 0x5060, |
---|
| 2362 | + "NVME-%s ERR Handling - hdl=%x status(%x) tr_len:%x resid=%x ox_id=%x\n", |
---|
| 2363 | + sp->name, sp->handle, comp_status, |
---|
| 2364 | + fd->transferred_length, le32_to_cpu(sts->residual_len), |
---|
| 2365 | + sts->ox_id); |
---|
| 2366 | + |
---|
| 2367 | + /* |
---|
| 2368 | + * If transport error then Failure (HBA rejects request) |
---|
| 2369 | + * otherwise transport will handle. |
---|
| 2370 | + */ |
---|
| 2371 | + switch (le16_to_cpu(comp_status)) { |
---|
1904 | 2372 | case CS_COMPLETE: |
---|
1905 | | - ret = QLA_SUCCESS; |
---|
1906 | 2373 | break; |
---|
1907 | | - case CS_ABORTED: |
---|
| 2374 | + |
---|
1908 | 2375 | case CS_RESET: |
---|
1909 | 2376 | case CS_PORT_UNAVAILABLE: |
---|
1910 | 2377 | case CS_PORT_LOGGED_OUT: |
---|
| 2378 | + fcport->nvme_flag |= NVME_FLAG_RESETTING; |
---|
| 2379 | + fallthrough; |
---|
| 2380 | + case CS_ABORTED: |
---|
1911 | 2381 | case CS_PORT_BUSY: |
---|
1912 | | - ql_log(ql_log_warn, fcport->vha, 0x5060, |
---|
1913 | | - "NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x ox_id=%x\n", |
---|
1914 | | - sp->name, sp->handle, sts->comp_status, |
---|
1915 | | - le32_to_cpu(sts->residual_len), sts->ox_id); |
---|
1916 | 2382 | fd->transferred_length = 0; |
---|
1917 | 2383 | iocb->u.nvme.rsp_pyld_len = 0; |
---|
1918 | 2384 | ret = QLA_ABORTED; |
---|
1919 | 2385 | break; |
---|
| 2386 | + case CS_DATA_UNDERRUN: |
---|
| 2387 | + break; |
---|
1920 | 2388 | default: |
---|
1921 | | - ql_log(ql_log_warn, fcport->vha, 0x5060, |
---|
1922 | | - "NVME-%s error - hdl=%x completion status(%x) resid=%x ox_id=%x\n", |
---|
1923 | | - sp->name, sp->handle, sts->comp_status, |
---|
1924 | | - le32_to_cpu(sts->residual_len), sts->ox_id); |
---|
1925 | 2389 | ret = QLA_FUNCTION_FAILED; |
---|
1926 | 2390 | break; |
---|
1927 | 2391 | } |
---|
.. | .. |
---|
1959 | 2423 | sp->done(sp, rval); |
---|
1960 | 2424 | } |
---|
1961 | 2425 | |
---|
| 2426 | +/* Process a single response queue entry. */ |
---|
| 2427 | +static void qla2x00_process_response_entry(struct scsi_qla_host *vha, |
---|
| 2428 | + struct rsp_que *rsp, |
---|
| 2429 | + sts_entry_t *pkt) |
---|
| 2430 | +{ |
---|
| 2431 | + sts21_entry_t *sts21_entry; |
---|
| 2432 | + sts22_entry_t *sts22_entry; |
---|
| 2433 | + uint16_t handle_cnt; |
---|
| 2434 | + uint16_t cnt; |
---|
| 2435 | + |
---|
| 2436 | + switch (pkt->entry_type) { |
---|
| 2437 | + case STATUS_TYPE: |
---|
| 2438 | + qla2x00_status_entry(vha, rsp, pkt); |
---|
| 2439 | + break; |
---|
| 2440 | + case STATUS_TYPE_21: |
---|
| 2441 | + sts21_entry = (sts21_entry_t *)pkt; |
---|
| 2442 | + handle_cnt = sts21_entry->handle_count; |
---|
| 2443 | + for (cnt = 0; cnt < handle_cnt; cnt++) |
---|
| 2444 | + qla2x00_process_completed_request(vha, rsp->req, |
---|
| 2445 | + sts21_entry->handle[cnt]); |
---|
| 2446 | + break; |
---|
| 2447 | + case STATUS_TYPE_22: |
---|
| 2448 | + sts22_entry = (sts22_entry_t *)pkt; |
---|
| 2449 | + handle_cnt = sts22_entry->handle_count; |
---|
| 2450 | + for (cnt = 0; cnt < handle_cnt; cnt++) |
---|
| 2451 | + qla2x00_process_completed_request(vha, rsp->req, |
---|
| 2452 | + sts22_entry->handle[cnt]); |
---|
| 2453 | + break; |
---|
| 2454 | + case STATUS_CONT_TYPE: |
---|
| 2455 | + qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt); |
---|
| 2456 | + break; |
---|
| 2457 | + case MBX_IOCB_TYPE: |
---|
| 2458 | + qla2x00_mbx_iocb_entry(vha, rsp->req, (struct mbx_entry *)pkt); |
---|
| 2459 | + break; |
---|
| 2460 | + case CT_IOCB_TYPE: |
---|
| 2461 | + qla2x00_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); |
---|
| 2462 | + break; |
---|
| 2463 | + default: |
---|
| 2464 | + /* Type Not Supported. */ |
---|
| 2465 | + ql_log(ql_log_warn, vha, 0x504a, |
---|
| 2466 | + "Received unknown response pkt type %x entry status=%x.\n", |
---|
| 2467 | + pkt->entry_type, pkt->entry_status); |
---|
| 2468 | + break; |
---|
| 2469 | + } |
---|
| 2470 | +} |
---|
| 2471 | + |
---|
1962 | 2472 | /** |
---|
1963 | 2473 | * qla2x00_process_response_queue() - Process response queue entries. |
---|
1964 | 2474 | * @rsp: response queue |
---|
.. | .. |
---|
1970 | 2480 | struct qla_hw_data *ha = rsp->hw; |
---|
1971 | 2481 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
---|
1972 | 2482 | sts_entry_t *pkt; |
---|
1973 | | - uint16_t handle_cnt; |
---|
1974 | | - uint16_t cnt; |
---|
1975 | 2483 | |
---|
1976 | 2484 | vha = pci_get_drvdata(ha->pdev); |
---|
1977 | 2485 | |
---|
.. | .. |
---|
1996 | 2504 | continue; |
---|
1997 | 2505 | } |
---|
1998 | 2506 | |
---|
1999 | | - switch (pkt->entry_type) { |
---|
2000 | | - case STATUS_TYPE: |
---|
2001 | | - qla2x00_status_entry(vha, rsp, pkt); |
---|
2002 | | - break; |
---|
2003 | | - case STATUS_TYPE_21: |
---|
2004 | | - handle_cnt = ((sts21_entry_t *)pkt)->handle_count; |
---|
2005 | | - for (cnt = 0; cnt < handle_cnt; cnt++) { |
---|
2006 | | - qla2x00_process_completed_request(vha, rsp->req, |
---|
2007 | | - ((sts21_entry_t *)pkt)->handle[cnt]); |
---|
2008 | | - } |
---|
2009 | | - break; |
---|
2010 | | - case STATUS_TYPE_22: |
---|
2011 | | - handle_cnt = ((sts22_entry_t *)pkt)->handle_count; |
---|
2012 | | - for (cnt = 0; cnt < handle_cnt; cnt++) { |
---|
2013 | | - qla2x00_process_completed_request(vha, rsp->req, |
---|
2014 | | - ((sts22_entry_t *)pkt)->handle[cnt]); |
---|
2015 | | - } |
---|
2016 | | - break; |
---|
2017 | | - case STATUS_CONT_TYPE: |
---|
2018 | | - qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt); |
---|
2019 | | - break; |
---|
2020 | | - case MBX_IOCB_TYPE: |
---|
2021 | | - qla2x00_mbx_iocb_entry(vha, rsp->req, |
---|
2022 | | - (struct mbx_entry *)pkt); |
---|
2023 | | - break; |
---|
2024 | | - case CT_IOCB_TYPE: |
---|
2025 | | - qla2x00_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); |
---|
2026 | | - break; |
---|
2027 | | - default: |
---|
2028 | | - /* Type Not Supported. */ |
---|
2029 | | - ql_log(ql_log_warn, vha, 0x504a, |
---|
2030 | | - "Received unknown response pkt type %x " |
---|
2031 | | - "entry status=%x.\n", |
---|
2032 | | - pkt->entry_type, pkt->entry_status); |
---|
2033 | | - break; |
---|
2034 | | - } |
---|
| 2507 | + qla2x00_process_response_entry(vha, rsp, pkt); |
---|
2035 | 2508 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; |
---|
2036 | 2509 | wmb(); |
---|
2037 | 2510 | } |
---|
2038 | 2511 | |
---|
2039 | 2512 | /* Adjust ring index */ |
---|
2040 | | - WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), rsp->ring_index); |
---|
| 2513 | + wrt_reg_word(ISP_RSP_Q_OUT(ha, reg), rsp->ring_index); |
---|
2041 | 2514 | } |
---|
2042 | 2515 | |
---|
2043 | 2516 | static inline void |
---|
.. | .. |
---|
2106 | 2579 | * swab32 of the "data" field in the beginning of qla2x00_status_entry() |
---|
2107 | 2580 | * would make guard field appear at offset 2 |
---|
2108 | 2581 | */ |
---|
2109 | | - a_guard = le16_to_cpu(*(uint16_t *)(ap + 2)); |
---|
2110 | | - a_app_tag = le16_to_cpu(*(uint16_t *)(ap + 0)); |
---|
2111 | | - a_ref_tag = le32_to_cpu(*(uint32_t *)(ap + 4)); |
---|
2112 | | - e_guard = le16_to_cpu(*(uint16_t *)(ep + 2)); |
---|
2113 | | - e_app_tag = le16_to_cpu(*(uint16_t *)(ep + 0)); |
---|
2114 | | - e_ref_tag = le32_to_cpu(*(uint32_t *)(ep + 4)); |
---|
| 2582 | + a_guard = get_unaligned_le16(ap + 2); |
---|
| 2583 | + a_app_tag = get_unaligned_le16(ap + 0); |
---|
| 2584 | + a_ref_tag = get_unaligned_le32(ap + 4); |
---|
| 2585 | + e_guard = get_unaligned_le16(ep + 2); |
---|
| 2586 | + e_app_tag = get_unaligned_le16(ep + 0); |
---|
| 2587 | + e_ref_tag = get_unaligned_le32(ep + 4); |
---|
2115 | 2588 | |
---|
2116 | 2589 | ql_dbg(ql_dbg_io, vha, 0x3023, |
---|
2117 | 2590 | "iocb(s) %p Returned STATUS.\n", sts24); |
---|
.. | .. |
---|
2128 | 2601 | * For type 3: ref & app tag is all 'f's |
---|
2129 | 2602 | * For type 0,1,2: app tag is all 'f's |
---|
2130 | 2603 | */ |
---|
2131 | | - if ((a_app_tag == T10_PI_APP_ESCAPE) && |
---|
2132 | | - ((scsi_get_prot_type(cmd) != SCSI_PROT_DIF_TYPE3) || |
---|
2133 | | - (a_ref_tag == T10_PI_REF_ESCAPE))) { |
---|
| 2604 | + if (a_app_tag == be16_to_cpu(T10_PI_APP_ESCAPE) && |
---|
| 2605 | + (scsi_get_prot_type(cmd) != SCSI_PROT_DIF_TYPE3 || |
---|
| 2606 | + a_ref_tag == be32_to_cpu(T10_PI_REF_ESCAPE))) { |
---|
2134 | 2607 | uint32_t blocks_done, resid; |
---|
2135 | 2608 | sector_t lba_s = scsi_get_lba(cmd); |
---|
2136 | 2609 | |
---|
.. | .. |
---|
2226 | 2699 | struct bsg_job *bsg_job = NULL; |
---|
2227 | 2700 | struct fc_bsg_request *bsg_request; |
---|
2228 | 2701 | struct fc_bsg_reply *bsg_reply; |
---|
2229 | | - sts_entry_t *sts; |
---|
2230 | | - struct sts_entry_24xx *sts24; |
---|
2231 | | - sts = (sts_entry_t *) pkt; |
---|
2232 | | - sts24 = (struct sts_entry_24xx *) pkt; |
---|
| 2702 | + sts_entry_t *sts = pkt; |
---|
| 2703 | + struct sts_entry_24xx *sts24 = pkt; |
---|
2233 | 2704 | |
---|
2234 | 2705 | /* Validate handle. */ |
---|
2235 | 2706 | if (index >= req->num_outstanding_cmds) { |
---|
.. | .. |
---|
2375 | 2846 | srb_t *sp; |
---|
2376 | 2847 | fc_port_t *fcport; |
---|
2377 | 2848 | struct scsi_cmnd *cp; |
---|
2378 | | - sts_entry_t *sts; |
---|
2379 | | - struct sts_entry_24xx *sts24; |
---|
| 2849 | + sts_entry_t *sts = pkt; |
---|
| 2850 | + struct sts_entry_24xx *sts24 = pkt; |
---|
2380 | 2851 | uint16_t comp_status; |
---|
2381 | 2852 | uint16_t scsi_status; |
---|
2382 | 2853 | uint16_t ox_id; |
---|
.. | .. |
---|
2392 | 2863 | int logit = 1; |
---|
2393 | 2864 | int res = 0; |
---|
2394 | 2865 | uint16_t state_flags = 0; |
---|
2395 | | - uint16_t retry_delay = 0; |
---|
| 2866 | + uint16_t sts_qual = 0; |
---|
2396 | 2867 | |
---|
2397 | | - sts = (sts_entry_t *) pkt; |
---|
2398 | | - sts24 = (struct sts_entry_24xx *) pkt; |
---|
2399 | 2868 | if (IS_FWI2_CAPABLE(ha)) { |
---|
2400 | 2869 | comp_status = le16_to_cpu(sts24->comp_status); |
---|
2401 | 2870 | scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK; |
---|
.. | .. |
---|
2440 | 2909 | } |
---|
2441 | 2910 | return; |
---|
2442 | 2911 | } |
---|
| 2912 | + qla_put_iocbs(sp->qpair, &sp->iores); |
---|
2443 | 2913 | |
---|
2444 | 2914 | if (sp->cmd_type != TYPE_SRB) { |
---|
2445 | 2915 | req->outstanding_cmds[handle] = NULL; |
---|
.. | .. |
---|
2505 | 2975 | host_to_fcp_swap(sts24->data, sizeof(sts24->data)); |
---|
2506 | 2976 | ox_id = le16_to_cpu(sts24->ox_id); |
---|
2507 | 2977 | par_sense_len = sizeof(sts24->data); |
---|
2508 | | - /* Valid values of the retry delay timer are 0x1-0xffef */ |
---|
2509 | | - if (sts24->retry_delay > 0 && sts24->retry_delay < 0xfff1) { |
---|
2510 | | - retry_delay = sts24->retry_delay & 0x3fff; |
---|
2511 | | - ql_dbg(ql_dbg_io, sp->vha, 0x3033, |
---|
2512 | | - "%s: scope=%#x retry_delay=%#x\n", __func__, |
---|
2513 | | - sts24->retry_delay >> 14, retry_delay); |
---|
2514 | | - } |
---|
| 2978 | + sts_qual = le16_to_cpu(sts24->status_qualifier); |
---|
2515 | 2979 | } else { |
---|
2516 | 2980 | if (scsi_status & SS_SENSE_LEN_VALID) |
---|
2517 | 2981 | sense_len = le16_to_cpu(sts->req_sense_length); |
---|
.. | .. |
---|
2549 | 3013 | * Check retry_delay_timer value if we receive a busy or |
---|
2550 | 3014 | * queue full. |
---|
2551 | 3015 | */ |
---|
2552 | | - if (lscsi_status == SAM_STAT_TASK_SET_FULL || |
---|
2553 | | - lscsi_status == SAM_STAT_BUSY) |
---|
2554 | | - qla2x00_set_retry_delay_timestamp(fcport, retry_delay); |
---|
| 3016 | + if (unlikely(lscsi_status == SAM_STAT_TASK_SET_FULL || |
---|
| 3017 | + lscsi_status == SAM_STAT_BUSY)) |
---|
| 3018 | + qla2x00_set_retry_delay_timestamp(fcport, sts_qual); |
---|
2555 | 3019 | |
---|
2556 | 3020 | /* |
---|
2557 | 3021 | * Based on Host and scsi status generate status code for Linux |
---|
.. | .. |
---|
2672 | 3136 | case CS_PORT_BUSY: |
---|
2673 | 3137 | case CS_INCOMPLETE: |
---|
2674 | 3138 | case CS_PORT_UNAVAILABLE: |
---|
2675 | | - case CS_TIMEOUT: |
---|
2676 | 3139 | case CS_RESET: |
---|
2677 | 3140 | |
---|
2678 | 3141 | /* |
---|
.. | .. |
---|
2695 | 3158 | "Port to be marked lost on fcport=%02x%02x%02x, current " |
---|
2696 | 3159 | "port state= %s comp_status %x.\n", fcport->d_id.b.domain, |
---|
2697 | 3160 | fcport->d_id.b.area, fcport->d_id.b.al_pa, |
---|
2698 | | - port_state_str[atomic_read(&fcport->state)], |
---|
| 3161 | + port_state_str[FCS_ONLINE], |
---|
2699 | 3162 | comp_status); |
---|
2700 | 3163 | |
---|
2701 | | - qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); |
---|
2702 | 3164 | qlt_schedule_sess_for_deletion(fcport); |
---|
2703 | 3165 | } |
---|
2704 | 3166 | |
---|
.. | .. |
---|
2725 | 3187 | cp->device->vendor); |
---|
2726 | 3188 | break; |
---|
2727 | 3189 | |
---|
| 3190 | + case CS_DMA: |
---|
| 3191 | + ql_log(ql_log_info, fcport->vha, 0x3022, |
---|
| 3192 | + "CS_DMA error: 0x%x-0x%x (0x%x) nexus=%ld:%d:%llu portid=%06x oxid=0x%x cdb=%10phN len=0x%x rsp_info=0x%x resid=0x%x fw_resid=0x%x sp=%p cp=%p.\n", |
---|
| 3193 | + comp_status, scsi_status, res, vha->host_no, |
---|
| 3194 | + cp->device->id, cp->device->lun, fcport->d_id.b24, |
---|
| 3195 | + ox_id, cp->cmnd, scsi_bufflen(cp), rsp_info_len, |
---|
| 3196 | + resid_len, fw_resid_len, sp, cp); |
---|
| 3197 | + ql_dump_buffer(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe0ee, |
---|
| 3198 | + pkt, sizeof(*sts24)); |
---|
| 3199 | + res = DID_ERROR << 16; |
---|
| 3200 | + break; |
---|
2728 | 3201 | default: |
---|
2729 | 3202 | res = DID_ERROR << 16; |
---|
2730 | 3203 | break; |
---|
.. | .. |
---|
2848 | 3321 | default: |
---|
2849 | 3322 | sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); |
---|
2850 | 3323 | if (sp) { |
---|
| 3324 | + qla_put_iocbs(sp->qpair, &sp->iores); |
---|
2851 | 3325 | sp->done(sp, res); |
---|
2852 | 3326 | return 0; |
---|
2853 | 3327 | } |
---|
.. | .. |
---|
2874 | 3348 | { |
---|
2875 | 3349 | uint16_t cnt; |
---|
2876 | 3350 | uint32_t mboxes; |
---|
2877 | | - uint16_t __iomem *wptr; |
---|
| 3351 | + __le16 __iomem *wptr; |
---|
2878 | 3352 | struct qla_hw_data *ha = vha->hw; |
---|
2879 | 3353 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
---|
2880 | 3354 | |
---|
.. | .. |
---|
2890 | 3364 | ha->flags.mbox_int = 1; |
---|
2891 | 3365 | ha->mailbox_out[0] = mb0; |
---|
2892 | 3366 | mboxes >>= 1; |
---|
2893 | | - wptr = (uint16_t __iomem *)®->mailbox1; |
---|
| 3367 | + wptr = ®->mailbox1; |
---|
2894 | 3368 | |
---|
2895 | 3369 | for (cnt = 1; cnt < ha->mbx_count; cnt++) { |
---|
2896 | 3370 | if (mboxes & BIT_0) |
---|
2897 | | - ha->mailbox_out[cnt] = RD_REG_WORD(wptr); |
---|
| 3371 | + ha->mailbox_out[cnt] = rd_reg_word(wptr); |
---|
2898 | 3372 | |
---|
2899 | 3373 | mboxes >>= 1; |
---|
2900 | 3374 | wptr++; |
---|
.. | .. |
---|
2914 | 3388 | return; |
---|
2915 | 3389 | |
---|
2916 | 3390 | abt = &sp->u.iocb_cmd; |
---|
2917 | | - abt->u.abt.comp_status = le16_to_cpu(pkt->nport_handle); |
---|
| 3391 | + abt->u.abt.comp_status = pkt->nport_handle; |
---|
2918 | 3392 | sp->done(sp, 0); |
---|
2919 | 3393 | } |
---|
2920 | 3394 | |
---|
.. | .. |
---|
2943 | 3417 | { |
---|
2944 | 3418 | struct sts_entry_24xx *pkt; |
---|
2945 | 3419 | struct qla_hw_data *ha = vha->hw; |
---|
| 3420 | + struct purex_entry_24xx *purex_entry; |
---|
| 3421 | + struct purex_item *pure_item; |
---|
2946 | 3422 | |
---|
2947 | 3423 | if (!ha->flags.fw_started) |
---|
2948 | 3424 | return; |
---|
2949 | 3425 | |
---|
2950 | | - if (rsp->qpair->cpuid != smp_processor_id()) |
---|
| 3426 | + if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) { |
---|
| 3427 | + rsp->qpair->rcv_intr = 1; |
---|
2951 | 3428 | qla_cpu_update(rsp->qpair, smp_processor_id()); |
---|
| 3429 | + } |
---|
2952 | 3430 | |
---|
2953 | 3431 | while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { |
---|
2954 | 3432 | pkt = (struct sts_entry_24xx *)rsp->ring_ptr; |
---|
.. | .. |
---|
2993 | 3471 | qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); |
---|
2994 | 3472 | break; |
---|
2995 | 3473 | case ABTS_RECV_24XX: |
---|
2996 | | - if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
---|
| 3474 | + if (qla_ini_mode_enabled(vha)) { |
---|
| 3475 | + pure_item = qla24xx_copy_std_pkt(vha, pkt); |
---|
| 3476 | + if (!pure_item) |
---|
| 3477 | + break; |
---|
| 3478 | + qla24xx_queue_purex_item(vha, pure_item, |
---|
| 3479 | + qla24xx_process_abts); |
---|
| 3480 | + break; |
---|
| 3481 | + } |
---|
| 3482 | + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
---|
| 3483 | + IS_QLA28XX(ha)) { |
---|
2997 | 3484 | /* ensure that the ATIO queue is empty */ |
---|
2998 | 3485 | qlt_handle_abts_recv(vha, rsp, |
---|
2999 | 3486 | (response_t *)pkt); |
---|
.. | .. |
---|
3001 | 3488 | } else { |
---|
3002 | 3489 | qlt_24xx_process_atio_queue(vha, 1); |
---|
3003 | 3490 | } |
---|
3004 | | - /* fall through */ |
---|
| 3491 | + fallthrough; |
---|
3005 | 3492 | case ABTS_RESP_24XX: |
---|
3006 | 3493 | case CTIO_TYPE7: |
---|
3007 | 3494 | case CTIO_CRC2: |
---|
.. | .. |
---|
3036 | 3523 | qla_ctrlvp_completed(vha, rsp->req, |
---|
3037 | 3524 | (struct vp_ctrl_entry_24xx *)pkt); |
---|
3038 | 3525 | break; |
---|
| 3526 | + case PUREX_IOCB_TYPE: |
---|
| 3527 | + purex_entry = (void *)pkt; |
---|
| 3528 | + switch (purex_entry->els_frame_payload[3]) { |
---|
| 3529 | + case ELS_RDP: |
---|
| 3530 | + pure_item = qla24xx_copy_std_pkt(vha, pkt); |
---|
| 3531 | + if (!pure_item) |
---|
| 3532 | + break; |
---|
| 3533 | + qla24xx_queue_purex_item(vha, pure_item, |
---|
| 3534 | + qla24xx_process_purex_rdp); |
---|
| 3535 | + break; |
---|
| 3536 | + case ELS_FPIN: |
---|
| 3537 | + if (!vha->hw->flags.scm_enabled) { |
---|
| 3538 | + ql_log(ql_log_warn, vha, 0x5094, |
---|
| 3539 | + "SCM not active for this port\n"); |
---|
| 3540 | + break; |
---|
| 3541 | + } |
---|
| 3542 | + pure_item = qla27xx_copy_fpin_pkt(vha, |
---|
| 3543 | + (void **)&pkt, &rsp); |
---|
| 3544 | + if (!pure_item) |
---|
| 3545 | + break; |
---|
| 3546 | + qla24xx_queue_purex_item(vha, pure_item, |
---|
| 3547 | + qla27xx_process_purex_fpin); |
---|
| 3548 | + break; |
---|
| 3549 | + |
---|
| 3550 | + default: |
---|
| 3551 | + ql_log(ql_log_warn, vha, 0x509c, |
---|
| 3552 | + "Discarding ELS Request opcode 0x%x\n", |
---|
| 3553 | + purex_entry->els_frame_payload[3]); |
---|
| 3554 | + } |
---|
| 3555 | + break; |
---|
3039 | 3556 | default: |
---|
3040 | 3557 | /* Type Not Supported. */ |
---|
3041 | 3558 | ql_dbg(ql_dbg_async, vha, 0x5042, |
---|
3042 | | - "Received unknown response pkt type %x " |
---|
3043 | | - "entry status=%x.\n", |
---|
3044 | | - pkt->entry_type, pkt->entry_status); |
---|
| 3559 | + "Received unknown response pkt type 0x%x entry status=%x.\n", |
---|
| 3560 | + pkt->entry_type, pkt->entry_status); |
---|
3045 | 3561 | break; |
---|
3046 | 3562 | } |
---|
3047 | 3563 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; |
---|
.. | .. |
---|
3051 | 3567 | /* Adjust ring index */ |
---|
3052 | 3568 | if (IS_P3P_TYPE(ha)) { |
---|
3053 | 3569 | struct device_reg_82xx __iomem *reg = &ha->iobase->isp82; |
---|
3054 | | - WRT_REG_DWORD(®->rsp_q_out[0], rsp->ring_index); |
---|
| 3570 | + |
---|
| 3571 | + wrt_reg_dword(®->rsp_q_out[0], rsp->ring_index); |
---|
3055 | 3572 | } else { |
---|
3056 | | - WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index); |
---|
| 3573 | + wrt_reg_dword(rsp->rsp_q_out, rsp->ring_index); |
---|
3057 | 3574 | } |
---|
3058 | 3575 | } |
---|
3059 | 3576 | |
---|
.. | .. |
---|
3066 | 3583 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
---|
3067 | 3584 | |
---|
3068 | 3585 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
---|
3069 | | - !IS_QLA27XX(ha)) |
---|
| 3586 | + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
---|
3070 | 3587 | return; |
---|
3071 | 3588 | |
---|
3072 | 3589 | rval = QLA_SUCCESS; |
---|
3073 | | - WRT_REG_DWORD(®->iobase_addr, 0x7C00); |
---|
3074 | | - RD_REG_DWORD(®->iobase_addr); |
---|
3075 | | - WRT_REG_DWORD(®->iobase_window, 0x0001); |
---|
3076 | | - for (cnt = 10000; (RD_REG_DWORD(®->iobase_window) & BIT_0) == 0 && |
---|
| 3590 | + wrt_reg_dword(®->iobase_addr, 0x7C00); |
---|
| 3591 | + rd_reg_dword(®->iobase_addr); |
---|
| 3592 | + wrt_reg_dword(®->iobase_window, 0x0001); |
---|
| 3593 | + for (cnt = 10000; (rd_reg_dword(®->iobase_window) & BIT_0) == 0 && |
---|
3077 | 3594 | rval == QLA_SUCCESS; cnt--) { |
---|
3078 | 3595 | if (cnt) { |
---|
3079 | | - WRT_REG_DWORD(®->iobase_window, 0x0001); |
---|
| 3596 | + wrt_reg_dword(®->iobase_window, 0x0001); |
---|
3080 | 3597 | udelay(10); |
---|
3081 | 3598 | } else |
---|
3082 | 3599 | rval = QLA_FUNCTION_TIMEOUT; |
---|
.. | .. |
---|
3085 | 3602 | goto next_test; |
---|
3086 | 3603 | |
---|
3087 | 3604 | rval = QLA_SUCCESS; |
---|
3088 | | - WRT_REG_DWORD(®->iobase_window, 0x0003); |
---|
3089 | | - for (cnt = 100; (RD_REG_DWORD(®->iobase_window) & BIT_0) == 0 && |
---|
| 3605 | + wrt_reg_dword(®->iobase_window, 0x0003); |
---|
| 3606 | + for (cnt = 100; (rd_reg_dword(®->iobase_window) & BIT_0) == 0 && |
---|
3090 | 3607 | rval == QLA_SUCCESS; cnt--) { |
---|
3091 | 3608 | if (cnt) { |
---|
3092 | | - WRT_REG_DWORD(®->iobase_window, 0x0003); |
---|
| 3609 | + wrt_reg_dword(®->iobase_window, 0x0003); |
---|
3093 | 3610 | udelay(10); |
---|
3094 | 3611 | } else |
---|
3095 | 3612 | rval = QLA_FUNCTION_TIMEOUT; |
---|
.. | .. |
---|
3098 | 3615 | goto done; |
---|
3099 | 3616 | |
---|
3100 | 3617 | next_test: |
---|
3101 | | - if (RD_REG_DWORD(®->iobase_c8) & BIT_3) |
---|
| 3618 | + if (rd_reg_dword(®->iobase_c8) & BIT_3) |
---|
3102 | 3619 | ql_log(ql_log_info, vha, 0x504c, |
---|
3103 | 3620 | "Additional code -- 0x55AA.\n"); |
---|
3104 | 3621 | |
---|
3105 | 3622 | done: |
---|
3106 | | - WRT_REG_DWORD(®->iobase_window, 0x0000); |
---|
3107 | | - RD_REG_DWORD(®->iobase_window); |
---|
| 3623 | + wrt_reg_dword(®->iobase_window, 0x0000); |
---|
| 3624 | + rd_reg_dword(®->iobase_window); |
---|
3108 | 3625 | } |
---|
3109 | 3626 | |
---|
3110 | 3627 | /** |
---|
3111 | 3628 | * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP24xx. |
---|
3112 | | - * @irq: |
---|
| 3629 | + * @irq: interrupt number |
---|
3113 | 3630 | * @dev_id: SCSI driver HA context |
---|
3114 | 3631 | * |
---|
3115 | 3632 | * Called by system whenever the host adapter generates an interrupt. |
---|
.. | .. |
---|
3148 | 3665 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
3149 | 3666 | vha = pci_get_drvdata(ha->pdev); |
---|
3150 | 3667 | for (iter = 50; iter--; ) { |
---|
3151 | | - stat = RD_REG_DWORD(®->host_status); |
---|
| 3668 | + stat = rd_reg_dword(®->host_status); |
---|
3152 | 3669 | if (qla2x00_check_reg32_for_disconnect(vha, stat)) |
---|
3153 | 3670 | break; |
---|
3154 | 3671 | if (stat & HSRX_RISC_PAUSED) { |
---|
3155 | 3672 | if (unlikely(pci_channel_offline(ha->pdev))) |
---|
3156 | 3673 | break; |
---|
3157 | 3674 | |
---|
3158 | | - hccr = RD_REG_DWORD(®->hccr); |
---|
| 3675 | + hccr = rd_reg_dword(®->hccr); |
---|
3159 | 3676 | |
---|
3160 | 3677 | ql_log(ql_log_warn, vha, 0x504b, |
---|
3161 | 3678 | "RISC paused -- HCCR=%x, Dumping firmware.\n", |
---|
.. | .. |
---|
3163 | 3680 | |
---|
3164 | 3681 | qla2xxx_check_risc_status(vha); |
---|
3165 | 3682 | |
---|
3166 | | - ha->isp_ops->fw_dump(vha, 1); |
---|
| 3683 | + ha->isp_ops->fw_dump(vha); |
---|
3167 | 3684 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
3168 | 3685 | break; |
---|
3169 | 3686 | } else if ((stat & HSRX_RISC_INT) == 0) |
---|
.. | .. |
---|
3180 | 3697 | break; |
---|
3181 | 3698 | case INTR_ASYNC_EVENT: |
---|
3182 | 3699 | mb[0] = MSW(stat); |
---|
3183 | | - mb[1] = RD_REG_WORD(®->mailbox1); |
---|
3184 | | - mb[2] = RD_REG_WORD(®->mailbox2); |
---|
3185 | | - mb[3] = RD_REG_WORD(®->mailbox3); |
---|
| 3700 | + mb[1] = rd_reg_word(®->mailbox1); |
---|
| 3701 | + mb[2] = rd_reg_word(®->mailbox2); |
---|
| 3702 | + mb[3] = rd_reg_word(®->mailbox3); |
---|
3186 | 3703 | qla2x00_async_event(vha, rsp, mb); |
---|
3187 | 3704 | break; |
---|
3188 | 3705 | case INTR_RSP_QUE_UPDATE: |
---|
.. | .. |
---|
3202 | 3719 | "Unrecognized interrupt type (%d).\n", stat * 0xff); |
---|
3203 | 3720 | break; |
---|
3204 | 3721 | } |
---|
3205 | | - WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
---|
3206 | | - RD_REG_DWORD_RELAXED(®->hccr); |
---|
| 3722 | + wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); |
---|
| 3723 | + rd_reg_dword_relaxed(®->hccr); |
---|
3207 | 3724 | if (unlikely(IS_QLA83XX(ha) && (ha->pdev->revision == 1))) |
---|
3208 | 3725 | ndelay(3500); |
---|
3209 | 3726 | } |
---|
.. | .. |
---|
3242 | 3759 | vha = pci_get_drvdata(ha->pdev); |
---|
3243 | 3760 | qla24xx_process_response_queue(vha, rsp); |
---|
3244 | 3761 | if (!ha->flags.disable_msix_handshake) { |
---|
3245 | | - WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
---|
3246 | | - RD_REG_DWORD_RELAXED(®->hccr); |
---|
| 3762 | + wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); |
---|
| 3763 | + rd_reg_dword_relaxed(®->hccr); |
---|
3247 | 3764 | } |
---|
3248 | 3765 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
3249 | 3766 | |
---|
.. | .. |
---|
3277 | 3794 | spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
3278 | 3795 | vha = pci_get_drvdata(ha->pdev); |
---|
3279 | 3796 | do { |
---|
3280 | | - stat = RD_REG_DWORD(®->host_status); |
---|
| 3797 | + stat = rd_reg_dword(®->host_status); |
---|
3281 | 3798 | if (qla2x00_check_reg32_for_disconnect(vha, stat)) |
---|
3282 | 3799 | break; |
---|
3283 | 3800 | if (stat & HSRX_RISC_PAUSED) { |
---|
3284 | 3801 | if (unlikely(pci_channel_offline(ha->pdev))) |
---|
3285 | 3802 | break; |
---|
3286 | 3803 | |
---|
3287 | | - hccr = RD_REG_DWORD(®->hccr); |
---|
| 3804 | + hccr = rd_reg_dword(®->hccr); |
---|
3288 | 3805 | |
---|
3289 | 3806 | ql_log(ql_log_info, vha, 0x5050, |
---|
3290 | 3807 | "RISC paused -- HCCR=%x, Dumping firmware.\n", |
---|
.. | .. |
---|
3292 | 3809 | |
---|
3293 | 3810 | qla2xxx_check_risc_status(vha); |
---|
3294 | 3811 | |
---|
3295 | | - ha->isp_ops->fw_dump(vha, 1); |
---|
| 3812 | + ha->isp_ops->fw_dump(vha); |
---|
3296 | 3813 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
---|
3297 | 3814 | break; |
---|
3298 | 3815 | } else if ((stat & HSRX_RISC_INT) == 0) |
---|
.. | .. |
---|
3309 | 3826 | break; |
---|
3310 | 3827 | case INTR_ASYNC_EVENT: |
---|
3311 | 3828 | mb[0] = MSW(stat); |
---|
3312 | | - mb[1] = RD_REG_WORD(®->mailbox1); |
---|
3313 | | - mb[2] = RD_REG_WORD(®->mailbox2); |
---|
3314 | | - mb[3] = RD_REG_WORD(®->mailbox3); |
---|
| 3829 | + mb[1] = rd_reg_word(®->mailbox1); |
---|
| 3830 | + mb[2] = rd_reg_word(®->mailbox2); |
---|
| 3831 | + mb[3] = rd_reg_word(®->mailbox3); |
---|
3315 | 3832 | qla2x00_async_event(vha, rsp, mb); |
---|
3316 | 3833 | break; |
---|
3317 | 3834 | case INTR_RSP_QUE_UPDATE: |
---|
.. | .. |
---|
3331 | 3848 | "Unrecognized interrupt type (%d).\n", stat & 0xff); |
---|
3332 | 3849 | break; |
---|
3333 | 3850 | } |
---|
3334 | | - WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
---|
| 3851 | + wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); |
---|
3335 | 3852 | } while (0); |
---|
3336 | 3853 | qla2x00_handle_mbx_completion(ha, status); |
---|
3337 | 3854 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
.. | .. |
---|
3350 | 3867 | { |
---|
3351 | 3868 | struct qla_hw_data *ha; |
---|
3352 | 3869 | struct qla_qpair *qpair; |
---|
| 3870 | + |
---|
| 3871 | + qpair = dev_id; |
---|
| 3872 | + if (!qpair) { |
---|
| 3873 | + ql_log(ql_log_info, NULL, 0x505b, |
---|
| 3874 | + "%s: NULL response queue pointer.\n", __func__); |
---|
| 3875 | + return IRQ_NONE; |
---|
| 3876 | + } |
---|
| 3877 | + ha = qpair->hw; |
---|
| 3878 | + |
---|
| 3879 | + queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); |
---|
| 3880 | + |
---|
| 3881 | + return IRQ_HANDLED; |
---|
| 3882 | +} |
---|
| 3883 | + |
---|
| 3884 | +irqreturn_t |
---|
| 3885 | +qla2xxx_msix_rsp_q_hs(int irq, void *dev_id) |
---|
| 3886 | +{ |
---|
| 3887 | + struct qla_hw_data *ha; |
---|
| 3888 | + struct qla_qpair *qpair; |
---|
3353 | 3889 | struct device_reg_24xx __iomem *reg; |
---|
3354 | 3890 | unsigned long flags; |
---|
3355 | 3891 | |
---|
.. | .. |
---|
3361 | 3897 | } |
---|
3362 | 3898 | ha = qpair->hw; |
---|
3363 | 3899 | |
---|
3364 | | - /* Clear the interrupt, if enabled, for this response queue */ |
---|
3365 | | - if (unlikely(!ha->flags.disable_msix_handshake)) { |
---|
3366 | | - reg = &ha->iobase->isp24; |
---|
3367 | | - spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
3368 | | - WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
---|
3369 | | - spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
3370 | | - } |
---|
| 3900 | + reg = &ha->iobase->isp24; |
---|
| 3901 | + spin_lock_irqsave(&ha->hardware_lock, flags); |
---|
| 3902 | + wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); |
---|
| 3903 | + spin_unlock_irqrestore(&ha->hardware_lock, flags); |
---|
3371 | 3904 | |
---|
3372 | | - queue_work(ha->wq, &qpair->q_work); |
---|
| 3905 | + queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); |
---|
3373 | 3906 | |
---|
3374 | 3907 | return IRQ_HANDLED; |
---|
3375 | 3908 | } |
---|
.. | .. |
---|
3386 | 3919 | { "rsp_q", qla24xx_msix_rsp_q }, |
---|
3387 | 3920 | { "atio_q", qla83xx_msix_atio_q }, |
---|
3388 | 3921 | { "qpair_multiq", qla2xxx_msix_rsp_q }, |
---|
| 3922 | + { "qpair_multiq_hs", qla2xxx_msix_rsp_q_hs }, |
---|
3389 | 3923 | }; |
---|
3390 | 3924 | |
---|
3391 | 3925 | static const struct qla_init_msix_entry qla82xx_msix_entries[] = { |
---|
.. | .. |
---|
3410 | 3944 | min_vecs++; |
---|
3411 | 3945 | } |
---|
3412 | 3946 | |
---|
3413 | | - if (USER_CTRL_IRQ(ha)) { |
---|
| 3947 | + if (USER_CTRL_IRQ(ha) || !ha->mqiobase) { |
---|
3414 | 3948 | /* user wants to control IRQ setting for target mode */ |
---|
3415 | 3949 | ret = pci_alloc_irq_vectors(ha->pdev, min_vecs, |
---|
3416 | 3950 | ha->msix_count, PCI_IRQ_MSIX); |
---|
.. | .. |
---|
3444 | 3978 | "Adjusted Max no of queues pairs: %d.\n", ha->max_qpairs); |
---|
3445 | 3979 | } |
---|
3446 | 3980 | } |
---|
| 3981 | + vha->irq_offset = desc.pre_vectors; |
---|
3447 | 3982 | ha->msix_entries = kcalloc(ha->msix_count, |
---|
3448 | 3983 | sizeof(struct qla_msix_entry), |
---|
3449 | 3984 | GFP_KERNEL); |
---|
.. | .. |
---|
3515 | 4050 | } |
---|
3516 | 4051 | |
---|
3517 | 4052 | /* Enable MSI-X vector for response queue update for queue 0 */ |
---|
3518 | | - if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
---|
3519 | | - if (ha->msixbase && ha->mqiobase && |
---|
3520 | | - (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || |
---|
3521 | | - ql2xmqsupport)) |
---|
3522 | | - ha->mqenable = 1; |
---|
3523 | | - } else |
---|
3524 | | - if (ha->mqiobase && |
---|
3525 | | - (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || |
---|
3526 | | - ql2xmqsupport)) |
---|
3527 | | - ha->mqenable = 1; |
---|
| 4053 | + if (IS_MQUE_CAPABLE(ha) && |
---|
| 4054 | + (ha->msixbase && ha->mqiobase && ha->max_qpairs)) |
---|
| 4055 | + ha->mqenable = 1; |
---|
| 4056 | + else |
---|
| 4057 | + ha->mqenable = 0; |
---|
| 4058 | + |
---|
3528 | 4059 | ql_dbg(ql_dbg_multiq, vha, 0xc005, |
---|
3529 | 4060 | "mqiobase=%p, max_rsp_queues=%d, max_req_queues=%d.\n", |
---|
3530 | 4061 | ha->mqiobase, ha->max_rsp_queues, ha->max_req_queues); |
---|
.. | .. |
---|
3550 | 4081 | /* If possible, enable MSI-X. */ |
---|
3551 | 4082 | if (ql2xenablemsix == 0 || (!IS_QLA2432(ha) && !IS_QLA2532(ha) && |
---|
3552 | 4083 | !IS_QLA8432(ha) && !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && |
---|
3553 | | - !IS_QLAFX00(ha) && !IS_QLA27XX(ha))) |
---|
| 4084 | + !IS_QLAFX00(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))) |
---|
3554 | 4085 | goto skip_msi; |
---|
3555 | 4086 | |
---|
3556 | 4087 | if (ql2xenablemsix == 2) |
---|
.. | .. |
---|
3589 | 4120 | |
---|
3590 | 4121 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && |
---|
3591 | 4122 | !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) && |
---|
3592 | | - !IS_QLA27XX(ha)) |
---|
| 4123 | + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
---|
3593 | 4124 | goto skip_msi; |
---|
3594 | 4125 | |
---|
3595 | 4126 | ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); |
---|
.. | .. |
---|
3618 | 4149 | ql_dbg(ql_dbg_init, vha, 0x0125, |
---|
3619 | 4150 | "INTa mode: Enabled.\n"); |
---|
3620 | 4151 | ha->flags.mr_intr_valid = 1; |
---|
| 4152 | + /* Set max_qpair to 0, as MSI-X and MSI in not enabled */ |
---|
| 4153 | + ha->max_qpairs = 0; |
---|
3621 | 4154 | } |
---|
3622 | 4155 | |
---|
3623 | 4156 | clear_risc_ints: |
---|
.. | .. |
---|
3625 | 4158 | goto fail; |
---|
3626 | 4159 | |
---|
3627 | 4160 | spin_lock_irq(&ha->hardware_lock); |
---|
3628 | | - WRT_REG_WORD(®->isp.semaphore, 0); |
---|
| 4161 | + wrt_reg_word(®->isp.semaphore, 0); |
---|
3629 | 4162 | spin_unlock_irq(&ha->hardware_lock); |
---|
3630 | 4163 | |
---|
3631 | 4164 | fail: |
---|