[SCSI] lpfc 8.3.32: Correct host DIF configuration that hung system
authorJames Smart <james.smart@emulex.com>
Tue, 12 Jun 2012 17:54:27 +0000 (13:54 -0400)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 20 Jul 2012 07:58:27 +0000 (08:58 +0100)
Fix system hang due to bad protection module parameters (CR: 130769)

Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/lpfc/lpfc_init.c

index 411ed48d79da8c9ec1439628d8ef2f290a942fb7..a79e2c21c5e4fc35a95b383c1645eba7b72b267a 100644 (file)
@@ -5514,14 +5514,45 @@ lpfc_destroy_shost(struct lpfc_hba *phba)
 static void
 lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost)
 {
+       uint32_t old_mask;
+       uint32_t old_guard;
+
        int pagecnt = 10;
        if (lpfc_prot_mask && lpfc_prot_guard) {
                lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
                                "1478 Registering BlockGuard with the "
                                "SCSI layer\n");
-               scsi_host_set_prot(shost, lpfc_prot_mask);
-               scsi_host_set_guard(shost, lpfc_prot_guard);
+
+               old_mask = lpfc_prot_mask;
+               old_guard = lpfc_prot_guard;
+
+               /* Only allow supported values */
+               lpfc_prot_mask &= (SHOST_DIF_TYPE1_PROTECTION |
+                       SHOST_DIX_TYPE0_PROTECTION |
+                       SHOST_DIX_TYPE1_PROTECTION);
+               lpfc_prot_guard &= (SHOST_DIX_GUARD_IP | SHOST_DIX_GUARD_CRC);
+
+               /* DIF Type 1 protection for profiles AST1/C1 is end to end */
+               if (lpfc_prot_mask == SHOST_DIX_TYPE1_PROTECTION)
+                       lpfc_prot_mask |= SHOST_DIF_TYPE1_PROTECTION;
+
+               if (lpfc_prot_mask && lpfc_prot_guard) {
+                       if ((old_mask != lpfc_prot_mask) ||
+                               (old_guard != lpfc_prot_guard))
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "1475 Registering BlockGuard with the "
+                                       "SCSI layer: mask %d  guard %d\n",
+                                       lpfc_prot_mask, lpfc_prot_guard);
+
+                       scsi_host_set_prot(shost, lpfc_prot_mask);
+                       scsi_host_set_guard(shost, lpfc_prot_guard);
+               } else
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "1479 Not Registering BlockGuard with the SCSI "
+                               "layer, Bad protection parameters: %d %d\n",
+                               old_mask, old_guard);
        }
+
        if (!_dump_buf_data) {
                while (pagecnt) {
                        spin_lock_init(&_dump_buf_lock);