^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * QLogic Fibre Channel HBA Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2003-2014 QLogic Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "qla_def.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "qla_target.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * qla2x00_get_cmd_direction() - Determine control_flag data direction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * @sp: SCSI command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Returns the proper CF_* direction based on CDB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static inline uint16_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) qla2x00_get_cmd_direction(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) uint16_t cflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct scsi_cmnd *cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) cflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Set transfer direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (cmd->sc_data_direction == DMA_TO_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) cflags = CF_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) vha->qla_stats.output_bytes += scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) vha->qla_stats.output_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) cflags = CF_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) vha->qla_stats.input_bytes += scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) vha->qla_stats.input_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return (cflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * qla2x00_calc_iocbs_32() - Determine number of Command Type 2 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Continuation Type 0 IOCBs to allocate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @dsds: number of data segment descriptors needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Returns the number of IOCB entries needed to store @dsds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) uint16_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) qla2x00_calc_iocbs_32(uint16_t dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) uint16_t iocbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) iocbs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (dsds > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) iocbs += (dsds - 3) / 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if ((dsds - 3) % 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) iocbs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return (iocbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * qla2x00_calc_iocbs_64() - Determine number of Command Type 3 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Continuation Type 1 IOCBs to allocate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @dsds: number of data segment descriptors needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Returns the number of IOCB entries needed to store @dsds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) uint16_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) qla2x00_calc_iocbs_64(uint16_t dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) uint16_t iocbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) iocbs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (dsds > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) iocbs += (dsds - 2) / 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if ((dsds - 2) % 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) iocbs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return (iocbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * qla2x00_prep_cont_type0_iocb() - Initialize a Continuation Type 0 IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Returns a pointer to the Continuation Type 0 IOCB packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline cont_entry_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) cont_entry_t *cont_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct req_que *req = vha->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) cont_pkt = (cont_entry_t *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Load packet defaults. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) put_unaligned_le32(CONTINUE_TYPE, &cont_pkt->entry_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return (cont_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * qla2x00_prep_cont_type1_iocb() - Initialize a Continuation Type 1 IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @req: request queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Returns a pointer to the continuation type 1 IOCB packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static inline cont_a64_entry_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) cont_a64_entry_t *cont_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) cont_pkt = (cont_a64_entry_t *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* Load packet defaults. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) put_unaligned_le32(IS_QLAFX00(vha->hw) ? CONTINUE_A64_TYPE_FX00 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) CONTINUE_A64_TYPE, &cont_pkt->entry_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return (cont_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct scsi_cmnd *cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) uint8_t guard = scsi_host_get_guard(cmd->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* We always use DIFF Bundling for best performance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *fw_prot_opts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Translate SCSI opcode to a protection opcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) switch (scsi_get_prot_op(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case SCSI_PROT_READ_STRIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *fw_prot_opts |= PO_MODE_DIF_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) case SCSI_PROT_WRITE_INSERT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *fw_prot_opts |= PO_MODE_DIF_INSERT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case SCSI_PROT_READ_INSERT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *fw_prot_opts |= PO_MODE_DIF_INSERT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case SCSI_PROT_WRITE_STRIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *fw_prot_opts |= PO_MODE_DIF_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case SCSI_PROT_READ_PASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case SCSI_PROT_WRITE_PASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (guard & SHOST_DIX_GUARD_IP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) *fw_prot_opts |= PO_MODE_DIF_TCP_CKSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) *fw_prot_opts |= PO_MODE_DIF_PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) default: /* Normal Request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *fw_prot_opts |= PO_MODE_DIF_PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return scsi_prot_sg_count(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * qla2x00_build_scsi_iocbs_32() - Build IOCB command utilizing 32bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * capable IOCB types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * @sp: SRB command to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * @cmd_pkt: Command type 2 IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * @tot_dsds: Total number of segments to transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) uint16_t tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) uint16_t avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct dsd32 *cur_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) scsi_qla_host_t *vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Update entry type to indicate Command Type 2 IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) put_unaligned_le32(COMMAND_TYPE, &cmd_pkt->entry_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* No data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) cmd_pkt->byte_count = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Three DSDs are available in the Command Type 2 IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) avail_dsds = ARRAY_SIZE(cmd_pkt->dsd32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) cur_dsd = cmd_pkt->dsd32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* Load data segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) scsi_for_each_sg(cmd, sg, tot_dsds, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) cont_entry_t *cont_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * Seven DSDs are available in the Continuation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * Type 0 IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) cont_pkt = qla2x00_prep_cont_type0_iocb(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cur_dsd = cont_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) avail_dsds = ARRAY_SIZE(cont_pkt->dsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) append_dsd32(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * qla2x00_build_scsi_iocbs_64() - Build IOCB command utilizing 64bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * capable IOCB types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * @sp: SRB command to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @cmd_pkt: Command type 3 IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * @tot_dsds: Total number of segments to transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) uint16_t tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) uint16_t avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct dsd64 *cur_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) scsi_qla_host_t *vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* Update entry type to indicate Command Type 3 IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) put_unaligned_le32(COMMAND_A64_TYPE, &cmd_pkt->entry_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* No data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) cmd_pkt->byte_count = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* Two DSDs are available in the Command Type 3 IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) avail_dsds = ARRAY_SIZE(cmd_pkt->dsd64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) cur_dsd = cmd_pkt->dsd64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Load data segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) scsi_for_each_sg(cmd, sg, tot_dsds, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) cont_a64_entry_t *cont_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * Five DSDs are available in the Continuation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * Type 1 IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) cur_dsd = cont_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) avail_dsds = ARRAY_SIZE(cont_pkt->dsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * Find the first handle that is not in use, starting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * req->current_outstanding_cmd + 1. The caller must hold the lock that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * associated with @req.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) uint32_t qla2xxx_get_next_handle(struct req_que *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) uint32_t index, handle = req->current_outstanding_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) for (index = 1; index < req->num_outstanding_cmds; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) handle++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (handle == req->num_outstanding_cmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) handle = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (!req->outstanding_cmds[handle])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * qla2x00_start_scsi() - Send a SCSI command to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * @sp: command to send to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * Returns non-zero if a failure occurred, else zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) qla2x00_start_scsi(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) scsi_qla_host_t *vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) uint32_t *clr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) uint32_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) cmd_entry_t *cmd_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) uint16_t req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) uint16_t tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct device_reg_2xxx __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct qla_hw_data *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct req_que *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct rsp_que *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* Setup device pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) rsp = ha->rsp_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* So we know we haven't pci_map'ed anything yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) tot_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* Send marker if required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (vha->marker_needed != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return (QLA_FUNCTION_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* Acquire ring specific lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) handle = qla2xxx_get_next_handle(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (handle == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* Map the sg table so we have an accurate count of sg entries needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (scsi_sg_count(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) scsi_sg_count(cmd), cmd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (unlikely(!nseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) tot_dsds = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* Calculate the number of request entries needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) req_cnt = ha->isp_ops->calc_req_entries(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (req->cnt < (req_cnt + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) cnt = rd_reg_word_relaxed(ISP_REQ_Q_OUT(ha, reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* If still no head room then bail out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (req->cnt < (req_cnt + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* Build command packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) req->current_outstanding_cmd = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) req->outstanding_cmds[handle] = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) sp->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) cmd->host_scribble = (unsigned char *)(unsigned long)handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) req->cnt -= req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) cmd_pkt = (cmd_entry_t *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) cmd_pkt->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* Zero out remaining portion of packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) clr_ptr = (uint32_t *)cmd_pkt + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* Set target ID and LUN number*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) SET_TARGET_ID(ha, cmd_pkt->target, sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) cmd_pkt->lun = cpu_to_le16(cmd->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) cmd_pkt->control_flags = cpu_to_le16(CF_SIMPLE_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* Load SCSI command packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) memcpy(cmd_pkt->scsi_cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Build IOCB segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ha->isp_ops->build_iocbs(sp, cmd_pkt, tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* Set total data segment count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) cmd_pkt->entry_count = (uint8_t)req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) sp->flags |= SRB_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* Set chip new ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) wrt_reg_word(ISP_REQ_Q_IN(ha, reg), req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) rd_reg_word_relaxed(ISP_REQ_Q_IN(ha, reg)); /* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Manage unprocessed RIO/ZIO commands in response queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (vha->flags.process_response_queue &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) rsp->ring_ptr->signature != RESPONSE_PROCESSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) qla2x00_process_response_queue(rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return (QLA_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) scsi_dma_unmap(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return (QLA_FUNCTION_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * qla2x00_start_iocbs() - Execute the IOCB command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * @req: request queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) device_reg_t *reg = ISP_QUE_REG(ha, req->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (IS_P3P_TYPE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) qla82xx_start_iocbs(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* Set chip new ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (ha->mqenable || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) wrt_reg_dword(req->req_q_in, req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) } else if (IS_QLA83XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) wrt_reg_dword(req->req_q_in, req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) rd_reg_dword_relaxed(&ha->iobase->isp24.hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) } else if (IS_QLAFX00(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) wrt_reg_dword(®->ispfx00.req_q_in, req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) rd_reg_dword_relaxed(®->ispfx00.req_q_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) QLAFX00_SET_HST_INTR(ha, ha->rqstq_intr_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) } else if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) wrt_reg_dword(®->isp24.req_q_in, req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) rd_reg_dword_relaxed(®->isp24.req_q_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) wrt_reg_word(ISP_REQ_Q_IN(ha, ®->isp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) rd_reg_word_relaxed(ISP_REQ_Q_IN(ha, ®->isp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * qla2x00_marker() - Send a marker IOCB to the firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * @qpair: queue pair pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * @loop_id: loop ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * @lun: LUN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * @type: marker modifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * Can be called from both normal and interrupt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * Returns non-zero if a failure occurred, else zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) __qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) uint16_t loop_id, uint64_t lun, uint8_t type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) mrk_entry_t *mrk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct mrk_entry_24xx *mrk24 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct req_que *req = qpair->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) mrk = (mrk_entry_t *)__qla2x00_alloc_iocbs(qpair, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (mrk == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ql_log(ql_log_warn, base_vha, 0x3026,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) "Failed to allocate Marker IOCB.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return (QLA_FUNCTION_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) mrk->entry_type = MARKER_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) mrk->modifier = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (type != MK_SYNC_ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) mrk24 = (struct mrk_entry_24xx *) mrk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mrk24->nport_handle = cpu_to_le16(loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int_to_scsilun(lun, (struct scsi_lun *)&mrk24->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) mrk24->vp_index = vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) mrk24->handle = make_handle(req->id, mrk24->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) SET_TARGET_ID(ha, mrk->target, loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) mrk->lun = cpu_to_le16((uint16_t)lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) qla2x00_start_iocbs(vha, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return (QLA_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) uint16_t loop_id, uint64_t lun, uint8_t type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) spin_lock_irqsave(qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ret = __qla2x00_marker(vha, qpair, loop_id, lun, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return (ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * qla2x00_issue_marker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * Issue marker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * Caller CAN have hardware lock held as specified by ha_locked parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * Might release it, then reaquire.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int qla2x00_issue_marker(scsi_qla_host_t *vha, int ha_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (ha_locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (__qla2x00_marker(vha, vha->hw->base_qpair, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) MK_SYNC_ALL) != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (qla2x00_marker(vha, vha->hw->base_qpair, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) MK_SYNC_ALL) != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) uint16_t tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct dsd64 *cur_dsd = NULL, *next_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) scsi_qla_host_t *vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct qla_hw_data *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct scatterlist *cur_seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) uint8_t avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) uint8_t first_iocb = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) uint32_t dsd_list_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct dsd_dma *dsd_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct ct6_dsd *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct qla_qpair *qpair = sp->qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* Update entry type to indicate Command Type 3 IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) put_unaligned_le32(COMMAND_TYPE_6, &cmd_pkt->entry_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* No data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) cmd_pkt->byte_count = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* Set transfer direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (cmd->sc_data_direction == DMA_TO_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) qpair->counters.output_bytes += scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) qpair->counters.output_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) qpair->counters.input_bytes += scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) qpair->counters.input_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) cur_seg = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) ctx = sp->u.scmd.ct6_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) while (tot_dsds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) QLA_DSDS_PER_IOCB : tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) tot_dsds -= avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dsd_list_len = (avail_dsds + 1) * QLA_DSD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) dsd_ptr = list_first_entry(&ha->gbl_dsd_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct dsd_dma, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) next_dsd = dsd_ptr->dsd_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) list_del(&dsd_ptr->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ha->gbl_dsd_avail--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) list_add_tail(&dsd_ptr->list, &ctx->dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ctx->dsd_use_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ha->gbl_dsd_inuse++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (first_iocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) first_iocb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) put_unaligned_le64(dsd_ptr->dsd_list_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) &cmd_pkt->fcp_dsd.address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) cmd_pkt->fcp_dsd.length = cpu_to_le32(dsd_list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) put_unaligned_le64(dsd_ptr->dsd_list_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) &cur_dsd->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) cur_dsd->length = cpu_to_le32(dsd_list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) cur_dsd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) cur_dsd = next_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) while (avail_dsds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) append_dsd64(&cur_dsd, cur_seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) cur_seg = sg_next(cur_seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* Null termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) cur_dsd->address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) cur_dsd->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) cur_dsd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) cmd_pkt->control_flags |= cpu_to_le16(CF_DATA_SEG_DESCR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * qla24xx_calc_dsd_lists() - Determine number of DSD list required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * for Command Type 6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * @dsds: number of data segment descriptors needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * Returns the number of dsd list needed to store @dsds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static inline uint16_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) qla24xx_calc_dsd_lists(uint16_t dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) uint16_t dsd_lists = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) dsd_lists = (dsds/QLA_DSDS_PER_IOCB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (dsds % QLA_DSDS_PER_IOCB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) dsd_lists++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return dsd_lists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * qla24xx_build_scsi_iocbs() - Build IOCB command utilizing Command Type 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * IOCB types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * @sp: SRB command to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * @cmd_pkt: Command type 3 IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * @tot_dsds: Total number of segments to transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * @req: pointer to request queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) uint16_t tot_dsds, struct req_que *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) uint16_t avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct dsd64 *cur_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) scsi_qla_host_t *vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct qla_qpair *qpair = sp->qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* Update entry type to indicate Command Type 3 IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) put_unaligned_le32(COMMAND_TYPE_7, &cmd_pkt->entry_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* No data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) cmd_pkt->byte_count = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* Set transfer direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (cmd->sc_data_direction == DMA_TO_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) cmd_pkt->task_mgmt_flags = cpu_to_le16(TMF_WRITE_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) qpair->counters.output_bytes += scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) qpair->counters.output_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) cmd_pkt->task_mgmt_flags = cpu_to_le16(TMF_READ_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) qpair->counters.input_bytes += scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) qpair->counters.input_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* One DSD is available in the Command Type 3 IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) avail_dsds = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) cur_dsd = &cmd_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* Load data segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) scsi_for_each_sg(cmd, sg, tot_dsds, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) cont_a64_entry_t *cont_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * Five DSDs are available in the Continuation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * Type 1 IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) cont_pkt = qla2x00_prep_cont_type1_iocb(vha, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) cur_dsd = cont_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) avail_dsds = ARRAY_SIZE(cont_pkt->dsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct fw_dif_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) __le32 ref_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) __le16 app_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) uint8_t ref_tag_mask[4]; /* Validation/Replacement Mask*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) uint8_t app_tag_mask[2]; /* Validation/Replacement Mask*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * qla24xx_set_t10dif_tags_from_cmd - Extract Ref and App tags from SCSI command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) unsigned int protcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct scsi_cmnd *cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) switch (scsi_get_prot_type(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) case SCSI_PROT_DIF_TYPE0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * No check for ql2xenablehba_err_chk, as it would be an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * I/O error if hba tag generation is not done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) pkt->ref_tag = cpu_to_le32((uint32_t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) (0xffffffff & scsi_get_lba(cmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (!qla2x00_hba_err_chk_enabled(sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) pkt->ref_tag_mask[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) pkt->ref_tag_mask[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) pkt->ref_tag_mask[2] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) pkt->ref_tag_mask[3] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * For TYPE 2 protection: 16 bit GUARD + 32 bit REF tag has to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * match LBA in CDB + N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) case SCSI_PROT_DIF_TYPE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) pkt->app_tag = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pkt->app_tag_mask[0] = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) pkt->app_tag_mask[1] = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) pkt->ref_tag = cpu_to_le32((uint32_t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) (0xffffffff & scsi_get_lba(cmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (!qla2x00_hba_err_chk_enabled(sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* enable ALL bytes of the ref tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) pkt->ref_tag_mask[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) pkt->ref_tag_mask[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) pkt->ref_tag_mask[2] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) pkt->ref_tag_mask[3] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* For Type 3 protection: 16 bit GUARD only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case SCSI_PROT_DIF_TYPE3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) pkt->ref_tag_mask[0] = pkt->ref_tag_mask[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) pkt->ref_tag_mask[2] = pkt->ref_tag_mask[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * For TYpe 1 protection: 16 bit GUARD tag, 32 bit REF tag, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * 16 bit app tag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) case SCSI_PROT_DIF_TYPE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) pkt->ref_tag = cpu_to_le32((uint32_t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) (0xffffffff & scsi_get_lba(cmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) pkt->app_tag = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) pkt->app_tag_mask[0] = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) pkt->app_tag_mask[1] = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (!qla2x00_hba_err_chk_enabled(sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /* enable ALL bytes of the ref tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) pkt->ref_tag_mask[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) pkt->ref_tag_mask[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) pkt->ref_tag_mask[2] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) pkt->ref_tag_mask[3] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) uint32_t *partial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) uint32_t cumulative_partial, sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) dma_addr_t sg_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (sgx->num_bytes == sgx->tot_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) sg = sgx->cur_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) cumulative_partial = sgx->tot_partial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) sg_dma_addr = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) sg_len = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) sgx->dma_addr = sg_dma_addr + sgx->bytes_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if ((cumulative_partial + (sg_len - sgx->bytes_consumed)) >= blk_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) sgx->dma_len = (blk_sz - cumulative_partial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) sgx->tot_partial = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) sgx->num_bytes += blk_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) *partial = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) sgx->dma_len = sg_len - sgx->bytes_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) sgx->tot_partial += sgx->dma_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) *partial = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) sgx->bytes_consumed += sgx->dma_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (sg_len == sgx->bytes_consumed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) sgx->num_sg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) sgx->cur_sg = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) sgx->bytes_consumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct dsd64 *dsd, uint16_t tot_dsds, struct qla_tc_param *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) void *next_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) uint8_t avail_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) uint32_t dsd_list_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct dsd_dma *dsd_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct scatterlist *sg_prot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct dsd64 *cur_dsd = dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) uint16_t used_dsds = tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) uint32_t prot_int; /* protection interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) uint32_t partial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct qla2_sgx sgx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) dma_addr_t sle_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) uint32_t sle_dma_len, tot_prot_dma_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) memset(&sgx, 0, sizeof(struct qla2_sgx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) prot_int = cmd->device->sector_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) sgx.tot_bytes = scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) sgx.cur_sg = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) sgx.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) sg_prot = scsi_prot_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) } else if (tc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) prot_int = tc->blk_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) sgx.tot_bytes = tc->bufflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) sgx.cur_sg = tc->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) sg_prot = tc->prot_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) sle_dma = sgx.dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) sle_dma_len = sgx.dma_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) alloc_and_fill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) QLA_DSDS_PER_IOCB : used_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) dsd_list_len = (avail_dsds + 1) * 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) used_dsds -= avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) /* allocate tracking DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (!dsd_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /* allocate new list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) dsd_ptr->dsd_addr = next_dsd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) &dsd_ptr->dsd_list_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (!next_dsd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * Need to cleanup only this dsd_ptr, rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * will be done by sp_free_dma()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) kfree(dsd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) &sp->u.scmd.crc_ctx->dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) sp->flags |= SRB_CRC_CTX_DSD_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) &(tc->ctx->dsd_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) *tc->ctx_dsd_alloced = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /* add new list to cmd iocb or last list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) put_unaligned_le64(dsd_ptr->dsd_list_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) &cur_dsd->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) cur_dsd->length = cpu_to_le32(dsd_list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) cur_dsd = next_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) put_unaligned_le64(sle_dma, &cur_dsd->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) cur_dsd->length = cpu_to_le32(sle_dma_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) cur_dsd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (partial == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /* Got a full protection interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) sle_dma = sg_dma_address(sg_prot) + tot_prot_dma_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) sle_dma_len = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) tot_prot_dma_len += sle_dma_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (tot_prot_dma_len == sg_dma_len(sg_prot)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) tot_prot_dma_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) sg_prot = sg_next(sg_prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) partial = 1; /* So as to not re-enter this block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) goto alloc_and_fill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* Null termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) cur_dsd->address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) cur_dsd->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) cur_dsd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct dsd64 *dsd, uint16_t tot_dsds, struct qla_tc_param *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) void *next_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) uint8_t avail_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) uint32_t dsd_list_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) struct dsd_dma *dsd_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct scatterlist *sg, *sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct dsd64 *cur_dsd = dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) uint16_t used_dsds = tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) sgl = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) } else if (tc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) sgl = tc->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) for_each_sg(sgl, sg, tot_dsds, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) QLA_DSDS_PER_IOCB : used_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) dsd_list_len = (avail_dsds + 1) * 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) used_dsds -= avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* allocate tracking DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (!dsd_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* allocate new list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) dsd_ptr->dsd_addr = next_dsd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) &dsd_ptr->dsd_list_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (!next_dsd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * Need to cleanup only this dsd_ptr, rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * will be done by sp_free_dma()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) kfree(dsd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) &sp->u.scmd.crc_ctx->dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) sp->flags |= SRB_CRC_CTX_DSD_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) &(tc->ctx->dsd_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) *tc->ctx_dsd_alloced = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /* add new list to cmd iocb or last list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) put_unaligned_le64(dsd_ptr->dsd_list_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) &cur_dsd->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) cur_dsd->length = cpu_to_le32(dsd_list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) cur_dsd = next_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* Null termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) cur_dsd->address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) cur_dsd->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) cur_dsd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct dsd64 *cur_dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) struct dsd_dma *dsd_ptr = NULL, *dif_dsd, *nxt_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) struct scatterlist *sg, *sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct crc_context *difctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct scsi_qla_host *vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) uint dsd_list_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) uint avail_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) uint used_dsds = tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) bool dif_local_dma_alloc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) bool direction_to_device = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct scsi_cmnd *cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) sgl = scsi_prot_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) difctx = sp->u.scmd.crc_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) direction_to_device = cmd->sc_data_direction == DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe021,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) "%s: scsi_cmnd: %p, crc_ctx: %p, sp: %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) __func__, cmd, difctx, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) } else if (tc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) vha = tc->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) sgl = tc->prot_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) difctx = tc->ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) direction_to_device = tc->dma_data_direction == DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe021,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) "%s: enter (write=%u)\n", __func__, direction_to_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) /* if initiator doing write or target doing read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (direction_to_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) for_each_sg(sgl, sg, tot_dsds, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) u64 sle_phys = sg_phys(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /* If SGE addr + len flips bits in upper 32-bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (MSD(sle_phys + sg->length) ^ MSD(sle_phys)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe022,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) "%s: page boundary crossing (phys=%llx len=%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) __func__, sle_phys, sg->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (difctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ha->dif_bundle_crossed_pages++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) dif_local_dma_alloc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) ql_dbg(ql_dbg_tgt + ql_dbg_verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) vha, 0xe022,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) "%s: difctx pointer is NULL\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) ha->dif_bundle_writes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ha->dif_bundle_reads++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (ql2xdifbundlinginternalbuffers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) dif_local_dma_alloc = direction_to_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (dif_local_dma_alloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) u32 track_difbundl_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) u32 ldma_sg_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) u8 ldma_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) difctx->no_dif_bundl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) difctx->dif_bundl_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /* Track DSD buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) INIT_LIST_HEAD(&difctx->ldif_dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /* Track local DMA buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) INIT_LIST_HEAD(&difctx->ldif_dma_hndl_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) for_each_sg(sgl, sg, tot_dsds, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) u32 sglen = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) "%s: sg[%x] (phys=%llx sglen=%x) ldma_sg_len: %x dif_bundl_len: %x ldma_needed: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) __func__, i, (u64)sg_phys(sg), sglen, ldma_sg_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) difctx->dif_bundl_len, ldma_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) while (sglen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) u32 xfrlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (ldma_needed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * Allocate list item to store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * the DMA buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) dsd_ptr = kzalloc(sizeof(*dsd_ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (!dsd_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ql_dbg(ql_dbg_tgt, vha, 0xe024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) "%s: failed alloc dsd_ptr\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) ha->dif_bundle_kallocs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* allocate dma buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) dsd_ptr->dsd_addr = dma_pool_alloc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) (ha->dif_bundl_pool, GFP_ATOMIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) &dsd_ptr->dsd_list_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (!dsd_ptr->dsd_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) ql_dbg(ql_dbg_tgt, vha, 0xe024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) "%s: failed alloc ->dsd_ptr\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * need to cleanup only this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * dsd_ptr rest will be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * by sp_free_dma()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) kfree(dsd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ha->dif_bundle_kallocs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) ha->dif_bundle_dma_allocs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) ldma_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) difctx->no_dif_bundl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) &difctx->ldif_dma_hndl_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /* xfrlen is min of dma pool size and sglen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) xfrlen = (sglen >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) (DIF_BUNDLING_DMA_POOL_SIZE - ldma_sg_len)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) DIF_BUNDLING_DMA_POOL_SIZE - ldma_sg_len :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) sglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* replace with local allocated dma buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) sg_pcopy_to_buffer(sgl, sg_nents(sgl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) dsd_ptr->dsd_addr + ldma_sg_len, xfrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) difctx->dif_bundl_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) difctx->dif_bundl_len += xfrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) sglen -= xfrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) ldma_sg_len += xfrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (ldma_sg_len == DIF_BUNDLING_DMA_POOL_SIZE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) sg_is_last(sg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) ldma_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) ldma_sg_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) track_difbundl_buf = used_dsds = difctx->no_dif_bundl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe025,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) "dif_bundl_len=%x, no_dif_bundl=%x track_difbundl_buf: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) difctx->dif_bundl_len, difctx->no_dif_bundl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) track_difbundl_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) sp->flags |= SRB_DIF_BUNDL_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) tc->prot_flags = DIF_BUNDL_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) list_for_each_entry_safe(dif_dsd, nxt_dsd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) &difctx->ldif_dma_hndl_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) u32 sglen = (difctx->dif_bundl_len >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) DIF_BUNDLING_DMA_POOL_SIZE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) DIF_BUNDLING_DMA_POOL_SIZE : difctx->dif_bundl_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) BUG_ON(track_difbundl_buf == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 0xe024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) "%s: adding continuation iocb's\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) QLA_DSDS_PER_IOCB : used_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) dsd_list_len = (avail_dsds + 1) * 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) used_dsds -= avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /* allocate tracking DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) dsd_ptr = kzalloc(sizeof(*dsd_ptr), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (!dsd_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) ql_dbg(ql_dbg_tgt, vha, 0xe026,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) "%s: failed alloc dsd_ptr\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) ha->dif_bundle_kallocs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) difctx->no_ldif_dsd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) /* allocate new list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) dsd_ptr->dsd_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) &dsd_ptr->dsd_list_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (!dsd_ptr->dsd_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) ql_dbg(ql_dbg_tgt, vha, 0xe026,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) "%s: failed alloc ->dsd_addr\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) * need to cleanup only this dsd_ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) * rest will be done by sp_free_dma()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) kfree(dsd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ha->dif_bundle_kallocs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ha->dif_bundle_dma_allocs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) &difctx->ldif_dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) sp->flags |= SRB_CRC_CTX_DSD_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) &difctx->ldif_dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) tc->ctx_dsd_alloced = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) /* add new list to cmd iocb or last list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) put_unaligned_le64(dsd_ptr->dsd_list_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) &cur_dsd->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) cur_dsd->length = cpu_to_le32(dsd_list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) cur_dsd = dsd_ptr->dsd_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) put_unaligned_le64(dif_dsd->dsd_list_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) &cur_dsd->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) cur_dsd->length = cpu_to_le32(sglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) cur_dsd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) difctx->dif_bundl_len -= sglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) track_difbundl_buf--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe026,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) "%s: no_ldif_dsd:%x, no_dif_bundl:%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) difctx->no_ldif_dsd, difctx->no_dif_bundl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) for_each_sg(sgl, sg, tot_dsds, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) QLA_DSDS_PER_IOCB : used_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) dsd_list_len = (avail_dsds + 1) * 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) used_dsds -= avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) /* allocate tracking DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) dsd_ptr = kzalloc(sizeof(*dsd_ptr), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (!dsd_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ql_dbg(ql_dbg_tgt + ql_dbg_verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) vha, 0xe027,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) "%s: failed alloc dsd_dma...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) /* allocate new list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) dsd_ptr->dsd_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) &dsd_ptr->dsd_list_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (!dsd_ptr->dsd_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) /* need to cleanup only this dsd_ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /* rest will be done by sp_free_dma() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) kfree(dsd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) &difctx->dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) sp->flags |= SRB_CRC_CTX_DSD_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) list_add_tail(&dsd_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) &difctx->dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) tc->ctx_dsd_alloced = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) /* add new list to cmd iocb or last list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) put_unaligned_le64(dsd_ptr->dsd_list_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) &cur_dsd->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) cur_dsd->length = cpu_to_le32(dsd_list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) cur_dsd = dsd_ptr->dsd_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /* Null termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) cur_dsd->address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) cur_dsd->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) cur_dsd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * qla24xx_build_scsi_crc_2_iocbs() - Build IOCB command utilizing Command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * Type 6 IOCB types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) * @sp: SRB command to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * @cmd_pkt: Command type 3 IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * @tot_dsds: Total number of segments to transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * @tot_prot_dsds: Total number of segments with protection information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * @fw_prot_opts: Protection options to be passed to firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) uint16_t tot_dsds, uint16_t tot_prot_dsds, uint16_t fw_prot_opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) struct dsd64 *cur_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) __be32 *fcp_dl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) scsi_qla_host_t *vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) uint32_t total_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) uint32_t data_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) uint32_t dif_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) uint8_t bundling = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) uint16_t blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) struct crc_context *crc_ctx_pkt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct qla_hw_data *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) uint8_t additional_fcpcdb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) uint16_t fcp_cmnd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct fcp_cmnd *fcp_cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) dma_addr_t crc_ctx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) /* Update entry type to indicate Command Type CRC_2 IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) put_unaligned_le32(COMMAND_TYPE_CRC_2, &cmd_pkt->entry_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) /* No data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) data_bytes = scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (!data_bytes || cmd->sc_data_direction == DMA_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) cmd_pkt->byte_count = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) cmd_pkt->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /* Set transfer direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (cmd->sc_data_direction == DMA_TO_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) cmd_pkt->control_flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) cpu_to_le16(CF_WRITE_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) cmd_pkt->control_flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) cpu_to_le16(CF_READ_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) (scsi_get_prot_op(cmd) == SCSI_PROT_READ_STRIP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_INSERT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) bundling = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) /* Allocate CRC context from global pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) crc_ctx_pkt = sp->u.scmd.crc_ctx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) dma_pool_zalloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (!crc_ctx_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) goto crc_queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) sp->flags |= SRB_CRC_CTX_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* Set handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) crc_ctx_pkt->handle = cmd_pkt->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) qla24xx_set_t10dif_tags(sp, (struct fw_dif_context *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) &crc_ctx_pkt->ref_tag, tot_prot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) put_unaligned_le64(crc_ctx_dma, &cmd_pkt->crc_context_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) cmd_pkt->crc_context_len = cpu_to_le16(CRC_CONTEXT_LEN_FW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) /* Determine SCSI command length -- align to 4 byte boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (cmd->cmd_len > 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) additional_fcpcdb_len = cmd->cmd_len - 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if ((cmd->cmd_len % 4) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) /* SCSI cmd > 16 bytes must be multiple of 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) goto crc_queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) fcp_cmnd_len = 12 + cmd->cmd_len + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) additional_fcpcdb_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) fcp_cmnd_len = 12 + 16 + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) fcp_cmnd = &crc_ctx_pkt->fcp_cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) fcp_cmnd->additional_cdb_len = additional_fcpcdb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (cmd->sc_data_direction == DMA_TO_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) fcp_cmnd->additional_cdb_len |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) fcp_cmnd->additional_cdb_len |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) int_to_scsilun(cmd->device->lun, &fcp_cmnd->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) put_unaligned_le64(crc_ctx_dma + CRC_CONTEXT_FCPCMND_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) &cmd_pkt->fcp_cmnd_dseg_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) fcp_cmnd->task_management = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) fcp_cmnd->task_attribute = TSK_SIMPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) /* Compute dif len and adjust data len to incude protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) dif_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) blk_size = cmd->device->sector_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) dif_bytes = (data_bytes / blk_size) * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) case SCSI_PROT_READ_INSERT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) case SCSI_PROT_WRITE_STRIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) total_bytes = data_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) data_bytes += dif_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) case SCSI_PROT_READ_STRIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) case SCSI_PROT_WRITE_INSERT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) case SCSI_PROT_READ_PASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) case SCSI_PROT_WRITE_PASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) total_bytes = data_bytes + dif_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) if (!qla2x00_hba_err_chk_enabled(sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) fw_prot_opts |= 0x10; /* Disable Guard tag checking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) /* HBA error checking enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) else if (IS_PI_UNINIT_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if ((scsi_get_prot_type(GET_CMD_SP(sp)) == SCSI_PROT_DIF_TYPE1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) || (scsi_get_prot_type(GET_CMD_SP(sp)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) SCSI_PROT_DIF_TYPE2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) fw_prot_opts |= BIT_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) else if (scsi_get_prot_type(GET_CMD_SP(sp)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) SCSI_PROT_DIF_TYPE3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) fw_prot_opts |= BIT_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (!bundling) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) cur_dsd = &crc_ctx_pkt->u.nobundling.data_dsd[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * Configure Bundling if we need to fetch interlaving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * protection PCI accesses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) fw_prot_opts |= PO_ENABLE_DIF_BUNDLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) crc_ctx_pkt->u.bundling.dif_byte_count = cpu_to_le32(dif_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) crc_ctx_pkt->u.bundling.dseg_count = cpu_to_le16(tot_dsds -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) tot_prot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) cur_dsd = &crc_ctx_pkt->u.bundling.data_dsd[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) /* Finish the common fields of CRC pkt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) crc_ctx_pkt->blk_size = cpu_to_le16(blk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) crc_ctx_pkt->prot_opts = cpu_to_le16(fw_prot_opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) crc_ctx_pkt->byte_count = cpu_to_le32(data_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) crc_ctx_pkt->guard_seed = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) /* Fibre channel byte count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) cmd_pkt->byte_count = cpu_to_le32(total_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) fcp_dl = (__be32 *)(crc_ctx_pkt->fcp_cmnd.cdb + 16 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) additional_fcpcdb_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) *fcp_dl = htonl(total_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (!data_bytes || cmd->sc_data_direction == DMA_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) cmd_pkt->byte_count = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) /* Walks data segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) cmd_pkt->control_flags |= cpu_to_le16(CF_DATA_SEG_DESCR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (!bundling && tot_prot_dsds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (qla24xx_walk_and_build_sglist_no_difb(ha, sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) cur_dsd, tot_dsds, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) goto crc_queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) } else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) (tot_dsds - tot_prot_dsds), NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) goto crc_queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (bundling && tot_prot_dsds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /* Walks dif segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) cmd_pkt->control_flags |= cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) cur_dsd = &crc_ctx_pkt->u.bundling.dif_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) tot_prot_dsds, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) goto crc_queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) crc_queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) /* Cleanup will be performed by the caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * qla24xx_start_scsi() - Send a SCSI command to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * @sp: command to send to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) * Returns non-zero if a failure occurred, else zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) qla24xx_start_scsi(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) uint32_t *clr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) uint32_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) struct cmd_type_7 *cmd_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) uint16_t req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) uint16_t tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) struct req_que *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) struct scsi_cmnd *cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) /* Setup device pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) req = vha->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /* So we know we haven't pci_map'ed anything yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) tot_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) /* Send marker if required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (vha->marker_needed != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) /* Acquire ring specific lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) handle = qla2xxx_get_next_handle(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (handle == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /* Map the sg table so we have an accurate count of sg entries needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (scsi_sg_count(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) scsi_sg_count(cmd), cmd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (unlikely(!nseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) tot_dsds = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) sp->iores.res_type = RESOURCE_INI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) sp->iores.iocb_cnt = req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (qla_get_iocbs(sp->qpair, &sp->iores))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (req->cnt < (req_cnt + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) rd_reg_dword_relaxed(req->req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (req->cnt < (req_cnt + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) /* Build command packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) req->current_outstanding_cmd = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) req->outstanding_cmds[handle] = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) sp->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) cmd->host_scribble = (unsigned char *)(unsigned long)handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) req->cnt -= req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) cmd_pkt->handle = make_handle(req->id, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) /* Zero out remaining portion of packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) /* tagged queuing modifier -- default is TSK_SIMPLE (0). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) clr_ptr = (uint32_t *)cmd_pkt + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) /* Set NPORT-ID and LUN number*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) cmd_pkt->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) cmd_pkt->task = TSK_SIMPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) /* Load SCSI command packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) /* Build IOCB segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) qla24xx_build_scsi_iocbs(sp, cmd_pkt, tot_dsds, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) /* Set total data segment count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) cmd_pkt->entry_count = (uint8_t)req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) sp->flags |= SRB_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) /* Set chip new ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) wrt_reg_dword(req->req_q_in, req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) scsi_dma_unmap(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) qla_put_iocbs(sp->qpair, &sp->iores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) * qla24xx_dif_start_scsi() - Send a SCSI command to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * @sp: command to send to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) * Returns non-zero if a failure occurred, else zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) qla24xx_dif_start_scsi(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) uint32_t *clr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) uint32_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) uint16_t req_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) uint16_t tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) uint16_t tot_prot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) uint16_t fw_prot_opts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) struct req_que *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) struct rsp_que *rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) struct scsi_cmnd *cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) struct cmd_type_crc_2 *cmd_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) uint32_t status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) #define QDSS_GOT_Q_SPACE BIT_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) /* Only process protection or >16 cdb in this routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) if (scsi_get_prot_op(cmd) == SCSI_PROT_NORMAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (cmd->cmd_len <= 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) return qla24xx_start_scsi(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) /* Setup device pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) req = vha->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) rsp = req->rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) /* So we know we haven't pci_map'ed anything yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) tot_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) /* Send marker if required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) if (vha->marker_needed != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) /* Acquire ring specific lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) handle = qla2xxx_get_next_handle(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (handle == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) /* Compute number of required data segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) /* Map the sg table so we have an accurate count of sg entries needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) if (scsi_sg_count(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) scsi_sg_count(cmd), cmd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (unlikely(!nseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) sp->flags |= SRB_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) struct qla2_sgx sgx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) uint32_t partial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) memset(&sgx, 0, sizeof(struct qla2_sgx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) sgx.tot_bytes = scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) sgx.cur_sg = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) sgx.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) while (qla24xx_get_one_block_sg(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) cmd->device->sector_size, &sgx, &partial))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) nseg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) /* number of required data segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) tot_dsds = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) /* Compute number of required protection segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if (qla24xx_configure_prot_mode(sp, &fw_prot_opts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) nseg = dma_map_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) scsi_prot_sg_count(cmd), cmd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (unlikely(!nseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) sp->flags |= SRB_CRC_PROT_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) nseg = scsi_bufflen(cmd) / cmd->device->sector_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) req_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) /* Total Data and protection sg segment(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) tot_prot_dsds = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) tot_dsds += nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) sp->iores.res_type = RESOURCE_INI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) sp->iores.iocb_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (qla_get_iocbs(sp->qpair, &sp->iores))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) if (req->cnt < (req_cnt + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) rd_reg_dword_relaxed(req->req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if (req->cnt < (req_cnt + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) status |= QDSS_GOT_Q_SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) /* Build header part of command packet (excluding the OPCODE). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) req->current_outstanding_cmd = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) req->outstanding_cmds[handle] = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) sp->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) cmd->host_scribble = (unsigned char *)(unsigned long)handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) req->cnt -= req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) /* Fill-in common area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) cmd_pkt = (struct cmd_type_crc_2 *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) cmd_pkt->handle = make_handle(req->id, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) clr_ptr = (uint32_t *)cmd_pkt + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) /* Set NPORT-ID and LUN number*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) /* Total Data and protection segment(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) /* Build IOCB segments and adjust for data protection segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (qla24xx_build_scsi_crc_2_iocbs(sp, (struct cmd_type_crc_2 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) req->ring_ptr, tot_dsds, tot_prot_dsds, fw_prot_opts) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) cmd_pkt->entry_count = (uint8_t)req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) /* Specify response queue number where completion should happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) cmd_pkt->entry_status = (uint8_t) rsp->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) cmd_pkt->timeout = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) /* Set chip new ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) wrt_reg_dword(req->req_q_in, req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) if (status & QDSS_GOT_Q_SPACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) req->outstanding_cmds[handle] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) req->cnt += req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) /* Cleanup will be performed by the caller (queuecommand) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) qla_put_iocbs(sp->qpair, &sp->iores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * qla2xxx_start_scsi_mq() - Send a SCSI command to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) * @sp: command to send to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) * Returns non-zero if a failure occurred, else zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) qla2xxx_start_scsi_mq(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) uint32_t *clr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) uint32_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) struct cmd_type_7 *cmd_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) uint16_t req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) uint16_t tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) struct req_que *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) struct scsi_cmnd *cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) struct scsi_qla_host *vha = sp->fcport->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) struct qla_qpair *qpair = sp->qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) /* Acquire qpair specific lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) spin_lock_irqsave(&qpair->qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) /* Setup qpair pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) req = qpair->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) /* So we know we haven't pci_map'ed anything yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) tot_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) /* Send marker if required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (vha->marker_needed != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) if (__qla2x00_marker(vha, qpair, 0, 0, MK_SYNC_ALL) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) spin_unlock_irqrestore(&qpair->qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) handle = qla2xxx_get_next_handle(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) if (handle == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) /* Map the sg table so we have an accurate count of sg entries needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (scsi_sg_count(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) scsi_sg_count(cmd), cmd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (unlikely(!nseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) tot_dsds = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) sp->iores.res_type = RESOURCE_INI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) sp->iores.iocb_cnt = req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (qla_get_iocbs(sp->qpair, &sp->iores))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (req->cnt < (req_cnt + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) rd_reg_dword_relaxed(req->req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) if (req->cnt < (req_cnt + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) /* Build command packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) req->current_outstanding_cmd = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) req->outstanding_cmds[handle] = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) sp->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) cmd->host_scribble = (unsigned char *)(unsigned long)handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) req->cnt -= req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) cmd_pkt->handle = make_handle(req->id, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) /* Zero out remaining portion of packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) /* tagged queuing modifier -- default is TSK_SIMPLE (0). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) clr_ptr = (uint32_t *)cmd_pkt + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) /* Set NPORT-ID and LUN number*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) cmd_pkt->vp_index = sp->fcport->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) cmd_pkt->task = TSK_SIMPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) /* Load SCSI command packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) /* Build IOCB segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) qla24xx_build_scsi_iocbs(sp, cmd_pkt, tot_dsds, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) /* Set total data segment count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) cmd_pkt->entry_count = (uint8_t)req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) sp->flags |= SRB_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) /* Set chip new ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) wrt_reg_dword(req->req_q_in, req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) spin_unlock_irqrestore(&qpair->qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) if (tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) scsi_dma_unmap(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) qla_put_iocbs(sp->qpair, &sp->iores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) spin_unlock_irqrestore(&qpair->qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) * qla2xxx_dif_start_scsi_mq() - Send a SCSI command to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * @sp: command to send to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) * Returns non-zero if a failure occurred, else zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) qla2xxx_dif_start_scsi_mq(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) uint32_t *clr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) uint32_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) uint16_t req_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) uint16_t tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) uint16_t tot_prot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) uint16_t fw_prot_opts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) struct req_que *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) struct rsp_que *rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) struct scsi_cmnd *cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) struct scsi_qla_host *vha = sp->fcport->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) struct cmd_type_crc_2 *cmd_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) uint32_t status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) struct qla_qpair *qpair = sp->qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) #define QDSS_GOT_Q_SPACE BIT_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) /* Check for host side state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) if (!qpair->online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) cmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) return QLA_INTERFACE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) if (!qpair->difdix_supported &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) cmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) return QLA_INTERFACE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) /* Only process protection or >16 cdb in this routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if (scsi_get_prot_op(cmd) == SCSI_PROT_NORMAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) if (cmd->cmd_len <= 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) return qla2xxx_start_scsi_mq(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) spin_lock_irqsave(&qpair->qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) /* Setup qpair pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) rsp = qpair->rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) req = qpair->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) /* So we know we haven't pci_map'ed anything yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) tot_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) /* Send marker if required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) if (vha->marker_needed != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) if (__qla2x00_marker(vha, qpair, 0, 0, MK_SYNC_ALL) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) spin_unlock_irqrestore(&qpair->qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) handle = qla2xxx_get_next_handle(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (handle == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) /* Compute number of required data segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) /* Map the sg table so we have an accurate count of sg entries needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) if (scsi_sg_count(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) scsi_sg_count(cmd), cmd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) if (unlikely(!nseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) sp->flags |= SRB_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) struct qla2_sgx sgx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) uint32_t partial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) memset(&sgx, 0, sizeof(struct qla2_sgx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) sgx.tot_bytes = scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) sgx.cur_sg = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) sgx.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) while (qla24xx_get_one_block_sg(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) cmd->device->sector_size, &sgx, &partial))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) nseg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) /* number of required data segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) tot_dsds = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) /* Compute number of required protection segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if (qla24xx_configure_prot_mode(sp, &fw_prot_opts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) nseg = dma_map_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) scsi_prot_sg_count(cmd), cmd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) if (unlikely(!nseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) sp->flags |= SRB_CRC_PROT_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) nseg = scsi_bufflen(cmd) / cmd->device->sector_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) req_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) /* Total Data and protection sg segment(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) tot_prot_dsds = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) tot_dsds += nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) sp->iores.res_type = RESOURCE_INI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) sp->iores.iocb_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) if (qla_get_iocbs(sp->qpair, &sp->iores))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if (req->cnt < (req_cnt + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) rd_reg_dword_relaxed(req->req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if (req->cnt < (req_cnt + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) status |= QDSS_GOT_Q_SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) /* Build header part of command packet (excluding the OPCODE). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) req->current_outstanding_cmd = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) req->outstanding_cmds[handle] = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) sp->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) cmd->host_scribble = (unsigned char *)(unsigned long)handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) req->cnt -= req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) /* Fill-in common area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) cmd_pkt = (struct cmd_type_crc_2 *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) cmd_pkt->handle = make_handle(req->id, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) clr_ptr = (uint32_t *)cmd_pkt + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) /* Set NPORT-ID and LUN number*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) /* Total Data and protection segment(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) /* Build IOCB segments and adjust for data protection segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) if (qla24xx_build_scsi_crc_2_iocbs(sp, (struct cmd_type_crc_2 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) req->ring_ptr, tot_dsds, tot_prot_dsds, fw_prot_opts) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) cmd_pkt->entry_count = (uint8_t)req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) cmd_pkt->timeout = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) /* Set chip new ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) wrt_reg_dword(req->req_q_in, req->ring_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) /* Manage unprocessed RIO/ZIO commands in response queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) if (vha->flags.process_response_queue &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) rsp->ring_ptr->signature != RESPONSE_PROCESSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) qla24xx_process_response_queue(vha, rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) spin_unlock_irqrestore(&qpair->qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) if (status & QDSS_GOT_Q_SPACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) req->outstanding_cmds[handle] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) req->cnt += req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) /* Cleanup will be performed by the caller (queuecommand) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) qla_put_iocbs(sp->qpair, &sp->iores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) spin_unlock_irqrestore(&qpair->qp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) /* Generic Control-SRB manipulation functions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) /* hardware_lock assumed to be held. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) scsi_qla_host_t *vha = qpair->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) struct req_que *req = qpair->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) device_reg_t *reg = ISP_QUE_REG(ha, req->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) uint32_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) request_t *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) uint16_t cnt, req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) pkt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) req_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) handle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) if (sp && (sp->type != SRB_SCSI_CMD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) /* Adjust entry-counts as needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) req_cnt = sp->iocbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) /* Check for room on request queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if (req->cnt < req_cnt + 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) if (qpair->use_shadow_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) cnt = *req->out_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) else if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) IS_QLA28XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) cnt = rd_reg_dword(®->isp25mq.req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) else if (IS_P3P_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) cnt = rd_reg_dword(reg->isp82.req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) else if (IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) cnt = rd_reg_dword(®->isp24.req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) else if (IS_QLAFX00(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) cnt = rd_reg_dword(®->ispfx00.req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) cnt = qla2x00_debounce_register(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) ISP_REQ_Q_OUT(ha, ®->isp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) if (req->cnt < req_cnt + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) handle = qla2xxx_get_next_handle(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) if (handle == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) ql_log(ql_log_warn, vha, 0x700b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) "No room on outstanding cmd array.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) /* Prep command array. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) req->current_outstanding_cmd = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) req->outstanding_cmds[handle] = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) sp->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) /* Prep packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) req->cnt -= req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) pkt = req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) memset(pkt, 0, REQUEST_ENTRY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) if (IS_QLAFX00(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) wrt_reg_byte((u8 __force __iomem *)&pkt->entry_count, req_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) wrt_reg_dword((__le32 __force __iomem *)&pkt->handle, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) pkt->entry_count = req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) pkt->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) return pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) qpair->tgt_counters.num_alloc_iocb_failed++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) return pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) qla2x00_alloc_iocbs_ready(struct qla_qpair *qpair, srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) scsi_qla_host_t *vha = qpair->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) if (qla2x00_reset_active(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) return __qla2x00_alloc_iocbs(qpair, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) qla2x00_alloc_iocbs(struct scsi_qla_host *vha, srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) return __qla2x00_alloc_iocbs(vha->hw->base_qpair, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) logio->control_flags |= cpu_to_le16(LCF_NVME_PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) if (sp->vha->flags.nvme_first_burst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) logio->io_parameter[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) cpu_to_le32(NVME_PRLI_SP_FIRST_BURST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) if (sp->vha->flags.nvme2_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) /* Set service parameter BIT_8 for SLER support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) logio->io_parameter[0] |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) cpu_to_le32(NVME_PRLI_SP_SLER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) /* Set service parameter BIT_9 for PI control support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) logio->io_parameter[0] |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) cpu_to_le32(NVME_PRLI_SP_PI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) logio->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) logio->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) logio->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) logio->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) if (lio->u.logio.flags & SRB_LOGIN_PRLI_ONLY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) if (lio->u.logio.flags & SRB_LOGIN_COND_PLOGI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) if (lio->u.logio.flags & SRB_LOGIN_SKIP_PRLI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) logio->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) logio->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) logio->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) logio->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) logio->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) struct qla_hw_data *ha = sp->vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) uint16_t opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) mbx->entry_type = MBX_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) mbx->mb0 = cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) opts = lio->u.logio.flags & SRB_LOGIN_COND_PLOGI ? BIT_0 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) opts |= lio->u.logio.flags & SRB_LOGIN_SKIP_PRLI ? BIT_1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) if (HAS_EXTENDED_IDS(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) mbx->mb1 = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) mbx->mb10 = cpu_to_le16(opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) mbx->mb1 = cpu_to_le16((sp->fcport->loop_id << 8) | opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) sp->fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) mbx->mb9 = cpu_to_le16(sp->vha->vp_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) u16 control_flags = LCF_COMMAND_LOGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (sp->fcport->explicit_logout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) control_flags |= LCF_EXPL_LOGO|LCF_FREE_NPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) control_flags |= LCF_IMPL_LOGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) if (!sp->fcport->keep_nport_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) control_flags |= LCF_FREE_NPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) logio->control_flags = cpu_to_le16(control_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) logio->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) logio->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) logio->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) logio->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) struct qla_hw_data *ha = sp->vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) mbx->entry_type = MBX_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) mbx->mb0 = cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) mbx->mb1 = HAS_EXTENDED_IDS(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) cpu_to_le16(sp->fcport->loop_id) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) cpu_to_le16(sp->fcport->loop_id << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) sp->fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) mbx->mb9 = cpu_to_le16(sp->vha->vp_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) /* Implicit: mbx->mbx10 = 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) qla24xx_adisc_iocb(srb_t *sp, struct logio_entry_24xx *logio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) logio->control_flags = cpu_to_le16(LCF_COMMAND_ADISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) logio->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) qla2x00_adisc_iocb(srb_t *sp, struct mbx_entry *mbx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) struct qla_hw_data *ha = sp->vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) mbx->entry_type = MBX_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) mbx->mb0 = cpu_to_le16(MBC_GET_PORT_DATABASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) if (HAS_EXTENDED_IDS(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) mbx->mb1 = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) mbx->mb10 = cpu_to_le16(BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) mbx->mb1 = cpu_to_le16((sp->fcport->loop_id << 8) | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) mbx->mb2 = cpu_to_le16(MSW(ha->async_pd_dma));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) mbx->mb3 = cpu_to_le16(LSW(ha->async_pd_dma));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) mbx->mb6 = cpu_to_le16(MSW(MSD(ha->async_pd_dma)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) mbx->mb7 = cpu_to_le16(LSW(MSD(ha->async_pd_dma)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) mbx->mb9 = cpu_to_le16(sp->vha->vp_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) uint32_t flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) uint64_t lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) struct fc_port *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) scsi_qla_host_t *vha = fcport->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) struct srb_iocb *iocb = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) struct req_que *req = vha->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) flags = iocb->u.tmf.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) lun = iocb->u.tmf.lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) tsk->entry_type = TSK_MGMT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) tsk->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) tsk->handle = make_handle(req->id, tsk->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) tsk->nport_handle = cpu_to_le16(fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) tsk->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) tsk->control_flags = cpu_to_le32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) tsk->port_id[0] = fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) tsk->port_id[1] = fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) tsk->port_id[2] = fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) tsk->vp_index = fcport->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) if (flags == TCF_LUN_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) int_to_scsilun(lun, &tsk->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) host_to_fcp_swap((uint8_t *)&tsk->lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) sizeof(tsk->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) void qla2x00_init_timer(srb_t *sp, unsigned long tmo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) timer_setup(&sp->u.iocb_cmd.timer, qla2x00_sp_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) sp->free = qla2x00_sp_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) if (IS_QLAFX00(sp->vha->hw) && sp->type == SRB_FXIOCB_DCMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) sp->start_timer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) static void qla2x00_els_dcmd_sp_free(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) struct srb_iocb *elsio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) kfree(sp->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) if (elsio->u.els_logo.els_logo_pyld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) dma_free_coherent(&sp->vha->hw->pdev->dev, DMA_POOL_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) elsio->u.els_logo.els_logo_pyld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) elsio->u.els_logo.els_logo_pyld_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) del_timer(&elsio->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) qla2x00_rel_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) qla2x00_els_dcmd_iocb_timeout(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) srb_t *sp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) int res, h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) ql_dbg(ql_dbg_io, vha, 0x3069,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) "%s Timeout, hdl=%x, portid=%02x%02x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) /* Abort the exchange */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) res = qla24xx_async_abort_cmd(sp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) ql_dbg(ql_dbg_io, vha, 0x3070,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) "mbx abort_command failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) if (sp->qpair->req->outstanding_cmds[h] == sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) sp->qpair->req->outstanding_cmds[h] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) complete(&lio->u.els_logo.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) ql_dbg(ql_dbg_io, vha, 0x3071,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) "mbx abort_command success.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) ql_dbg(ql_dbg_io, vha, 0x3072,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) "%s hdl=%x, portid=%02x%02x%02x done\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) sp->name, sp->handle, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) complete(&lio->u.els_logo.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) port_id_t remote_did)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) fc_port_t *fcport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) struct srb_iocb *elsio = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) struct els_logo_payload logo_pyld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) if (!fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) ql_log(ql_log_info, vha, 0x70e5, "fcport allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) /* Alloc SRB structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) if (!sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) kfree(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) ql_log(ql_log_info, vha, 0x70e6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) "SRB allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) elsio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) fcport->loop_id = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) fcport->d_id.b.domain = remote_did.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) fcport->d_id.b.area = remote_did.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) fcport->d_id.b.al_pa = remote_did.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) ql_dbg(ql_dbg_io, vha, 0x3073, "portid=%02x%02x%02x done\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) sp->type = SRB_ELS_DCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) sp->name = "ELS_DCMD";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) sp->fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) sp->done = qla2x00_els_dcmd_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) sp->free = qla2x00_els_dcmd_sp_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) elsio->u.els_logo.els_logo_pyld = dma_alloc_coherent(&ha->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) DMA_POOL_SIZE, &elsio->u.els_logo.els_logo_pyld_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) if (!elsio->u.els_logo.els_logo_pyld) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) memset(&logo_pyld, 0, sizeof(struct els_logo_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) elsio->u.els_logo.els_cmd = els_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) logo_pyld.opcode = els_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) logo_pyld.s_id[0] = vha->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) logo_pyld.s_id[1] = vha->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) logo_pyld.s_id[2] = vha->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) host_to_fcp_swap(logo_pyld.s_id, sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) memcpy(&logo_pyld.wwpn, vha->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) memcpy(elsio->u.els_logo.els_logo_pyld, &logo_pyld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) sizeof(struct els_logo_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3075, "LOGO buffer:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x010a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) elsio->u.els_logo.els_logo_pyld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) sizeof(*elsio->u.els_logo.els_logo_pyld));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) ql_dbg(ql_dbg_io, vha, 0x3074,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) "%s LOGO sent, hdl=%x, loopid=%x, portid=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) sp->name, sp->handle, fcport->loop_id, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) wait_for_completion(&elsio->u.els_logo.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) scsi_qla_host_t *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) struct srb_iocb *elsio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) els_iocb->entry_type = ELS_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) els_iocb->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) els_iocb->sys_define = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) els_iocb->entry_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) els_iocb->handle = sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) els_iocb->tx_dsd_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) els_iocb->vp_index = vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) els_iocb->sof_type = EST_SOFI3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) els_iocb->rx_dsd_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) els_iocb->opcode = elsio->u.els_logo.els_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) els_iocb->d_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) els_iocb->d_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) els_iocb->d_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) /* For SID the byte order is different than DID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) els_iocb->s_id[1] = vha->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) els_iocb->s_id[2] = vha->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) els_iocb->s_id[0] = vha->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) els_iocb->control_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) els_iocb->tx_byte_count = els_iocb->tx_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) cpu_to_le32(sizeof(struct els_plogi_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) put_unaligned_le64(elsio->u.els_plogi.els_plogi_pyld_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) &els_iocb->tx_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) els_iocb->rx_dsd_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) els_iocb->rx_byte_count = els_iocb->rx_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) cpu_to_le32(sizeof(struct els_plogi_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) put_unaligned_le64(elsio->u.els_plogi.els_resp_pyld_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) &els_iocb->rx_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) "PLOGI ELS IOCB:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) ql_dump_buffer(ql_log_info, vha, 0x0109,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) (uint8_t *)els_iocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) sizeof(*els_iocb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) els_iocb->control_flags = cpu_to_le16(1 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) els_iocb->tx_byte_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) cpu_to_le32(sizeof(struct els_logo_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) put_unaligned_le64(elsio->u.els_logo.els_logo_pyld_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) &els_iocb->tx_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) els_iocb->tx_len = cpu_to_le32(sizeof(struct els_logo_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) els_iocb->rx_byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) els_iocb->rx_address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) els_iocb->rx_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3076,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) "LOGO ELS IOCB:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) ql_dump_buffer(ql_log_info, vha, 0x010b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) els_iocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) sizeof(*els_iocb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) sp->vha->qla_stats.control_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) qla2x00_els_dcmd2_iocb_timeout(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) srb_t *sp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) int res, h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3069,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) "%s hdl=%x ELS Timeout, %8phC portid=%06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) sp->name, sp->handle, fcport->port_name, fcport->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) /* Abort the exchange */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) res = qla24xx_async_abort_cmd(sp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) ql_dbg(ql_dbg_io, vha, 0x3070,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) "mbx abort_command %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) (res == QLA_SUCCESS) ? "successful" : "failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) if (sp->qpair->req->outstanding_cmds[h] == sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) sp->qpair->req->outstanding_cmds[h] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) sp->done(sp, QLA_FUNCTION_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) if (els_plogi->els_plogi_pyld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) els_plogi->tx_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) els_plogi->els_plogi_pyld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) els_plogi->els_plogi_pyld_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) if (els_plogi->els_resp_pyld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) els_plogi->rx_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) els_plogi->els_resp_pyld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) els_plogi->els_resp_pyld_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) struct fc_port *conflict_fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) port_id_t cid; /* conflict Nport id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) const __le32 *fw_status = sp->u.iocb_cmd.u.els_plogi.fw_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) u16 lid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) ql_dbg(ql_dbg_disc, vha, 0x3072,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) "%s ELS done rc %d hdl=%x, portid=%06x %8phC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) del_timer(&sp->u.iocb_cmd.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) if (sp->flags & SRB_WAKEUP_ON_COMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) complete(&lio->u.els_plogi.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) switch (le32_to_cpu(fw_status[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) case CS_DATA_UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) case CS_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) ea.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) ea.rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) qla_handle_els_plogi_done(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) case CS_IOCB_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) switch (le32_to_cpu(fw_status[1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) case LSC_SCODE_PORTID_USED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) lid = le32_to_cpu(fw_status[2]) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) qlt_find_sess_invalidate_other(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) wwn_to_u64(fcport->port_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) fcport->d_id, lid, &conflict_fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) if (conflict_fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) * Another fcport shares the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) * loop_id & nport id; conflict
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) * fcport needs to finish cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) * before this fcport can proceed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) * to login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) conflict_fcport->conflict = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) fcport->login_pause = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) ql_dbg(ql_dbg_disc, vha, 0x20ed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) "%s %d %8phC pid %06x inuse with lid %#x post gidpn\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) fcport->d_id.b24, lid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) ql_dbg(ql_dbg_disc, vha, 0x20ed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) "%s %d %8phC pid %06x inuse with lid %#x sched del\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) fcport->d_id.b24, lid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) qla2x00_clear_loop_id(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) set_bit(lid, vha->hw->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) fcport->loop_id = lid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) fcport->keep_nport_handle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) case LSC_SCODE_NPORT_USED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) cid.b.domain = (le32_to_cpu(fw_status[2]) >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) cid.b.area = (le32_to_cpu(fw_status[2]) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) cid.b.al_pa = le32_to_cpu(fw_status[2]) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) cid.b.rsvd_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) ql_dbg(ql_dbg_disc, vha, 0x20ec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) "%s %d %8phC lid %#x in use with pid %06x post gnl\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) __func__, __LINE__, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) fcport->loop_id, cid.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) set_bit(fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) vha->hw->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) fcport->loop_id = FC_NO_LOOP_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) qla24xx_post_gnl_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) case LSC_SCODE_NOXCB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) vha->hw->exch_starvation++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) if (vha->hw->exch_starvation > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) ql_log(ql_log_warn, vha, 0xd046,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) "Exchange starvation. Resetting RISC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) vha->hw->exch_starvation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) set_bit(ISP_ABORT_NEEDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) qla2xxx_wake_dpc(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) ql_dbg(ql_dbg_disc, vha, 0x20eb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) "%s %8phC cmd error fw_status 0x%x 0x%x 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) __func__, sp->fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) fw_status[0], fw_status[1], fw_status[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) ql_dbg(ql_dbg_disc, vha, 0x20eb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) "%s %8phC cmd error 2 fw_status 0x%x 0x%x 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) __func__, sp->fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) fw_status[0], fw_status[1], fw_status[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) sp->fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) if (!e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) struct srb_iocb *elsio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) e->u.iosb.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) fc_port_t *fcport, bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) struct srb_iocb *elsio = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) void *ptr, *resp_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) /* Alloc SRB structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) if (!sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) ql_log(ql_log_info, vha, 0x70e6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) "SRB allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) fcport->flags &= ~FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) elsio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) ql_dbg(ql_dbg_io, vha, 0x3073,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) "Enter: PLOGI portid=%06x\n", fcport->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) sp->type = SRB_ELS_DCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) sp->name = "ELS_DCMD";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) sp->fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) elsio->timeout = qla2x00_els_dcmd2_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) sp->flags = SRB_WAKEUP_ON_COMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) sp->done = qla2x00_els_dcmd2_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) elsio->u.els_plogi.tx_size = elsio->u.els_plogi.rx_size = DMA_POOL_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) ptr = elsio->u.els_plogi.els_plogi_pyld =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) dma_alloc_coherent(&ha->pdev->dev, elsio->u.els_plogi.tx_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) &elsio->u.els_plogi.els_plogi_pyld_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) if (!elsio->u.els_plogi.els_plogi_pyld) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) resp_ptr = elsio->u.els_plogi.els_resp_pyld =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) dma_alloc_coherent(&ha->pdev->dev, elsio->u.els_plogi.rx_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) &elsio->u.els_plogi.els_resp_pyld_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) if (!elsio->u.els_plogi.els_resp_pyld) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) ql_dbg(ql_dbg_io, vha, 0x3073, "PLOGI %p %p\n", ptr, resp_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) memset(ptr, 0, sizeof(struct els_plogi_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) memset(resp_ptr, 0, sizeof(struct els_plogi_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) memcpy(elsio->u.els_plogi.els_plogi_pyld->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) &ha->plogi_els_payld.fl_csp, LOGIN_TEMPLATE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) elsio->u.els_plogi.els_cmd = els_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) (uint8_t *)elsio->u.els_plogi.els_plogi_pyld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) sizeof(*elsio->u.els_plogi.els_plogi_pyld));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) init_completion(&elsio->u.els_plogi.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) ql_dbg(ql_dbg_disc, vha, 0x3074,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) "%s PLOGI sent, hdl=%x, loopid=%x, to port_id %06x from port_id %06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) sp->name, sp->handle, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) fcport->d_id.b24, vha->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) if (wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) wait_for_completion(&elsio->u.els_plogi.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) if (elsio->u.els_plogi.comp_status != CS_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) struct bsg_job *bsg_job = sp->u.bsg_job;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) struct fc_bsg_request *bsg_request = bsg_job->request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) els_iocb->entry_type = ELS_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) els_iocb->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) els_iocb->sys_define = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) els_iocb->entry_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) els_iocb->handle = sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) els_iocb->tx_dsd_count = cpu_to_le16(bsg_job->request_payload.sg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) els_iocb->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) els_iocb->sof_type = EST_SOFI3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) els_iocb->rx_dsd_count = cpu_to_le16(bsg_job->reply_payload.sg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) els_iocb->opcode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) sp->type == SRB_ELS_CMD_RPT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) bsg_request->rqst_data.r_els.els_code :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) bsg_request->rqst_data.h_els.command_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) els_iocb->d_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) els_iocb->d_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) els_iocb->d_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) els_iocb->control_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) els_iocb->rx_byte_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) cpu_to_le32(bsg_job->reply_payload.payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) els_iocb->tx_byte_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) cpu_to_le32(bsg_job->request_payload.payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) put_unaligned_le64(sg_dma_address(bsg_job->request_payload.sg_list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) &els_iocb->tx_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) els_iocb->tx_len = cpu_to_le32(sg_dma_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) (bsg_job->request_payload.sg_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) put_unaligned_le64(sg_dma_address(bsg_job->reply_payload.sg_list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) &els_iocb->rx_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) els_iocb->rx_len = cpu_to_le32(sg_dma_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) (bsg_job->reply_payload.sg_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) sp->vha->qla_stats.control_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) uint16_t avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) struct dsd64 *cur_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) uint16_t tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) scsi_qla_host_t *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) struct bsg_job *bsg_job = sp->u.bsg_job;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) int entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) memset(ct_iocb, 0, sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) ct_iocb->entry_type = CT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) ct_iocb->entry_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) ct_iocb->handle1 = sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) SET_TARGET_ID(ha, ct_iocb->loop_id, sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) ct_iocb->status = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) ct_iocb->control_flags = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) ct_iocb->timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) ct_iocb->cmd_dsd_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) cpu_to_le16(bsg_job->request_payload.sg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) ct_iocb->total_dsd_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) cpu_to_le16(bsg_job->request_payload.sg_cnt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) ct_iocb->req_bytecount =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) cpu_to_le32(bsg_job->request_payload.payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) ct_iocb->rsp_bytecount =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) cpu_to_le32(bsg_job->reply_payload.payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) put_unaligned_le64(sg_dma_address(bsg_job->request_payload.sg_list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) &ct_iocb->req_dsd.address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) ct_iocb->req_dsd.length = ct_iocb->req_bytecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) put_unaligned_le64(sg_dma_address(bsg_job->reply_payload.sg_list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) &ct_iocb->rsp_dsd.address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) ct_iocb->rsp_dsd.length = ct_iocb->rsp_bytecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) avail_dsds = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) cur_dsd = &ct_iocb->rsp_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) tot_dsds = bsg_job->reply_payload.sg_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) for_each_sg(bsg_job->reply_payload.sg_list, sg, tot_dsds, index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) cont_a64_entry_t *cont_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) * Five DSDs are available in the Cont.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) * Type 1 IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) cont_pkt = qla2x00_prep_cont_type1_iocb(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) vha->hw->req_q_map[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) cur_dsd = cont_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) avail_dsds = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) entry_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) ct_iocb->entry_count = entry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) sp->vha->qla_stats.control_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) uint16_t avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) struct dsd64 *cur_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) uint16_t cmd_dsds, rsp_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) scsi_qla_host_t *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) struct bsg_job *bsg_job = sp->u.bsg_job;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) int entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) cont_a64_entry_t *cont_pkt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) ct_iocb->entry_type = CT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) ct_iocb->entry_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) ct_iocb->sys_define = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) ct_iocb->handle = sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) ct_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) ct_iocb->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) ct_iocb->comp_status = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) cmd_dsds = bsg_job->request_payload.sg_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) rsp_dsds = bsg_job->reply_payload.sg_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) ct_iocb->cmd_dsd_count = cpu_to_le16(cmd_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) ct_iocb->timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) ct_iocb->rsp_dsd_count = cpu_to_le16(rsp_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) ct_iocb->cmd_byte_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) cpu_to_le32(bsg_job->request_payload.payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) avail_dsds = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) cur_dsd = ct_iocb->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) for_each_sg(bsg_job->request_payload.sg_list, sg, cmd_dsds, index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) * Five DSDs are available in the Cont.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) * Type 1 IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) cont_pkt = qla2x00_prep_cont_type1_iocb(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) vha, ha->req_q_map[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) cur_dsd = cont_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) avail_dsds = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) entry_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) for_each_sg(bsg_job->reply_payload.sg_list, sg, rsp_dsds, index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) /* Allocate additional continuation packets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) * Five DSDs are available in the Cont.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) * Type 1 IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) cont_pkt = qla2x00_prep_cont_type1_iocb(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) ha->req_q_map[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) cur_dsd = cont_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) avail_dsds = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) entry_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) ct_iocb->entry_count = entry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) * qla82xx_start_scsi() - Send a SCSI command to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) * @sp: command to send to the ISP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) * Returns non-zero if a failure occurred, else zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) qla82xx_start_scsi(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) uint32_t *clr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) uint32_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) uint16_t req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) uint16_t tot_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) struct device_reg_82xx __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) uint32_t dbval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) __be32 *fcp_dl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) uint8_t additional_cdb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) struct ct6_dsd *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) struct req_que *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) struct rsp_que *rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) /* Setup device pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) reg = &ha->iobase->isp82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) cmd = GET_CMD_SP(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) req = vha->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) rsp = ha->rsp_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) /* So we know we haven't pci_map'ed anything yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) tot_dsds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) dbval = 0x04 | (ha->portnum << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) /* Send marker if required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) if (vha->marker_needed != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) if (qla2x00_marker(vha, ha->base_qpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 0, 0, MK_SYNC_ALL) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) ql_log(ql_log_warn, vha, 0x300c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) "qla2x00_marker failed for cmd=%p.\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) /* Acquire ring specific lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) handle = qla2xxx_get_next_handle(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) if (handle == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) /* Map the sg table so we have an accurate count of sg entries needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) if (scsi_sg_count(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) scsi_sg_count(cmd), cmd->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) if (unlikely(!nseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) nseg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) tot_dsds = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) if (tot_dsds > ql2xshiftctondsd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) struct cmd_type_6 *cmd_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) uint16_t more_dsd_lists = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) struct dsd_dma *dsd_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) uint16_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) more_dsd_lists = qla24xx_calc_dsd_lists(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) if ((more_dsd_lists + ha->gbl_dsd_inuse) >= NUM_DSD_CHAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) ql_dbg(ql_dbg_io, vha, 0x300d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) "Num of DSD list %d is than %d for cmd=%p.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) more_dsd_lists + ha->gbl_dsd_inuse, NUM_DSD_CHAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) if (more_dsd_lists <= ha->gbl_dsd_avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) goto sufficient_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) more_dsd_lists -= ha->gbl_dsd_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) for (i = 0; i < more_dsd_lists; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) if (!dsd_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) ql_log(ql_log_fatal, vha, 0x300e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) "Failed to allocate memory for dsd_dma "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) "for cmd=%p.\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) dsd_ptr->dsd_addr = dma_pool_alloc(ha->dl_dma_pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) GFP_ATOMIC, &dsd_ptr->dsd_list_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) if (!dsd_ptr->dsd_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) kfree(dsd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) ql_log(ql_log_fatal, vha, 0x300f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) "Failed to allocate memory for dsd_addr "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) "for cmd=%p.\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) list_add_tail(&dsd_ptr->list, &ha->gbl_dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) ha->gbl_dsd_avail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) sufficient_dsds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) req_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) if (req->cnt < (req_cnt + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) cnt = (uint16_t)rd_reg_dword_relaxed(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) ®->req_q_out[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) if (req->cnt < (req_cnt + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) ctx = sp->u.scmd.ct6_ctx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) if (!ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) ql_log(ql_log_fatal, vha, 0x3010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) "Failed to allocate ctx for cmd=%p.\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) memset(ctx, 0, sizeof(struct ct6_dsd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) GFP_ATOMIC, &ctx->fcp_cmnd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) if (!ctx->fcp_cmnd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) ql_log(ql_log_fatal, vha, 0x3011,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) /* Initialize the DSD list and dma handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) INIT_LIST_HEAD(&ctx->dsd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) ctx->dsd_use_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) if (cmd->cmd_len > 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) additional_cdb_len = cmd->cmd_len - 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) if ((cmd->cmd_len % 4) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) /* SCSI command bigger than 16 bytes must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) * multiple of 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) ql_log(ql_log_warn, vha, 0x3012,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) "scsi cmd len %d not multiple of 4 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) "for cmd=%p.\n", cmd->cmd_len, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) goto queuing_error_fcp_cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) ctx->fcp_cmnd_len = 12 + cmd->cmd_len + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) additional_cdb_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) ctx->fcp_cmnd_len = 12 + 16 + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) cmd_pkt = (struct cmd_type_6 *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) cmd_pkt->handle = make_handle(req->id, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) /* Zero out remaining portion of packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) /* tagged queuing modifier -- default is TSK_SIMPLE (0). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) clr_ptr = (uint32_t *)cmd_pkt + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) /* Set NPORT-ID and LUN number*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) cmd_pkt->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) /* Build IOCB segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) if (qla24xx_build_scsi_type_6_iocbs(sp, cmd_pkt, tot_dsds))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) goto queuing_error_fcp_cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) /* build FCP_CMND IU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) if (cmd->sc_data_direction == DMA_TO_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) ctx->fcp_cmnd->additional_cdb_len |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) ctx->fcp_cmnd->additional_cdb_len |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) /* Populate the FCP_PRIO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) if (ha->flags.fcp_prio_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) ctx->fcp_cmnd->task_attribute |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) sp->fcport->fcp_prio << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) fcp_dl = (__be32 *)(ctx->fcp_cmnd->cdb + 16 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) additional_cdb_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) *fcp_dl = htonl((uint32_t)scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) put_unaligned_le64(ctx->fcp_cmnd_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) &cmd_pkt->fcp_cmnd_dseg_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) sp->flags |= SRB_FCP_CMND_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) /* Set total data segment count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) cmd_pkt->entry_count = (uint8_t)req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) /* Specify response queue number where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) * completion should happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) cmd_pkt->entry_status = (uint8_t) rsp->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) struct cmd_type_7 *cmd_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) if (req->cnt < (req_cnt + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) cnt = (uint16_t)rd_reg_dword_relaxed(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) ®->req_q_out[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) if (req->cnt < (req_cnt + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) cmd_pkt->handle = make_handle(req->id, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) /* Zero out remaining portion of packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) /* tagged queuing modifier -- default is TSK_SIMPLE (0).*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) clr_ptr = (uint32_t *)cmd_pkt + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) /* Set NPORT-ID and LUN number*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) cmd_pkt->vp_index = sp->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) host_to_fcp_swap((uint8_t *)&cmd_pkt->lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) sizeof(cmd_pkt->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) /* Populate the FCP_PRIO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) if (ha->flags.fcp_prio_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) cmd_pkt->task |= sp->fcport->fcp_prio << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) /* Load SCSI command packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) /* Build IOCB segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) qla24xx_build_scsi_iocbs(sp, cmd_pkt, tot_dsds, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) /* Set total data segment count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) cmd_pkt->entry_count = (uint8_t)req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) /* Specify response queue number where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) * completion should happen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) cmd_pkt->entry_status = (uint8_t) rsp->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) /* Build command packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) req->current_outstanding_cmd = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) req->outstanding_cmds[handle] = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) sp->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) cmd->host_scribble = (unsigned char *)(unsigned long)handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) req->cnt -= req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) /* Adjust ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) req->ring_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) if (req->ring_index == req->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) req->ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) req->ring_ptr = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) req->ring_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) sp->flags |= SRB_DMA_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) /* Set chip new ring index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) /* write, read and verify logic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) dbval = dbval | (req->id << 8) | (req->ring_index << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) if (ql2xdbwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr, dbval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) wrt_reg_dword(ha->nxdb_wr_ptr, dbval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) while (rd_reg_dword(ha->nxdb_rd_ptr) != dbval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) wrt_reg_dword(ha->nxdb_wr_ptr, dbval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) /* Manage unprocessed RIO/ZIO commands in response queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) if (vha->flags.process_response_queue &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) rsp->ring_ptr->signature != RESPONSE_PROCESSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) qla24xx_process_response_queue(vha, rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) queuing_error_fcp_cmnd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) if (tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) scsi_dma_unmap(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) if (sp->u.scmd.crc_ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) mempool_free(sp->u.scmd.crc_ctx, ha->ctx_mempool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) sp->u.scmd.crc_ctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) struct srb_iocb *aio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) scsi_qla_host_t *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) struct req_que *req = sp->qpair->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) memset(abt_iocb, 0, sizeof(struct abort_entry_24xx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) abt_iocb->entry_type = ABORT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) abt_iocb->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) abt_iocb->handle = make_handle(req->id, sp->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) if (sp->fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) abt_iocb->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) abt_iocb->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) abt_iocb->handle_to_abort =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) make_handle(le16_to_cpu(aio->u.abt.req_que_no),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) aio->u.abt.cmd_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) abt_iocb->vp_index = vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) abt_iocb->req_que_no = aio->u.abt.req_que_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) /* Send the command to the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) qla2x00_mb_iocb(srb_t *sp, struct mbx_24xx_entry *mbx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) int i, sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) mbx->entry_type = MBX_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) mbx->handle = sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) sz = min(ARRAY_SIZE(mbx->mb), ARRAY_SIZE(sp->u.iocb_cmd.u.mbx.out_mb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) for (i = 0; i < sz; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) mbx->mb[i] = sp->u.iocb_cmd.u.mbx.out_mb[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) qla2x00_ctpthru_cmd_iocb(srb_t *sp, struct ct_entry_24xx *ct_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) sp->u.iocb_cmd.u.ctarg.iocb = ct_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) qla24xx_prep_ms_iocb(sp->vha, &sp->u.iocb_cmd.u.ctarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) ct_pkt->handle = sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) static void qla2x00_send_notify_ack_iocb(srb_t *sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) struct nack_to_isp *nack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) struct imm_ntfy_from_isp *ntfy = sp->u.iocb_cmd.u.nack.ntfy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) nack->entry_type = NOTIFY_ACK_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) nack->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) nack->ox_id = ntfy->ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) nack->u.isp24.handle = sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) nack->u.isp24.nport_handle = ntfy->u.isp24.nport_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) if (le16_to_cpu(ntfy->u.isp24.status) == IMM_NTFY_ELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) nack->u.isp24.flags = ntfy->u.isp24.flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) cpu_to_le16(NOTIFY24XX_FLAGS_PUREX_IOCB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) nack->u.isp24.srr_rx_id = ntfy->u.isp24.srr_rx_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) nack->u.isp24.status = ntfy->u.isp24.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) nack->u.isp24.status_subcode = ntfy->u.isp24.status_subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) nack->u.isp24.fw_handle = ntfy->u.isp24.fw_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) nack->u.isp24.exchange_address = ntfy->u.isp24.exchange_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) nack->u.isp24.srr_rel_offs = ntfy->u.isp24.srr_rel_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) nack->u.isp24.srr_ui = ntfy->u.isp24.srr_ui;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) nack->u.isp24.srr_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) nack->u.isp24.srr_reject_code = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) nack->u.isp24.srr_reject_code_expl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) nack->u.isp24.vp_index = ntfy->u.isp24.vp_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) * Build NVME LS request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) qla_nvme_ls(srb_t *sp, struct pt_ls4_request *cmd_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) struct srb_iocb *nvme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) nvme = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) cmd_pkt->entry_type = PT_LS4_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) cmd_pkt->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) cmd_pkt->control_flags = cpu_to_le16(CF_LS4_ORIGINATOR << CF_LS4_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) cmd_pkt->timeout = cpu_to_le16(nvme->u.nvme.timeout_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) cmd_pkt->vp_index = sp->fcport->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) cmd_pkt->tx_dseg_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) cmd_pkt->tx_byte_count = cpu_to_le32(nvme->u.nvme.cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) cmd_pkt->dsd[0].length = cpu_to_le32(nvme->u.nvme.cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) put_unaligned_le64(nvme->u.nvme.cmd_dma, &cmd_pkt->dsd[0].address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) cmd_pkt->rx_dseg_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) cmd_pkt->rx_byte_count = cpu_to_le32(nvme->u.nvme.rsp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) cmd_pkt->dsd[1].length = cpu_to_le32(nvme->u.nvme.rsp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) put_unaligned_le64(nvme->u.nvme.rsp_dma, &cmd_pkt->dsd[1].address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) qla25xx_ctrlvp_iocb(srb_t *sp, struct vp_ctrl_entry_24xx *vce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) int map, pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) vce->entry_type = VP_CTRL_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) vce->handle = sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) vce->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) vce->command = cpu_to_le16(sp->u.iocb_cmd.u.ctrlvp.cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) vce->vp_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) * index map in firmware starts with 1; decrement index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) * this is ok as we never use index 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) map = (sp->u.iocb_cmd.u.ctrlvp.vp_index - 1) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) pos = (sp->u.iocb_cmd.u.ctrlvp.vp_index - 1) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) vce->vp_idx_map[map] |= 1 << pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) qla24xx_prlo_iocb(srb_t *sp, struct logio_entry_24xx *logio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) logio->control_flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) cpu_to_le16(LCF_COMMAND_PRLO|LCF_IMPL_PRLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) logio->port_id[0] = sp->fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) logio->port_id[1] = sp->fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) logio->port_id[2] = sp->fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) logio->vp_index = sp->fcport->vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) qla2x00_start_sp(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) scsi_qla_host_t *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) struct qla_qpair *qp = sp->qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) void *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) spin_lock_irqsave(qp->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) pkt = __qla2x00_alloc_iocbs(sp->qpair, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) if (!pkt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) rval = EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) ql_log(ql_log_warn, vha, 0x700c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) "qla2x00_alloc_iocbs failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) switch (sp->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) case SRB_LOGIN_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) IS_FWI2_CAPABLE(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) qla24xx_login_iocb(sp, pkt) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) qla2x00_login_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) case SRB_PRLI_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) qla24xx_prli_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) case SRB_LOGOUT_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) IS_FWI2_CAPABLE(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) qla24xx_logout_iocb(sp, pkt) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) qla2x00_logout_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) case SRB_ELS_CMD_RPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) case SRB_ELS_CMD_HST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) qla24xx_els_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) case SRB_CT_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) IS_FWI2_CAPABLE(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) qla24xx_ct_iocb(sp, pkt) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) qla2x00_ct_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) case SRB_ADISC_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) IS_FWI2_CAPABLE(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) qla24xx_adisc_iocb(sp, pkt) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) qla2x00_adisc_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) case SRB_TM_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) IS_QLAFX00(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) qlafx00_tm_iocb(sp, pkt) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) qla24xx_tm_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) case SRB_FXIOCB_DCMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) case SRB_FXIOCB_BCMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) qlafx00_fxdisc_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) case SRB_NVME_LS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) qla_nvme_ls(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) case SRB_ABT_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) IS_QLAFX00(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) qlafx00_abort_iocb(sp, pkt) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) qla24xx_abort_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) case SRB_ELS_DCMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) qla24xx_els_logo_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) case SRB_CT_PTHRU_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) qla2x00_ctpthru_cmd_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) case SRB_MB_IOCB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) qla2x00_mb_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) case SRB_NACK_PLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) case SRB_NACK_PRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) case SRB_NACK_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) qla2x00_send_notify_ack_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) case SRB_CTRL_VP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) qla25xx_ctrlvp_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) case SRB_PRLO_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) qla24xx_prlo_iocb(sp, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) if (sp->start_timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) add_timer(&sp->u.iocb_cmd.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) qla2x00_start_iocbs(vha, qp->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) struct cmd_bidir *cmd_pkt, uint32_t tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) uint16_t avail_dsds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) struct dsd64 *cur_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) uint32_t req_data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) uint32_t rsp_data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) int entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) struct bsg_job *bsg_job = sp->u.bsg_job;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) /*Update entry type to indicate bidir command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) put_unaligned_le32(COMMAND_BIDIRECTIONAL, &cmd_pkt->entry_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) /* Set the transfer direction, in this set both flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) * Also set the BD_WRAP_BACK flag, firmware will take care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) * assigning DID=SID for outgoing pkts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) cmd_pkt->wr_dseg_count = cpu_to_le16(bsg_job->request_payload.sg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) cmd_pkt->rd_dseg_count = cpu_to_le16(bsg_job->reply_payload.sg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) cmd_pkt->control_flags = cpu_to_le16(BD_WRITE_DATA | BD_READ_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) BD_WRAP_BACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) cmd_pkt->wr_byte_count = cpu_to_le32(req_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) cmd_pkt->rd_byte_count = cpu_to_le32(rsp_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) cmd_pkt->timeout = cpu_to_le16(qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) vha->bidi_stats.transfer_bytes += req_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) vha->bidi_stats.io_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) vha->qla_stats.output_bytes += req_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) vha->qla_stats.output_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) /* Only one dsd is available for bidirectional IOCB, remaining dsds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) * are bundled in continuation iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) avail_dsds = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) cur_dsd = &cmd_pkt->fcp_dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) for_each_sg(bsg_job->request_payload.sg_list, sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) bsg_job->request_payload.sg_cnt, index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) cont_a64_entry_t *cont_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) /* Allocate additional continuation packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) /* Continuation type 1 IOCB can accomodate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) * 5 DSDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) cur_dsd = cont_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) avail_dsds = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) entry_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) /* For read request DSD will always goes to continuation IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) * and follow the write DSD. If there is room on the current IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) * then it is added to that IOCB else new continuation IOCB is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) * allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) for_each_sg(bsg_job->reply_payload.sg_list, sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) bsg_job->reply_payload.sg_cnt, index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) cont_a64_entry_t *cont_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) /* Allocate additional continuation packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) if (avail_dsds == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) /* Continuation type 1 IOCB can accomodate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) * 5 DSDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) cur_dsd = cont_pkt->dsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) avail_dsds = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) entry_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) append_dsd64(&cur_dsd, sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) avail_dsds--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) /* This value should be same as number of IOCB required for this cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) cmd_pkt->entry_count = entry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) uint32_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) uint16_t req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) uint32_t *clr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) struct cmd_bidir *cmd_pkt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) struct rsp_que *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) struct req_que *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) int rval = EXT_STATUS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) rsp = ha->rsp_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) req = vha->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) /* Send marker if required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) if (vha->marker_needed != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) if (qla2x00_marker(vha, ha->base_qpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 0, 0, MK_SYNC_ALL) != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) return EXT_STATUS_MAILBOX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) /* Acquire ring specific lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) handle = qla2xxx_get_next_handle(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) if (handle == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) rval = EXT_STATUS_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) /* Calculate number of IOCB required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) /* Check for room on request queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) if (req->cnt < req_cnt + 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) rd_reg_dword_relaxed(req->req_q_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) if (req->ring_index < cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) req->cnt = cnt - req->ring_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) req->cnt = req->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) (req->ring_index - cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) if (req->cnt < req_cnt + 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) rval = EXT_STATUS_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) goto queuing_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) cmd_pkt = (struct cmd_bidir *)req->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) cmd_pkt->handle = make_handle(req->id, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) /* Zero out remaining portion of packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) /* tagged queuing modifier -- default is TSK_SIMPLE (0).*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) clr_ptr = (uint32_t *)cmd_pkt + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) /* Set NPORT-ID (of vha)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) cmd_pkt->nport_handle = cpu_to_le16(vha->self_login_loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) cmd_pkt->port_id[0] = vha->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) cmd_pkt->port_id[1] = vha->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) cmd_pkt->port_id[2] = vha->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) qla25xx_build_bidir_iocb(sp, vha, cmd_pkt, tot_dsds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) cmd_pkt->entry_status = (uint8_t) rsp->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) /* Build command packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) req->current_outstanding_cmd = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) req->outstanding_cmds[handle] = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) sp->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) req->cnt -= req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) /* Send the command to the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) qla2x00_start_iocbs(vha, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) queuing_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) }