lpfc: Implement support for wire-only DIF devices
Subsystems (2)
PATCH 15/21 lpfc: Implement support for wire-only DIF devices
--- drivers/scsi/lpfc/lpfc.h | 41 ++++ drivers/scsi/lpfc/lpfc_attr.c | 65 ++++++- drivers/scsi/lpfc/lpfc_crtn.h | 3 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 + drivers/scsi/lpfc/lpfc_init.c | 24 ++- drivers/scsi/lpfc/lpfc_mbox.c | 4 +- drivers/scsi/lpfc/lpfc_scsi.c | 410 ++++++++++++++++++++++++++++++++++++--- drivers/scsi/lpfc/lpfc_scsi.h | 7 +- drivers/scsi/lpfc/lpfc_sli.c | 36 ++-- 9 files changed, 532 insertions(+), 61 deletions(-)
drivers/scsi/lpfc/lpfc.h +41 -0
@@ -295,6 +295,42 @@ enum hba_state {LPFC_HBA_ERROR =-1 }; +/* Structure used to identify all devices controlled +* by the External DIF logic. +*/ +struct lpfc_external_dif_support { +struct list_head listentry; +struct lpfc_name portName; +uint64_t lun; +uint16_t sid; +uint8_t dif_info; +uint8_t reserved1; +}; + +/* Struct used to identify External DIF vendor specific info */ +struct lpfc_vendor_dif { +uint8_t length; +uint8_t version; +uint8_t dif_info; +#define LPFC_FDIF_ATO 0x01 +#define LPFC_FDIF_REFCHK 0x02 +#define LPFC_FDIF_APPCHK 0x04 +#define LPFC_FDIF_GRDCHK 0x08 +#define LPFC_FDIF_SPTMASK 0x70 +#define LPFC_FDIF_PROTECT 0x80 +uint8_t reserved1; +}; + +/* Defines used to identify a External DIF device */ +#define LPFC_INQ_VID_OFFSET 8 +#define LPFC_INQ_VDIF_OFFSET 168 +#define LPFC_INQ_FDIF_SZ (LPFC_INQ_VDIF_OFFSET + 4) +#define LPFC_INQ_FDIF_VENDOR "3PARdata"/* Vendor Identification */ +#define LPFC_INQ_FDIF_VERSION 1 +#define LPFC_INQ_FDIF_SIZE 2 +#define LPFC_FDIF_CDB_PROTECT 0x20/* Set RD/WR PROTECT = 001 */ + +struct lpfc_vport {struct lpfc_hba *phba;struct list_head listentry;
@@ -441,6 +477,10 @@ struct lpfc_vport {unsigned long rcv_buffer_time_stamp;uint32_t vport_flag;#define STATIC_VPORT 1 + +/* Used to discover External DIF devices */ +struct list_head external_dif_list; +spinlock_t external_dif_lock;/* lock for external_dif_list */ };struct hbq_s {
@@ -739,6 +779,7 @@ struct lpfc_hba {#define OAS_LUN_VALID 0x04uint32_t cfg_XLanePriority;uint32_t cfg_enable_bg; +uint32_t cfg_external_dif;uint32_t cfg_hostmem_hgp;uint32_t cfg_log_verbose;uint32_t cfg_aer_support;
drivers/scsi/lpfc/lpfc_attr.c +59 -6
112 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_crtn.h +2 -1
@@ -366,7 +366,8 @@ extern int lpfc_delay_discovery;int lpfc_vport_symbolic_node_name (struct lpfc_vport *,char *,size_t );int lpfc_vport_symbolic_port_name (struct lpfc_vport *,char *,size_t );void lpfc_terminate_rport_io (struct fc_rport *); -void lpfc_dev_loss_tmo_callbk (struct fc_rport *rport); +void lpfc_dev_loss_tmo_callbk (struct fc_rport *); +void lpfc_external_dif_cleanup (struct lpfc_vport *,struct lpfc_name *);struct lpfc_vport *lpfc_create_port (struct lpfc_hba *,int ,struct device *);int lpfc_vport_disable (struct fc_vport *fc_vport,bool disable);
drivers/scsi/lpfc/lpfc_hbadisc.c +3 -0
@@ -143,6 +143,9 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)return ; } +/* Cleanup all External DIF devices that match this rports WWPN */ +lpfc_external_dif_cleanup (vport, &ndlp->nlp_portname); +if (ndlp->nlp_state ==NLP_STE_MAPPED_NODE )return ;
drivers/scsi/lpfc/lpfc_init.c +19 -5
@@ -154,8 +154,6 @@ lpfc_config_port_prep(struct lpfc_hba *phba) sizeof(phba->wwpn)); } - phba->sli3_options =0x0 ; -/* Setup and issue mailbox READ REV command */ lpfc_read_rev (phba, pmb); rc =lpfc_sli_issue_mbox (phba, pmb,MBX_POLL );
@@ -2523,6 +2521,7 @@ lpfc_cleanup(struct lpfc_vport *vport) {struct lpfc_hba *phba = vport->phba;struct lpfc_nodelist *ndlp, *next_ndlp; +struct lpfc_external_dif_support *dp, *next_dp;int i =0 ;if (phba->link_state >LPFC_LINK_DOWN )
@@ -2600,6 +2599,15 @@ lpfc_cleanup(struct lpfc_vport *vport)msleep (10 ); }lpfc_cleanup_vports_rrqs (vport,NULL ); + +/* Cleanup any discovered External DIF devices for this vport */ +list_for_each_entry_safe (dp, next_dp, &vport->external_dif_list, + listentry) { +spin_lock_irq (&vport->external_dif_lock); +list_del (&dp->listentry); +spin_unlock_irq (&vport->external_dif_lock); +kfree (dp); + } }/**
@@ -3348,6 +3356,10 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)if (error) goto out_put_shost; +/* Initialize objects used to discover External DIF devices */ +INIT_LIST_HEAD (&vport->external_dif_list); +spin_lock_init (&vport->external_dif_lock); +spin_lock_irq (&phba->hbalock);list_add_tail (&vport->listentry, &phba->port_list);spin_unlock_irq (&phba->hbalock);
@@ -4992,7 +5004,7 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt;/* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */ -if (phba->cfg_enable_bg) { +if (phba->sli3_options &LPFC_SLI3_BG_ENABLED ) {/* * The scsi_buf for a T10-DIF I/O will hold the FCP cmnd, * the FCP rsp, and a BDE for each. Sice we have no control
@@ -5185,7 +5197,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)* used to create the sg_dma_buf_pool must be dynamically calculated. */ -if (phba->cfg_enable_bg) { +if (phba->sli3_options &LPFC_SLI3_BG_ENABLED ) {/* * The scsi_buf for a T10-DIF I/O will hold the FCP cmnd, * the FCP rsp, and a SGE for each. Sice we have no control
@@ -6286,7 +6298,9 @@ lpfc_post_init_setup(struct lpfc_hba *phba)*/ shost =pci_get_drvdata (phba->pcidev); shost->can_queue = phba->cfg_hba_queue_depth -10 ; -if (phba->sli3_options &LPFC_SLI3_BG_ENABLED ) + +/* Setup T10-DIF interface with SCSI Layer API */ +if (phba->cfg_enable_bg)lpfc_setup_bg (phba, shost);lpfc_host_attrib_init (shost);
drivers/scsi/lpfc/lpfc_mbox.c +2 -2
@@ -1280,7 +1280,7 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)/* If HBA supports SLI=3 ask for it */ if (phba->sli_rev ==LPFC_SLI_REV3 && phba->vpd.sli3Feat.cerbm) { -if (phba->cfg_enable_bg) +if (phba->sli3_options &LPFC_SLI3_BG_ENABLED ) mb->un.varCfgPort.cbg =1 ;/* configure BlockGuard */ if (phba->cfg_enable_dss) mb->un.varCfgPort.cdss =1 ;/* Configure Security */
@@ -2071,7 +2071,7 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)bf_set (lpfc_mbx_rq_ftr_rq_perfh, &mboxq->u.mqe.un.req_ftrs,1 );/* Enable DIF (block guard) only if configured to do so. */ -if (phba->cfg_enable_bg) +if (phba->sli3_options &LPFC_SLI3_BG_ENABLED )bf_set (lpfc_mbx_rq_ftr_rq_dif, &mboxq->u.mqe.un.req_ftrs,1 );/* Enable NPIV only if configured to do so. */
drivers/scsi/lpfc/lpfc_scsi.c +378 -32
611 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_scsi.h +6 -1
@@ -134,7 +134,12 @@ struct lpfc_scsi_buf {uint32_t timeout; -uint16_t exch_busy;/* SLI4 hba reported XB on complete WCQE */ +uint16_t flags; +#define LPFC_SBUF_XBUSY 0x1/* SLI4 hba reported XB on WCQE cmpl */ +/* External DIF device IO conversions */ +#define LPFC_SBUF_NORMAL_DIF 0x2/* normal mode to insert/strip */ +#define LPFC_SBUF_PASS_DIF 0x4/* insert/strip mode to passthru */ +uint16_t status;/* From IOCB Word 7- ulpStatus */ uint32_t result;/* From IOCB Word 4. */
drivers/scsi/lpfc/lpfc_sli.c +22 -14
@@ -4526,7 +4526,6 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) phba->sli3_options &= ~(LPFC_SLI3_NPIV_ENABLED |LPFC_SLI3_HBQ_ENABLED |LPFC_SLI3_CRP_ENABLED | -LPFC_SLI3_BG_ENABLED |LPFC_SLI3_DSS_ENABLED );if (rc !=MBX_SUCCESS ) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -4592,13 +4591,20 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get; phba->port_gp = phba->mbox->us.s3_pgp.port; -if (phba->cfg_enable_bg) { -if (pmb->u.mb.un.varCfgPort.gbg) - phba->sli3_options |=LPFC_SLI3_BG_ENABLED ; -else +/* +* If the port cannot support the host's requested features +* then turn off the global config parameters to disable the +* feature in the driver. This is not a fatal error. +*/ +if (phba->sli3_options &LPFC_SLI3_BG_ENABLED ) { +if (pmb->u.mb.un.varCfgPort.gbg ==0 ) { + phba->cfg_enable_bg =0 ; + phba->cfg_external_dif =0 ; + phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED ;lpfc_printf_log (phba,KERN_ERR ,LOG_INIT ,"0443 Adapter did not grant " "BlockGuard\n" ); + } } }else { phba->hbq_get =NULL ;
@@ -4689,7 +4695,6 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) }else { phba->iocb_cmd_size =SLI2_IOCB_CMD_SIZE ; phba->iocb_rsp_size =SLI2_IOCB_RSP_SIZE ; - phba->sli3_options =0 ; } lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
@@ -6407,12 +6412,13 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)* then turn off the global config parameters to disable the * feature in the driver. This is not a fatal error. */ - phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED ; -if (phba->cfg_enable_bg) { -if (bf_get (lpfc_mbx_rq_ftr_rsp_dif, &mqe->un.req_ftrs)) - phba->sli3_options |=LPFC_SLI3_BG_ENABLED ; -else +if (phba->sli3_options &LPFC_SLI3_BG_ENABLED ) { +if (!(bf_get (lpfc_mbx_rq_ftr_rsp_dif, &mqe->un.req_ftrs))) { + phba->cfg_enable_bg =0 ; + phba->cfg_external_dif =0 ; + phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED ; ftr_rsp++; + } } if (phba->max_vpi && phba->cfg_enable_npiv &&
@@ -6425,8 +6431,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)"x%x x%x x%x\n" , mqe->un.req_ftrs.word2, mqe->un.req_ftrs.word3, phba->cfg_enable_bg, phba->cfg_enable_npiv, phba->max_vpi); -if (!(bf_get (lpfc_mbx_rq_ftr_rsp_dif, &mqe->un.req_ftrs))) - phba->cfg_enable_bg =0 ; +if (!(bf_get (lpfc_mbx_rq_ftr_rsp_npiv, &mqe->un.req_ftrs))) phba->cfg_enable_npiv =0 ; }
@@ -10326,7 +10331,10 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) { lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf, cur_iocbq); - lpfc_cmd->exch_busy = rspiocbq->iocb_flag &LPFC_EXCHANGE_BUSY ; +if (rspiocbq->iocb_flag &LPFC_EXCHANGE_BUSY ) + lpfc_cmd->flags |=LPFC_SBUF_XBUSY ; +else + lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY ; } pdone_q = cmdiocbq->context_un.wait_queue;
Signature · 4 lines
1.7.11.7 Signed-off-by: James Smart <[email protected]> Signed-off-by: Dick Kennedy <[email protected]>