[SCSI] lpfc 8.1.11 : Fix lpfc_multi_ring_support
authorJames Smart <James.Smart@Emulex.Com>
Sat, 2 Dec 2006 18:34:16 +0000 (13:34 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Sun, 3 Dec 2006 15:29:18 +0000 (09:29 -0600)
It was not accounted for in the fast/slow rings.
Genericize the implementation and control it via sysfs

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_hw.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli.h

index 3f7f5f8abd7517524b330ac2cd98c13f3444999a..e94190e83fc3a339b4b8b1bbb280f967baee71b1 100644 (file)
@@ -296,6 +296,8 @@ struct lpfc_hba {
        uint32_t cfg_cr_delay;
        uint32_t cfg_cr_count;
        uint32_t cfg_multi_ring_support;
+       uint32_t cfg_multi_ring_rctl;
+       uint32_t cfg_multi_ring_type;
        uint32_t cfg_fdmi_on;
        uint32_t cfg_discovery_threads;
        uint32_t cfg_max_luns;
index 2a4e02e7a39211d83960c8522417d1b89f2d9be4..f05ef301130708da6cdbc1fccb678ad761a7ef29 100644 (file)
@@ -802,7 +802,6 @@ static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
 # LOG_MBOX                      0x4        Mailbox events
 # LOG_INIT                      0x8        Initialization events
 # LOG_LINK_EVENT                0x10       Link events
-# LOG_IP                        0x20       IP traffic history
 # LOG_FCP                       0x40       FCP traffic history
 # LOG_NODE                      0x80       Node table events
 # LOG_MISC                      0x400      Miscellaneous events
@@ -915,6 +914,22 @@ LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
 LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
                "SLI rings to spread IOCB entries across");
 
+/*
+# lpfc_multi_ring_rctl:  If lpfc_multi_ring_support is enabled, this
+# identifies what rctl value to configure the additional ring for.
+# Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
+*/
+LPFC_ATTR_R(multi_ring_rctl, FC_UNSOL_DATA, 1,
+            255, "Identifies RCTL for additional ring configuration");
+
+/*
+# lpfc_multi_ring_type:  If lpfc_multi_ring_support is enabled, this
+# identifies what type value to configure the additional ring for.
+# Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
+*/
+LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1,
+            255, "Identifies TYPE for additional ring configuration");
+
 /*
 # lpfc_fdmi_on: controls FDMI support.
 #       0 = no FDMI support
@@ -974,6 +989,8 @@ struct class_device_attribute *lpfc_host_attrs[] = {
        &class_device_attr_lpfc_cr_delay,
        &class_device_attr_lpfc_cr_count,
        &class_device_attr_lpfc_multi_ring_support,
+       &class_device_attr_lpfc_multi_ring_rctl,
+       &class_device_attr_lpfc_multi_ring_type,
        &class_device_attr_lpfc_fdmi_on,
        &class_device_attr_lpfc_max_luns,
        &class_device_attr_nport_evt_cnt,
@@ -1771,6 +1788,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
        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_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
+       lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
        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);
index 60af1c60fe9bdc9c86d525f948e97578d180b7df..a47e5ab1ec4dd69a3b16776701a09c1cc6a96d3a 100644 (file)
@@ -1128,7 +1128,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                                                mempool_free(mbox,
                                                     phba->mbox_mem_pool);
                                                lpfc_disc_flush_list(phba);
-                                               psli->ring[(psli->ip_ring)].
+                                               psli->ring[(psli->extra_ring)].
                                                    flag &=
                                                    ~LPFC_STOP_IOCB_EVENT;
                                                psli->ring[(psli->fcp_ring)].
@@ -3046,7 +3046,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
        /* FARP-REQ received from DID <did> */
        lpfc_printf_log(phba,
                         KERN_INFO,
-                        LOG_IP,
+                        LOG_ELS,
                         "%d:0601 FARP-REQ received from DID x%x\n",
                         phba->brd_no, did);
 
@@ -3108,7 +3108,7 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba,
        /* FARP-RSP received from DID <did> */
        lpfc_printf_log(phba,
                         KERN_INFO,
-                        LOG_IP,
+                        LOG_ELS,
                         "%d:0600 FARP-RSP received from DID x%x\n",
                         phba->brd_no, did);
 
index 983faadec5f3aa37ed1952cba782f1c7a93c92b8..7c28184ad56d5ca293179cffe3945a99b02631f2 100644 (file)
@@ -525,7 +525,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
        psli = &phba->sli;
        mb = &pmb->mb;
        /* Since we don't do discovery right now, turn these off here */
-       psli->ring[psli->ip_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
+       psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
        psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
        psli->ring[psli->next_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
 
@@ -641,7 +641,7 @@ out:
        if (rc == MBX_NOT_FINISHED) {
                mempool_free(pmb, phba->mbox_mem_pool);
                lpfc_disc_flush_list(phba);
-               psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
+               psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
                psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
                psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
                phba->hba_state = LPFC_HBA_READY;
@@ -696,7 +696,7 @@ out:
                    == MBX_NOT_FINISHED) {
                        mempool_free( pmb, phba->mbox_mem_pool);
                        lpfc_disc_flush_list(phba);
-                       psli->ring[(psli->ip_ring)].flag &=
+                       psli->ring[(psli->extra_ring)].flag &=
                            ~LPFC_STOP_IOCB_EVENT;
                        psli->ring[(psli->fcp_ring)].flag &=
                            ~LPFC_STOP_IOCB_EVENT;
@@ -1424,7 +1424,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba,
                        if (iocb->context1 == (uint8_t *) ndlp)
                                return 1;
                }
-       } else if (pring->ringno == psli->ip_ring) {
+       } else if (pring->ringno == psli->extra_ring) {
 
        } else if (pring->ringno == psli->fcp_ring) {
                /* Skip match check if waiting to relogin to FCP target */
@@ -1889,7 +1889,7 @@ lpfc_disc_start(struct lpfc_hba * phba)
                        if (rc == MBX_NOT_FINISHED) {
                                mempool_free( mbox, phba->mbox_mem_pool);
                                lpfc_disc_flush_list(phba);
-                               psli->ring[(psli->ip_ring)].flag &=
+                               psli->ring[(psli->extra_ring)].flag &=
                                        ~LPFC_STOP_IOCB_EVENT;
                                psli->ring[(psli->fcp_ring)].flag &=
                                        ~LPFC_STOP_IOCB_EVENT;
@@ -2268,7 +2268,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 
        if (clrlaerr) {
                lpfc_disc_flush_list(phba);
-               psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
+               psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
                psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
                psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
                phba->hba_state = LPFC_HBA_READY;
index d7306679f1f9a4a86e4ce5b16df4236aa36bcc14..0d08a50ca41e0488a940fa41d7f8ec19184c6383 100644 (file)
 #define FCELSSIZE             1024     /* maximum ELS transfer size */
 
 #define LPFC_FCP_RING            0     /* ring 0 for FCP initiator commands */
-#define LPFC_IP_RING             1     /* ring 1 for IP commands */
+#define LPFC_EXTRA_RING          1     /* ring 1 for other protocols */
 #define LPFC_ELS_RING            2     /* ring 2 for ELS commands */
 #define LPFC_FCP_NEXT_RING       3
 
 #define SLI2_IOCB_CMD_R0_ENTRIES    172        /* SLI-2 FCP command ring entries */
 #define SLI2_IOCB_RSP_R0_ENTRIES    134        /* SLI-2 FCP response ring entries */
-#define SLI2_IOCB_CMD_R1_ENTRIES      4        /* SLI-2 IP command ring entries */
-#define SLI2_IOCB_RSP_R1_ENTRIES      4        /* SLI-2 IP response ring entries */
+#define SLI2_IOCB_CMD_R1_ENTRIES      4        /* SLI-2 extra command ring entries */
+#define SLI2_IOCB_RSP_R1_ENTRIES      4        /* SLI-2 extra response ring entries */
 #define SLI2_IOCB_CMD_R1XTRA_ENTRIES 36        /* SLI-2 extra FCP cmd ring entries */
 #define SLI2_IOCB_RSP_R1XTRA_ENTRIES 52        /* SLI-2 extra FCP rsp ring entries */
 #define SLI2_IOCB_CMD_R2_ENTRIES     20        /* SLI-2 ELS command ring entries */
index a5723ad0a0992c9026e759c7a5899cac4f51ea96..fd734b0fe95ffd96970d84f6484a06bdb1f51ef8 100644 (file)
@@ -349,8 +349,8 @@ lpfc_config_port_post(struct lpfc_hba * phba)
        phba->hba_state = LPFC_LINK_DOWN;
 
        /* Only process IOCBs on ring 0 till hba_state is READY */
-       if (psli->ring[psli->ip_ring].cmdringaddr)
-               psli->ring[psli->ip_ring].flag |= LPFC_STOP_IOCB_EVENT;
+       if (psli->ring[psli->extra_ring].cmdringaddr)
+               psli->ring[psli->extra_ring].flag |= LPFC_STOP_IOCB_EVENT;
        if (psli->ring[psli->fcp_ring].cmdringaddr)
                psli->ring[psli->fcp_ring].flag |= LPFC_STOP_IOCB_EVENT;
        if (psli->ring[psli->next_ring].cmdringaddr)
index 582f5ea4e84e3c7b9f00c59ae58f5fab2af41925..120af3db635a0faa65f358f19593add7b6009ab9 100644 (file)
@@ -1098,6 +1098,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
                lpfc_sli_pcimem_bcopy((uint32_t *) entry,
                                      (uint32_t *) &rspiocbq.iocb,
                                      sizeof (IOCB_t));
+               INIT_LIST_HEAD(&(rspiocbq.list));
                irsp = &rspiocbq.iocb;
 
                type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
@@ -1149,6 +1150,11 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
                                }
                        }
                        break;
+               case LPFC_UNSOL_IOCB:
+                       spin_unlock_irqrestore(phba->host->host_lock, iflag);
+                       lpfc_sli_process_unsol_iocb(phba, pring, &rspiocbq);
+                       spin_lock_irqsave(phba->host->host_lock, iflag);
+                       break;
                default:
                        if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
                                char adaptermsg[LPFC_MAX_ADPTMSG];
@@ -2472,13 +2478,17 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba)
        psli = &phba->sli;
 
        /* Adjust cmd/rsp ring iocb entries more evenly */
+
+       /* Take some away from the FCP ring */
        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];
+       /* and give them to the extra ring */
+       pring = &psli->ring[psli->extra_ring];
+
        pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES;
        pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES;
        pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES;
@@ -2488,8 +2498,8 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba)
        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].rctl = phba->cfg_multi_ring_rctl;
+       pring->prt[0].type = phba->cfg_multi_ring_type;
        pring->prt[0].lpfc_sli_rcv_unsol_event = NULL;
        return 0;
 }
@@ -2505,7 +2515,7 @@ lpfc_sli_setup(struct lpfc_hba *phba)
        psli->sli_flag = 0;
        psli->fcp_ring = LPFC_FCP_RING;
        psli->next_ring = LPFC_FCP_NEXT_RING;
-       psli->ip_ring = LPFC_IP_RING;
+       psli->extra_ring = LPFC_EXTRA_RING;
 
        psli->iocbq_lookup = NULL;
        psli->iocbq_lookup_len = 0;
@@ -2528,7 +2538,7 @@ lpfc_sli_setup(struct lpfc_hba *phba)
                        pring->fast_iotag = pring->iotag_max;
                        pring->num_mask = 0;
                        break;
-               case LPFC_IP_RING:      /* ring 1 - IP */
+               case LPFC_EXTRA_RING:   /* ring 1 - EXTRA */
                        /* numCiocb and numRiocb are used in config_port */
                        pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES;
                        pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES;
@@ -3238,6 +3248,21 @@ lpfc_intr_handler(int irq, void *dev_id)
                lpfc_sli_handle_fast_ring_event(phba,
                                                &phba->sli.ring[LPFC_FCP_RING],
                                                status);
+
+       if (phba->cfg_multi_ring_support == 2) {
+               /*
+                * Process all events on extra ring.  Take the optimized path
+                * for extra ring IO.  Any other IO is slow path and is handled
+                * by the worker thread.
+                */
+               status = (ha_copy & (HA_RXMASK  << (4*LPFC_EXTRA_RING)));
+               status >>= (4*LPFC_EXTRA_RING);
+               if (status & HA_RXATT) {
+                       lpfc_sli_handle_fast_ring_event(phba,
+                                       &phba->sli.ring[LPFC_EXTRA_RING],
+                                       status);
+               }
+       }
        return IRQ_HANDLED;
 
 } /* lpfc_intr_handler */
index e26de6809358a8529b5df6b2a3e88611be709cbd..a43549959dc7bb45bd9ebabcd8121afdcf201a00 100644 (file)
@@ -198,7 +198,7 @@ struct lpfc_sli {
        int fcp_ring;           /* ring used for FCP initiator commands */
        int next_ring;
 
-       int ip_ring;            /* ring used for IP network drv cmds */
+       int extra_ring;         /* extra ring used for other protocols */
 
        struct lpfc_sli_stat slistat;   /* SLI statistical info */
        struct list_head mboxq;