summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorAda <Ada.Feng@Sun.COM>2008-09-11 15:05:11 +0800
committerAda <Ada.Feng@Sun.COM>2008-09-11 15:05:11 +0800
commit62c8caf3fac65817982e780c1efa988846153bf0 (patch)
tree99ef87d3436bb3e732a1688d8a15e2817adb6a10 /usr/src
parent5ef3d48f3eade4d7bb0730f19e26c782232c09ad (diff)
downloadillumos-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.c74
-rw-r--r--usr/src/uts/intel/io/dktp/controller/ata/atapi.c10
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);