|
@@ -243,6 +243,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
|
|
* Search the list of AdapterFibContext addresses on the adapter
|
|
* Search the list of AdapterFibContext addresses on the adapter
|
|
* to be sure this is a valid address
|
|
* to be sure this is a valid address
|
|
*/
|
|
*/
|
|
|
|
+ spin_lock_irqsave(&dev->fib_lock, flags);
|
|
entry = dev->fib_list.next;
|
|
entry = dev->fib_list.next;
|
|
fibctx = NULL;
|
|
fibctx = NULL;
|
|
|
|
|
|
@@ -251,24 +252,25 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
|
|
/*
|
|
/*
|
|
* Extract the AdapterFibContext from the Input parameters.
|
|
* Extract the AdapterFibContext from the Input parameters.
|
|
*/
|
|
*/
|
|
- if (fibctx->unique == f.fibctx) { /* We found a winner */
|
|
|
|
|
|
+ if (fibctx->unique == f.fibctx) { /* We found a winner */
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
entry = entry->next;
|
|
entry = entry->next;
|
|
fibctx = NULL;
|
|
fibctx = NULL;
|
|
}
|
|
}
|
|
if (!fibctx) {
|
|
if (!fibctx) {
|
|
|
|
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
|
|
dprintk ((KERN_INFO "Fib Context not found\n"));
|
|
dprintk ((KERN_INFO "Fib Context not found\n"));
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
|
|
if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
|
|
(fibctx->size != sizeof(struct aac_fib_context))) {
|
|
(fibctx->size != sizeof(struct aac_fib_context))) {
|
|
|
|
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
|
|
dprintk ((KERN_INFO "Fib Context corrupt?\n"));
|
|
dprintk ((KERN_INFO "Fib Context corrupt?\n"));
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
status = 0;
|
|
status = 0;
|
|
- spin_lock_irqsave(&dev->fib_lock, flags);
|
|
|
|
/*
|
|
/*
|
|
* If there are no fibs to send back, then either wait or return
|
|
* If there are no fibs to send back, then either wait or return
|
|
* -EAGAIN
|
|
* -EAGAIN
|
|
@@ -326,7 +328,9 @@ return_fib:
|
|
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
|
|
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
|
|
{
|
|
{
|
|
struct fib *fib;
|
|
struct fib *fib;
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
|
|
+ spin_lock_irqsave(&dev->fib_lock, flags);
|
|
/*
|
|
/*
|
|
* First free any FIBs that have not been consumed.
|
|
* First free any FIBs that have not been consumed.
|
|
*/
|
|
*/
|
|
@@ -349,6 +353,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
|
|
* Remove the Context from the AdapterFibContext List
|
|
* Remove the Context from the AdapterFibContext List
|
|
*/
|
|
*/
|
|
list_del(&fibctx->next);
|
|
list_del(&fibctx->next);
|
|
|
|
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
|
|
/*
|
|
/*
|
|
* Invalidate context
|
|
* Invalidate context
|
|
*/
|
|
*/
|
|
@@ -414,8 +419,8 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
|
|
* @arg: ioctl arguments
|
|
* @arg: ioctl arguments
|
|
*
|
|
*
|
|
* This routine returns the driver version.
|
|
* This routine returns the driver version.
|
|
- * Under Linux, there have been no version incompatibilities, so this is
|
|
|
|
- * simple!
|
|
|
|
|
|
+ * Under Linux, there have been no version incompatibilities, so this is
|
|
|
|
+ * simple!
|
|
*/
|
|
*/
|
|
|
|
|
|
static int check_revision(struct aac_dev *dev, void __user *arg)
|
|
static int check_revision(struct aac_dev *dev, void __user *arg)
|
|
@@ -463,7 +468,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
|
u32 data_dir;
|
|
u32 data_dir;
|
|
void __user *sg_user[32];
|
|
void __user *sg_user[32];
|
|
void *sg_list[32];
|
|
void *sg_list[32];
|
|
- u32 sg_indx = 0;
|
|
|
|
|
|
+ u32 sg_indx = 0;
|
|
u32 byte_count = 0;
|
|
u32 byte_count = 0;
|
|
u32 actual_fibsize64, actual_fibsize = 0;
|
|
u32 actual_fibsize64, actual_fibsize = 0;
|
|
int i;
|
|
int i;
|
|
@@ -517,11 +522,11 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
|
// Fix up srb for endian and force some values
|
|
// Fix up srb for endian and force some values
|
|
|
|
|
|
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
|
|
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
|
|
- srbcmd->channel = cpu_to_le32(user_srbcmd->channel);
|
|
|
|
|
|
+ srbcmd->channel = cpu_to_le32(user_srbcmd->channel);
|
|
srbcmd->id = cpu_to_le32(user_srbcmd->id);
|
|
srbcmd->id = cpu_to_le32(user_srbcmd->id);
|
|
- srbcmd->lun = cpu_to_le32(user_srbcmd->lun);
|
|
|
|
- srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout);
|
|
|
|
- srbcmd->flags = cpu_to_le32(flags);
|
|
|
|
|
|
+ srbcmd->lun = cpu_to_le32(user_srbcmd->lun);
|
|
|
|
+ srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout);
|
|
|
|
+ srbcmd->flags = cpu_to_le32(flags);
|
|
srbcmd->retry_limit = 0; // Obsolete parameter
|
|
srbcmd->retry_limit = 0; // Obsolete parameter
|
|
srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
|
|
srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
|
|
memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
|
|
memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
|
|
@@ -786,9 +791,9 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
|
|
pci_info.bus = dev->pdev->bus->number;
|
|
pci_info.bus = dev->pdev->bus->number;
|
|
pci_info.slot = PCI_SLOT(dev->pdev->devfn);
|
|
pci_info.slot = PCI_SLOT(dev->pdev->devfn);
|
|
|
|
|
|
- if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
|
|
|
|
- dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
|
|
|
|
- return -EFAULT;
|
|
|
|
|
|
+ if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
|
|
|
|
+ dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
|
|
|
|
+ return -EFAULT;
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|