#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#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>
unsigned size;
int retval;
+ if (dev->in_reset) {
+ return -EBUSY;
+ }
fibptr = aac_fib_alloc(dev);
if(fibptr == NULL) {
return -ENOMEM;
}
- kfib = fibptr->hw_fib;
+ kfib = fibptr->hw_fib_va;
/*
* First copy in the header so that we can check the size field.
*/
goto cleanup;
}
/* Highjack the hw_fib */
- hw_fib = fibptr->hw_fib;
+ hw_fib = fibptr->hw_fib_va;
hw_fib_pa = fibptr->hw_fib_pa;
- fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa);
+ fibptr->hw_fib_va = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa);
memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size);
memcpy(kfib, hw_fib, dev->max_fib_size);
}
if (hw_fib) {
pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa);
fibptr->hw_fib_pa = hw_fib_pa;
- fibptr->hw_fib = hw_fib;
+ fibptr->hw_fib_va = hw_fib;
}
- aac_fib_free(fibptr);
+ if (retval != -EINTR)
+ aac_fib_free(fibptr);
return retval;
}
fib = list_entry(entry, struct fib, fiblink);
fibctx->count--;
spin_unlock_irqrestore(&dev->fib_lock, flags);
- if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) {
- kfree(fib->hw_fib);
+ if (copy_to_user(f.fib, fib->hw_fib_va, sizeof(struct hw_fib))) {
+ kfree(fib->hw_fib_va);
kfree(fib);
return -EFAULT;
}
/*
* Free the space occupied by this copy of the fib.
*/
- kfree(fib->hw_fib);
+ kfree(fib->hw_fib_va);
kfree(fib);
status = 0;
} else {
spin_unlock_irqrestore(&dev->fib_lock, flags);
/* If someone killed the AIF aacraid thread, restart it */
status = !dev->aif_thread;
- if (status && dev->queues && dev->fsa_dev) {
+ if (status && !dev->in_reset && dev->queues && dev->fsa_dev) {
/* Be paranoid, be very paranoid! */
kthread_stop(dev->thread);
ssleep(1);
/*
* Free the space occupied by this copy of the fib.
*/
- kfree(fib->hw_fib);
+ kfree(fib->hw_fib_va);
kfree(fib);
}
/*
int i;
+ if (dev->in_reset) {
+ dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n"));
+ return -EBUSY;
+ }
if (!capable(CAP_SYS_ADMIN)){
dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n"));
return -EPERM;
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;
}