LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
                "interrupt response is generated");
 
+/*
+# lpfc_multi_ring_support:  Determines how many rings to spread available
+# cmd/rsp IOCB entries across.
+# Value range is [1,2]. Default value is 1.
+*/
+LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
+               "SLI rings to spread IOCB entries across");
+
 /*
 # lpfc_fdmi_on: controls FDMI support.
 #       0 = no FDMI support
        &class_device_attr_lpfc_link_speed,
        &class_device_attr_lpfc_cr_delay,
        &class_device_attr_lpfc_cr_count,
+       &class_device_attr_lpfc_multi_ring_support,
        &class_device_attr_lpfc_fdmi_on,
        &class_device_attr_lpfc_max_luns,
        &class_device_attr_nport_evt_cnt,
        lpfc_log_verbose_init(phba, lpfc_log_verbose);
        lpfc_cr_delay_init(phba, lpfc_cr_delay);
        lpfc_cr_count_init(phba, lpfc_cr_count);
+       lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
        lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
        lpfc_fcp_class_init(phba, lpfc_fcp_class);
        lpfc_use_adisc_init(phba, lpfc_use_adisc);
 
        }
        /* unSolicited Responses */
        if (pring->prt[0].profile) {
-               (pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring, saveq);
+               if (pring->prt[0].lpfc_sli_rcv_unsol_event)
+                       (pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring,
+                                                                       saveq);
                match = 1;
        } else {
                /* We must search, based on rctl / type
                             Rctl)
                            && (pring->prt[i].
                                type == Type)) {
-                               (pring->prt[i].lpfc_sli_rcv_unsol_event)
-                                       (phba, pring, saveq);
+                               if (pring->prt[i].lpfc_sli_rcv_unsol_event)
+                                       (pring->prt[i].lpfc_sli_rcv_unsol_event)
+                                                       (phba, pring, saveq);
                                match = 1;
                                break;
                        }
        return IOCB_BUSY;
 }
 
+static int
+lpfc_extra_ring_setup( struct lpfc_hba *phba)
+{
+       struct lpfc_sli *psli;
+       struct lpfc_sli_ring *pring;
+
+       psli = &phba->sli;
+
+       /* Adjust cmd/rsp ring iocb entries more evenly */
+       pring = &psli->ring[psli->fcp_ring];
+       pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES;
+       pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES;
+       pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES;
+       pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES;
+
+       pring = &psli->ring[1];
+       pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES;
+       pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES;
+       pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES;
+       pring->numRiocb += SLI2_IOCB_RSP_R3XTRA_ENTRIES;
+
+       /* Setup default profile for this ring */
+       pring->iotag_max = 4096;
+       pring->num_mask = 1;
+       pring->prt[0].profile = 0;      /* Mask 0 */
+       pring->prt[0].rctl = FC_UNSOL_DATA;
+       pring->prt[0].type = 5;
+       pring->prt[0].lpfc_sli_rcv_unsol_event = NULL;
+       return 0;
+}
+
 int
 lpfc_sli_setup(struct lpfc_hba *phba)
 {
                                "SLI2 SLIM Data: x%x x%x\n",
                                phba->brd_no, totiocb, MAX_SLI2_IOCB);
        }
+       if (phba->cfg_multi_ring_support == 2)
+               lpfc_extra_ring_setup(phba);
 
        return 0;
 }