DAC960: push down BKL

Signed-off-by: Alan Cox <alan@redhat.com>
Cc: Richard Knutsson <ricknu-0@student.ltu.se>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
Alan Cox 2008-07-04 09:29:31 +02:00 committed by Jens Axboe
parent 5b6155ee70
commit 2610324fca

View File

@ -6628,15 +6628,18 @@ static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller)
* DAC960_gam_ioctl is the ioctl function for performing RAID operations. * DAC960_gam_ioctl is the ioctl function for performing RAID operations.
*/ */
static int DAC960_gam_ioctl(struct inode *inode, struct file *file, static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
unsigned int Request, unsigned long Argument) unsigned long Argument)
{ {
int ErrorCode = 0; long ErrorCode = 0;
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!capable(CAP_SYS_ADMIN)) return -EACCES;
lock_kernel();
switch (Request) switch (Request)
{ {
case DAC960_IOCTL_GET_CONTROLLER_COUNT: case DAC960_IOCTL_GET_CONTROLLER_COUNT:
return DAC960_ControllerCount; ErrorCode = DAC960_ControllerCount;
break;
case DAC960_IOCTL_GET_CONTROLLER_INFO: case DAC960_IOCTL_GET_CONTROLLER_INFO:
{ {
DAC960_ControllerInfo_T __user *UserSpaceControllerInfo = DAC960_ControllerInfo_T __user *UserSpaceControllerInfo =
@ -6644,15 +6647,20 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
DAC960_ControllerInfo_T ControllerInfo; DAC960_ControllerInfo_T ControllerInfo;
DAC960_Controller_T *Controller; DAC960_Controller_T *Controller;
int ControllerNumber; int ControllerNumber;
if (UserSpaceControllerInfo == NULL) return -EINVAL; if (UserSpaceControllerInfo == NULL)
ErrorCode = get_user(ControllerNumber, ErrorCode = -EINVAL;
else ErrorCode = get_user(ControllerNumber,
&UserSpaceControllerInfo->ControllerNumber); &UserSpaceControllerInfo->ControllerNumber);
if (ErrorCode != 0) return ErrorCode; if (ErrorCode != 0)
break;;
ErrorCode = -ENXIO;
if (ControllerNumber < 0 || if (ControllerNumber < 0 ||
ControllerNumber > DAC960_ControllerCount - 1) ControllerNumber > DAC960_ControllerCount - 1) {
return -ENXIO; break;
}
Controller = DAC960_Controllers[ControllerNumber]; Controller = DAC960_Controllers[ControllerNumber];
if (Controller == NULL) return -ENXIO; if (Controller == NULL)
break;;
memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
ControllerInfo.ControllerNumber = ControllerNumber; ControllerInfo.ControllerNumber = ControllerNumber;
ControllerInfo.FirmwareType = Controller->FirmwareType; ControllerInfo.FirmwareType = Controller->FirmwareType;
@ -6665,8 +6673,9 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
ControllerInfo.PCI_Address = Controller->PCI_Address; ControllerInfo.PCI_Address = Controller->PCI_Address;
strcpy(ControllerInfo.ModelName, Controller->ModelName); strcpy(ControllerInfo.ModelName, Controller->ModelName);
strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0);
break;
} }
case DAC960_IOCTL_V1_EXECUTE_COMMAND: case DAC960_IOCTL_V1_EXECUTE_COMMAND:
{ {
@ -6684,30 +6693,39 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
int ControllerNumber, DataTransferLength; int ControllerNumber, DataTransferLength;
unsigned char *DataTransferBuffer = NULL; unsigned char *DataTransferBuffer = NULL;
dma_addr_t DataTransferBufferDMA; dma_addr_t DataTransferBufferDMA;
if (UserSpaceUserCommand == NULL) return -EINVAL; if (UserSpaceUserCommand == NULL) {
ErrorCode = -EINVAL;
break;
}
if (copy_from_user(&UserCommand, UserSpaceUserCommand, if (copy_from_user(&UserCommand, UserSpaceUserCommand,
sizeof(DAC960_V1_UserCommand_T))) { sizeof(DAC960_V1_UserCommand_T))) {
ErrorCode = -EFAULT; ErrorCode = -EFAULT;
goto Failure1a; break;
} }
ControllerNumber = UserCommand.ControllerNumber; ControllerNumber = UserCommand.ControllerNumber;
ErrorCode = -ENXIO;
if (ControllerNumber < 0 || if (ControllerNumber < 0 ||
ControllerNumber > DAC960_ControllerCount - 1) ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO; break;
Controller = DAC960_Controllers[ControllerNumber]; Controller = DAC960_Controllers[ControllerNumber];
if (Controller == NULL) return -ENXIO; if (Controller == NULL)
if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL; break;
ErrorCode = -EINVAL;
if (Controller->FirmwareType != DAC960_V1_Controller)
break;
CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
DataTransferLength = UserCommand.DataTransferLength; DataTransferLength = UserCommand.DataTransferLength;
if (CommandOpcode & 0x80) return -EINVAL; if (CommandOpcode & 0x80)
break;
if (CommandOpcode == DAC960_V1_DCDB) if (CommandOpcode == DAC960_V1_DCDB)
{ {
if (copy_from_user(&DCDB, UserCommand.DCDB, if (copy_from_user(&DCDB, UserCommand.DCDB,
sizeof(DAC960_V1_DCDB_T))) { sizeof(DAC960_V1_DCDB_T))) {
ErrorCode = -EFAULT; ErrorCode = -EFAULT;
goto Failure1a; break;
} }
if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL; if (DCDB.Channel >= DAC960_V1_MaxChannels)
break;
if (!((DataTransferLength == 0 && if (!((DataTransferLength == 0 &&
DCDB.Direction DCDB.Direction
== DAC960_V1_DCDB_NoDataTransfer) || == DAC960_V1_DCDB_NoDataTransfer) ||
@ -6717,38 +6735,37 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
(DataTransferLength < 0 && (DataTransferLength < 0 &&
DCDB.Direction DCDB.Direction
== DAC960_V1_DCDB_DataTransferSystemToDevice))) == DAC960_V1_DCDB_DataTransferSystemToDevice)))
return -EINVAL; break;
if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
!= abs(DataTransferLength)) != abs(DataTransferLength))
return -EINVAL; break;
DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice,
sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA);
if (DCDB_IOBUF == NULL) if (DCDB_IOBUF == NULL) {
return -ENOMEM; ErrorCode = -ENOMEM;
break;
}
} }
ErrorCode = -ENOMEM;
if (DataTransferLength > 0) if (DataTransferLength > 0)
{ {
DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
DataTransferLength, &DataTransferBufferDMA); DataTransferLength, &DataTransferBufferDMA);
if (DataTransferBuffer == NULL) { if (DataTransferBuffer == NULL)
ErrorCode = -ENOMEM; break;
goto Failure1;
}
memset(DataTransferBuffer, 0, DataTransferLength); memset(DataTransferBuffer, 0, DataTransferLength);
} }
else if (DataTransferLength < 0) else if (DataTransferLength < 0)
{ {
DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
-DataTransferLength, &DataTransferBufferDMA); -DataTransferLength, &DataTransferBufferDMA);
if (DataTransferBuffer == NULL) { if (DataTransferBuffer == NULL)
ErrorCode = -ENOMEM; break;
goto Failure1;
}
if (copy_from_user(DataTransferBuffer, if (copy_from_user(DataTransferBuffer,
UserCommand.DataTransferBuffer, UserCommand.DataTransferBuffer,
-DataTransferLength)) { -DataTransferLength)) {
ErrorCode = -EFAULT; ErrorCode = -EFAULT;
goto Failure1; break;
} }
} }
if (CommandOpcode == DAC960_V1_DCDB) if (CommandOpcode == DAC960_V1_DCDB)
@ -6825,8 +6842,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
if (DCDB_IOBUF != NULL) if (DCDB_IOBUF != NULL)
pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T),
DCDB_IOBUF, DCDB_IOBUFDMA); DCDB_IOBUF, DCDB_IOBUFDMA);
Failure1a: break;
return ErrorCode;
} }
case DAC960_IOCTL_V2_EXECUTE_COMMAND: case DAC960_IOCTL_V2_EXECUTE_COMMAND:
{ {
@ -6844,32 +6860,43 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
dma_addr_t DataTransferBufferDMA; dma_addr_t DataTransferBufferDMA;
unsigned char *RequestSenseBuffer = NULL; unsigned char *RequestSenseBuffer = NULL;
dma_addr_t RequestSenseBufferDMA; dma_addr_t RequestSenseBufferDMA;
if (UserSpaceUserCommand == NULL) return -EINVAL;
ErrorCode = -EINVAL;
if (UserSpaceUserCommand == NULL)
break;
if (copy_from_user(&UserCommand, UserSpaceUserCommand, if (copy_from_user(&UserCommand, UserSpaceUserCommand,
sizeof(DAC960_V2_UserCommand_T))) { sizeof(DAC960_V2_UserCommand_T))) {
ErrorCode = -EFAULT; ErrorCode = -EFAULT;
goto Failure2a; break;
} }
ErrorCode = -ENXIO;
ControllerNumber = UserCommand.ControllerNumber; ControllerNumber = UserCommand.ControllerNumber;
if (ControllerNumber < 0 || if (ControllerNumber < 0 ||
ControllerNumber > DAC960_ControllerCount - 1) ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO; break;
Controller = DAC960_Controllers[ControllerNumber]; Controller = DAC960_Controllers[ControllerNumber];
if (Controller == NULL) return -ENXIO; if (Controller == NULL)
if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; break;
if (Controller->FirmwareType != DAC960_V2_Controller){
ErrorCode = -EINVAL;
break;
}
DataTransferLength = UserCommand.DataTransferLength; DataTransferLength = UserCommand.DataTransferLength;
ErrorCode = -ENOMEM;
if (DataTransferLength > 0) if (DataTransferLength > 0)
{ {
DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
DataTransferLength, &DataTransferBufferDMA); DataTransferLength, &DataTransferBufferDMA);
if (DataTransferBuffer == NULL) return -ENOMEM; if (DataTransferBuffer == NULL)
break;
memset(DataTransferBuffer, 0, DataTransferLength); memset(DataTransferBuffer, 0, DataTransferLength);
} }
else if (DataTransferLength < 0) else if (DataTransferLength < 0)
{ {
DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
-DataTransferLength, &DataTransferBufferDMA); -DataTransferLength, &DataTransferBufferDMA);
if (DataTransferBuffer == NULL) return -ENOMEM; if (DataTransferBuffer == NULL)
break;
if (copy_from_user(DataTransferBuffer, if (copy_from_user(DataTransferBuffer,
UserCommand.DataTransferBuffer, UserCommand.DataTransferBuffer,
-DataTransferLength)) { -DataTransferLength)) {
@ -6979,8 +7006,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
if (RequestSenseBuffer != NULL) if (RequestSenseBuffer != NULL)
pci_free_consistent(Controller->PCIDevice, RequestSenseLength, pci_free_consistent(Controller->PCIDevice, RequestSenseLength,
RequestSenseBuffer, RequestSenseBufferDMA); RequestSenseBuffer, RequestSenseBufferDMA);
Failure2a: break;
return ErrorCode;
} }
case DAC960_IOCTL_V2_GET_HEALTH_STATUS: case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
{ {
@ -6990,21 +7016,33 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
DAC960_Controller_T *Controller; DAC960_Controller_T *Controller;
int ControllerNumber; int ControllerNumber;
if (UserSpaceGetHealthStatus == NULL) return -EINVAL; if (UserSpaceGetHealthStatus == NULL) {
ErrorCode = -EINVAL;
break;
}
if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
sizeof(DAC960_V2_GetHealthStatus_T))) sizeof(DAC960_V2_GetHealthStatus_T))) {
return -EFAULT; ErrorCode = -EFAULT;
break;
}
ErrorCode = -ENXIO;
ControllerNumber = GetHealthStatus.ControllerNumber; ControllerNumber = GetHealthStatus.ControllerNumber;
if (ControllerNumber < 0 || if (ControllerNumber < 0 ||
ControllerNumber > DAC960_ControllerCount - 1) ControllerNumber > DAC960_ControllerCount - 1)
return -ENXIO; break;
Controller = DAC960_Controllers[ControllerNumber]; Controller = DAC960_Controllers[ControllerNumber];
if (Controller == NULL) return -ENXIO; if (Controller == NULL)
if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; break;
if (Controller->FirmwareType != DAC960_V2_Controller) {
ErrorCode = -EINVAL;
break;
}
if (copy_from_user(&HealthStatusBuffer, if (copy_from_user(&HealthStatusBuffer,
GetHealthStatus.HealthStatusBuffer, GetHealthStatus.HealthStatusBuffer,
sizeof(DAC960_V2_HealthStatusBuffer_T))) sizeof(DAC960_V2_HealthStatusBuffer_T))) {
return -EFAULT; ErrorCode = -EFAULT;
break;
}
while (Controller->V2.HealthStatusBuffer->StatusChangeCounter while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
== HealthStatusBuffer.StatusChangeCounter && == HealthStatusBuffer.StatusChangeCounter &&
Controller->V2.HealthStatusBuffer->NextEventSequenceNumber Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
@ -7012,21 +7050,28 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
{ {
interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
DAC960_MonitoringTimerInterval); DAC960_MonitoringTimerInterval);
if (signal_pending(current)) return -EINTR; if (signal_pending(current)) {
ErrorCode = -EINTR;
break;
}
} }
if (copy_to_user(GetHealthStatus.HealthStatusBuffer, if (copy_to_user(GetHealthStatus.HealthStatusBuffer,
Controller->V2.HealthStatusBuffer, Controller->V2.HealthStatusBuffer,
sizeof(DAC960_V2_HealthStatusBuffer_T))) sizeof(DAC960_V2_HealthStatusBuffer_T)))
return -EFAULT; ErrorCode = -EFAULT;
return 0; else
ErrorCode = 0;
} }
default:
ErrorCode = -ENOTTY;
} }
return -EINVAL; unlock_kernel();
return ErrorCode;
} }
static const struct file_operations DAC960_gam_fops = { static const struct file_operations DAC960_gam_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.ioctl = DAC960_gam_ioctl .unlocked_ioctl = DAC960_gam_ioctl
}; };
static struct miscdevice DAC960_gam_dev = { static struct miscdevice DAC960_gam_dev = {