summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tsbogend@alpha.franken.de>1999-03-28 23:06:06 +0000
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>1999-03-28 23:06:06 +0000
commit11fb413571e57b2b1c054e357fcd077de58252ee (patch)
treec4e76212a0851bde47bbe90e2c2678db3641632a /drivers
parent5bc48dda552ceed7f0e97f14a2cb12f229489816 (diff)
added reset code, to get even a busy wd93 back to its feets
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/sgiwd93.c12
-rw-r--r--drivers/scsi/wd33c93.c21
2 files changed, 32 insertions, 1 deletions
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index 05ea49782..8e516723e 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -5,13 +5,14 @@
*
* (In all truth, Jed Schimmel wrote all this code.)
*
- * $Id: sgiwd93.c,v 1.11 1999/03/25 22:41:20 tsbogend Exp $
+ * $Id: sgiwd93.c,v 1.12 1999/03/28 22:03:20 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/blk.h>
#include <linux/version.h>
+#include <linux/delay.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -235,6 +236,15 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
#endif
}
+void sgiwd93_reset(void)
+{
+ struct hpc3_scsiregs *hregs = &hpc3c0->scsi_chan0;
+
+ hregs->ctrl = HPC3_SCTRL_CRESET;
+ udelay (50);
+ hregs->ctrl = 0;
+}
+
static inline void init_hpc_chain(uchar *buf)
{
struct hpc_chunk *hcp = (struct hpc_chunk *) buf;
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 16fe5e022..b0f568855 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -1359,6 +1359,27 @@ uchar sr;
hostdata = (struct WD33C93_hostdata *)instance->hostdata;
regp = hostdata->regp;
+#ifdef CONFIG_SGI
+{
+int busycount = 0;
+extern void sgiwd93_reset(void);
+
+ /* wait 'til the chip gets some time for us */
+ while (READ_AUX_STAT() & ASR_BSY && busycount++ < 100)
+ udelay (10);
+ /*
+ * there are scsi devices out there, which manage to lock up
+ * the wd33c93 in a busy condition. In this state it won't
+ * accept the reset command. The only way to solve this is to
+ * give the chip a hardware reset (if possible). The code below
+ * does this for the SGI Indy, where this is possible
+ */
+ /* still busy ? */
+ if (READ_AUX_STAT() & ASR_BSY)
+ sgiwd93_reset(); /* yeah, give it the hard one */
+}
+#endif
+
write_wd33c93(regp, WD_OWN_ID, OWNID_EAF | OWNID_RAF |
instance->this_id | hostdata->clock_freq);
write_wd33c93(regp, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);