[PATCH] 2.4.21-pre5 cciss fix unlikely startup problem

From: Stephen Cameron (steve.cameron@hp.com)
Date: Wed Feb 26 2003 - 23:37:41 EST


* Make driver wait longer for board to enter simple mode to
  handle an unlikely corner case. (If you hot replace a 144 GB
  failed disk in a RAID 5 set at just the right time prior to
  driver initialization, the board can take an extra long time
  to become ready when switched into "simple mode" when the
  driver is starting up. Without the patch, in those cases, the
  driver will give up before the board becomes ready, and will not work.
  (Though rebooting will generally "fix" it). This patch avoids
  the problem.)
* Fix a couple of affected ioctls to return EAGAIN instead of
  inappropriate EFAULT.

--- lx2421p5/drivers/block/cciss.c~cfg_table_wait 2003-02-27 10:11:35.000000000 +0600
+++ lx2421p5-scameron/drivers/block/cciss.c 2003-02-27 10:11:35.000000000 +0600
@@ -94,7 +94,8 @@ static struct board_type products[] = {
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
-#define MAX_CONFIG_WAIT 1000
+#define MAX_CONFIG_WAIT 30000
+#define MAX_IOCTL_CONFIG_WAIT 1000
 
 /*define how many times we will try a command because of bus resets */
 #define MAX_CMD_RETRIES 3
@@ -578,7 +579,7 @@ static int cciss_ioctl(struct inode *ino
                         &(c->cfgtable->HostWrite.CoalIntCount));
                 writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
- for(i=0;i<MAX_CONFIG_WAIT;i++) {
+ for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
                         if (!(readl(c->vaddr + SA5_DOORBELL)
                                         & CFGTBL_ChangeReq))
                                 break;
@@ -586,8 +587,11 @@ static int cciss_ioctl(struct inode *ino
                         udelay(1000);
                 }
                 spin_unlock_irqrestore(&io_request_lock, flags);
- if (i >= MAX_CONFIG_WAIT)
- return -EFAULT;
+ if (i >= MAX_IOCTL_CONFIG_WAIT)
+ /* there is an unlikely case where this can happen,
+ * involving hot replacing a failed 144 GB drive in a
+ * RAID 5 set just as we attempt this ioctl. */
+ return -EAGAIN;
                 return 0;
         }
         case CCISS_GETNODENAME:
@@ -627,7 +631,7 @@ static int cciss_ioctl(struct inode *ino
                         
                 writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
- for(i=0;i<MAX_CONFIG_WAIT;i++) {
+ for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
                         if (!(readl(c->vaddr + SA5_DOORBELL)
                                         & CFGTBL_ChangeReq))
                                 break;
@@ -635,8 +639,11 @@ static int cciss_ioctl(struct inode *ino
                         udelay(1000);
                 }
                 spin_unlock_irqrestore(&io_request_lock, flags);
- if (i >= MAX_CONFIG_WAIT)
- return -EFAULT;
+ if (i >= MAX_IOCTL_CONFIG_WAIT)
+ /* there is an unlikely case where this can happen,
+ * involving hot replacing a failed 144 GB drive in a
+ * RAID 5 set just as we attempt this ioctl. */
+ return -EAGAIN;
                 return 0;
         }
 
@@ -2583,11 +2590,17 @@ static int cciss_pci_init(ctlr_info_t *c
                 &(c->cfgtable->HostWrite.TransportRequest));
         writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
+ /* Here, we wait, possibly for a long time, (4 secs or more).
+ * In some unlikely cases, (e.g. A failed 144 GB drive in a
+ * RAID 5 set was hot replaced just as we're coming in here) it
+ * can take that long. Normally (almost always) we will wait
+ * less than 1 sec. */
         for(i=0;i<MAX_CONFIG_WAIT;i++) {
                 if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
                         break;
                 /* delay and try again */
- udelay(1000);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
         }
 
 #ifdef CCISS_DEBUG

_
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Feb 28 2003 - 22:00:44 EST