Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33bb3b29 authored by Mark Haverkamp's avatar Mark Haverkamp Committed by James Bottomley
Browse files

[SCSI] aacraid: Fix ioctl handling when adapter resets



Received from Mark Salyzyn,

Outstanding ioctl calls still have some problems with aborting cleanly
in the face of a reset iop recovery action should the adapter ever enter
into a Firmware Assert (BlinkLED) condition. The enclosed patch resolves
some uncovered flawed handling.

Signed-off-by: default avatarMark Haverkamp <markh@linux-foundation.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent fe76df42
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -64,6 +64,9 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
	unsigned size;
	int retval;

	if (dev->in_reset) {
		return -EBUSY;
	}
	fibptr = aac_fib_alloc(dev);
	if(fibptr == NULL) {
		return -ENOMEM;
@@ -469,6 +472,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
	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;
+12 −8
Original line number Diff line number Diff line
@@ -513,7 +513,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
				}
				udelay(5);
			}
		} else if (down_interruptible(&fibptr->event_wait)) {
		} else
			(void)down_interruptible(&fibptr->event_wait);
		spin_lock_irqsave(&fibptr->event_lock, flags);
		if (fibptr->done == 0) {
			fibptr->done = 2; /* Tell interrupt we aborted */
@@ -521,7 +522,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
			return -EINTR;
		}
		spin_unlock_irqrestore(&fibptr->event_lock, flags);
		}
		BUG_ON(fibptr->done == 0);
			
		if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){
@@ -1062,7 +1062,7 @@ static int _aac_reset_adapter(struct aac_dev *aac)
	/*
	 *	Loop through the fibs, close the synchronous FIBS
	 */
	for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) {
	for (retval = 1, index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) {
		struct fib *fib = &aac->fibs[index];
		if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
		  (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) {
@@ -1071,8 +1071,12 @@ static int _aac_reset_adapter(struct aac_dev *aac)
			up(&fib->event_wait);
			spin_unlock_irqrestore(&fib->event_lock, flagv);
			schedule();
			retval = 0;
		}
	}
	/* Give some extra time for ioctls to complete. */
	if (retval == 0)
		ssleep(2);
	index = aac->cardtype;

	/*