lpfc 8.3.0 : Add BlockGuard support (T10-DIF) Part 2
Subsystems (2)
PATCH 12/14 lpfc 8.3.0 : Add BlockGuard support (T10-DIF) Part 2
lpfc 8.3.0 : Add BlockGuard support (T10-DIF) Part 2
Add SCSI data path, error handling, and debugfs code to complete BlockGuard support.
Signed-off-by James Smart <[email protected]>
---
drivers/scsi/lpfc/lpfc_debugfs.c | 152 +++++++ drivers/scsi/lpfc/lpfc_mbox.c | 2 drivers/scsi/lpfc/lpfc_scsi.c | 874 +++++++++++++++++++++++++++++++++++++- drivers/scsi/lpfc/lpfc_scsi.h | 2 drivers/scsi/lpfc/lpfc_sli.c | 13 + 5 files changed, 1026 insertions(+), 17 deletions(-)
drivers/scsi/lpfc/lpfc_debugfs.c +152 -0
@@ -907,6 +907,91 @@ out:return rc; } +static int +lpfc_debugfs_dumpData_open (struct inode *inode,struct file *file) +{ +struct lpfc_debug *debug; +int rc = -ENOMEM ; + +if (!_dump_buf_data) +return -EBUSY ; + + debug =kmalloc (sizeof (*debug),GFP_KERNEL ); +if (!debug) + goto out; + +/* Round to page boundry */ +printk (KERN_ERR "BLKGRD %s: _dump_buf_data=0x%p\n" , + __func__, _dump_buf_data); + debug->buffer = _dump_buf_data; +if (!debug->buffer) { +kfree (debug); + goto out; + } + + debug->len = (1 << _dump_buf_data_order) <<PAGE_SHIFT ; + file->private_data = debug; + + rc =0 ; +out: +return rc; +} + +static int +lpfc_debugfs_dumpDif_open (struct inode *inode,struct file *file) +{ +struct lpfc_debug *debug; +int rc = -ENOMEM ; + +if (!_dump_buf_dif) +return -EBUSY ; + + debug =kmalloc (sizeof (*debug),GFP_KERNEL ); +if (!debug) + goto out; + +/* Round to page boundry */ +printk (KERN_ERR "BLKGRD %s: _dump_buf_dif=0x%p file=%s\n" , __func__, + _dump_buf_dif, file->f_dentry->d_name.name); + debug->buffer = _dump_buf_dif; +if (!debug->buffer) { +kfree (debug); + goto out; + } + + debug->len = (1 << _dump_buf_dif_order) <<PAGE_SHIFT ; + file->private_data = debug; + + rc =0 ; +out: +return rc; +} + +static ssize_t +lpfc_debugfs_dumpDataDif_write (struct file *file,const char __user *buf, +size_t nbytes,loff_t *ppos) +{ +/* +* The Data/DIF buffers only save one failing IO +* The write op is used as a reset mechanism after an IO has +* already been saved to the next one can be saved +*/ +spin_lock (&_dump_buf_lock); + +memset ((void *)_dump_buf_data,0 , + ((1 <<PAGE_SHIFT ) << _dump_buf_data_order)); +memset ((void *)_dump_buf_dif,0 , + ((1 <<PAGE_SHIFT ) << _dump_buf_dif_order)); + + _dump_buf_done =0 ; + +spin_unlock (&_dump_buf_lock); + +return nbytes; +} + + +/** * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file. * @inode: The inode pointer that contains a vport pointer.
@@ -1035,6 +1120,17 @@ lpfc_debugfs_release(struct inode *inode, struct file *file)return 0 ; } +static int +lpfc_debugfs_dumpDataDif_release (struct inode *inode,struct file *file) +{ +struct lpfc_debug *debug = file->private_data; + + debug->buffer =NULL ; +kfree (debug); + +return 0 ; +} +#undef lpfc_debugfs_op_disc_trcstatic struct file_operations lpfc_debugfs_op_disc_trc = { .owner =THIS_MODULE ,
@@ -1080,6 +1176,26 @@ static struct file_operations lpfc_debugfs_op_dumpHostSlim = { .release = lpfc_debugfs_release, }; +#undef lpfc_debugfs_op_dumpData +static struct file_operations lpfc_debugfs_op_dumpData = { + .owner =THIS_MODULE , + .open = lpfc_debugfs_dumpData_open, + .llseek = lpfc_debugfs_lseek, + .read = lpfc_debugfs_read, + .write = lpfc_debugfs_dumpDataDif_write, + .release = lpfc_debugfs_dumpDataDif_release, +}; + +#undef lpfc_debugfs_op_dumpDif +static struct file_operations lpfc_debugfs_op_dumpDif = { + .owner =THIS_MODULE , + .open = lpfc_debugfs_dumpDif_open, + .llseek = lpfc_debugfs_lseek, + .read = lpfc_debugfs_read, + .write = lpfc_debugfs_dumpDataDif_write, + .release = lpfc_debugfs_dumpDataDif_release, +}; +#undef lpfc_debugfs_op_slow_ring_trcstatic struct file_operations lpfc_debugfs_op_slow_ring_trc = { .owner =THIS_MODULE ,
@@ -1176,6 +1292,32 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) goto debug_failed; } +/* Setup dumpData */ +snprintf (name,sizeof (name),"dumpData" ); + phba->debug_dumpData = +debugfs_create_file (name,S_IFREG |S_IRUGO |S_IWUSR , + phba->hba_debugfs_root, + phba, &lpfc_debugfs_op_dumpData); +if (!phba->debug_dumpData) { +lpfc_printf_vlog (vport,KERN_ERR ,LOG_INIT , +"0800 Cannot create debugfs dumpData\n" ); + goto debug_failed; + } + +/* Setup dumpDif */ +snprintf (name,sizeof (name),"dumpDif" ); + phba->debug_dumpDif = +debugfs_create_file (name,S_IFREG |S_IRUGO |S_IWUSR , + phba->hba_debugfs_root, + phba, &lpfc_debugfs_op_dumpDif); +if (!phba->debug_dumpDif) { +lpfc_printf_vlog (vport,KERN_ERR ,LOG_INIT , +"0801 Cannot create debugfs dumpDif\n" ); + goto debug_failed; + } + + +/* Setup slow ring trace */ if (lpfc_debugfs_max_slow_ring_trc) { num = lpfc_debugfs_max_slow_ring_trc -1 ;
@@ -1340,6 +1482,16 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)debugfs_remove (phba->debug_dumpHostSlim);/* HostSlim */ phba->debug_dumpHostSlim =NULL ; } +if (phba->debug_dumpData) { +debugfs_remove (phba->debug_dumpData);/* dumpData */ + phba->debug_dumpData =NULL ; + } + +if (phba->debug_dumpDif) { +debugfs_remove (phba->debug_dumpDif);/* dumpDif */ + phba->debug_dumpDif =NULL ; + } +if (phba->slow_ring_trc) {kfree (phba->slow_ring_trc); phba->slow_ring_trc =NULL ;
drivers/scsi/lpfc/lpfc_mbox.c +2 -0
@@ -1099,6 +1099,8 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)/* If HBA supports SLI=3 ask for it */ if (phba->sli_rev ==3 && phba->vpd.sli3Feat.cerbm) { +if (phba->cfg_enable_bg) + mb->un.varCfgPort.cbg =1 ;/* configure BlockGuard */ mb->un.varCfgPort.cerbm =1 ;/* Request HBQs */ mb->un.varCfgPort.ccrp =1 ;/* Command Ring Polling */ mb->un.varCfgPort.cinb =1 ;/* Interrupt Notification Block */
drivers/scsi/lpfc/lpfc_scsi.c +858 -16
1,015 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_scsi.h +2 -0
@@ -124,6 +124,8 @@ struct lpfc_scsi_buf {uint32_t seg_cnt;/* Number of scatter-gather segments returned by * dma_map_sg. The driver needs this for calls * to dma_unmap_sg. */ +uint32_t prot_seg_cnt;/* seg_cnt's counterpart for protection data */ +dma_addr_t nonsg_phys;/* Non scatter-gather physical address. */ /*
drivers/scsi/lpfc/lpfc_sli.c +12 -1
@@ -542,6 +542,7 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,*/ nextiocb->iocb.ulpIoTag = (nextiocb->iocb_cmpl) ? nextiocb->iotag :0 ; +if (pring->ringno ==LPFC_ELS_RING ) { lpfc_debugfs_slow_ring_trc(phba, "IOCB cmd ring: wd4:x%08x wd6:x%08x wd7:x%08x",
@@ -3044,7 +3045,8 @@ 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_INB_ENABLED ); +LPFC_SLI3_INB_ENABLED | +LPFC_SLI3_BG_ENABLED );if (rc !=MBX_SUCCESS ) {lpfc_printf_log (phba,KERN_ERR ,LOG_INIT , "0442 Adapter failed to init, mbxCmd x%x "
@@ -3089,6 +3091,15 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) phba->inb_ha_copy =NULL ; phba->inb_counter =NULL ; } + +if (phba->cfg_enable_bg) { +if (pmb->mb.un.varCfgPort.gbg) + phba->sli3_options |=LPFC_SLI3_BG_ENABLED ; +else +lpfc_printf_log (phba,KERN_ERR ,LOG_INIT , +"0443 Adapter did not grant " +"BlockGuard\n" ); + } }else { phba->hbq_get =NULL ; phba->port_gp = phba->mbox->us.s2.port;