qla2xxx: Avoid side effects when using endianizer macros.
[deliverable/linux.git] / drivers / scsi / qla2xxx / qla_init.c
index 52a87657c7dd3e4945aad29e9b3cbf983b94efad..c3aa1eb8c1bac2d7321d74fe3115e3fcd3843a92 100644 (file)
@@ -2062,6 +2062,10 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
        if (IS_P3P_TYPE(ha))
                return;
 
+       /*  Hold status IOCBs until ABTS response received. */
+       if (ql2xfwholdabts)
+               ha->fw_options[3] |= BIT_12;
+
        /* Update Serial Link options. */
        if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
                return;
@@ -2204,7 +2208,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
        /* Clear outstanding commands array. */
        for (que = 0; que < ha->max_req_queues; que++) {
                req = ha->req_q_map[que];
-               if (!req)
+               if (!req || !test_bit(que, ha->req_qid_map))
                        continue;
                req->out_ptr = (void *)(req->ring + req->length);
                *req->out_ptr = 0;
@@ -2221,7 +2225,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
 
        for (que = 0; que < ha->max_rsp_queues; que++) {
                rsp = ha->rsp_q_map[que];
-               if (!rsp)
+               if (!rsp || !test_bit(que, ha->rsp_qid_map))
                        continue;
                rsp->in_ptr = (void *)(rsp->ring + rsp->length);
                *rsp->in_ptr = 0;
@@ -2844,7 +2848,6 @@ qla2x00_nvram_config(scsi_qla_host_t *vha)
        if (nv->login_timeout < 4)
                nv->login_timeout = 4;
        ha->login_timeout = nv->login_timeout;
-       icb->login_timeout = nv->login_timeout;
 
        /* Set minimum RATOV to 100 tenths of a second. */
        ha->r_a_tov = 100;
@@ -4981,7 +4984,7 @@ qla25xx_init_queues(struct qla_hw_data *ha)
 
        for (i = 1; i < ha->max_rsp_queues; i++) {
                rsp = ha->rsp_q_map[i];
-               if (rsp) {
+               if (rsp && test_bit(i, ha->rsp_qid_map)) {
                        rsp->options &= ~BIT_0;
                        ret = qla25xx_init_rsp_que(base_vha, rsp);
                        if (ret != QLA_SUCCESS)
@@ -4996,8 +4999,8 @@ qla25xx_init_queues(struct qla_hw_data *ha)
        }
        for (i = 1; i < ha->max_req_queues; i++) {
                req = ha->req_q_map[i];
-               if (req) {
-               /* Clear outstanding commands array. */
+               if (req && test_bit(i, ha->req_qid_map)) {
+                       /* Clear outstanding commands array. */
                        req->options &= ~BIT_0;
                        ret = qla25xx_init_req_que(base_vha, req);
                        if (ret != QLA_SUCCESS)
@@ -5122,8 +5125,8 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
        dptr = (uint32_t *)nv;
        ha->isp_ops->read_nvram(vha, (uint8_t *)dptr, ha->nvram_base,
            ha->nvram_size);
-       for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
-               chksum += le32_to_cpu(*dptr++);
+       for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
+               chksum += le32_to_cpu(*dptr);
 
        ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x006a,
            "Contents of NVRAM\n");
@@ -5274,7 +5277,6 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
        if (le16_to_cpu(nv->login_timeout) < 4)
                nv->login_timeout = cpu_to_le16(4);
        ha->login_timeout = le16_to_cpu(nv->login_timeout);
-       icb->login_timeout = nv->login_timeout;
 
        /* Set minimum RATOV to 100 tenths of a second. */
        ha->r_a_tov = 100;
@@ -5346,6 +5348,93 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
        return (rval);
 }
 
+uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha)
+{
+       struct qla27xx_image_status pri_image_status, sec_image_status;
+       uint8_t valid_pri_image, valid_sec_image;
+       uint32_t *wptr;
+       uint32_t cnt, chksum, size;
+       struct qla_hw_data *ha = vha->hw;
+
+       valid_pri_image = valid_sec_image = 1;
+       ha->active_image = 0;
+       size = sizeof(struct qla27xx_image_status) / sizeof(uint32_t);
+
+       if (!ha->flt_region_img_status_pri) {
+               valid_pri_image = 0;
+               goto check_sec_image;
+       }
+
+       qla24xx_read_flash_data(vha, (uint32_t *)(&pri_image_status),
+           ha->flt_region_img_status_pri, size);
+
+       if (pri_image_status.signature != QLA27XX_IMG_STATUS_SIGN) {
+               ql_dbg(ql_dbg_init, vha, 0x018b,
+                   "Primary image signature (0x%x) not valid\n",
+                   pri_image_status.signature);
+               valid_pri_image = 0;
+               goto check_sec_image;
+       }
+
+       wptr = (uint32_t *)(&pri_image_status);
+       cnt = size;
+
+       for (chksum = 0; cnt--; wptr++)
+               chksum += le32_to_cpu(*wptr);
+       if (chksum) {
+               ql_dbg(ql_dbg_init, vha, 0x018c,
+                   "Checksum validation failed for primary image (0x%x)\n",
+                   chksum);
+               valid_pri_image = 0;
+       }
+
+check_sec_image:
+       if (!ha->flt_region_img_status_sec) {
+               valid_sec_image = 0;
+               goto check_valid_image;
+       }
+
+       qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
+           ha->flt_region_img_status_sec, size);
+
+       if (sec_image_status.signature != QLA27XX_IMG_STATUS_SIGN) {
+               ql_dbg(ql_dbg_init, vha, 0x018d,
+                   "Secondary image signature(0x%x) not valid\n",
+                   sec_image_status.signature);
+               valid_sec_image = 0;
+               goto check_valid_image;
+       }
+
+       wptr = (uint32_t *)(&sec_image_status);
+       cnt = size;
+       for (chksum = 0; cnt--; wptr++)
+               chksum += le32_to_cpu(*wptr);
+       if (chksum) {
+               ql_dbg(ql_dbg_init, vha, 0x018e,
+                   "Checksum validation failed for secondary image (0x%x)\n",
+                   chksum);
+               valid_sec_image = 0;
+       }
+
+check_valid_image:
+       if (valid_pri_image && (pri_image_status.image_status_mask & 0x1))
+               ha->active_image = QLA27XX_PRIMARY_IMAGE;
+       if (valid_sec_image && (sec_image_status.image_status_mask & 0x1)) {
+               if (!ha->active_image ||
+                   pri_image_status.generation_number <
+                   sec_image_status.generation_number)
+                       ha->active_image = QLA27XX_SECONDARY_IMAGE;
+       }
+
+       ql_dbg(ql_dbg_init, vha, 0x018f, "%s image\n",
+           ha->active_image == 0 ? "default bootld and fw" :
+           ha->active_image == 1 ? "primary" :
+           ha->active_image == 2 ? "secondary" :
+           "Invalid");
+
+       return ha->active_image;
+}
+
 static int
 qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
     uint32_t faddr)
@@ -5368,6 +5457,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
        dcode = (uint32_t *)req->ring;
        *srisc_addr = 0;
 
+       if (IS_QLA27XX(ha) &&
+           qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE)
+               faddr = ha->flt_region_fw_sec;
+
        /* Validate firmware image by checking version. */
        qla24xx_read_flash_data(vha, dcode, faddr + 4, 4);
        for (i = 0; i < 4; i++)
@@ -6068,8 +6161,8 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
        ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2,
            ha->nvram_size);
        dptr = (uint32_t *)nv;
-       for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
-               chksum += le32_to_cpu(*dptr++);
+       for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
+               chksum += le32_to_cpu(*dptr);
 
        ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0111,
            "Contents of NVRAM:\n");
@@ -6231,7 +6324,6 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
        if (le16_to_cpu(nv->login_timeout) < 4)
                nv->login_timeout = cpu_to_le16(4);
        ha->login_timeout = le16_to_cpu(nv->login_timeout);
-       icb->login_timeout = nv->login_timeout;
 
        /* Set minimum RATOV to 100 tenths of a second. */
        ha->r_a_tov = 100;
@@ -6413,12 +6505,17 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha)
 {
        struct qla_hw_data *ha = vha->hw;
 
+       /*  Hold status IOCBs until ABTS response received. */
+       if (ql2xfwholdabts)
+               ha->fw_options[3] |= BIT_12;
+
        if (!ql2xetsenable)
-               return;
+               goto out;
 
        /* Enable ETS Burst. */
        memset(ha->fw_options, 0, sizeof(ha->fw_options));
        ha->fw_options[2] |= BIT_9;
+out:
        qla2x00_set_fw_options(vha, ha->fw_options);
 }
 
This page took 0.027188 seconds and 5 git commands to generate.