lpfc 8.3.19: Added support for ELS RRQ command
Subsystems (2)
PATCH 4/6 lpfc 8.3.19: Added support for ELS RRQ command
Added support for ELS RRQ command
- Add new routine lpfc_set_rrq_active() to track XRI qualifier state.
- Add new module parameter lpfc_enable_rrq to control RRQ operation.
- Add logic to ELS RRQ completion handler and xri qualifier timeout to clear XRI qualifier state.
- Use OX_ID from XRI_ABORTED_CQE for RRQ payload.
- Tie abort and XRI_ABORTED_CQE andler to RRQ generation.
Signed-off-by Alex Iannicelli <[email protected]>
Signed-off-by James Smart <[email protected]>
---
lpfc.h | 7 - lpfc_attr.c | 9 + lpfc_crtn.h | 12 + lpfc_disc.h | 17 ++ lpfc_els.c | 232 +++++++++++++++++++++++++++++++++ lpfc_hbadisc.c | 4 lpfc_hw.h | 18 ++ lpfc_init.c | 34 ++++ lpfc_mem.c | 10 + lpfc_scsi.c | 82 ++++++++++- lpfc_sli.c | 396 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- lpfc_sli.h | 1 lpfc_sli4.h | 1 13 files changed, 803 insertions(+), 20 deletions(-)
drivers/scsi/lpfc/lpfc_attr.c +9 -0
@@ -1977,6 +1977,13 @@ lpfc_param_show(enable_npiv);lpfc_param_init (enable_npiv,1 ,0 ,1 ); static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, lpfc_enable_npiv_show, NULL); +int lpfc_enable_rrq; +module_param (lpfc_enable_rrq, int,0 ); +MODULE_PARM_DESC (lpfc_enable_rrq,"Enable RRQ functionality" ); +lpfc_param_show (enable_rrq); +lpfc_param_init (enable_rrq,0 ,0 ,1 ); +static DEVICE_ATTR(lpfc_enable_rrq, S_IRUGO, lpfc_enable_rrq_show, NULL); +/* # lpfc_suppress_link_up: Bring link up at initialization # 0x0 = bring link up (issue MBX_INIT_LINK)
@@ -3394,6 +3401,7 @@ struct device_attribute *lpfc_hba_attrs[ &dev_attr_lpfc_fdmi_on, &dev_attr_lpfc_max_luns, &dev_attr_lpfc_enable_npiv, + &dev_attr_lpfc_enable_rrq, &dev_attr_nport_evt_cnt, &dev_attr_board_mode, &dev_attr_max_vpi,
@@ -4610,6 +4618,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)lpfc_link_speed_init (phba, lpfc_link_speed);lpfc_poll_tmo_init (phba, lpfc_poll_tmo);lpfc_enable_npiv_init (phba, lpfc_enable_npiv); +lpfc_enable_rrq_init (phba, lpfc_enable_rrq);lpfc_use_msi_init (phba, lpfc_use_msi);lpfc_fcp_imax_init (phba, lpfc_fcp_imax);lpfc_fcp_wq_count_init (phba, lpfc_fcp_wq_count);
drivers/scsi/lpfc/lpfc_crtn.h +10 -2
@@ -416,5 +416,13 @@ struct lpfc_iocbq *lpfc_sli_ringtx_get(sint __lpfc_sli_issue_iocb (struct lpfc_hba *,uint32_t ,struct lpfc_iocbq *,uint32_t );uint32_t lpfc_drain_txq (struct lpfc_hba *); - - +void lpfc_clr_rrq_active (struct lpfc_hba *,uint16_t ,struct lpfc_node_rrq *); +int lpfc_test_rrq_active (struct lpfc_hba *,struct lpfc_nodelist *,uint16_t ); +void lpfc_handle_rrq_active (struct lpfc_hba *); +int lpfc_send_rrq (struct lpfc_hba *,struct lpfc_node_rrq *); +int lpfc_set_rrq_active (struct lpfc_hba *,struct lpfc_nodelist *, +uint16_t ,uint16_t ,uint16_t ); +void lpfc_cleanup_wt_rrqs (struct lpfc_hba *); +void lpfc_cleanup_vports_rrqs (struct lpfc_vport *); +struct lpfc_node_rrq *lpfc_get_active_rrq (struct lpfc_vport *,uint16_t , +uint32_t );
drivers/scsi/lpfc/lpfc_disc.h +17 -0
@@ -68,6 +68,12 @@ struct lpfc_fast_path_event { } un; }; +#define LPFC_SLI4_MAX_XRI 1024/* Used to make the ndlp's xri_bitmap */ +#define XRI_BITMAP_ULONGS (LPFC_SLI4_MAX_XRI / BITS_PER_LONG) +struct lpfc_node_rrqs { +unsigned long xri_bitmap[XRI_BITMAP_ULONGS ]; +}; +struct lpfc_nodelist {struct list_head nlp_listp;struct lpfc_name nlp_portname;
@@ -110,8 +116,19 @@ struct lpfc_nodelist {atomic_t cmd_pending;uint32_t cmd_qdepth;unsigned long last_change_time; +struct lpfc_node_rrqs active_rrqs;struct lpfc_scsicmd_bkt *lat_data;/* Latency data */ }; +struct lpfc_node_rrq { +struct list_head list; +uint16_t xritag; +uint16_t send_rrq; +uint16_t rxid; +uint32_t nlp_DID;/* FC D_ID of entry */ +struct lpfc_vport *vport; +struct lpfc_nodelist *ndlp; +unsigned long rrq_stop_time; +};/* Defines for nlp_flag (uint32) */ #define NLP_IGNR_REG_CMPL 0x00000001/* Rcvd rscn before we cmpl reg login */
drivers/scsi/lpfc/lpfc_els.c +231 -1
310 lines not on this page · raw message
drivers/scsi/lpfc/lpfc.h +6 -1
@@ -486,7 +486,7 @@ struct lpfc_hba {int (*lpfc_new_scsi_buf) (struct lpfc_vport *,int );struct lpfc_scsi_buf * (*lpfc_get_scsi_buf) - (struct lpfc_hba *); + (struct lpfc_hba *,struct lpfc_nodelist *);int (*lpfc_scsi_prep_dma_buf) (struct lpfc_hba *,struct lpfc_scsi_buf *);void (*lpfc_scsi_unprep_dma_buf)
@@ -574,6 +574,7 @@ struct lpfc_hba {#define HBA_FIP_SUPPORT 0x800/* FIP support in HBA */ #define HBA_AER_ENABLED 0x1000/* AER enabled with HBA */ #define HBA_DEVLOSS_TMO 0x2000/* HBA in devloss timeout */ +#define HBA_RRQ_ACTIVE 0x4000/* process the rrq active list */ uint32_t fcp_ring_in_use;/* When polling test if intr-hndlr active*/ struct lpfc_dmabuf slim2p;
@@ -623,6 +624,7 @@ struct lpfc_hba {/* HBA Config Parameters */ uint32_t cfg_ack0;uint32_t cfg_enable_npiv; +uint32_t cfg_enable_rrq;uint32_t cfg_topology;uint32_t cfg_link_speed;uint32_t cfg_cr_delay;
@@ -733,6 +735,7 @@ struct lpfc_hba {uint32_t total_scsi_bufs;struct list_head lpfc_iocb_list;uint32_t total_iocbq_bufs; +struct list_head active_rrq_list;spinlock_t hbalock;/* pci_mem_pools */
@@ -745,6 +748,7 @@ struct lpfc_hba {mempool_t *mbox_mem_pool;mempool_t *nlp_mem_pool; +mempool_t *rrq_pool;struct fc_host_statistics link_stats;enum intr_type_t intr_type;
@@ -801,6 +805,7 @@ struct lpfc_hba {unsigned long skipped_hb;struct timer_list hb_tmofunc;uint8_t hb_outstanding; +struct timer_list rrq_tmr;enum hba_temp_state over_temp_state;/* ndlp reference management */ spinlock_t ndlp_lock;
drivers/scsi/lpfc/lpfc_hbadisc.c +4 -0
@@ -607,6 +607,8 @@ lpfc_work_done(struct lpfc_hba *phba)/* Process SLI4 events */ if (phba->pci_dev_grp ==LPFC_PCI_DEV_OC ) { +if (phba->hba_flag &HBA_RRQ_ACTIVE ) +lpfc_handle_rrq_active (phba);if (phba->hba_flag &FCP_XRI_ABORT_EVENT )lpfc_sli4_fcp_xri_abort_event_proc (phba);if (phba->hba_flag &ELS_XRI_ABORT_EVENT )
@@ -966,6 +968,7 @@ lpfc_linkup(struct lpfc_hba *phba)struct lpfc_vport **vports;int i; +lpfc_cleanup_wt_rrqs (phba); phba->link_state =LPFC_LINK_UP ;/* Unblock fabric iocbs if they are blocked */
@@ -3161,6 +3164,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hbaspin_unlock_irq (shost->host_lock); vport->unreg_vpi_cmpl =VPORT_OK ;mempool_free (pmb, phba->mbox_mem_pool); +lpfc_cleanup_vports_rrqs (vport);/* * This shost reference might have been taken at the beginning of * lpfc_vport_delete()
drivers/scsi/lpfc/lpfc_hw.h +18 -0
@@ -880,6 +880,24 @@ struct RLS_RSP { /* Structure is in Biuint32_t crcCnt; }; +struct RRQ {/* Structure is in Big Endian format */ +uint32_t rrq; +#define rrq_rsvd_SHIFT 24 +#define rrq_rsvd_MASK 0x000000ff +#define rrq_rsvd_WORD rrq +#define rrq_did_SHIFT 0 +#define rrq_did_MASK 0x00ffffff +#define rrq_did_WORD rrq +uint32_t rrq_exchg; +#define rrq_oxid_SHIFT 16 +#define rrq_oxid_MASK 0xffff +#define rrq_oxid_WORD rrq_exchg +#define rrq_rxid_SHIFT 0 +#define rrq_rxid_MASK 0xffff +#define rrq_rxid_WORD rrq_exchg +}; + +struct RTV_RSP {/* Structure is in Big Endian format */ uint32_t ratov;uint32_t edtov;
drivers/scsi/lpfc/lpfc_init.c +34 -0
@@ -930,6 +930,35 @@ lpfc_hb_timeout(unsigned long ptr) }/** +* lpfc_rrq_timeout - The RRQ-timer timeout handler +* @ptr: unsigned long holds the pointer to lpfc hba data structure. +* +* This is the RRQ-timer timeout handler registered to the lpfc driver. When +* this timer fires, a RRQ timeout event shall be posted to the lpfc driver +* work-port-events bitmap and the worker thread is notified. This timeout +* event will be used by the worker thread to invoke the actual timeout +* handler routine, lpfc_rrq_handler. Any periodical operations will +* be performed in the timeout handler and the RRQ timeout event bit shall +* be cleared by the worker thread after it has taken the event bitmap out. +**/ +static void +lpfc_rrq_timeout (unsigned long ptr) +{ +struct lpfc_hba *phba; +uint32_t tmo_posted; +unsigned long iflag; + + phba = (struct lpfc_hba *)ptr; +spin_lock_irqsave (&phba->pport->work_port_lock, iflag); + tmo_posted = phba->hba_flag &HBA_RRQ_ACTIVE ; +if (!tmo_posted) + phba->hba_flag |=HBA_RRQ_ACTIVE ; +spin_unlock_irqrestore (&phba->pport->work_port_lock, iflag); +if (!tmo_posted) +lpfc_worker_wake_up (phba); +} + +/** * lpfc_hb_mbox_cmpl - The lpfc heart-beat mailbox command callback function * @phba: pointer to lpfc hba data structure. * @pmboxq: pointer to the driver internal queue element for mailbox command.
@@ -3990,6 +4019,9 @@ lpfc_sli4_driver_resource_setup(struct linit_timer (&phba->hb_tmofunc); phba->hb_tmofunc.function = lpfc_hb_timeout; phba->hb_tmofunc.data = (unsigned long )phba; +init_timer (&phba->rrq_tmr); + phba->rrq_tmr.function = lpfc_rrq_timeout; + phba->rrq_tmr.data = (unsigned long )phba; psli = &phba->sli;/* MBOX heartbeat timer */
@@ -8192,6 +8224,8 @@ lpfc_pci_probe_one_s4(struct pci_dev *pd goto out_unset_driver_resource_s4; } +INIT_LIST_HEAD (&phba->active_rrq_list); +/* Set up common device driver resources */ error =lpfc_setup_driver_resource_phase2 (phba);if (error) {
drivers/scsi/lpfc/lpfc_mem.c +9 -1
@@ -113,11 +113,16 @@ lpfc_mem_alloc(struct lpfc_hba *phba, in goto fail_free_mbox_pool;if (phba->sli_rev ==LPFC_SLI_REV4 ) { + phba->rrq_pool = +mempool_create_kmalloc_pool (LPFC_MEM_POOL_SIZE , +sizeof (struct lpfc_node_rrq )); +if (!phba->rrq_pool) + goto fail_free_nlp_mem_pool; phba->lpfc_hrb_pool =pci_pool_create ("lpfc_hrb_pool" , phba->pcidev,LPFC_HDR_BUF_SIZE , align,0 );if (!phba->lpfc_hrb_pool) - goto fail_free_nlp_mem_pool; + goto fail_free_rrq_mem_pool; phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool", phba->pcidev,
@@ -147,6 +152,9 @@ lpfc_mem_alloc(struct lpfc_hba *phba, in fail_free_hrb_pool:pci_pool_destroy (phba->lpfc_hrb_pool); phba->lpfc_hrb_pool =NULL ; + fail_free_rrq_mem_pool: +mempool_destroy (phba->rrq_pool); + phba->rrq_pool =NULL ; fail_free_nlp_mem_pool:mempool_destroy (phba->nlp_mem_pool); phba->nlp_mem_pool =NULL ;
drivers/scsi/lpfc/lpfc_scsi.c +76 -6
153 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli4.h +1 -0
@@ -466,6 +466,7 @@ struct lpfc_sglq {struct list_head clist;enum lpfc_sge_type buff_type;/* is this a scsi sgl */ enum lpfc_sgl_state state; +struct lpfc_nodelist *ndlp;/* ndlp associated with IO */ uint16_t iotag;/* pre-assigned IO tag */ uint16_t sli4_xritag;/* pre-assigned XRI, (OXID) tag. */ struct sli4_sge *sgl;/* pre-assigned SGL */
drivers/scsi/lpfc/lpfc_sli.c +387 -9
443 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli.h +1 -0
@@ -82,6 +82,7 @@ struct lpfc_iocbq {struct lpfc_iocbq *rsp_iocb;struct lpfcMboxq *mbox;struct lpfc_nodelist *ndlp; +struct lpfc_node_rrq *rrq; } context_un; void (*fabric_iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,