From aff8f744de4ee8056413b4ee36da58323bd88341 Mon Sep 17 00:00:00 2001 From: Alexander Yurchenko Date: Thu, 13 Feb 2003 20:55:00 +0000 Subject: Don't force all ATAPI devices to PIO mode 3, there are devices which only support PIO mode 2 or less. Use atap_oldpiotiming to obtain supported mode for such devices. Also use SET FEATURES only for PIO mode > 2. Work by Alec Skelly with my little help. ok costa@ --- sys/dev/ata/ata_wdc.c | 5 ++++- sys/dev/atapiscsi/atapiscsi.c | 15 +++++---------- sys/dev/ic/wdc.c | 42 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 14 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/ata/ata_wdc.c b/sys/dev/ata/ata_wdc.c index ffb72cd78aa..99e8eca3f4b 100644 --- a/sys/dev/ata/ata_wdc.c +++ b/sys/dev/ata/ata_wdc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ata_wdc.c,v 1.18 2003/01/10 13:50:56 grange Exp $ */ +/* $OpenBSD: ata_wdc.c,v 1.19 2003/02/13 20:54:59 grange Exp $ */ /* $NetBSD: ata_wdc.c,v 1.21 1999/08/09 09:43:11 bouyer Exp $ */ /* @@ -608,6 +608,9 @@ again: /* Also don't try if the drive didn't report its mode */ if ((drvp->drive_flags & DRIVE_MODE) == 0) goto geometry; + /* SET FEATURES 0x08 is only for PIO mode > 2 */ + if (drvp->PIO_mode <= 2) + goto geometry; wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x08 | drvp->PIO_mode, WDSF_SET_MODE); drvp->state = PIOMODE_WAIT; diff --git a/sys/dev/atapiscsi/atapiscsi.c b/sys/dev/atapiscsi/atapiscsi.c index 3260aa9b482..192a470c5f9 100644 --- a/sys/dev/atapiscsi/atapiscsi.c +++ b/sys/dev/atapiscsi/atapiscsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atapiscsi.c,v 1.62 2002/12/19 16:32:59 grange Exp $ */ +/* $OpenBSD: atapiscsi.c,v 1.63 2003/02/13 20:54:59 grange Exp $ */ /* * This code is derived from code with the copyright below. @@ -1448,13 +1448,15 @@ wdc_atapi_ctrl(chp, xfer, timeout, ret) } case ATAPI_PIOMODE_STATE: -piomode: /* Don't try to set mode if controller can't be adjusted */ if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0) goto ready; /* Also don't try if the drive didn't report its mode */ if ((drvp->drive_flags & DRIVE_MODE) == 0) goto ready; + /* SET FEATURES 0x08 is only for PIO mode > 2 */ + if (drvp->PIO_mode <= 2) + goto ready; wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x08 | drvp->PIO_mode, WDSF_SET_MODE); drvp->state = ATAPI_PIOMODE_WAIT_STATE; @@ -1465,14 +1467,7 @@ piomode: if (chp->wdc->cap & WDC_CAPABILITY_IRQACK) chp->wdc->irqack(chp); if (chp->ch_status & WDCS_ERR) { - if (drvp->PIO_mode < 3) { - drvp->PIO_mode = 3; - goto piomode; - } - /* - * All ATAPI drives are supposed to support - * PIO mode 3 or greater. - */ + /* Downgrade straight to PIO mode 3 */ drvp->PIO_mode = 3; chp->wdc->set_modes(chp); } diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c index c20b7ae4ef9..15d5530a615 100644 --- a/sys/dev/ic/wdc.c +++ b/sys/dev/ic/wdc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wdc.c,v 1.58 2002/12/22 18:28:06 grange Exp $ */ +/* $OpenBSD: wdc.c,v 1.59 2003/02/13 20:54:59 grange Exp $ */ /* $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $ */ @@ -1238,20 +1238,56 @@ wdc_probe_caps(drvp, params) } } else #endif - /* An ATAPI device is at last PIO mode 3 */ + /* Use PIO mode 3 as a default value for ATAPI devices */ if (drvp->drive_flags & DRIVE_ATAPI) drvp->PIO_mode = 3; WDCDEBUG_PRINT(("wdc_probe_caps: wdc_cap %d cf_flags %d\n", wdc->cap, cf_flags), DEBUG_PROBE); + valid_mode_found = 0; + + WDCDEBUG_PRINT(("%s: atap_oldpiotiming=%d\n", __func__, + params->atap_oldpiotiming), DEBUG_PROBE); + /* + * ATA-4 compliant devices contain PIO mode + * number in atap_oldpiotiming. + */ + if (params->atap_oldpiotiming <= 2) { + drvp->PIO_cap = params->atap_oldpiotiming; + valid_mode_found = 1; + drvp->drive_flags |= DRIVE_MODE; + } else if (params->atap_oldpiotiming > 180 && + params->atap_oldpiotiming <= 600) { + /* + * ATA-2 compliant devices contain cycle + * time in atap_oldpiotiming. + * A device with a cycle time of 180ns + * or less is at least PIO mode 3 and + * should be reporting that in + * atap_piomode_supp, so ignore it here. + * A cycle time greater than 600ns seems + * to be invalid. + */ + if (params->atap_oldpiotiming <= 240) { + drvp->PIO_cap = 2; + } else if (params->atap_oldpiotiming <= 480) { + drvp->PIO_cap = 1; + } else { + drvp->PIO_cap = 0; + } + valid_mode_found = 1; + drvp->drive_flags |= DRIVE_MODE; + } + if (valid_mode_found) + drvp->PIO_mode = drvp->PIO_cap; + /* * It's not in the specs, but it seems that some drive * returns 0xffff in atap_extensions when this field is invalid */ if (params->atap_extensions != 0xffff && (params->atap_extensions & WDC_EXT_MODES)) { - valid_mode_found = 0; /* * XXX some drives report something wrong here (they claim to * support PIO mode 8 !). As mode is coded on 3 bits in -- cgit v1.2.3