Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[sfrench/cifs-2.6.git] / drivers / scsi / bnx2i / bnx2i_hwi.c
index 41e1b0e7e2ef30403909c226c21f6365afa73c1c..1af578dec276da2b2254cf85451d9c4c235503f0 100644 (file)
@@ -133,20 +133,38 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action)
 {
        struct bnx2i_5771x_cq_db *cq_db;
        u16 cq_index;
+       u16 next_index;
+       u32 num_active_cmds;
 
+
+       /* Coalesce CQ entries only on 10G devices */
        if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
                return;
 
+       /* Do not update CQ DB multiple times before firmware writes
+        * '0xFFFF' to CQDB->SQN field. Deviation may cause spurious
+        * interrupts and other unwanted results
+        */
+       cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt;
+       if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF)
+               return;
+
        if (action == CNIC_ARM_CQE) {
-               cq_index = ep->qp.cqe_exp_seq_sn +
-                          ep->num_active_cmds / event_coal_div;
-               cq_index %= (ep->qp.cqe_size * 2 + 1);
-               if (!cq_index) {
+               num_active_cmds = ep->num_active_cmds;
+               if (num_active_cmds <= event_coal_min)
+                       next_index = 1;
+               else
+                       next_index = event_coal_min +
+                               (num_active_cmds - event_coal_min) / event_coal_div;
+               if (!next_index)
+                       next_index = 1;
+               cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1;
+               if (cq_index > ep->qp.cqe_size * 2)
+                       cq_index -= ep->qp.cqe_size * 2;
+               if (!cq_index)
                        cq_index = 1;
-                       cq_db = (struct bnx2i_5771x_cq_db *)
-                                       ep->qp.cq_pgtbl_virt;
-                       cq_db->sqn[0] = cq_index;
-               }
+
+               cq_db->sqn[0] = cq_index;
        }
 }
 
@@ -366,6 +384,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
        struct bnx2i_cmd *bnx2i_cmd;
        struct bnx2i_tmf_request *tmfabort_wqe;
        u32 dword;
+       u32 scsi_lun[2];
 
        bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
        tmfabort_hdr = (struct iscsi_tm *)mtask->hdr;
@@ -376,27 +395,35 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
        tmfabort_wqe->op_attr = 0;
        tmfabort_wqe->op_attr =
                ISCSI_TMF_REQUEST_ALWAYS_ONE | ISCSI_TM_FUNC_ABORT_TASK;
-       tmfabort_wqe->lun[0] = be32_to_cpu(tmfabort_hdr->lun[0]);
-       tmfabort_wqe->lun[1] = be32_to_cpu(tmfabort_hdr->lun[1]);
 
        tmfabort_wqe->itt = (mtask->itt | (ISCSI_TASK_TYPE_MPATH << 14));
        tmfabort_wqe->reserved2 = 0;
        tmfabort_wqe->cmd_sn = be32_to_cpu(tmfabort_hdr->cmdsn);
 
        ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt);
-       if (!ctask || ctask->sc)
+       if (!ctask || !ctask->sc)
                /*
                 * the iscsi layer must have completed the cmd while this
                 * was starting up.
+                *
+                * Note: In the case of a SCSI cmd timeout, the task's sc
+                *       is still active; hence ctask->sc != 0
+                *       In this case, the task must be aborted
                 */
                return 0;
+
        ref_sc = ctask->sc;
 
+       /* Retrieve LUN directly from the ref_sc */
+       int_to_scsilun(ref_sc->device->lun, (struct scsi_lun *) scsi_lun);
+       tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]);
+       tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]);
+
        if (ref_sc->sc_data_direction == DMA_TO_DEVICE)
                dword = (ISCSI_TASK_TYPE_WRITE << ISCSI_CMD_REQUEST_TYPE_SHIFT);
        else
                dword = (ISCSI_TASK_TYPE_READ << ISCSI_CMD_REQUEST_TYPE_SHIFT);
-       tmfabort_wqe->ref_itt = (dword | tmfabort_hdr->rtt);
+       tmfabort_wqe->ref_itt = (dword | (tmfabort_hdr->rtt & ISCSI_ITT_MASK));
        tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn);
 
        tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
@@ -2386,7 +2413,7 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep)
                ctx_sz = (config2 & BNX2_MQ_CONFIG2_CONT_SZ) >> 3;
                if (ctx_sz)
                        reg_off = CTX_OFFSET + MAX_CID_CNT * MB_KERNEL_CTX_SIZE
-                                 + PAGE_SIZE *
+                                 + BNX2I_570X_PAGE_SIZE_DEFAULT *
                                  (((cid_num - first_l4l5) / ctx_sz) + 256);
                else
                        reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num);