diff options
author | Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 1999-03-28 23:06:06 +0000 |
---|---|---|
committer | Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 1999-03-28 23:06:06 +0000 |
commit | 11fb413571e57b2b1c054e357fcd077de58252ee (patch) | |
tree | c4e76212a0851bde47bbe90e2c2678db3641632a /drivers | |
parent | 5bc48dda552ceed7f0e97f14a2cb12f229489816 (diff) |
added reset code, to get even a busy wd93 back to its feets
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/sgiwd93.c | 12 | ||||
-rw-r--r-- | drivers/scsi/wd33c93.c | 21 |
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); |