summaryrefslogtreecommitdiff
path: root/drivers/scsi/aacraid/commctrl.c
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2006-08-03 19:02:24 +0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-08-20 00:32:57 +0400
commitc8f7b073e0e81499474a84ee2a90f77f7805c7f8 (patch)
treec5421bd69530488d78b76ffab3ebb9fa08000fc7 /drivers/scsi/aacraid/commctrl.c
parent04846f25920d4b05d6040c531cc601049260db52 (diff)
downloadlinux-c8f7b073e0e81499474a84ee2a90f77f7805c7f8.tar.xz
[SCSI] aacraid: interruptible ioctl
Received from Mark Salyzyn This patch allows the FSACTL_SEND_LARGE_FIB, FSACTL_SENDFIB and FSACTL_SEND_RAW_SRB ioctl calls into the aacraid driver to be interruptible. Only necessary if the adapter and/or the management software has gone into some sort of misbehavior and the system is being rebooted, thus permitting the user management software applications to be killed relatively cleanly. The FIB queue resource is held out of the free queue until the adapter finally, if ever, completes the command. Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid/commctrl.c')
-rw-r--r--drivers/scsi/aacraid/commctrl.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 255421de9d1a..14d7aa9b7df3 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -38,7 +38,7 @@
#include <linux/completion.h>
#include <linux/dma-mapping.h>
#include <linux/blkdev.h>
-#include <linux/delay.h>
+#include <linux/delay.h> /* ssleep prototype */
#include <linux/kthread.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
@@ -140,7 +140,8 @@ cleanup:
fibptr->hw_fib_pa = hw_fib_pa;
fibptr->hw_fib = hw_fib;
}
- aac_fib_free(fibptr);
+ if (retval != -EINTR)
+ aac_fib_free(fibptr);
return retval;
}
@@ -621,7 +622,13 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry));
if(actual_fibsize != fibsize){ // User made a mistake - should not continue
- dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"));
+ dprintk((KERN_DEBUG"aacraid: Bad Size specified in "
+ "Raw SRB command calculated fibsize=%d "
+ "user_srbcmd->sg.count=%d aac_srb=%d sgentry=%d "
+ "issued fibsize=%d\n",
+ actual_fibsize, user_srbcmd->sg.count,
+ sizeof(struct aac_srb), sizeof(struct sgentry),
+ fibsize));
rcode = -EINVAL;
goto cleanup;
}
@@ -663,6 +670,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
psg->count = cpu_to_le32(sg_indx+1);
status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
}
+ if (status == -EINTR) {
+ rcode = -EINTR;
+ goto cleanup;
+ }
if (status != 0){
dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"));
@@ -696,8 +707,10 @@ cleanup:
for(i=0; i <= sg_indx; i++){
kfree(sg_list[i]);
}
- aac_fib_complete(srbfib);
- aac_fib_free(srbfib);
+ if (rcode != -EINTR) {
+ aac_fib_complete(srbfib);
+ aac_fib_free(srbfib);
+ }
return rcode;
}