diff options
author | Ada <Ada.Feng@Sun.COM> | 2008-09-11 15:05:11 +0800 |
---|---|---|
committer | Ada <Ada.Feng@Sun.COM> | 2008-09-11 15:05:11 +0800 |
commit | 62c8caf3fac65817982e780c1efa988846153bf0 (patch) | |
tree | 99ef87d3436bb3e732a1688d8a15e2817adb6a10 /usr/src | |
parent | 5ef3d48f3eade4d7bb0730f19e26c782232c09ad (diff) | |
download | illumos-joyent-62c8caf3fac65817982e780c1efa988846153bf0.tar.gz |
6742621 ata driver causes system hang after resume back on M8 with snv_b97
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/intel/io/dktp/controller/ata/ata_common.c | 74 | ||||
-rw-r--r-- | usr/src/uts/intel/io/dktp/controller/ata/atapi.c | 10 |
2 files changed, 37 insertions, 47 deletions
diff --git a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c index 7815d00484..e51e2ca533 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c +++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/modctl.h> #include <sys/debug.h> @@ -3493,7 +3491,6 @@ ata_resume_drive(ata_drv_t *ata_drvp) ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp; int drive_type; struct ata_id id; - uint8_t udma; ADBG_TRACE(("ata_resume_drive entered\n")); @@ -3504,26 +3501,16 @@ ata_resume_drive(ata_drv_t *ata_drvp) if (drive_type == ATA_DEV_NONE) return; - /* Reset Ultra DMA mode */ - udma = ATACM_UDMA_SEL(&ata_drvp->ad_id); - if (udma != 0) { - uint8_t mode; - for (mode = 0; mode < 8; mode++) - if (((1 << mode) & udma) != 0) - break; - ASSERT(mode != 8); - - mode |= ATF_XFRMOD_UDMA; - - if (!ata_set_feature(ata_ctlp, ata_drvp, ATSF_SET_XFRMOD, mode)) - return; - } - if (!ATAPIDRV(ata_drvp)) { + /* Reset Ultra DMA mode */ + (void) ata_set_dma_mode(ata_ctlp, ata_drvp); if (!ata_disk_setup_parms(ata_ctlp, ata_drvp)) return; - (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0); + } else { + atapi_init_drive(ata_drvp); } + (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0); + } /* @@ -3652,31 +3639,33 @@ ata_change_power(dev_info_t *dip, uint8_t cmd) /* * Issue command on each disk device on the bus. */ - for (targ = 0; targ < ATA_MAXTARG; targ++) { - ata_drvp = CTL2DRV(ata_ctlp, targ, 0); - if (ata_drvp == NULL) - continue; - if (ata_drive_type(ata_drvp->ad_drive_bits, - ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1, - ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, - &id) != ATA_DEV_DISK) - continue; - (void) ata_flush_cache(ata_ctlp, ata_drvp); - if (!ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 5 * 1000000, - cmd, 0, 0, 0, 0, 0, 0)) { - cmn_err(CE_WARN, "!ata_controller - Can not put " - "drive %d in to power mode %u", targ, cmd); - (void) ata_devo_reset(dip, DDI_RESET_FORCE); - return (DDI_FAILURE); + if (cmd == ATC_SLEEP) { + for (targ = 0; targ < ATA_MAXTARG; targ++) { + ata_drvp = CTL2DRV(ata_ctlp, targ, 0); + if (ata_drvp == NULL) + continue; + if (ata_drive_type(ata_drvp->ad_drive_bits, + ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1, + ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, + &id) != ATA_DEV_DISK) + continue; + (void) ata_flush_cache(ata_ctlp, ata_drvp); + if (!ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, + 5 * 1000000, cmd, 0, 0, 0, 0, 0, 0)) { + cmn_err(CE_WARN, "!ata_controller - Can not " + "put drive %d in to power mode %u", + targ, cmd); + (void) ata_devo_reset(dip, DDI_RESET_FORCE); + return (DDI_FAILURE); + } } - } - - if (cmd == ATC_SLEEP) return (DDI_SUCCESS); + } + (void) ata_software_reset(ata_ctlp); for (targ = 0; targ < ATA_MAXTARG; targ++) { ata_drvp = CTL2DRV(ata_ctlp, targ, 0); - if ((ata_drvp == NULL) || !(ata_drvp->ad_flags & AD_DISK)) + if (ata_drvp == NULL) continue; ata_resume_drive(ata_drvp); @@ -3691,7 +3680,6 @@ ata_change_power(dev_info_t *dip, uint8_t cmd) if (ata_drvp != NULL) ata_resume_drive(ata_drvp); } - (void) ata_software_reset(ata_ctlp); } return (DDI_SUCCESS); @@ -3775,12 +3763,6 @@ ata_set_dma_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp) if (!(aidp->ai_cap & ATAC_DMA_SUPPORT)) return (rval); - /* Return if DMA mode is already selected */ - if (((aidp->ai_validinfo & ATAC_VALIDINFO_83) && - (aidp->ai_ultradma & ATAC_UDMA_SEL_MASK)) || - (aidp->ai_dworddma & ATAC_MDMA_SEL_MASK)) - return (rval); - /* First check Ultra DMA mode if no DMA is selected */ if ((aidp->ai_validinfo & ATAC_VALIDINFO_83) && (aidp->ai_ultradma & ATAC_UDMA_SUP_MASK)) { diff --git a/usr/src/uts/intel/io/dktp/controller/ata/atapi.c b/usr/src/uts/intel/io/dktp/controller/ata/atapi.c index c06e3aac75..627347be9e 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/atapi.c +++ b/usr/src/uts/intel/io/dktp/controller/ata/atapi.c @@ -24,7 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> @@ -188,6 +187,7 @@ atapi_init_drive( ADBG_TRACE(("atapi_init_drive entered\n")); /* Determine ATAPI CDB size */ + (void) atapi_id_update(ata_ctlp, ata_drvp, NULL); switch (ata_drvp->ad_id.ai_config & ATAPI_ID_CFG_PKT_SZ) { @@ -1158,6 +1158,14 @@ atapi_id_update( rc = atapi_id(ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1, ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, aidp); + if (rc) { + swab(aidp->ai_drvser, aidp->ai_drvser, + sizeof (aidp->ai_drvser)); + swab(aidp->ai_fw, aidp->ai_fw, + sizeof (aidp->ai_fw)); + swab(aidp->ai_model, aidp->ai_model, + sizeof (aidp->ai_model)); + } if (ata_pktp == NULL) return (ATA_FSM_RC_FINI); |