staging/bcm: move IOCTL_BCM_NVM_[READ|WRITE] cases out to their own function.
bcm_char_ioctl is one of the longest non-generated functions in the kernel, at 1906 lines. Splitting it up into multiple functions should simplify this a lot. Signed-off-by: Dave Jones <davej@fedoraproject.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
085ca029be
commit
5be531c22a
1 changed files with 149 additions and 141 deletions
|
@ -1286,6 +1286,152 @@ static int bcm_char_ioctl_set_debug(void __user *argp, struct bcm_mini_adapter *
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bcm_char_ioctl_nvm_rw(void __user *argp, struct bcm_mini_adapter *Adapter, UINT cmd)
|
||||||
|
{
|
||||||
|
struct bcm_nvm_readwrite stNVMReadWrite;
|
||||||
|
struct timeval tv0, tv1;
|
||||||
|
struct bcm_ioctl_buffer IoBuffer;
|
||||||
|
PUCHAR pReadData = NULL;
|
||||||
|
ULONG ulDSDMagicNumInUsrBuff = 0;
|
||||||
|
INT Status = STATUS_FAILURE;
|
||||||
|
|
||||||
|
memset(&tv0, 0, sizeof(struct timeval));
|
||||||
|
memset(&tv1, 0, sizeof(struct timeval));
|
||||||
|
if ((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) {
|
||||||
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsFlash2x(Adapter)) {
|
||||||
|
if ((Adapter->eActiveDSD != DSD0) &&
|
||||||
|
(Adapter->eActiveDSD != DSD1) &&
|
||||||
|
(Adapter->eActiveDSD != DSD2)) {
|
||||||
|
|
||||||
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No DSD is active..hence NVM Command is blocked");
|
||||||
|
return STATUS_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy Ioctl Buffer structure */
|
||||||
|
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (copy_from_user(&stNVMReadWrite,
|
||||||
|
(IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
|
||||||
|
sizeof(struct bcm_nvm_readwrite)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deny the access if the offset crosses the cal area limit.
|
||||||
|
*/
|
||||||
|
if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize)
|
||||||
|
return STATUS_FAILURE;
|
||||||
|
|
||||||
|
if (stNVMReadWrite.uiOffset > Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes) {
|
||||||
|
/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */
|
||||||
|
return STATUS_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pReadData = memdup_user(stNVMReadWrite.pBuffer,
|
||||||
|
stNVMReadWrite.uiNumBytes);
|
||||||
|
if (IS_ERR(pReadData))
|
||||||
|
return PTR_ERR(pReadData);
|
||||||
|
|
||||||
|
do_gettimeofday(&tv0);
|
||||||
|
if (IOCTL_BCM_NVM_READ == cmd) {
|
||||||
|
down(&Adapter->NVMRdmWrmLock);
|
||||||
|
|
||||||
|
if ((Adapter->IdleMode == TRUE) ||
|
||||||
|
(Adapter->bShutStatus == TRUE) ||
|
||||||
|
(Adapter->bPreparingForLowPowerMode == TRUE)) {
|
||||||
|
|
||||||
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
|
||||||
|
up(&Adapter->NVMRdmWrmLock);
|
||||||
|
kfree(pReadData);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = BeceemNVMRead(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
|
||||||
|
up(&Adapter->NVMRdmWrmLock);
|
||||||
|
|
||||||
|
if (Status != STATUS_SUCCESS) {
|
||||||
|
kfree(pReadData);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy_to_user(stNVMReadWrite.pBuffer, pReadData, stNVMReadWrite.uiNumBytes)) {
|
||||||
|
kfree(pReadData);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
down(&Adapter->NVMRdmWrmLock);
|
||||||
|
|
||||||
|
if ((Adapter->IdleMode == TRUE) ||
|
||||||
|
(Adapter->bShutStatus == TRUE) ||
|
||||||
|
(Adapter->bPreparingForLowPowerMode == TRUE)) {
|
||||||
|
|
||||||
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
|
||||||
|
up(&Adapter->NVMRdmWrmLock);
|
||||||
|
kfree(pReadData);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Adapter->bHeaderChangeAllowed = TRUE;
|
||||||
|
if (IsFlash2x(Adapter)) {
|
||||||
|
/*
|
||||||
|
* New Requirement:-
|
||||||
|
* DSD section updation will be allowed in two case:-
|
||||||
|
* 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull
|
||||||
|
* 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is
|
||||||
|
* corrupted then user space program first modify the DSD header with valid DSD sig so
|
||||||
|
* that this as well as further write may be worthwhile.
|
||||||
|
*
|
||||||
|
* This restriction has been put assuming that if DSD sig is corrupted, DSD
|
||||||
|
* data won't be considered valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Status = BcmFlash2xCorruptSig(Adapter, Adapter->eActiveDSD);
|
||||||
|
if (Status != STATUS_SUCCESS) {
|
||||||
|
if (((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize) ||
|
||||||
|
(stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) {
|
||||||
|
|
||||||
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input..");
|
||||||
|
up(&Adapter->NVMRdmWrmLock);
|
||||||
|
kfree(pReadData);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
|
||||||
|
if (ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) {
|
||||||
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input..");
|
||||||
|
up(&Adapter->NVMRdmWrmLock);
|
||||||
|
kfree(pReadData);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = BeceemNVMWrite(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify);
|
||||||
|
if (IsFlash2x(Adapter))
|
||||||
|
BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD);
|
||||||
|
|
||||||
|
Adapter->bHeaderChangeAllowed = false;
|
||||||
|
|
||||||
|
up(&Adapter->NVMRdmWrmLock);
|
||||||
|
|
||||||
|
if (Status != STATUS_SUCCESS) {
|
||||||
|
kfree(pReadData);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_gettimeofday(&tv1);
|
||||||
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n", (tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000);
|
||||||
|
|
||||||
|
kfree(pReadData);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
|
static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
|
||||||
{
|
{
|
||||||
|
@ -1479,147 +1625,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
case IOCTL_BCM_NVM_READ:
|
case IOCTL_BCM_NVM_READ:
|
||||||
case IOCTL_BCM_NVM_WRITE: {
|
case IOCTL_BCM_NVM_WRITE:
|
||||||
struct bcm_nvm_readwrite stNVMReadWrite;
|
Status = bcm_char_ioctl_nvm_rw(argp, Adapter, cmd);
|
||||||
PUCHAR pReadData = NULL;
|
return Status;
|
||||||
ULONG ulDSDMagicNumInUsrBuff = 0;
|
|
||||||
struct timeval tv0, tv1;
|
|
||||||
memset(&tv0, 0, sizeof(struct timeval));
|
|
||||||
memset(&tv1, 0, sizeof(struct timeval));
|
|
||||||
if ((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) {
|
|
||||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsFlash2x(Adapter)) {
|
|
||||||
if ((Adapter->eActiveDSD != DSD0) &&
|
|
||||||
(Adapter->eActiveDSD != DSD1) &&
|
|
||||||
(Adapter->eActiveDSD != DSD2)) {
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No DSD is active..hence NVM Command is blocked");
|
|
||||||
return STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy Ioctl Buffer structure */
|
|
||||||
if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (copy_from_user(&stNVMReadWrite,
|
|
||||||
(IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
|
|
||||||
sizeof(struct bcm_nvm_readwrite)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Deny the access if the offset crosses the cal area limit.
|
|
||||||
*/
|
|
||||||
if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize)
|
|
||||||
return STATUS_FAILURE;
|
|
||||||
|
|
||||||
if (stNVMReadWrite.uiOffset > Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes) {
|
|
||||||
/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */
|
|
||||||
return STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pReadData = memdup_user(stNVMReadWrite.pBuffer,
|
|
||||||
stNVMReadWrite.uiNumBytes);
|
|
||||||
if (IS_ERR(pReadData))
|
|
||||||
return PTR_ERR(pReadData);
|
|
||||||
|
|
||||||
do_gettimeofday(&tv0);
|
|
||||||
if (IOCTL_BCM_NVM_READ == cmd) {
|
|
||||||
down(&Adapter->NVMRdmWrmLock);
|
|
||||||
|
|
||||||
if ((Adapter->IdleMode == TRUE) ||
|
|
||||||
(Adapter->bShutStatus == TRUE) ||
|
|
||||||
(Adapter->bPreparingForLowPowerMode == TRUE)) {
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
|
|
||||||
up(&Adapter->NVMRdmWrmLock);
|
|
||||||
kfree(pReadData);
|
|
||||||
return -EACCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = BeceemNVMRead(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
|
|
||||||
up(&Adapter->NVMRdmWrmLock);
|
|
||||||
|
|
||||||
if (Status != STATUS_SUCCESS) {
|
|
||||||
kfree(pReadData);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (copy_to_user(stNVMReadWrite.pBuffer, pReadData, stNVMReadWrite.uiNumBytes)) {
|
|
||||||
kfree(pReadData);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
down(&Adapter->NVMRdmWrmLock);
|
|
||||||
|
|
||||||
if ((Adapter->IdleMode == TRUE) ||
|
|
||||||
(Adapter->bShutStatus == TRUE) ||
|
|
||||||
(Adapter->bPreparingForLowPowerMode == TRUE)) {
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
|
|
||||||
up(&Adapter->NVMRdmWrmLock);
|
|
||||||
kfree(pReadData);
|
|
||||||
return -EACCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Adapter->bHeaderChangeAllowed = TRUE;
|
|
||||||
if (IsFlash2x(Adapter)) {
|
|
||||||
/*
|
|
||||||
* New Requirement:-
|
|
||||||
* DSD section updation will be allowed in two case:-
|
|
||||||
* 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull
|
|
||||||
* 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is
|
|
||||||
* corrupted then user space program first modify the DSD header with valid DSD sig so
|
|
||||||
* that this as well as further write may be worthwhile.
|
|
||||||
*
|
|
||||||
* This restriction has been put assuming that if DSD sig is corrupted, DSD
|
|
||||||
* data won't be considered valid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Status = BcmFlash2xCorruptSig(Adapter, Adapter->eActiveDSD);
|
|
||||||
if (Status != STATUS_SUCCESS) {
|
|
||||||
if (((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize) ||
|
|
||||||
(stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) {
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input..");
|
|
||||||
up(&Adapter->NVMRdmWrmLock);
|
|
||||||
kfree(pReadData);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
|
|
||||||
if (ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) {
|
|
||||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input..");
|
|
||||||
up(&Adapter->NVMRdmWrmLock);
|
|
||||||
kfree(pReadData);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = BeceemNVMWrite(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify);
|
|
||||||
if (IsFlash2x(Adapter))
|
|
||||||
BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD);
|
|
||||||
|
|
||||||
Adapter->bHeaderChangeAllowed = false;
|
|
||||||
|
|
||||||
up(&Adapter->NVMRdmWrmLock);
|
|
||||||
|
|
||||||
if (Status != STATUS_SUCCESS) {
|
|
||||||
kfree(pReadData);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do_gettimeofday(&tv1);
|
|
||||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n", (tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000);
|
|
||||||
|
|
||||||
kfree(pReadData);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IOCTL_BCM_FLASH2X_SECTION_READ: {
|
case IOCTL_BCM_FLASH2X_SECTION_READ: {
|
||||||
struct bcm_flash2x_readwrite sFlash2xRead = {0};
|
struct bcm_flash2x_readwrite sFlash2xRead = {0};
|
||||||
|
|
Loading…
Add table
Reference in a new issue