summaryrefslogtreecommitdiff
path: root/drivers/scsi/mpt3sas/mpt3sas_ctl.c
diff options
context:
space:
mode:
authorSreekanth Reddy <sreekanth.reddy@broadcom.com>2019-09-13 09:04:45 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2019-09-30 22:32:47 -0400
commita8a6cbcd038de4ee3722c17edd7a4d84ce423f7d (patch)
tree27f56d95142f7ea835ca3f5e4924aa5b7b8b3816 /drivers/scsi/mpt3sas/mpt3sas_ctl.c
parenta066f4c31359d07b1a2c5144b4b9a29901365fd0 (diff)
scsi: mpt3sas: Add app owned flag support for diag buffer
Added a new status flag named MPT3_DIAG_BUFFER_IS_APP_OWNED and it will set whenever application registers the diag buffer & it will be cleared when application unregisters the buffer. When this flag is enabled, and if application issues diag buffer register command without releasing the buffer, then register command will be failed with -EINVAL status by saying that this buffer is already registered by the application. When user issues a trace buffer register command through sysfs parameter, and if trace buffer is in released stated but not yet unregistered by the application which was owning it, then driver will unregister the buffer by itself and freshly register the 1MB sized trace buffer with the HBA firmware. Link: https://lore.kernel.org/r/1568379890-18347-9-git-send-email-sreekanth.reddy@broadcom.com Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c')
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_ctl.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index b5492f1a73a0..62e878d6a52b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -1565,6 +1565,16 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
return -EINVAL;
}
+ if ((ioc->diag_buffer_status[buffer_type] &
+ MPT3_DIAG_BUFFER_IS_APP_OWNED) &&
+ !(ioc->diag_buffer_status[buffer_type] &
+ MPT3_DIAG_BUFFER_IS_RELEASED)) {
+ ioc_err(ioc,
+ "%s: buffer_type(0x%02x) is already registered by application with UID(0x%08x)\n",
+ __func__, buffer_type, ioc->unique_id[buffer_type]);
+ return -EINVAL;
+ }
+
if (ioc->diag_buffer_status[buffer_type] &
MPT3_DIAG_BUFFER_IS_REGISTERED) {
/*
@@ -1884,6 +1894,12 @@ _ctl_diag_register(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
}
rc = _ctl_diag_register_2(ioc, &karg);
+
+ if (!rc && (ioc->diag_buffer_status[karg.buffer_type] &
+ MPT3_DIAG_BUFFER_IS_REGISTERED))
+ ioc->diag_buffer_status[karg.buffer_type] |=
+ MPT3_DIAG_BUFFER_IS_APP_OWNED;
+
return rc;
}
@@ -1956,6 +1972,8 @@ _ctl_diag_unregister(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED) {
ioc->unique_id[buffer_type] = MPT3DIAGBUFFUNIQUEID;
ioc->diag_buffer_status[buffer_type] &=
+ ~MPT3_DIAG_BUFFER_IS_APP_OWNED;
+ ioc->diag_buffer_status[buffer_type] &=
~MPT3_DIAG_BUFFER_IS_REGISTERED;
} else {
request_data_sz = ioc->diag_buffer_sz[buffer_type];
@@ -2040,6 +2058,10 @@ _ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED))
karg.application_flags |= MPT3_APP_FLAGS_DYNAMIC_BUFFER_ALLOC;
+ if ((ioc->diag_buffer_status[buffer_type] &
+ MPT3_DIAG_BUFFER_IS_APP_OWNED))
+ karg.application_flags |= MPT3_APP_FLAGS_APP_OWNED;
+
for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++)
karg.product_specific[i] =
ioc->product_specific[buffer_type][i];
@@ -3331,8 +3353,27 @@ host_trace_buffer_enable_store(struct device *cdev,
/* post the same buffer allocated previously */
diag_register.requested_buffer_size =
ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE];
- } else
+ } else {
+ /*
+ * Free the diag buffer memory which was previously
+ * allocated by an application.
+ */
+ if ((ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE] != 0)
+ &&
+ (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
+ MPT3_DIAG_BUFFER_IS_APP_OWNED)) {
+ pci_free_consistent(ioc->pdev,
+ ioc->diag_buffer_sz[
+ MPI2_DIAG_BUF_TYPE_TRACE],
+ ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE],
+ ioc->diag_buffer_dma[
+ MPI2_DIAG_BUF_TYPE_TRACE]);
+ ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE] =
+ NULL;
+ }
+
diag_register.requested_buffer_size = (1024 * 1024);
+ }
diag_register.unique_id =
(ioc->hba_mpi_version_belonged == MPI2_VERSION) ?