diff options
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.h | 1 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_ctl.c | 43 |
2 files changed, 43 insertions, 1 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index eaeb71f9b546..91f663688bf0 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -304,6 +304,7 @@ struct mpt3sas_nvme_cmd { #define MPT3_DIAG_BUFFER_IS_RELEASED (0x02) #define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04) #define MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED (0x08) +#define MPT3_DIAG_BUFFER_IS_APP_OWNED (0x10) /* * HP HBA branding 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) ? |