Skip to content

Commit

Permalink
[SCSI] aacraid: interruptible ioctl
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Haverkamp authored and James Bottomley committed Aug 19, 2006
1 parent 04846f2 commit c8f7b07
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
23 changes: 18 additions & 5 deletions drivers/scsi/aacraid/commctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -140,7 +140,8 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
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;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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"));
Expand Down Expand Up @@ -696,8 +707,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
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;
}
Expand Down
15 changes: 12 additions & 3 deletions drivers/scsi/aacraid/commsup.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr));

if (!dev->queues)
return -ENODEV;
q = &dev->queues->queue[AdapNormCmdQueue];

if(wait)
Expand Down Expand Up @@ -527,8 +529,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
}
udelay(5);
}
} else
down(&fibptr->event_wait);
} else if (down_interruptible(&fibptr->event_wait)) {
spin_lock_irqsave(&fibptr->event_lock, flags);
if (fibptr->done == 0) {
fibptr->done = 2; /* Tell interrupt we aborted */
spin_unlock_irqrestore(&fibptr->event_lock, flags);
return -EINTR;
}
spin_unlock_irqrestore(&fibptr->event_lock, flags);
}
BUG_ON(fibptr->done == 0);

if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){
Expand Down Expand Up @@ -795,7 +804,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)

/* Sniff for container changes */

if (!dev)
if (!dev || !dev->fsa_dev)
return;
container = (u32)-1;

Expand Down
10 changes: 8 additions & 2 deletions drivers/scsi/aacraid/dpcsup.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,15 @@ unsigned int aac_response_normal(struct aac_queue * q)
} else {
unsigned long flagv;
spin_lock_irqsave(&fib->event_lock, flagv);
fib->done = 1;
if (!fib->done)
fib->done = 1;
up(&fib->event_wait);
spin_unlock_irqrestore(&fib->event_lock, flagv);
FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
if (fib->done == 2) {
aac_fib_complete(fib);
aac_fib_free(fib);
}
}
consumed++;
spin_lock_irqsave(q->lock, flags);
Expand Down Expand Up @@ -316,7 +321,8 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index)
unsigned long flagv;
dprintk((KERN_INFO "event_wait up\n"));
spin_lock_irqsave(&fib->event_lock, flagv);
fib->done = 1;
if (!fib->done)
fib->done = 1;
up(&fib->event_wait);
spin_unlock_irqrestore(&fib->event_lock, flagv);
FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
Expand Down

0 comments on commit c8f7b07

Please sign in to comment.