forked from Minki/linux
[SCSI] lpfc 8.3.0 : Add BlockGuard support (T10-DIF) code
Add SCSI data path, error handling, and debugfs code to complete BlockGuard support. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
81301a9b05
commit
e2a0a9d69c
@ -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_trc
|
||||
static 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_trc
|
||||
static 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;
|
||||
|
@ -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 */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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. */
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user