diff options
author | Salyzyn, Mark <Mark_Salyzyn@adaptec.com> | 2008-01-28 15:16:52 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-02-07 19:02:33 -0500 |
commit | 5234e25c35a708708559727b1e3e04de3a538828 (patch) | |
tree | 6de1cc9084ab1ff3b469382b0a515111300f545c | |
parent | df922075f2a55b1ae71a6fe589c1cc1b91381f4f (diff) |
[SCSI] aacraid: fib context lock for management ioctls (take 2)
The first patch (a119ee8ee3045bf559d4cf02d72b112f3de2a15b) was a bit
too aggressive and nested the locks (!) unit testing was in
error. This patch was reverted by
203a512f0976e8ba85df36d76b40af6c80239121.
This new patch should fix the locks correctly.
Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index f8afa358b6b6..abef05146d75 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -243,6 +243,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg) | |||
243 | * Search the list of AdapterFibContext addresses on the adapter | 243 | * Search the list of AdapterFibContext addresses on the adapter |
244 | * to be sure this is a valid address | 244 | * to be sure this is a valid address |
245 | */ | 245 | */ |
246 | spin_lock_irqsave(&dev->fib_lock, flags); | ||
246 | entry = dev->fib_list.next; | 247 | entry = dev->fib_list.next; |
247 | fibctx = NULL; | 248 | fibctx = NULL; |
248 | 249 | ||
@@ -251,24 +252,25 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg) | |||
251 | /* | 252 | /* |
252 | * Extract the AdapterFibContext from the Input parameters. | 253 | * Extract the AdapterFibContext from the Input parameters. |
253 | */ | 254 | */ |
254 | if (fibctx->unique == f.fibctx) { /* We found a winner */ | 255 | if (fibctx->unique == f.fibctx) { /* We found a winner */ |
255 | break; | 256 | break; |
256 | } | 257 | } |
257 | entry = entry->next; | 258 | entry = entry->next; |
258 | fibctx = NULL; | 259 | fibctx = NULL; |
259 | } | 260 | } |
260 | if (!fibctx) { | 261 | if (!fibctx) { |
262 | spin_unlock_irqrestore(&dev->fib_lock, flags); | ||
261 | dprintk ((KERN_INFO "Fib Context not found\n")); | 263 | dprintk ((KERN_INFO "Fib Context not found\n")); |
262 | return -EINVAL; | 264 | return -EINVAL; |
263 | } | 265 | } |
264 | 266 | ||
265 | if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || | 267 | if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || |
266 | (fibctx->size != sizeof(struct aac_fib_context))) { | 268 | (fibctx->size != sizeof(struct aac_fib_context))) { |
269 | spin_unlock_irqrestore(&dev->fib_lock, flags); | ||
267 | dprintk ((KERN_INFO "Fib Context corrupt?\n")); | 270 | dprintk ((KERN_INFO "Fib Context corrupt?\n")); |
268 | return -EINVAL; | 271 | return -EINVAL; |
269 | } | 272 | } |
270 | status = 0; | 273 | status = 0; |
271 | spin_lock_irqsave(&dev->fib_lock, flags); | ||
272 | /* | 274 | /* |
273 | * If there are no fibs to send back, then either wait or return | 275 | * If there are no fibs to send back, then either wait or return |
274 | * -EAGAIN | 276 | * -EAGAIN |
@@ -414,8 +416,8 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg) | |||
414 | * @arg: ioctl arguments | 416 | * @arg: ioctl arguments |
415 | * | 417 | * |
416 | * This routine returns the driver version. | 418 | * This routine returns the driver version. |
417 | * Under Linux, there have been no version incompatibilities, so this is | 419 | * Under Linux, there have been no version incompatibilities, so this is |
418 | * simple! | 420 | * simple! |
419 | */ | 421 | */ |
420 | 422 | ||
421 | static int check_revision(struct aac_dev *dev, void __user *arg) | 423 | static int check_revision(struct aac_dev *dev, void __user *arg) |
@@ -463,7 +465,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
463 | u32 data_dir; | 465 | u32 data_dir; |
464 | void __user *sg_user[32]; | 466 | void __user *sg_user[32]; |
465 | void *sg_list[32]; | 467 | void *sg_list[32]; |
466 | u32 sg_indx = 0; | 468 | u32 sg_indx = 0; |
467 | u32 byte_count = 0; | 469 | u32 byte_count = 0; |
468 | u32 actual_fibsize64, actual_fibsize = 0; | 470 | u32 actual_fibsize64, actual_fibsize = 0; |
469 | int i; | 471 | int i; |
@@ -517,11 +519,11 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
517 | // Fix up srb for endian and force some values | 519 | // Fix up srb for endian and force some values |
518 | 520 | ||
519 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this | 521 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this |
520 | srbcmd->channel = cpu_to_le32(user_srbcmd->channel); | 522 | srbcmd->channel = cpu_to_le32(user_srbcmd->channel); |
521 | srbcmd->id = cpu_to_le32(user_srbcmd->id); | 523 | srbcmd->id = cpu_to_le32(user_srbcmd->id); |
522 | srbcmd->lun = cpu_to_le32(user_srbcmd->lun); | 524 | srbcmd->lun = cpu_to_le32(user_srbcmd->lun); |
523 | srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout); | 525 | srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout); |
524 | srbcmd->flags = cpu_to_le32(flags); | 526 | srbcmd->flags = cpu_to_le32(flags); |
525 | srbcmd->retry_limit = 0; // Obsolete parameter | 527 | srbcmd->retry_limit = 0; // Obsolete parameter |
526 | srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size); | 528 | srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size); |
527 | memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb)); | 529 | memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb)); |
@@ -786,9 +788,9 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg) | |||
786 | pci_info.bus = dev->pdev->bus->number; | 788 | pci_info.bus = dev->pdev->bus->number; |
787 | pci_info.slot = PCI_SLOT(dev->pdev->devfn); | 789 | pci_info.slot = PCI_SLOT(dev->pdev->devfn); |
788 | 790 | ||
789 | if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) { | 791 | if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) { |
790 | dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n")); | 792 | dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n")); |
791 | return -EFAULT; | 793 | return -EFAULT; |
792 | } | 794 | } |
793 | return 0; | 795 | return 0; |
794 | } | 796 | } |