#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>
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;
}
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;
}
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"));
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;
}
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)
}
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)){
/* Sniff for container changes */
- if (!dev)
+ if (!dev || !dev->fsa_dev)
return;
container = (u32)-1;
} 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);
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);