diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2001-07-10 01:08:03 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2001-07-10 01:08:03 +0000 |
commit | 36190ca6431afcd90a9448bb3e517a7f8a9f06a0 (patch) | |
tree | 932929db82544ab93bf37f8fea91125f25d6e26d | |
parent | 7a2177e8fc71947e4273a0ad44848af8f6376567 (diff) |
Wait 1 second after soft reset.
Add back IDENTIFY after soft reset.
Fix ch_flags -> ch_status in a couple places
-rw-r--r-- | sys/dev/atapiscsi/atapiscsi.c | 74 |
1 files changed, 57 insertions, 17 deletions
diff --git a/sys/dev/atapiscsi/atapiscsi.c b/sys/dev/atapiscsi/atapiscsi.c index c37c13f2d7d..c9a5f126236 100644 --- a/sys/dev/atapiscsi/atapiscsi.c +++ b/sys/dev/atapiscsi/atapiscsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atapiscsi.c,v 1.47 2001/07/03 01:42:20 niklas Exp $ */ +/* $OpenBSD: atapiscsi.c,v 1.48 2001/07/10 01:08:02 csapuntz Exp $ */ /* * This code is derived from code with the copyright below. @@ -73,11 +73,13 @@ enum atapi_drive_states { ATAPI_RESET_BASE_STATE = 0, ATAPI_DEVICE_RESET_WAIT_STATE = 1, - ATAPI_PIOMODE_STATE = 2, - ATAPI_PIOMODE_WAIT_STATE = 3, - ATAPI_DMAMODE_STATE = 4, - ATAPI_DMAMODE_WAIT_STATE = 5, - ATAPI_READY_STATE = 6 + ATAPI_IDENTIFY_STATE = 2, + ATAPI_IDENTIFY_WAIT_STATE = 3, + ATAPI_PIOMODE_STATE = 4, + ATAPI_PIOMODE_WAIT_STATE = 5, + ATAPI_DMAMODE_STATE = 6, + ATAPI_DMAMODE_WAIT_STATE = 7, + ATAPI_READY_STATE = 8 }; #define DEBUG_INTR 0x01 @@ -100,6 +102,7 @@ int wdcdebug_atapi_mask = 0x0; /* 10 ms, this is used only before sending a cmd. */ #define ATAPI_DELAY 10 +#define ATAPI_RESET_DELAY 1000 #define ATAPI_RESET_WAIT 2000 #define ATAPI_CTRL_WAIT 4000 @@ -1254,10 +1257,20 @@ wdc_atapi_ctrl(chp, xfer, timeout, ret) struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive]; char *errstring = NULL; - wdc_atapi_update_status(chp); + wdc_atapi_update_status(chp); - if ((chp->ch_flags & (WDCS_BSY | WDCS_DRQ)) && !timeout) - return; + if (!timeout) { + switch (drvp->state) { + case ATAPI_IDENTIFY_WAIT_STATE: + if (chp->ch_status & WDCS_BSY) + return; + break; + default: + if (chp->ch_status & (WDCS_BSY | WDCS_DRQ)) + return; + break; + } + } if (!wdc_atapi_drive_selected(chp, xfer->drive)) { @@ -1274,16 +1287,24 @@ wdc_atapi_ctrl(chp, xfer, timeout, ret) drvp->drive_flags &= ~DRIVE_DEVICE_RESET; break; + case ATAPI_IDENTIFY_WAIT_STATE: + errstring = "Identify"; + if (!(chp->ch_status & WDCS_BSY) && + (chp->ch_status & (WDCS_DRQ | WDCS_ERR))) + trigger_timeout = 0; + + break; + case ATAPI_PIOMODE_WAIT_STATE: errstring = "PIOMODE"; - if (chp->ch_flags & (WDCS_BSY | WDCS_DRQ)) + if (chp->ch_status & (WDCS_BSY | WDCS_DRQ)) drvp->drive_flags &= ~DRIVE_MODE; else trigger_timeout = 0; break; case ATAPI_DMAMODE_WAIT_STATE: errstring = "dmamode"; - if (chp->ch_flags & (WDCS_BSY | WDCS_DRQ)) + if (chp->ch_status & (WDCS_BSY | WDCS_DRQ)) drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA); else trigger_timeout = 0; @@ -1320,22 +1341,41 @@ wdc_atapi_ctrl(chp, xfer, timeout, ret) */ case ATAPI_RESET_BASE_STATE: if ((drvp->drive_flags & DRIVE_DEVICE_RESET) == 0) { - drvp->state = ATAPI_PIOMODE_STATE; + drvp->state = ATAPI_IDENTIFY_STATE; break; } wdccommandshort(chp, drvp->drive, ATAPI_DEVICE_RESET); drvp->state = ATAPI_DEVICE_RESET_WAIT_STATE; - ret->delay = 500; + ret->delay = ATAPI_RESET_DELAY; ret->timeout = ATAPI_RESET_WAIT; break; case ATAPI_DEVICE_RESET_WAIT_STATE: - drvp->state = ATAPI_PIOMODE_STATE; - ret->delay = 500; + /* fall through */ + + case ATAPI_IDENTIFY_STATE: + wdccommandshort(chp, drvp->drive, ATAPI_IDENTIFY_DEVICE); + drvp->state = ATAPI_IDENTIFY_WAIT_STATE; + ret->delay = 10; ret->timeout = ATAPI_RESET_WAIT; break; + case ATAPI_IDENTIFY_WAIT_STATE: { + int idx = 0; + + while ((chp->ch_status & WDCS_DRQ) && + idx++ < 20) { + wdcbit_bucket(chp, 512); + + DELAY(1); + wdc_atapi_update_status(chp); + } + + drvp->state = ATAPI_PIOMODE_STATE; + } + /* fall through */ + case ATAPI_PIOMODE_STATE: piomode: /* Don't try to set mode if controller can't be adjusted */ @@ -1481,14 +1521,14 @@ wdc_atapi_reset(chp, xfer, timeout, ret) WDCDEBUG_PRINT(("wdc_atapi_reset\n"), DEBUG_XFERS); wdccommandshort(chp, xfer->drive, ATAPI_SOFT_RESET); - drvp->state = ATAPI_PIOMODE_STATE; + drvp->state = ATAPI_IDENTIFY_STATE; drvp->n_resets++; /* Some ATAPI devices need extra time to find their brains after a reset */ xfer->next = wdc_atapi_reset_2; - ret->delay = 150; + ret->delay = ATAPI_RESET_DELAY; ret->timeout = ATAPI_RESET_WAIT; return; } |