diff options
author | yt160523 <none@none> | 2008-04-10 21:52:34 -0700 |
---|---|---|
committer | yt160523 <none@none> | 2008-04-10 21:52:34 -0700 |
commit | c8531848467a8747b65b91ab83c4b57f4c000848 (patch) | |
tree | c95c6bfde4cb2c8086841865f40f2bbb9e4181b4 | |
parent | fb91fd8a302dfb13e250bbefb6a3970c2edc3ae3 (diff) | |
download | illumos-gate-c8531848467a8747b65b91ab83c4b57f4c000848.tar.gz |
6681215 DVD is not being recognized in IDE mode on a Intel Prototype SDV
-rw-r--r-- | usr/src/uts/intel/io/dktp/controller/ata/ata_common.c | 54 | ||||
-rw-r--r-- | usr/src/uts/intel/io/dktp/controller/ata/ata_common.h | 10 | ||||
-rw-r--r-- | usr/src/uts/intel/io/dktp/controller/ata/atapi.c | 27 |
3 files changed, 86 insertions, 5 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 20f4dac44d..e7d6387357 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 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -3755,3 +3755,55 @@ ata_disable_DMA(ata_drv_t *ata_drvp) buf, ata_drvp->ad_targ, ata_drvp->ad_lun); cmn_err(CE_CONT, "?most likely due to the CF-to-IDE adapter."); } + +/* + * Check and select DMA mode + * + * TRUE is returned when set feature is called successfully, + * otherwise return FALSE + */ +int +ata_set_dma_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp) +{ + struct ata_id *aidp; + int mode, rval = FALSE; + uint8_t subcmd; + + aidp = &ata_drvp->ad_id; + + /* Return directly if DMA is not supported */ + 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)) { + for (mode = 6; mode >= 0; --mode) { + if (aidp->ai_ultradma & (1 << mode)) + break; + } + subcmd = ATF_XFRMOD_UDMA; + + } else if (aidp->ai_dworddma & ATAC_MDMA_SUP_MASK) { + /* Then check multi-word DMA mode */ + for (mode = 2; mode >= 0; --mode) { + if (aidp->ai_dworddma & (1 << mode)) + break; + } + subcmd = ATF_XFRMOD_MDMA; + + } else { + return (rval); + } + + rval = ata_set_feature(ata_ctlp, ata_drvp, ATSF_SET_XFRMOD, + subcmd|mode); + + return (rval); +} diff --git a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h index 1eac4c44e1..6ed2c16498 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h +++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -177,6 +177,7 @@ extern "C" { * Feature register bits */ #define ATF_ATAPI_DMA 0x01 /* ATAPI DMA enable bit */ +#define ATF_XFRMOD_MDMA 0x20 /* Multi-Word DMA mode */ #define ATF_XFRMOD_UDMA 0x40 /* Ultra DMA mode */ #define ATACM_UDMA_SEL(id) (((id)->ai_ultradma >> 8) & 0x7f) @@ -415,6 +416,7 @@ struct ata_id { /* Identify Drive: ai_dworddma (word 63) */ +#define ATAC_MDMA_SUP_MASK 0x0007 /* Multiword DMA supported */ #define ATAC_MDMA_SEL_MASK 0x0700 /* Multiword DMA selected */ #define ATAC_MDMA_2_SEL 0x0400 /* Multiword DMA mode 2 selected */ #define ATAC_MDMA_1_SEL 0x0200 /* Multiword DMA mode 1 selected */ @@ -442,6 +444,11 @@ struct ata_id { /* Identify Drive: ai_features85 (word 85) */ #define ATAC_FEATURES85_WCE 0x0020 /* write cache enabled */ +/* Identify Drive: ai_ultradma (word 88) */ +#define ATAC_UDMA_SUP_MASK 0x007f /* UDMA modes supported */ +#define ATAC_UDMA_SEL_MASK 0x7f00 /* UDMA modes selected */ + + /* per-drive data struct */ typedef struct ata_drv { @@ -667,6 +674,7 @@ int ata_wait3(ddi_acc_handle_t io_hdl, caddr_t ioaddr, uchar_t onbits1, uchar_t failure_offbits3, uint_t timeout_usec); int ata_test_lba_support(struct ata_id *aidp); void ata_nsecwait(clock_t count); +int ata_set_dma_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp); /* 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 d714e53d98..c06e3aac75 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/atapi.c +++ b/usr/src/uts/intel/io/dktp/controller/ata/atapi.c @@ -183,6 +183,8 @@ int atapi_init_drive( ata_drv_t *ata_drvp) { + ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp; + ADBG_TRACE(("atapi_init_drive entered\n")); /* Determine ATAPI CDB size */ @@ -206,6 +208,16 @@ atapi_init_drive( ATAPI_ID_CFG_DRQ_INTR) ata_drvp->ad_flags |= AD_NO_CDB_INTR; + /* + * Some devices may have no DMA mode enabled (UDMA or MWDMA) + * by default, so here we need check and enable DMA if none + * mode is selected. + */ + if (ata_set_dma_mode(ata_ctlp, ata_drvp) == TRUE) { + /* Update the IDENTIFY PACKET DEVICE data */ + (void) atapi_id_update(ata_ctlp, ata_drvp, NULL); + } + return (TRUE); } @@ -1119,6 +1131,7 @@ atapi_id_update( caddr_t ioaddr1 = ata_ctlp->ac_ioaddr1; ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2; caddr_t ioaddr2 = ata_ctlp->ac_ioaddr2; + struct ata_id *aidp; int rc; /* @@ -1133,13 +1146,21 @@ atapi_id_update( */ if (!ata_wait(io_hdl2, ioaddr2, ATS_DRDY, ATS_BSY, 5 * 1000000)) { ADBG_ERROR(("atapi_id_update: select failed\n")); - ata_pktp->ap_flags |= AP_ERROR; + if (ata_pktp != NULL) + ata_pktp->ap_flags |= AP_ERROR; return (ATA_FSM_RC_FINI); } + if (ata_pktp != NULL) + aidp = (struct ata_id *)ata_pktp->ap_v_addr; + else + aidp = &ata_drvp->ad_id; + rc = atapi_id(ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1, - ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, - (struct ata_id *)ata_pktp->ap_v_addr); + ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, aidp); + + if (ata_pktp == NULL) + return (ATA_FSM_RC_FINI); if (!rc) { ata_pktp->ap_flags |= AP_ERROR; |