]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/scsi/qla2xxx/qla_iocb.c
scsi: qla2xxx: Use an on-stack completion in qla24xx_control_vp()
[linux.git] / drivers / scsi / qla2xxx / qla_iocb.c
index 2c27ae1924c575d62972b57e3b7c4aed4fa6ca13..60f6685cb3424a962bc22eabaff0f0b38bfd7595 100644 (file)
@@ -107,7 +107,7 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha)
        cont_pkt = (cont_entry_t *)req->ring_ptr;
 
        /* Load packet defaults. */
-       *((uint32_t *)(&cont_pkt->entry_type)) = cpu_to_le32(CONTINUE_TYPE);
+       put_unaligned_le32(CONTINUE_TYPE, &cont_pkt->entry_type);
 
        return (cont_pkt);
 }
@@ -136,9 +136,8 @@ qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req)
        cont_pkt = (cont_a64_entry_t *)req->ring_ptr;
 
        /* Load packet defaults. */
-       *((uint32_t *)(&cont_pkt->entry_type)) = IS_QLAFX00(vha->hw) ?
-           cpu_to_le32(CONTINUE_A64_TYPE_FX00) :
-           cpu_to_le32(CONTINUE_A64_TYPE);
+       put_unaligned_le32(IS_QLAFX00(vha->hw) ? CONTINUE_A64_TYPE_FX00 :
+                          CONTINUE_A64_TYPE, &cont_pkt->entry_type);
 
        return (cont_pkt);
 }
@@ -202,8 +201,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
        cmd = GET_CMD_SP(sp);
 
        /* Update entry type to indicate Command Type 2 IOCB */
-       *((uint32_t *)(&cmd_pkt->entry_type)) =
-           cpu_to_le32(COMMAND_TYPE);
+       put_unaligned_le32(COMMAND_TYPE, &cmd_pkt->entry_type);
 
        /* No data transfer */
        if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
@@ -260,7 +258,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
        cmd = GET_CMD_SP(sp);
 
        /* Update entry type to indicate Command Type 3 IOCB */
-       *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_A64_TYPE);
+       put_unaligned_le32(COMMAND_A64_TYPE, &cmd_pkt->entry_type);
 
        /* No data transfer */
        if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
@@ -336,7 +334,7 @@ qla2x00_start_scsi(srb_t *sp)
 
        /* Send marker if required */
        if (vha->marker_needed != 0) {
-               if (qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
+               if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
                    QLA_SUCCESS) {
                        return (QLA_FUNCTION_FAILED);
                }
@@ -467,7 +465,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
                        req->ring_ptr++;
 
                /* Set chip new ring index. */
-               if (ha->mqenable || IS_QLA27XX(ha)) {
+               if (ha->mqenable || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
                        WRT_REG_DWORD(req->req_q_in, req->ring_index);
                } else if (IS_QLA83XX(ha)) {
                        WRT_REG_DWORD(req->req_q_in, req->ring_index);
@@ -490,8 +488,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
 /**
  * qla2x00_marker() - Send a marker IOCB to the firmware.
  * @vha: HA context
- * @req: request queue
- * @rsp: response queue
+ * @qpair: queue pair pointer
  * @loop_id: loop ID
  * @lun: LUN
  * @type: marker modifier
@@ -501,18 +498,16 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
  * Returns non-zero if a failure occurred, else zero.
  */
 static int
-__qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
-                       struct rsp_que *rsp, uint16_t loop_id,
-                       uint64_t lun, uint8_t type)
+__qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
+    uint16_t loop_id, uint64_t lun, uint8_t type)
 {
        mrk_entry_t *mrk;
        struct mrk_entry_24xx *mrk24 = NULL;
-
+       struct req_que *req = qpair->req;
        struct qla_hw_data *ha = vha->hw;
        scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
 
-       req = ha->req_q_map[0];
-       mrk = (mrk_entry_t *)qla2x00_alloc_iocbs(vha, NULL);
+       mrk = (mrk_entry_t *)__qla2x00_alloc_iocbs(qpair, NULL);
        if (mrk == NULL) {
                ql_log(ql_log_warn, base_vha, 0x3026,
                    "Failed to allocate Marker IOCB.\n");
@@ -543,16 +538,15 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
 }
 
 int
-qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
-               struct rsp_que *rsp, uint16_t loop_id, uint64_t lun,
-               uint8_t type)
+qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
+    uint16_t loop_id, uint64_t lun, uint8_t type)
 {
        int ret;
        unsigned long flags = 0;
 
-       spin_lock_irqsave(&vha->hw->hardware_lock, flags);
-       ret = __qla2x00_marker(vha, req, rsp, loop_id, lun, type);
-       spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+       ret = __qla2x00_marker(vha, qpair, loop_id, lun, type);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        return (ret);
 }
@@ -567,11 +561,11 @@ qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
 int qla2x00_issue_marker(scsi_qla_host_t *vha, int ha_locked)
 {
        if (ha_locked) {
-               if (__qla2x00_marker(vha, vha->req, vha->req->rsp, 0, 0,
+               if (__qla2x00_marker(vha, vha->hw->base_qpair, 0, 0,
                                        MK_SYNC_ALL) != QLA_SUCCESS)
                        return QLA_FUNCTION_FAILED;
        } else {
-               if (qla2x00_marker(vha, vha->req, vha->req->rsp, 0, 0,
+               if (qla2x00_marker(vha, vha->hw->base_qpair, 0, 0,
                                        MK_SYNC_ALL) != QLA_SUCCESS)
                        return QLA_FUNCTION_FAILED;
        }
@@ -600,7 +594,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
        cmd = GET_CMD_SP(sp);
 
        /* Update entry type to indicate Command Type 3 IOCB */
-       *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_TYPE_6);
+       put_unaligned_le32(COMMAND_TYPE_6, &cmd_pkt->entry_type);
 
        /* No data transfer */
        if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
@@ -715,7 +709,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
        cmd = GET_CMD_SP(sp);
 
        /* Update entry type to indicate Command Type 3 IOCB */
-       *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_TYPE_7);
+       put_unaligned_le32(COMMAND_TYPE_7, &cmd_pkt->entry_type);
 
        /* No data transfer */
        if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
@@ -1113,6 +1107,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
 
        if (sp) {
                struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+
                sgl = scsi_prot_sglist(cmd);
                vha = sp->vha;
                difctx = sp->u.scmd.ctx;
@@ -1136,7 +1131,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
        /* if initiator doing write or target doing read */
        if (direction_to_device) {
                for_each_sg(sgl, sg, tot_dsds, i) {
-                       dma_addr_t sle_phys = sg_phys(sg);
+                       u64 sle_phys = sg_phys(sg);
 
                        /* If SGE addr + len flips bits in upper 32-bits */
                        if (MSD(sle_phys + sg->length) ^ MSD(sle_phys)) {
@@ -1182,7 +1177,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
 
                        ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe023,
                            "%s: sg[%x] (phys=%llx sglen=%x) ldma_sg_len: %x dif_bundl_len: %x ldma_needed: %x\n",
-                           __func__, i, sg_phys(sg), sglen, ldma_sg_len,
+                           __func__, i, (u64)sg_phys(sg), sglen, ldma_sg_len,
                            difctx->dif_bundl_len, ldma_needed);
 
                        while (sglen) {
@@ -1409,7 +1404,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
  * @tot_prot_dsds: Total number of segments with protection information
  * @fw_prot_opts: Protection options to be passed to firmware
  */
-inline int
+static inline int
 qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
     uint16_t tot_dsds, uint16_t tot_prot_dsds, uint16_t fw_prot_opts)
 {
@@ -1431,7 +1426,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
        cmd = GET_CMD_SP(sp);
 
        /* Update entry type to indicate Command Type CRC_2 IOCB */
-       *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_TYPE_CRC_2);
+       put_unaligned_le32(COMMAND_TYPE_CRC_2, &cmd_pkt->entry_type);
 
        vha = sp->vha;
        ha = vha->hw;
@@ -1524,18 +1519,18 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
        switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
        case SCSI_PROT_READ_INSERT:
        case SCSI_PROT_WRITE_STRIP:
-           total_bytes = data_bytes;
-           data_bytes += dif_bytes;
-           break;
+               total_bytes = data_bytes;
+               data_bytes += dif_bytes;
+               break;
 
        case SCSI_PROT_READ_STRIP:
        case SCSI_PROT_WRITE_INSERT:
        case SCSI_PROT_READ_PASS:
        case SCSI_PROT_WRITE_PASS:
-           total_bytes = data_bytes + dif_bytes;
-           break;
+               total_bytes = data_bytes + dif_bytes;
+               break;
        default:
-           BUG();
+               BUG();
        }
 
        if (!qla2x00_hba_err_chk_enabled(sp))
@@ -1627,21 +1622,19 @@ qla24xx_start_scsi(srb_t *sp)
        uint16_t        req_cnt;
        uint16_t        tot_dsds;
        struct req_que *req = NULL;
-       struct rsp_que *rsp = NULL;
        struct scsi_cmnd *cmd = GET_CMD_SP(sp);
        struct scsi_qla_host *vha = sp->vha;
        struct qla_hw_data *ha = vha->hw;
 
        /* Setup device pointers. */
        req = vha->req;
-       rsp = req->rsp;
 
        /* So we know we haven't pci_map'ed anything yet */
        tot_dsds = 0;
 
        /* Send marker if required */
        if (vha->marker_needed != 0) {
-               if (qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
+               if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
                    QLA_SUCCESS)
                        return QLA_FUNCTION_FAILED;
                vha->marker_needed = 0;
@@ -1794,7 +1787,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
 
        /* Send marker if required */
        if (vha->marker_needed != 0) {
-               if (qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
+               if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
                    QLA_SUCCESS)
                        return QLA_FUNCTION_FAILED;
                vha->marker_needed = 0;
@@ -1965,7 +1958,6 @@ qla2xxx_start_scsi_mq(srb_t *sp)
        uint16_t        req_cnt;
        uint16_t        tot_dsds;
        struct req_que *req = NULL;
-       struct rsp_que *rsp = NULL;
        struct scsi_cmnd *cmd = GET_CMD_SP(sp);
        struct scsi_qla_host *vha = sp->fcport->vha;
        struct qla_hw_data *ha = vha->hw;
@@ -1975,7 +1967,6 @@ qla2xxx_start_scsi_mq(srb_t *sp)
        spin_lock_irqsave(&qpair->qp_lock, flags);
 
        /* Setup qpair pointers */
-       rsp = qpair->rsp;
        req = qpair->req;
 
        /* So we know we haven't pci_map'ed anything yet */
@@ -1983,7 +1974,7 @@ qla2xxx_start_scsi_mq(srb_t *sp)
 
        /* Send marker if required */
        if (vha->marker_needed != 0) {
-               if (__qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
+               if (__qla2x00_marker(vha, qpair, 0, 0, MK_SYNC_ALL) !=
                    QLA_SUCCESS) {
                        spin_unlock_irqrestore(&qpair->qp_lock, flags);
                        return QLA_FUNCTION_FAILED;
@@ -2151,7 +2142,7 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
 
        /* Send marker if required */
        if (vha->marker_needed != 0) {
-               if (__qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
+               if (__qla2x00_marker(vha, qpair, 0, 0, MK_SYNC_ALL) !=
                    QLA_SUCCESS) {
                        spin_unlock_irqrestore(&qpair->qp_lock, flags);
                        return QLA_FUNCTION_FAILED;
@@ -2333,7 +2324,8 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
        if (req->cnt < req_cnt + 2) {
                if (qpair->use_shadow_reg)
                        cnt = *req->out_ptr;
-               else if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha))
+               else if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
+                   IS_QLA28XX(ha))
                        cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
                else if (IS_P3P_TYPE(ha))
                        cnt = RD_REG_DWORD(&reg->isp82.req_q_out);
@@ -2419,8 +2411,11 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio)
 
        logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
        logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI);
-       if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI)
+       if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI) {
                logio->control_flags |= LCF_NVME_PRLI;
+               if (sp->vha->flags.nvme_first_burst)
+                       logio->io_parameter[0] = NVME_PRLI_SP_FIRST_BURST;
+       }
 
        logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
        logio->port_id[0] = sp->fcport->d_id.b.al_pa;
@@ -2499,7 +2494,7 @@ qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx)
        SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
        mbx->mb0 = cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
        mbx->mb1 = HAS_EXTENDED_IDS(ha) ?
-           cpu_to_le16(sp->fcport->loop_id):
+           cpu_to_le16(sp->fcport->loop_id) :
            cpu_to_le16(sp->fcport->loop_id << 8);
        mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
        mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
@@ -2570,6 +2565,16 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
        }
 }
 
+void qla2x00_init_timer(srb_t *sp, unsigned long tmo)
+{
+       timer_setup(&sp->u.iocb_cmd.timer, qla2x00_sp_timeout, 0);
+       sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
+       sp->free = qla2x00_sp_free;
+       if (IS_QLAFX00(sp->vha->hw) && sp->type == SRB_FXIOCB_DCMD)
+               init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
+       add_timer(&sp->u.iocb_cmd.timer);
+}
+
 static void
 qla2x00_els_dcmd_sp_free(void *data)
 {
@@ -3009,7 +3014,6 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
        scsi_qla_host_t *vha = sp->vha;
        struct qla_hw_data *ha = vha->hw;
        struct bsg_job *bsg_job = sp->u.bsg_job;
-       int loop_iterartion = 0;
        int entry_count = 1;
 
        memset(ct_iocb, 0, sizeof(ms_iocb_entry_t));
@@ -3067,7 +3071,6 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
                *cur_dsd++   = cpu_to_le32(LSD(sle_dma));
                *cur_dsd++   = cpu_to_le32(MSD(sle_dma));
                *cur_dsd++   = cpu_to_le32(sg_dma_len(sg));
-               loop_iterartion++;
                avail_dsds--;
        }
        ct_iocb->entry_count = entry_count;
@@ -3202,8 +3205,8 @@ qla82xx_start_scsi(srb_t *sp)
 
        /* Send marker if required */
        if (vha->marker_needed != 0) {
-               if (qla2x00_marker(vha, req,
-                       rsp, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS) {
+               if (qla2x00_marker(vha, ha->base_qpair,
+                       0, 0, MK_SYNC_ALL) != QLA_SUCCESS) {
                        ql_log(ql_log_warn, vha, 0x300c,
                            "qla2x00_marker failed for cmd=%p.\n", cmd);
                        return QLA_FUNCTION_FAILED;
@@ -3391,6 +3394,7 @@ qla82xx_start_scsi(srb_t *sp)
                cmd_pkt->entry_status = (uint8_t) rsp->id;
        } else {
                struct cmd_type_7 *cmd_pkt;
+
                req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
                if (req->cnt < (req_cnt + 2)) {
                        cnt = (uint16_t)RD_REG_DWORD_RELAXED(
@@ -3751,8 +3755,7 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha,
        struct bsg_job *bsg_job = sp->u.bsg_job;
 
        /*Update entry type to indicate bidir command */
-       *((uint32_t *)(&cmd_pkt->entry_type)) =
-               cpu_to_le32(COMMAND_BIDIRECTIONAL);
+       put_unaligned_le32(COMMAND_BIDIRECTIONAL, &cmd_pkt->entry_type);
 
        /* Set the transfer direction, in this set both flags
         * Also set the BD_WRAP_BACK flag, firmware will take care
@@ -3856,8 +3859,8 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
 
        /* Send marker if required */
        if (vha->marker_needed != 0) {
-               if (qla2x00_marker(vha, req,
-                       rsp, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS)
+               if (qla2x00_marker(vha, ha->base_qpair,
+                       0, 0, MK_SYNC_ALL) != QLA_SUCCESS)
                        return EXT_STATUS_MAILBOX;
                vha->marker_needed = 0;
        }