1507c3241Smlf /* 2507c3241Smlf * CDDL HEADER START 3507c3241Smlf * 4507c3241Smlf * The contents of this file are subject to the terms of the 5507c3241Smlf * Common Development and Distribution License (the "License"). 6507c3241Smlf * You may not use this file except in compliance with the License. 7507c3241Smlf * 8507c3241Smlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9507c3241Smlf * or http://www.opensolaris.org/os/licensing. 10507c3241Smlf * See the License for the specific language governing permissions 11507c3241Smlf * and limitations under the License. 12507c3241Smlf * 13507c3241Smlf * When distributing Covered Code, include this CDDL HEADER in each 14507c3241Smlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15507c3241Smlf * If applicable, add the following below this CDDL HEADER, with the 16507c3241Smlf * fields enclosed by brackets "[]" replaced with your own identifying 17507c3241Smlf * information: Portions Copyright [yyyy] [name of copyright owner] 18507c3241Smlf * 19507c3241Smlf * CDDL HEADER END 20507c3241Smlf */ 21507c3241Smlf 22507c3241Smlf /* 23c8531848Syt160523 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24507c3241Smlf * Use is subject to license terms. 25507c3241Smlf */ 26507c3241Smlf 27507c3241Smlf #include <sys/types.h> 28507c3241Smlf #include <sys/modctl.h> 29507c3241Smlf #include <sys/debug.h> 30507c3241Smlf #include <sys/promif.h> 31507c3241Smlf #include <sys/pci.h> 32507c3241Smlf #include <sys/errno.h> 33507c3241Smlf #include <sys/open.h> 34507c3241Smlf #include <sys/uio.h> 35507c3241Smlf #include <sys/cred.h> 369f49ae27Smlf #include <sys/cpu.h> 37507c3241Smlf #include "ata_common.h" 38507c3241Smlf #include "ata_disk.h" 39507c3241Smlf #include "atapi.h" 40507c3241Smlf #include "ata_blacklist.h" 41507c3241Smlf #include "sil3xxx.h" 42507c3241Smlf 43507c3241Smlf /* 44507c3241Smlf * Solaris Entry Points. 45507c3241Smlf */ 46507c3241Smlf 47507c3241Smlf static int ata_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 48507c3241Smlf static int ata_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 49507c3241Smlf static int ata_bus_ctl(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t o, 50507c3241Smlf void *a, void *v); 51507c3241Smlf static uint_t ata_intr(caddr_t arg); 52507c3241Smlf 53507c3241Smlf /* 54507c3241Smlf * GHD Entry points 55507c3241Smlf */ 56507c3241Smlf 57507c3241Smlf static int ata_get_status(void *hba_handle, void *intr_status); 58507c3241Smlf static void ata_process_intr(void *hba_handle, void *intr_status); 59507c3241Smlf static int ata_hba_start(void *handle, gcmd_t *gcmdp); 60507c3241Smlf static void ata_hba_complete(void *handle, gcmd_t *gcmdp, int do_callback); 61507c3241Smlf static int ata_timeout_func(void *hba_handle, gcmd_t *gcmdp, 62507c3241Smlf gtgt_t *gtgtp, gact_t action, int calltype); 63507c3241Smlf 64507c3241Smlf /* 65507c3241Smlf * Local Function Prototypes 66507c3241Smlf */ 67507c3241Smlf static int ata_prop_lookup_int(dev_t match_dev, dev_info_t *dip, 68507c3241Smlf uint_t flags, char *name, int defvalue); 69507c3241Smlf static int ata_ctlr_fsm(uchar_t fsm_func, ata_ctl_t *ata_ctlp, 70507c3241Smlf ata_drv_t *ata_drvp, ata_pkt_t *ata_pktp, 71507c3241Smlf int *DoneFlgp); 72507c3241Smlf static void ata_destroy_controller(dev_info_t *dip); 73507c3241Smlf static int ata_drive_type(uchar_t drvhd, 74507c3241Smlf ddi_acc_handle_t io_hdl1, caddr_t ioaddr1, 75507c3241Smlf ddi_acc_handle_t io_hdl2, caddr_t ioaddr2, 76507c3241Smlf struct ata_id *ata_id_bufp); 77507c3241Smlf static ata_ctl_t *ata_init_controller(dev_info_t *dip); 78507c3241Smlf static ata_drv_t *ata_init_drive(ata_ctl_t *ata_ctlp, 79507c3241Smlf uchar_t targ, uchar_t lun); 80507c3241Smlf static int ata_init_drive_pcidma(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp, 81507c3241Smlf dev_info_t *tdip); 82507c3241Smlf static int ata_flush_cache(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp); 83507c3241Smlf static void ata_init_pciide(dev_info_t *dip, ata_ctl_t *ata_ctlp); 84507c3241Smlf static int ata_reset_bus(ata_ctl_t *ata_ctlp); 85507c3241Smlf static int ata_setup_ioaddr(dev_info_t *dip, 86507c3241Smlf ddi_acc_handle_t *iohandle1, caddr_t *ioaddr1p, 87507c3241Smlf ddi_acc_handle_t *iohandle2, caddr_t *ioaddr2p, 88507c3241Smlf ddi_acc_handle_t *bm_hdlp, caddr_t *bm_addrp); 89507c3241Smlf static int ata_software_reset(ata_ctl_t *ata_ctlp); 90507c3241Smlf static int ata_start_arq(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp, 91507c3241Smlf ata_pkt_t *ata_pktp); 92507c3241Smlf static int ata_strncmp(char *p1, char *p2, int cnt); 93507c3241Smlf static void ata_uninit_drive(ata_drv_t *ata_drvp); 94507c3241Smlf 95507c3241Smlf static int ata_check_pciide_blacklist(dev_info_t *dip, uint_t flags); 96507c3241Smlf static int ata_check_revert_to_defaults(ata_drv_t *ata_drvp); 97507c3241Smlf static void ata_show_transfer_mode(ata_ctl_t *, ata_drv_t *); 98507c3241Smlf static int ata_spec_init_controller(dev_info_t *dip); 99507c3241Smlf 1002df1fe9cSrandyf static void ata_init_pm(dev_info_t *); 1012df1fe9cSrandyf static int ata_suspend(dev_info_t *); 1022df1fe9cSrandyf static int ata_resume(dev_info_t *); 1032df1fe9cSrandyf static int ata_power(dev_info_t *, int, int); 1042df1fe9cSrandyf static int ata_change_power(dev_info_t *, uint8_t); 1052df1fe9cSrandyf static int ata_is_pci(dev_info_t *); 1065fb86baeSml40262 static void ata_disable_DMA(ata_drv_t *ata_drvp); 107507c3241Smlf 108507c3241Smlf /* 109507c3241Smlf * Local static data 110507c3241Smlf */ 111507c3241Smlf static void *ata_state; 112507c3241Smlf 113507c3241Smlf static tmr_t ata_timer_conf; /* single timeout list for all instances */ 114507c3241Smlf static int ata_watchdog_usec = 100000; /* check timeouts every 100 ms */ 115507c3241Smlf 116507c3241Smlf int ata_hba_start_watchdog = 1000; 117507c3241Smlf int ata_process_intr_watchdog = 1000; 118507c3241Smlf int ata_reset_bus_watchdog = 1000; 119507c3241Smlf 120507c3241Smlf 121507c3241Smlf /* 1222df1fe9cSrandyf * Use local or framework power management 1232df1fe9cSrandyf */ 1242df1fe9cSrandyf 1252df1fe9cSrandyf #ifdef ATA_USE_AUTOPM 1262df1fe9cSrandyf #define ATA_BUSY_COMPONENT(d, c) ((void)pm_busy_component(d, c)) 1272df1fe9cSrandyf #define ATA_IDLE_COMPONENT(d, c) ((void)pm_idle_component(d, c)) 1282df1fe9cSrandyf #define ATA_RAISE_POWER(d, c, l) pm_raise_power(d, c, l) 1292df1fe9cSrandyf #define ATA_LOWER_POWER(d, c, l) pm_lower_power(d, c, l) 1302df1fe9cSrandyf #else 1312df1fe9cSrandyf #define ATA_BUSY_COMPONENT(d, c) 1322df1fe9cSrandyf #define ATA_IDLE_COMPONENT(d, c) 1332df1fe9cSrandyf #define ATA_RAISE_POWER(d, c, l) ata_power(d, c, l) 1342df1fe9cSrandyf #define ATA_LOWER_POWER(d, c, l) ata_power(d, c, l) 1352df1fe9cSrandyf #endif 1362df1fe9cSrandyf /* 137507c3241Smlf * number of seconds to wait during various operations 138507c3241Smlf */ 139507c3241Smlf int ata_flush_delay = 5 * 1000000; 140507c3241Smlf uint_t ata_set_feature_wait = 4 * 1000000; 141507c3241Smlf uint_t ata_flush_cache_wait = 60 * 1000000; /* may take a long time */ 142507c3241Smlf 143507c3241Smlf /* 144507c3241Smlf * Change this for SFF-8070i support. Currently SFF-8070i is 145507c3241Smlf * using a field in the IDENTIFY PACKET DEVICE response which 146507c3241Smlf * already seems to be in use by some vendor's drives. I suspect 147507c3241Smlf * SFF will either move their laslun field or provide a reliable 148507c3241Smlf * way to validate it. 149507c3241Smlf */ 150507c3241Smlf int ata_enable_atapi_luns = FALSE; 151507c3241Smlf 152507c3241Smlf /* 153507c3241Smlf * set this to disable all DMA requests 154507c3241Smlf */ 155507c3241Smlf int ata_dma_disabled = FALSE; 156507c3241Smlf 157507c3241Smlf /* 158507c3241Smlf * set this to TRUE to enable storing the IDENTIFY DEVICE result in the 159507c3241Smlf * "ata" or "atapi" property. 160507c3241Smlf */ 161507c3241Smlf int ata_id_debug = FALSE; 162507c3241Smlf 163507c3241Smlf /* 164507c3241Smlf * set this to TRUE to enable logging device-capability data 165507c3241Smlf */ 166507c3241Smlf int ata_capability_data = FALSE; 167507c3241Smlf 168507c3241Smlf /* 169507c3241Smlf * DMA selection message pointers 170507c3241Smlf */ 171507c3241Smlf char *ata_cntrl_DMA_sel_msg; 172507c3241Smlf char *ata_dev_DMA_sel_msg; 173507c3241Smlf 174507c3241Smlf /* 175507c3241Smlf * bus nexus operations 176507c3241Smlf */ 177507c3241Smlf static struct bus_ops ata_bus_ops; 178507c3241Smlf static struct bus_ops *scsa_bus_ops_p; 179507c3241Smlf 180507c3241Smlf /* ARGSUSED */ 181507c3241Smlf static int 182507c3241Smlf ata_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) 183507c3241Smlf { 184507c3241Smlf if (ddi_get_soft_state(ata_state, getminor(*devp)) == NULL) 185507c3241Smlf return (ENXIO); 186507c3241Smlf 187507c3241Smlf return (0); 188507c3241Smlf } 189507c3241Smlf 190507c3241Smlf /* 191507c3241Smlf * The purpose of this function is to pass the ioaddress of the controller 192507c3241Smlf * to the caller, specifically used for upgrade from pre-pciide 193507c3241Smlf * to pciide nodes 194507c3241Smlf */ 195507c3241Smlf /* ARGSUSED */ 196507c3241Smlf static int 197507c3241Smlf ata_read(dev_t dev, struct uio *uio_p, cred_t *cred_p) 198507c3241Smlf { 199507c3241Smlf ata_ctl_t *ata_ctlp; 200507c3241Smlf char buf[18]; 201507c3241Smlf long len; 202507c3241Smlf 203507c3241Smlf ata_ctlp = ddi_get_soft_state(ata_state, getminor(dev)); 204507c3241Smlf 205507c3241Smlf if (ata_ctlp == NULL) 206507c3241Smlf return (ENXIO); 207507c3241Smlf 208507c3241Smlf (void) sprintf(buf, "%p\n", (void *) ata_ctlp->ac_ioaddr1); 209507c3241Smlf 210507c3241Smlf len = strlen(buf) - uio_p->uio_offset; 211507c3241Smlf len = min(uio_p->uio_resid, len); 212507c3241Smlf if (len <= 0) 213507c3241Smlf return (0); 214507c3241Smlf 215507c3241Smlf return (uiomove((caddr_t)(buf + uio_p->uio_offset), len, 216507c3241Smlf UIO_READ, uio_p)); 217507c3241Smlf } 218507c3241Smlf 219507c3241Smlf int 220507c3241Smlf ata_devo_reset( 221507c3241Smlf dev_info_t *dip, 222507c3241Smlf ddi_reset_cmd_t cmd) 223507c3241Smlf { 224507c3241Smlf ata_ctl_t *ata_ctlp; 225507c3241Smlf ata_drv_t *ata_drvp; 226507c3241Smlf int instance; 227507c3241Smlf int i; 228507c3241Smlf int rc; 229507c3241Smlf int flush_okay; 230507c3241Smlf 231507c3241Smlf if (cmd != DDI_RESET_FORCE) 232507c3241Smlf return (0); 233507c3241Smlf 234507c3241Smlf instance = ddi_get_instance(dip); 235507c3241Smlf ata_ctlp = ddi_get_soft_state(ata_state, instance); 236507c3241Smlf 237507c3241Smlf if (!ata_ctlp) 238507c3241Smlf return (0); 239507c3241Smlf 240507c3241Smlf /* 241507c3241Smlf * reset ATA drives and flush the write cache of any drives 242507c3241Smlf */ 243507c3241Smlf flush_okay = TRUE; 244507c3241Smlf for (i = 0; i < ATA_MAXTARG; i++) { 245507c3241Smlf if ((ata_drvp = CTL2DRV(ata_ctlp, i, 0)) == 0) 246507c3241Smlf continue; 247507c3241Smlf /* Don't revert to defaults for certain IBM drives */ 248507c3241Smlf if ((ata_drvp->ad_flags & AD_DISK) != 0 && 249507c3241Smlf ((ata_drvp->ad_flags & AD_NORVRT) == 0)) { 250507c3241Smlf /* Enable revert to defaults when reset */ 2512df1fe9cSrandyf (void) ata_set_feature(ata_ctlp, ata_drvp, 2522df1fe9cSrandyf ATSF_ENA_REVPOD, 0); 253507c3241Smlf } 254507c3241Smlf 255507c3241Smlf /* 256507c3241Smlf * skip flush cache if device type is cdrom 257507c3241Smlf * 258507c3241Smlf * notes: the structure definitions for ata_drvp->ad_id are 259507c3241Smlf * defined for the ATA IDENTIFY_DEVICE, but if AD_ATAPI is set 260507c3241Smlf * the struct holds data for the ATAPI IDENTIFY_PACKET_DEVICE 261507c3241Smlf */ 262507c3241Smlf if (!IS_CDROM(ata_drvp)) { 263507c3241Smlf 264507c3241Smlf /* 265507c3241Smlf * Try the ATA/ATAPI flush write cache command 266507c3241Smlf */ 267507c3241Smlf rc = ata_flush_cache(ata_ctlp, ata_drvp); 268507c3241Smlf ADBG_WARN(("ata_flush_cache %s\n", 269507c3241Smlf rc ? "okay" : "failed")); 270507c3241Smlf 271507c3241Smlf if (!rc) 272507c3241Smlf flush_okay = FALSE; 273507c3241Smlf } 274507c3241Smlf 275507c3241Smlf 276507c3241Smlf /* 277507c3241Smlf * do something else if flush cache not supported 278507c3241Smlf */ 279507c3241Smlf } 280507c3241Smlf 281507c3241Smlf /* 282507c3241Smlf * just busy wait if any drive doesn't support FLUSH CACHE 283507c3241Smlf */ 284507c3241Smlf if (!flush_okay) 285507c3241Smlf drv_usecwait(ata_flush_delay); 286507c3241Smlf return (0); 287507c3241Smlf } 288507c3241Smlf 28919397407SSherry Moore /* 29019397407SSherry Moore * quiesce(9E) entry point. 29119397407SSherry Moore * 29219397407SSherry Moore * This function is called when the system is single-threaded at high 29319397407SSherry Moore * PIL with preemption disabled. Therefore, this function must not be 29419397407SSherry Moore * blocked. 29519397407SSherry Moore * 29619397407SSherry Moore * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 29719397407SSherry Moore * DDI_FAILURE indicates an error condition and should almost never happen. 29819397407SSherry Moore */ 29919397407SSherry Moore int 30019397407SSherry Moore ata_quiesce(dev_info_t *dip) 30119397407SSherry Moore { 30219397407SSherry Moore #ifdef ATA_DEBUG 30319397407SSherry Moore /* 30419397407SSherry Moore * Turn off debugging 30519397407SSherry Moore */ 30619397407SSherry Moore ata_debug = 0; 30719397407SSherry Moore #endif 30819397407SSherry Moore 30919397407SSherry Moore return (ata_devo_reset(dip, DDI_RESET_FORCE)); 31019397407SSherry Moore } 31119397407SSherry Moore 312507c3241Smlf 313507c3241Smlf static struct cb_ops ata_cb_ops = { 314507c3241Smlf ata_open, /* open */ 315507c3241Smlf nulldev, /* close */ 316507c3241Smlf nodev, /* strategy */ 317507c3241Smlf nodev, /* print */ 318507c3241Smlf nodev, /* dump */ 319507c3241Smlf ata_read, /* read */ 320507c3241Smlf nodev, /* write */ 321507c3241Smlf nodev, /* ioctl */ 322507c3241Smlf nodev, /* devmap */ 323507c3241Smlf nodev, /* mmap */ 324507c3241Smlf nodev, /* segmap */ 325507c3241Smlf nochpoll, /* chpoll */ 326507c3241Smlf ddi_prop_op, /* prop_op */ 327507c3241Smlf NULL, /* stream info */ 328507c3241Smlf D_MP, /* driver compatibility flag */ 329507c3241Smlf CB_REV, /* cb_ops revision */ 330507c3241Smlf nodev, /* aread */ 331507c3241Smlf nodev /* awrite */ 332507c3241Smlf }; 333507c3241Smlf 334507c3241Smlf static struct dev_ops ata_ops = { 335507c3241Smlf DEVO_REV, /* devo_rev, */ 336507c3241Smlf 0, /* refcnt */ 337507c3241Smlf ddi_getinfo_1to1, /* info */ 338507c3241Smlf nulldev, /* identify */ 339b3c0e203Smlf NULL, /* probe */ 340507c3241Smlf ata_attach, /* attach */ 341507c3241Smlf ata_detach, /* detach */ 342507c3241Smlf ata_devo_reset, /* reset */ 343507c3241Smlf &ata_cb_ops, /* driver operations */ 3442df1fe9cSrandyf NULL, /* bus operations */ 34519397407SSherry Moore ata_power, /* power */ 34619397407SSherry Moore ata_quiesce /* quiesce */ 347507c3241Smlf }; 348507c3241Smlf 349507c3241Smlf /* driver loadable module wrapper */ 350507c3241Smlf static struct modldrv modldrv = { 351507c3241Smlf &mod_driverops, /* Type of module. This one is a driver */ 352507c3241Smlf "ATA AT-bus attachment disk controller Driver", /* module name */ 353507c3241Smlf &ata_ops, /* driver ops */ 354507c3241Smlf }; 355507c3241Smlf 356507c3241Smlf static struct modlinkage modlinkage = { 357507c3241Smlf MODREV_1, (void *)&modldrv, NULL 358507c3241Smlf }; 359507c3241Smlf 360507c3241Smlf #ifdef ATA_DEBUG 361507c3241Smlf int ata_debug_init = FALSE; 362507c3241Smlf int ata_debug_attach = FALSE; 363507c3241Smlf 364507c3241Smlf int ata_debug = ADBG_FLAG_ERROR 365507c3241Smlf /* | ADBG_FLAG_ARQ */ 366507c3241Smlf /* | ADBG_FLAG_INIT */ 367507c3241Smlf /* | ADBG_FLAG_TRACE */ 368507c3241Smlf /* | ADBG_FLAG_TRANSPORT */ 369507c3241Smlf /* | ADBG_FLAG_WARN */ 370507c3241Smlf ; 371507c3241Smlf #endif 372507c3241Smlf 373507c3241Smlf int 374507c3241Smlf _init(void) 375507c3241Smlf { 376507c3241Smlf int err; 377507c3241Smlf 378507c3241Smlf #ifdef ATA_DEBUG 379507c3241Smlf if (ata_debug_init) 380507c3241Smlf debug_enter("\nATA _INIT\n"); 381507c3241Smlf #endif 382507c3241Smlf 383507c3241Smlf if ((err = ddi_soft_state_init(&ata_state, sizeof (ata_ctl_t), 0)) != 0) 384507c3241Smlf return (err); 385507c3241Smlf 386507c3241Smlf if ((err = scsi_hba_init(&modlinkage)) != 0) { 387507c3241Smlf ddi_soft_state_fini(&ata_state); 388507c3241Smlf return (err); 389507c3241Smlf } 390507c3241Smlf 391507c3241Smlf /* save pointer to SCSA provided bus_ops struct */ 392507c3241Smlf scsa_bus_ops_p = ata_ops.devo_bus_ops; 393507c3241Smlf 394507c3241Smlf /* make a copy of SCSA bus_ops */ 395507c3241Smlf ata_bus_ops = *(ata_ops.devo_bus_ops); 396507c3241Smlf 397507c3241Smlf /* 398507c3241Smlf * Modify our bus_ops to call our routines. Our implementation 399507c3241Smlf * will determine if the device is ATA or ATAPI/SCSA and react 400507c3241Smlf * accordingly. 401507c3241Smlf */ 402507c3241Smlf ata_bus_ops.bus_ctl = ata_bus_ctl; 403507c3241Smlf 404507c3241Smlf /* patch our bus_ops into the dev_ops struct */ 405507c3241Smlf ata_ops.devo_bus_ops = &ata_bus_ops; 406507c3241Smlf 407507c3241Smlf if ((err = mod_install(&modlinkage)) != 0) { 408507c3241Smlf scsi_hba_fini(&modlinkage); 409507c3241Smlf ddi_soft_state_fini(&ata_state); 410507c3241Smlf } 411507c3241Smlf 412507c3241Smlf /* 413507c3241Smlf * Initialize the per driver timer info. 414507c3241Smlf */ 415507c3241Smlf 416507c3241Smlf ghd_timer_init(&ata_timer_conf, drv_usectohz(ata_watchdog_usec)); 417507c3241Smlf 418507c3241Smlf return (err); 419507c3241Smlf } 420507c3241Smlf 421507c3241Smlf int 422507c3241Smlf _fini(void) 423507c3241Smlf { 424507c3241Smlf int err; 425507c3241Smlf 426507c3241Smlf if ((err = mod_remove(&modlinkage)) == 0) { 427507c3241Smlf ghd_timer_fini(&ata_timer_conf); 428507c3241Smlf scsi_hba_fini(&modlinkage); 429507c3241Smlf ddi_soft_state_fini(&ata_state); 430507c3241Smlf } 431507c3241Smlf 432507c3241Smlf return (err); 433507c3241Smlf } 434507c3241Smlf 435507c3241Smlf int 436507c3241Smlf _info(struct modinfo *modinfop) 437507c3241Smlf { 438507c3241Smlf return (mod_info(&modlinkage, modinfop)); 439507c3241Smlf } 440507c3241Smlf 441507c3241Smlf 442507c3241Smlf /* 443507c3241Smlf * 444507c3241Smlf * driver attach entry point 445507c3241Smlf * 446507c3241Smlf */ 447507c3241Smlf 448507c3241Smlf static int 449507c3241Smlf ata_attach( 450507c3241Smlf dev_info_t *dip, 451507c3241Smlf ddi_attach_cmd_t cmd) 452507c3241Smlf { 453507c3241Smlf ata_ctl_t *ata_ctlp; 454507c3241Smlf ata_drv_t *ata_drvp; 455507c3241Smlf ata_drv_t *first_drvp = NULL; 456507c3241Smlf uchar_t targ; 457507c3241Smlf uchar_t lun; 458507c3241Smlf uchar_t lastlun; 459507c3241Smlf int atapi_count = 0; 460507c3241Smlf int disk_count = 0; 461507c3241Smlf 462507c3241Smlf ADBG_TRACE(("ata_attach entered\n")); 463507c3241Smlf #ifdef ATA_DEBUG 464507c3241Smlf if (ata_debug_attach) 465507c3241Smlf debug_enter("\nATA_ATTACH\n\n"); 466507c3241Smlf #endif 467507c3241Smlf 4682df1fe9cSrandyf switch (cmd) { 4692df1fe9cSrandyf case DDI_ATTACH: 4702df1fe9cSrandyf break; 4712df1fe9cSrandyf case DDI_RESUME: 4722df1fe9cSrandyf return (ata_resume(dip)); 4732df1fe9cSrandyf default: 474507c3241Smlf return (DDI_FAILURE); 4752df1fe9cSrandyf } 476507c3241Smlf 477507c3241Smlf /* initialize controller */ 478507c3241Smlf ata_ctlp = ata_init_controller(dip); 479507c3241Smlf 480507c3241Smlf if (ata_ctlp == NULL) 481507c3241Smlf goto errout; 482507c3241Smlf 483507c3241Smlf mutex_enter(&ata_ctlp->ac_ccc.ccc_hba_mutex); 484507c3241Smlf 485507c3241Smlf /* initialize drives */ 486507c3241Smlf 487507c3241Smlf for (targ = 0; targ < ATA_MAXTARG; targ++) { 488507c3241Smlf 489507c3241Smlf ata_drvp = ata_init_drive(ata_ctlp, targ, 0); 490507c3241Smlf if (ata_drvp == NULL) 491507c3241Smlf continue; 492507c3241Smlf 493507c3241Smlf if (first_drvp == NULL) 494507c3241Smlf first_drvp = ata_drvp; 495507c3241Smlf 496507c3241Smlf if (ATAPIDRV(ata_drvp)) { 497507c3241Smlf atapi_count++; 498507c3241Smlf lastlun = ata_drvp->ad_id.ai_lastlun; 499507c3241Smlf } else { 500507c3241Smlf disk_count++; 501507c3241Smlf lastlun = 0; 502507c3241Smlf } 503507c3241Smlf 504507c3241Smlf /* 505507c3241Smlf * LUN support is currently disabled. Check with SFF-8070i 506507c3241Smlf * before enabling. 507507c3241Smlf */ 508507c3241Smlf if (!ata_enable_atapi_luns) 509507c3241Smlf lastlun = 0; 510507c3241Smlf 511507c3241Smlf /* Initialize higher LUNs, if there are any */ 512507c3241Smlf for (lun = 1; lun <= lastlun && lun < ATA_MAXLUN; lun++) { 513507c3241Smlf if ((ata_drvp = 514507c3241Smlf ata_init_drive(ata_ctlp, targ, lun)) != NULL) { 515507c3241Smlf ata_show_transfer_mode(ata_ctlp, ata_drvp); 516507c3241Smlf } 517507c3241Smlf } 518507c3241Smlf } 519507c3241Smlf 520507c3241Smlf if ((atapi_count == 0) && (disk_count == 0)) { 521507c3241Smlf ADBG_WARN(("ata_attach: no drives detected\n")); 522507c3241Smlf goto errout1; 523507c3241Smlf } 524507c3241Smlf 525507c3241Smlf /* 526507c3241Smlf * Always make certain that a valid drive is selected so 527507c3241Smlf * that routines which poll the status register don't get 528507c3241Smlf * confused by non-existent drives. 529507c3241Smlf */ 530507c3241Smlf ddi_put8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_drvhd, 531507c3241Smlf first_drvp->ad_drive_bits); 5329f49ae27Smlf ata_nsecwait(400); 533507c3241Smlf 534507c3241Smlf /* 535507c3241Smlf * make certain the drive selected 536507c3241Smlf */ 537507c3241Smlf if (!ata_wait(ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, 538507c3241Smlf 0, ATS_BSY, 5000000)) { 539507c3241Smlf ADBG_ERROR(("ata_attach: select failed\n")); 540507c3241Smlf } 541507c3241Smlf 542507c3241Smlf /* 543507c3241Smlf * initialize atapi/ata_dsk modules if we have at least 544507c3241Smlf * one drive of that type. 545507c3241Smlf */ 546507c3241Smlf 547507c3241Smlf if (atapi_count) { 548507c3241Smlf if (!atapi_attach(ata_ctlp)) 549507c3241Smlf goto errout1; 550507c3241Smlf ata_ctlp->ac_flags |= AC_ATAPI_INIT; 551507c3241Smlf } 552507c3241Smlf 553507c3241Smlf if (disk_count) { 554507c3241Smlf if (!ata_disk_attach(ata_ctlp)) 555507c3241Smlf goto errout1; 556507c3241Smlf ata_ctlp->ac_flags |= AC_DISK_INIT; 557507c3241Smlf } 558507c3241Smlf 559507c3241Smlf /* 560507c3241Smlf * make certain the interrupt and error latches are clear 561507c3241Smlf */ 562507c3241Smlf if (ata_ctlp->ac_pciide) { 563507c3241Smlf 564507c3241Smlf int instance = ddi_get_instance(dip); 565507c3241Smlf if (ddi_create_minor_node(dip, "control", S_IFCHR, instance, 566507c3241Smlf DDI_PSEUDO, 0) != DDI_SUCCESS) { 567507c3241Smlf goto errout1; 568507c3241Smlf } 569507c3241Smlf 570507c3241Smlf (void) ata_pciide_status_clear(ata_ctlp); 571507c3241Smlf 572507c3241Smlf } 573507c3241Smlf 574507c3241Smlf /* 575507c3241Smlf * enable the interrupt handler and drop the mutex 576507c3241Smlf */ 577507c3241Smlf ata_ctlp->ac_flags |= AC_ATTACHED; 578507c3241Smlf mutex_exit(&ata_ctlp->ac_ccc.ccc_hba_mutex); 579507c3241Smlf 5802df1fe9cSrandyf ata_init_pm(dip); 5812df1fe9cSrandyf 582507c3241Smlf ddi_report_dev(dip); 583507c3241Smlf return (DDI_SUCCESS); 584507c3241Smlf 585507c3241Smlf errout1: 586507c3241Smlf mutex_exit(&ata_ctlp->ac_ccc.ccc_hba_mutex); 587507c3241Smlf errout: 588507c3241Smlf (void) ata_detach(dip, DDI_DETACH); 589507c3241Smlf return (DDI_FAILURE); 590507c3241Smlf } 591507c3241Smlf 592507c3241Smlf /* driver detach entry point */ 593507c3241Smlf 594507c3241Smlf static int 595507c3241Smlf ata_detach( 596507c3241Smlf dev_info_t *dip, 597507c3241Smlf ddi_detach_cmd_t cmd) 598507c3241Smlf { 599507c3241Smlf ata_ctl_t *ata_ctlp; 600507c3241Smlf ata_drv_t *ata_drvp; 601507c3241Smlf int instance; 602507c3241Smlf int i; 603507c3241Smlf int j; 604507c3241Smlf 605507c3241Smlf ADBG_TRACE(("ata_detach entered\n")); 606507c3241Smlf 6072df1fe9cSrandyf switch (cmd) { 6082df1fe9cSrandyf case DDI_DETACH: 6092df1fe9cSrandyf break; 6102df1fe9cSrandyf case DDI_SUSPEND: 6112df1fe9cSrandyf return (ata_suspend(dip)); 6122df1fe9cSrandyf default: 613507c3241Smlf return (DDI_FAILURE); 6142df1fe9cSrandyf } 615507c3241Smlf 616507c3241Smlf instance = ddi_get_instance(dip); 617507c3241Smlf ata_ctlp = ddi_get_soft_state(ata_state, instance); 618507c3241Smlf 619507c3241Smlf if (!ata_ctlp) 620507c3241Smlf return (DDI_SUCCESS); 621507c3241Smlf 6222df1fe9cSrandyf if (ata_ctlp->ac_pm_support) { 6232df1fe9cSrandyf ATA_BUSY_COMPONENT(dip, 0); 6242df1fe9cSrandyf if (ata_ctlp->ac_pm_level != PM_LEVEL_D0) { 6252df1fe9cSrandyf if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) != 6262df1fe9cSrandyf DDI_SUCCESS) { 6272df1fe9cSrandyf ATA_IDLE_COMPONENT(dip, 0); 6282df1fe9cSrandyf return (DDI_FAILURE); 6292df1fe9cSrandyf } 6302df1fe9cSrandyf } 6312df1fe9cSrandyf (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components"); 6322df1fe9cSrandyf } 633507c3241Smlf ata_ctlp->ac_flags &= ~AC_ATTACHED; 634507c3241Smlf 635507c3241Smlf /* destroy ata module */ 636507c3241Smlf if (ata_ctlp->ac_flags & AC_DISK_INIT) 637507c3241Smlf ata_disk_detach(ata_ctlp); 638507c3241Smlf 639507c3241Smlf /* destroy atapi module */ 640507c3241Smlf if (ata_ctlp->ac_flags & AC_ATAPI_INIT) 641507c3241Smlf atapi_detach(ata_ctlp); 642507c3241Smlf 643507c3241Smlf ddi_remove_minor_node(dip, NULL); 644507c3241Smlf 645507c3241Smlf /* destroy drives */ 646507c3241Smlf for (i = 0; i < ATA_MAXTARG; i++) { 647507c3241Smlf for (j = 0; j < ATA_MAXLUN; j++) { 648507c3241Smlf ata_drvp = CTL2DRV(ata_ctlp, i, j); 649507c3241Smlf if (ata_drvp != NULL) 650507c3241Smlf ata_uninit_drive(ata_drvp); 651507c3241Smlf } 652507c3241Smlf } 653507c3241Smlf 654507c3241Smlf if (ata_ctlp->ac_iohandle1) 655507c3241Smlf ddi_regs_map_free(&ata_ctlp->ac_iohandle1); 656507c3241Smlf if (ata_ctlp->ac_iohandle2) 657507c3241Smlf ddi_regs_map_free(&ata_ctlp->ac_iohandle2); 658507c3241Smlf if (ata_ctlp->ac_bmhandle) 659507c3241Smlf ddi_regs_map_free(&ata_ctlp->ac_bmhandle); 660507c3241Smlf 661507c3241Smlf /* destroy controller */ 662507c3241Smlf ata_destroy_controller(dip); 663507c3241Smlf 664b3c0e203Smlf ddi_prop_remove_all(dip); 665b3c0e203Smlf 666507c3241Smlf return (DDI_SUCCESS); 667507c3241Smlf } 668507c3241Smlf 669507c3241Smlf /* 670507c3241Smlf * Nexus driver bus_ctl entry point 671507c3241Smlf */ 672507c3241Smlf /*ARGSUSED*/ 673507c3241Smlf static int 674507c3241Smlf ata_bus_ctl( 675507c3241Smlf dev_info_t *d, 676507c3241Smlf dev_info_t *r, 677507c3241Smlf ddi_ctl_enum_t o, 678507c3241Smlf void *a, 679507c3241Smlf void *v) 680507c3241Smlf { 681507c3241Smlf dev_info_t *tdip; 682507c3241Smlf int target_type; 683507c3241Smlf int rc; 684507c3241Smlf char *bufp; 685507c3241Smlf 686507c3241Smlf ADBG_TRACE(("ata_bus_ctl entered\n")); 687507c3241Smlf 688507c3241Smlf switch (o) { 689507c3241Smlf 690507c3241Smlf case DDI_CTLOPS_SIDDEV: 691507c3241Smlf return (DDI_FAILURE); 692507c3241Smlf 693507c3241Smlf case DDI_CTLOPS_IOMIN: 694507c3241Smlf 695507c3241Smlf /* 696507c3241Smlf * Since we use PIO, we return a minimum I/O size of 697507c3241Smlf * one byte. This will need to be updated when we 698507c3241Smlf * implement DMA support 699507c3241Smlf */ 700507c3241Smlf 701507c3241Smlf *((int *)v) = 1; 702507c3241Smlf return (DDI_SUCCESS); 703507c3241Smlf 704507c3241Smlf case DDI_CTLOPS_DMAPMAPC: 705507c3241Smlf case DDI_CTLOPS_REPORTINT: 706507c3241Smlf case DDI_CTLOPS_REGSIZE: 707507c3241Smlf case DDI_CTLOPS_NREGS: 708507c3241Smlf case DDI_CTLOPS_SLAVEONLY: 709507c3241Smlf case DDI_CTLOPS_AFFINITY: 710507c3241Smlf case DDI_CTLOPS_POKE: 711507c3241Smlf case DDI_CTLOPS_PEEK: 712507c3241Smlf 713507c3241Smlf /* These ops shouldn't be called by a target driver */ 714507c3241Smlf ADBG_ERROR(("ata_bus_ctl: %s%d: invalid op (%d) from %s%d\n", 715507c3241Smlf ddi_driver_name(d), ddi_get_instance(d), o, 716507c3241Smlf ddi_driver_name(r), ddi_get_instance(r))); 717507c3241Smlf 718507c3241Smlf return (DDI_FAILURE); 719507c3241Smlf 720507c3241Smlf case DDI_CTLOPS_REPORTDEV: 721507c3241Smlf case DDI_CTLOPS_INITCHILD: 722507c3241Smlf case DDI_CTLOPS_UNINITCHILD: 723507c3241Smlf 724507c3241Smlf /* these require special handling below */ 725507c3241Smlf break; 726507c3241Smlf 727507c3241Smlf default: 728507c3241Smlf return (ddi_ctlops(d, r, o, a, v)); 729507c3241Smlf } 730507c3241Smlf 731507c3241Smlf /* get targets dip */ 732507c3241Smlf 733507c3241Smlf if (o == DDI_CTLOPS_INITCHILD || o == DDI_CTLOPS_UNINITCHILD) 734507c3241Smlf tdip = (dev_info_t *)a; 735507c3241Smlf else 736507c3241Smlf tdip = r; 737507c3241Smlf 738507c3241Smlf /* 739507c3241Smlf * XXX - Get class of target 740507c3241Smlf * Before the "class" entry in a conf file becomes 741507c3241Smlf * a real property, we use an additional property 742507c3241Smlf * tentatively called "class_prop". We will require that 743507c3241Smlf * new classes (ie. direct) export "class_prop". 744507c3241Smlf * SCSA target drivers will not have this property, so 745507c3241Smlf * no property implies SCSA. 746507c3241Smlf */ 747507c3241Smlf if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS, 748507c3241Smlf "class", &bufp) == DDI_PROP_SUCCESS) || 749507c3241Smlf (ddi_prop_lookup_string(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS, 750507c3241Smlf "class_prop", &bufp) == DDI_PROP_SUCCESS)) { 751507c3241Smlf if (strcmp(bufp, "dada") == 0) 752507c3241Smlf target_type = ATA_DEV_DISK; 753507c3241Smlf else if (strcmp(bufp, "scsi") == 0) 754507c3241Smlf target_type = ATA_DEV_ATAPI; 755507c3241Smlf else { 756507c3241Smlf ADBG_WARN(("ata_bus_ctl: invalid target class %s\n", 757507c3241Smlf bufp)); 758507c3241Smlf ddi_prop_free(bufp); 759507c3241Smlf return (DDI_FAILURE); 760507c3241Smlf } 761507c3241Smlf ddi_prop_free(bufp); 762507c3241Smlf } else { 763507c3241Smlf target_type = ATA_DEV_ATAPI; /* no class prop, assume SCSI */ 764507c3241Smlf } 765507c3241Smlf 766507c3241Smlf if (o == DDI_CTLOPS_INITCHILD) { 767507c3241Smlf int instance = ddi_get_instance(d); 768507c3241Smlf ata_ctl_t *ata_ctlp = ddi_get_soft_state(ata_state, instance); 769507c3241Smlf ata_drv_t *ata_drvp; 770507c3241Smlf int targ; 771507c3241Smlf int lun; 772507c3241Smlf int drive_type; 773507c3241Smlf char *disk_prop; 774507c3241Smlf char *class_prop; 775507c3241Smlf 776507c3241Smlf if (ata_ctlp == NULL) { 777507c3241Smlf ADBG_WARN(("ata_bus_ctl: failed to find ctl struct\n")); 778507c3241Smlf return (DDI_FAILURE); 779507c3241Smlf } 780507c3241Smlf 781507c3241Smlf /* get (target,lun) of child device */ 782507c3241Smlf 783507c3241Smlf targ = ddi_prop_get_int(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS, 784507c3241Smlf "target", -1); 785507c3241Smlf if (targ == -1) { 786507c3241Smlf ADBG_WARN(("ata_bus_ctl: failed to get targ num\n")); 787507c3241Smlf return (DDI_FAILURE); 788507c3241Smlf } 789507c3241Smlf 790507c3241Smlf lun = ddi_prop_get_int(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS, 791507c3241Smlf "lun", 0); 792507c3241Smlf 793507c3241Smlf if ((targ < 0) || (targ >= ATA_MAXTARG) || 794507c3241Smlf (lun < 0) || (lun >= ATA_MAXLUN)) { 795507c3241Smlf return (DDI_FAILURE); 796507c3241Smlf } 797507c3241Smlf 798507c3241Smlf ata_drvp = CTL2DRV(ata_ctlp, targ, lun); 799507c3241Smlf 800507c3241Smlf if (ata_drvp == NULL) 801507c3241Smlf return (DDI_FAILURE); /* no drive */ 802507c3241Smlf 803507c3241Smlf /* get type of device */ 804507c3241Smlf 805507c3241Smlf if (ATAPIDRV(ata_drvp)) 806507c3241Smlf drive_type = ATA_DEV_ATAPI; 807507c3241Smlf else 808507c3241Smlf drive_type = ATA_DEV_DISK; 809507c3241Smlf 810507c3241Smlf /* 811507c3241Smlf * Check for special handling when child driver is 812507c3241Smlf * cmdk (which morphs to the correct interface) 813507c3241Smlf */ 814507c3241Smlf if (strcmp(ddi_get_name(tdip), "cmdk") == 0) { 815507c3241Smlf 816507c3241Smlf if ((target_type == ATA_DEV_DISK) && 817507c3241Smlf (target_type != drive_type)) 818507c3241Smlf return (DDI_FAILURE); 819507c3241Smlf 820507c3241Smlf target_type = drive_type; 821507c3241Smlf 822507c3241Smlf if (drive_type == ATA_DEV_ATAPI) { 823507c3241Smlf class_prop = "scsi"; 824507c3241Smlf } else { 825507c3241Smlf disk_prop = "dadk"; 826507c3241Smlf class_prop = "dada"; 827507c3241Smlf 828507c3241Smlf if (ndi_prop_update_string(DDI_DEV_T_NONE, tdip, 829507c3241Smlf "disk", disk_prop) != DDI_PROP_SUCCESS) { 830507c3241Smlf ADBG_WARN(("ata_bus_ctl: failed to " 831507c3241Smlf "create disk prop\n")); 832507c3241Smlf return (DDI_FAILURE); 833507c3241Smlf } 834507c3241Smlf } 835507c3241Smlf 836507c3241Smlf if (ndi_prop_update_string(DDI_DEV_T_NONE, tdip, 837507c3241Smlf "class_prop", class_prop) != DDI_PROP_SUCCESS) { 838507c3241Smlf ADBG_WARN(("ata_bus_ctl: failed to " 839507c3241Smlf "create class prop\n")); 840507c3241Smlf return (DDI_FAILURE); 841507c3241Smlf } 842507c3241Smlf } 843507c3241Smlf 844507c3241Smlf /* Check that target class matches the device */ 845507c3241Smlf 846507c3241Smlf if (target_type != drive_type) 847507c3241Smlf return (DDI_FAILURE); 848507c3241Smlf 849507c3241Smlf /* save pointer to drive struct for ata_disk_bus_ctl */ 850507c3241Smlf ddi_set_driver_private(tdip, ata_drvp); 851507c3241Smlf 852507c3241Smlf /* 853507c3241Smlf * Determine whether to enable DMA support for this drive. This 854507c3241Smlf * check is deferred to this point so that the various dma 855507c3241Smlf * properties could reside on the devinfo node should finer 856507c3241Smlf * grained dma control be required. 857507c3241Smlf */ 8585fb86baeSml40262 if (ata_drvp->ad_pciide_dma == ATA_DMA_UNINITIALIZED) { 8595fb86baeSml40262 ata_drvp->ad_pciide_dma = 8605fb86baeSml40262 ata_init_drive_pcidma(ata_ctlp, ata_drvp, tdip); 861507c3241Smlf ata_show_transfer_mode(ata_ctlp, ata_drvp); 862507c3241Smlf } 8635fb86baeSml40262 } 864507c3241Smlf 865507c3241Smlf if (target_type == ATA_DEV_ATAPI) { 866507c3241Smlf rc = scsa_bus_ops_p->bus_ctl(d, r, o, a, v); 867507c3241Smlf } else { 868507c3241Smlf rc = ata_disk_bus_ctl(d, r, o, a, v); 869507c3241Smlf } 870507c3241Smlf 871507c3241Smlf return (rc); 872507c3241Smlf } 873507c3241Smlf 874507c3241Smlf /* 875507c3241Smlf * 876507c3241Smlf * GHD ccc_hba_complete callback 877507c3241Smlf * 878507c3241Smlf */ 879507c3241Smlf 880507c3241Smlf /* ARGSUSED */ 881507c3241Smlf static void 882507c3241Smlf ata_hba_complete( 883507c3241Smlf void *hba_handle, 884507c3241Smlf gcmd_t *gcmdp, 885507c3241Smlf int do_callback) 886507c3241Smlf { 887507c3241Smlf ata_drv_t *ata_drvp; 888507c3241Smlf ata_pkt_t *ata_pktp; 889507c3241Smlf 890507c3241Smlf ADBG_TRACE(("ata_hba_complete entered\n")); 891507c3241Smlf 892507c3241Smlf ata_drvp = GCMD2DRV(gcmdp); 893507c3241Smlf ata_pktp = GCMD2APKT(gcmdp); 894507c3241Smlf if (ata_pktp->ap_complete) 895507c3241Smlf (*ata_pktp->ap_complete)(ata_drvp, ata_pktp, 896507c3241Smlf do_callback); 897507c3241Smlf } 898507c3241Smlf 899507c3241Smlf /* GHD ccc_timeout_func callback */ 900507c3241Smlf 901507c3241Smlf /* ARGSUSED */ 902507c3241Smlf static int 903507c3241Smlf ata_timeout_func( 904507c3241Smlf void *hba_handle, 905507c3241Smlf gcmd_t *gcmdp, 906507c3241Smlf gtgt_t *gtgtp, 907507c3241Smlf gact_t action, 908507c3241Smlf int calltype) 909507c3241Smlf { 910507c3241Smlf ata_ctl_t *ata_ctlp; 911507c3241Smlf ata_pkt_t *ata_pktp; 9125fb86baeSml40262 ata_drv_t *ata_drvp; 913507c3241Smlf 914507c3241Smlf ADBG_TRACE(("ata_timeout_func entered\n")); 915507c3241Smlf 916507c3241Smlf ata_ctlp = (ata_ctl_t *)hba_handle; 917507c3241Smlf 918507c3241Smlf if (gcmdp != NULL) 919507c3241Smlf ata_pktp = GCMD2APKT(gcmdp); 920507c3241Smlf else 921507c3241Smlf ata_pktp = NULL; 922507c3241Smlf 923507c3241Smlf switch (action) { 924507c3241Smlf case GACTION_EARLY_ABORT: 925507c3241Smlf /* abort before request was started */ 926507c3241Smlf if (ata_pktp != NULL) { 927507c3241Smlf ata_pktp->ap_flags |= AP_ABORT; 928507c3241Smlf } 929507c3241Smlf ghd_complete(&ata_ctlp->ac_ccc, gcmdp); 930507c3241Smlf return (TRUE); 931507c3241Smlf 932507c3241Smlf case GACTION_EARLY_TIMEOUT: 933507c3241Smlf /* timeout before request was started */ 934507c3241Smlf if (ata_pktp != NULL) { 935507c3241Smlf ata_pktp->ap_flags |= AP_TIMEOUT; 936507c3241Smlf } 937507c3241Smlf ghd_complete(&ata_ctlp->ac_ccc, gcmdp); 938507c3241Smlf return (TRUE); 939507c3241Smlf 940507c3241Smlf case GACTION_RESET_TARGET: 941507c3241Smlf /* 942507c3241Smlf * Reset a device is not supported. Resetting a specific 943507c3241Smlf * device can't be done at all to an ATA device and if 944507c3241Smlf * you send a RESET to an ATAPI device you have to 945507c3241Smlf * reset the whole bus to make certain both devices 946507c3241Smlf * on the bus stay in sync regarding which device is 947507c3241Smlf * the currently selected one. 948507c3241Smlf */ 949507c3241Smlf return (FALSE); 950507c3241Smlf 951507c3241Smlf case GACTION_RESET_BUS: 952507c3241Smlf /* 953507c3241Smlf * Issue bus reset and reinitialize both drives. 954507c3241Smlf * But only if this is a timed-out request. Target 955507c3241Smlf * driver reset requests are ignored because ATA 956507c3241Smlf * and ATAPI devices shouldn't be gratuitously reset. 9575fb86baeSml40262 * Also disable DMA if it is a CF device. 958507c3241Smlf */ 959507c3241Smlf if (gcmdp == NULL) 960507c3241Smlf break; 9615fb86baeSml40262 ata_drvp = GCMD2DRV(gcmdp); 9625fb86baeSml40262 if (ata_drvp != NULL) 9635fb86baeSml40262 if (ata_drvp->ad_id.ai_config == ATA_ID_CF_TO_ATA) 9645fb86baeSml40262 ata_disable_DMA(ata_drvp); 965507c3241Smlf return (ata_reset_bus(ata_ctlp)); 966507c3241Smlf default: 967507c3241Smlf break; 968507c3241Smlf } 969507c3241Smlf return (FALSE); 970507c3241Smlf } 971507c3241Smlf 972507c3241Smlf /* 973507c3241Smlf * 974507c3241Smlf * Initialize controller's soft-state structure 975507c3241Smlf * 976507c3241Smlf */ 977507c3241Smlf 978507c3241Smlf static ata_ctl_t * 979507c3241Smlf ata_init_controller( 980507c3241Smlf dev_info_t *dip) 981507c3241Smlf { 982507c3241Smlf ata_ctl_t *ata_ctlp; 983507c3241Smlf int instance; 984507c3241Smlf caddr_t ioaddr1; 985507c3241Smlf caddr_t ioaddr2; 986507c3241Smlf 987507c3241Smlf ADBG_TRACE(("ata_init_controller entered\n")); 988507c3241Smlf 989507c3241Smlf instance = ddi_get_instance(dip); 990507c3241Smlf 991507c3241Smlf /* allocate controller structure */ 992507c3241Smlf if (ddi_soft_state_zalloc(ata_state, instance) != DDI_SUCCESS) { 993507c3241Smlf ADBG_WARN(("ata_init_controller: soft_state_zalloc failed\n")); 994507c3241Smlf return (NULL); 995507c3241Smlf } 996507c3241Smlf 997507c3241Smlf ata_ctlp = ddi_get_soft_state(ata_state, instance); 998507c3241Smlf 999507c3241Smlf if (ata_ctlp == NULL) { 1000507c3241Smlf ADBG_WARN(("ata_init_controller: failed to find " 1001507c3241Smlf "controller struct\n")); 1002507c3241Smlf return (NULL); 1003507c3241Smlf } 1004507c3241Smlf 1005507c3241Smlf /* 1006507c3241Smlf * initialize per-controller data 1007507c3241Smlf */ 1008507c3241Smlf ata_ctlp->ac_dip = dip; 1009507c3241Smlf ata_ctlp->ac_arq_pktp = kmem_zalloc(sizeof (ata_pkt_t), KM_SLEEP); 1010507c3241Smlf 1011507c3241Smlf /* 1012507c3241Smlf * map the device registers 1013507c3241Smlf */ 1014507c3241Smlf if (!ata_setup_ioaddr(dip, &ata_ctlp->ac_iohandle1, &ioaddr1, 1015507c3241Smlf &ata_ctlp->ac_iohandle2, &ioaddr2, 1016507c3241Smlf &ata_ctlp->ac_bmhandle, &ata_ctlp->ac_bmaddr)) { 1017507c3241Smlf (void) ata_detach(dip, DDI_DETACH); 1018507c3241Smlf return (NULL); 1019507c3241Smlf } 1020507c3241Smlf 1021507c3241Smlf ADBG_INIT(("ata_init_controller: ioaddr1 = 0x%p, ioaddr2 = 0x%p\n", 1022507c3241Smlf ioaddr1, ioaddr2)); 1023507c3241Smlf 1024507c3241Smlf /* 1025507c3241Smlf * Do ARQ setup 1026507c3241Smlf */ 1027507c3241Smlf atapi_init_arq(ata_ctlp); 1028507c3241Smlf 1029507c3241Smlf /* 1030507c3241Smlf * Do PCI-IDE setup 1031507c3241Smlf */ 1032507c3241Smlf ata_init_pciide(dip, ata_ctlp); 1033507c3241Smlf 1034507c3241Smlf /* 1035507c3241Smlf * port addresses associated with ioaddr1 1036507c3241Smlf */ 1037507c3241Smlf ata_ctlp->ac_ioaddr1 = ioaddr1; 1038507c3241Smlf ata_ctlp->ac_data = (ushort_t *)ioaddr1 + AT_DATA; 1039507c3241Smlf ata_ctlp->ac_error = (uchar_t *)ioaddr1 + AT_ERROR; 1040507c3241Smlf ata_ctlp->ac_feature = (uchar_t *)ioaddr1 + AT_FEATURE; 1041507c3241Smlf ata_ctlp->ac_count = (uchar_t *)ioaddr1 + AT_COUNT; 1042507c3241Smlf ata_ctlp->ac_sect = (uchar_t *)ioaddr1 + AT_SECT; 1043507c3241Smlf ata_ctlp->ac_lcyl = (uchar_t *)ioaddr1 + AT_LCYL; 1044507c3241Smlf ata_ctlp->ac_hcyl = (uchar_t *)ioaddr1 + AT_HCYL; 1045507c3241Smlf ata_ctlp->ac_drvhd = (uchar_t *)ioaddr1 + AT_DRVHD; 1046507c3241Smlf ata_ctlp->ac_status = (uchar_t *)ioaddr1 + AT_STATUS; 1047507c3241Smlf ata_ctlp->ac_cmd = (uchar_t *)ioaddr1 + AT_CMD; 1048507c3241Smlf 1049507c3241Smlf /* 1050507c3241Smlf * port addresses associated with ioaddr2 1051507c3241Smlf */ 1052507c3241Smlf ata_ctlp->ac_ioaddr2 = ioaddr2; 1053507c3241Smlf ata_ctlp->ac_altstatus = (uchar_t *)ioaddr2 + AT_ALTSTATUS; 1054507c3241Smlf ata_ctlp->ac_devctl = (uchar_t *)ioaddr2 + AT_DEVCTL; 1055507c3241Smlf 1056507c3241Smlf /* 1057507c3241Smlf * If AC_BSY_WAIT needs to be set for laptops that do 1058507c3241Smlf * suspend/resume but do not correctly wait for the busy bit to 1059507c3241Smlf * drop after a resume. 1060507c3241Smlf */ 1061507c3241Smlf ata_ctlp->ac_timing_flags = ddi_prop_get_int(DDI_DEV_T_ANY, 1062507c3241Smlf dip, DDI_PROP_DONTPASS, "timing_flags", 0); 1063507c3241Smlf /* 1064507c3241Smlf * get max transfer size, default to 256 sectors 1065507c3241Smlf */ 1066507c3241Smlf ata_ctlp->ac_max_transfer = ddi_prop_get_int(DDI_DEV_T_ANY, 1067507c3241Smlf dip, DDI_PROP_DONTPASS, "max_transfer", 0x100); 1068507c3241Smlf if (ata_ctlp->ac_max_transfer < 1) 1069507c3241Smlf ata_ctlp->ac_max_transfer = 1; 1070507c3241Smlf if (ata_ctlp->ac_max_transfer > 0x100) 1071507c3241Smlf ata_ctlp->ac_max_transfer = 0x100; 1072507c3241Smlf 1073507c3241Smlf /* 1074507c3241Smlf * Get the standby timer value 1075507c3241Smlf */ 1076507c3241Smlf ata_ctlp->ac_standby_time = ddi_prop_get_int(DDI_DEV_T_ANY, 1077507c3241Smlf dip, DDI_PROP_DONTPASS, "standby", -1); 1078507c3241Smlf 1079507c3241Smlf /* 1080507c3241Smlf * If this is a /pci/pci-ide instance check to see if 1081507c3241Smlf * it's supposed to be attached as an /isa/ata 1082507c3241Smlf */ 1083507c3241Smlf if (ata_ctlp->ac_pciide) { 1084507c3241Smlf static char prop_buf[] = "SUNW-ata-ffff-isa"; 1085507c3241Smlf int addr1 = (intptr_t)ioaddr1; 1086507c3241Smlf 1087507c3241Smlf 1088507c3241Smlf if (addr1 < 0 || addr1 > 0xffff) { 1089507c3241Smlf (void) ata_detach(dip, DDI_DETACH); 1090507c3241Smlf return (NULL); 1091507c3241Smlf } 1092507c3241Smlf (void) sprintf(prop_buf, "SUNW-ata-%04x-isa", 1093507c3241Smlf addr1); 1094507c3241Smlf if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(), 1095507c3241Smlf DDI_PROP_DONTPASS, prop_buf)) { 1096507c3241Smlf (void) ata_detach(dip, DDI_DETACH); 1097507c3241Smlf return (NULL); 1098507c3241Smlf } 1099507c3241Smlf } 1100507c3241Smlf 1101507c3241Smlf /* Init controller specific stuff */ 1102507c3241Smlf (void) ata_spec_init_controller(dip); 1103507c3241Smlf 1104507c3241Smlf /* 1105507c3241Smlf * initialize GHD 1106507c3241Smlf */ 1107507c3241Smlf 1108507c3241Smlf GHD_WAITQ_INIT(&ata_ctlp->ac_ccc.ccc_waitq, NULL, 1); 1109507c3241Smlf 1110507c3241Smlf if (!ghd_register("ata", &ata_ctlp->ac_ccc, dip, 0, ata_ctlp, 1111507c3241Smlf atapi_ccballoc, atapi_ccbfree, 1112507c3241Smlf ata_pciide_dma_sg_func, ata_hba_start, 1113507c3241Smlf ata_hba_complete, ata_intr, 1114507c3241Smlf ata_get_status, ata_process_intr, ata_timeout_func, 1115507c3241Smlf &ata_timer_conf, NULL)) { 1116507c3241Smlf (void) ata_detach(dip, DDI_DETACH); 1117507c3241Smlf return (NULL); 1118507c3241Smlf } 1119507c3241Smlf 1120507c3241Smlf ata_ctlp->ac_flags |= AC_GHD_INIT; 1121507c3241Smlf return (ata_ctlp); 1122507c3241Smlf } 1123507c3241Smlf 1124507c3241Smlf /* destroy a controller */ 1125507c3241Smlf 1126507c3241Smlf static void 1127507c3241Smlf ata_destroy_controller( 1128507c3241Smlf dev_info_t *dip) 1129507c3241Smlf { 1130507c3241Smlf ata_ctl_t *ata_ctlp; 1131507c3241Smlf int instance; 1132507c3241Smlf 1133507c3241Smlf ADBG_TRACE(("ata_destroy_controller entered\n")); 1134507c3241Smlf 1135507c3241Smlf instance = ddi_get_instance(dip); 1136507c3241Smlf ata_ctlp = ddi_get_soft_state(ata_state, instance); 1137507c3241Smlf 1138507c3241Smlf if (ata_ctlp == NULL) 1139507c3241Smlf return; 1140507c3241Smlf 1141507c3241Smlf /* destroy ghd */ 1142507c3241Smlf if (ata_ctlp->ac_flags & AC_GHD_INIT) 1143507c3241Smlf ghd_unregister(&ata_ctlp->ac_ccc); 1144507c3241Smlf 1145507c3241Smlf /* free the pciide buffer (if any) */ 1146507c3241Smlf ata_pciide_free(ata_ctlp); 1147507c3241Smlf 1148507c3241Smlf /* destroy controller struct */ 1149507c3241Smlf kmem_free(ata_ctlp->ac_arq_pktp, sizeof (ata_pkt_t)); 1150507c3241Smlf ddi_soft_state_free(ata_state, instance); 1151507c3241Smlf 1152507c3241Smlf } 1153507c3241Smlf 1154507c3241Smlf 1155507c3241Smlf /* 1156507c3241Smlf * 1157507c3241Smlf * initialize a drive 1158507c3241Smlf * 1159507c3241Smlf */ 1160507c3241Smlf 1161507c3241Smlf static ata_drv_t * 1162507c3241Smlf ata_init_drive( 1163507c3241Smlf ata_ctl_t *ata_ctlp, 1164507c3241Smlf uchar_t targ, 1165507c3241Smlf uchar_t lun) 1166507c3241Smlf { 1167507c3241Smlf static char nec_260[] = "NEC CD-ROM DRIVE"; 1168507c3241Smlf ata_drv_t *ata_drvp; 1169507c3241Smlf struct ata_id *aidp; 1170507c3241Smlf char buf[80]; 1171507c3241Smlf int drive_type; 1172507c3241Smlf int i; 1173507c3241Smlf int valid_version = 0; 1174507c3241Smlf 1175507c3241Smlf ADBG_TRACE(("ata_init_drive entered, targ = %d, lun = %d\n", 1176507c3241Smlf targ, lun)); 1177507c3241Smlf 1178507c3241Smlf /* check if device already exists */ 1179507c3241Smlf 1180507c3241Smlf ata_drvp = CTL2DRV(ata_ctlp, targ, lun); 1181507c3241Smlf 1182507c3241Smlf if (ata_drvp != NULL) 1183507c3241Smlf return (ata_drvp); 1184507c3241Smlf 1185507c3241Smlf /* allocate new device structure */ 1186507c3241Smlf 1187507c3241Smlf ata_drvp = kmem_zalloc(sizeof (ata_drv_t), KM_SLEEP); 1188507c3241Smlf aidp = &ata_drvp->ad_id; 1189507c3241Smlf 1190507c3241Smlf /* 1191507c3241Smlf * set up drive struct 1192507c3241Smlf */ 1193507c3241Smlf ata_drvp->ad_ctlp = ata_ctlp; 11945fb86baeSml40262 ata_drvp->ad_pciide_dma = ATA_DMA_UNINITIALIZED; 1195507c3241Smlf ata_drvp->ad_targ = targ; 1196507c3241Smlf ata_drvp->ad_drive_bits = 1197507c3241Smlf (ata_drvp->ad_targ == 0 ? ATDH_DRIVE0 : ATDH_DRIVE1); 1198507c3241Smlf /* 1199507c3241Smlf * Add the LUN for SFF-8070i support 1200507c3241Smlf */ 1201507c3241Smlf ata_drvp->ad_lun = lun; 1202507c3241Smlf ata_drvp->ad_drive_bits |= ata_drvp->ad_lun; 1203507c3241Smlf 1204507c3241Smlf /* 1205507c3241Smlf * get drive type, side effect is to collect 1206507c3241Smlf * IDENTIFY DRIVE data 1207507c3241Smlf */ 1208507c3241Smlf 1209507c3241Smlf drive_type = ata_drive_type(ata_drvp->ad_drive_bits, 1210507c3241Smlf ata_ctlp->ac_iohandle1, 1211507c3241Smlf ata_ctlp->ac_ioaddr1, 1212507c3241Smlf ata_ctlp->ac_iohandle2, 1213507c3241Smlf ata_ctlp->ac_ioaddr2, 1214507c3241Smlf aidp); 1215507c3241Smlf 1216507c3241Smlf switch (drive_type) { 1217507c3241Smlf case ATA_DEV_NONE: 1218507c3241Smlf /* no drive found */ 1219507c3241Smlf goto errout; 1220507c3241Smlf case ATA_DEV_ATAPI: 1221507c3241Smlf ata_drvp->ad_flags |= AD_ATAPI; 1222507c3241Smlf break; 1223507c3241Smlf case ATA_DEV_DISK: 1224507c3241Smlf ata_drvp->ad_flags |= AD_DISK; 1225507c3241Smlf break; 1226507c3241Smlf } 1227507c3241Smlf 1228507c3241Smlf /* 1229507c3241Smlf * swap bytes of all text fields 1230507c3241Smlf */ 1231507c3241Smlf if (!ata_strncmp(nec_260, aidp->ai_model, sizeof (aidp->ai_model))) { 1232507c3241Smlf swab(aidp->ai_drvser, aidp->ai_drvser, 1233507c3241Smlf sizeof (aidp->ai_drvser)); 1234507c3241Smlf swab(aidp->ai_fw, aidp->ai_fw, 1235507c3241Smlf sizeof (aidp->ai_fw)); 1236507c3241Smlf swab(aidp->ai_model, aidp->ai_model, 1237507c3241Smlf sizeof (aidp->ai_model)); 1238507c3241Smlf } 1239507c3241Smlf 1240507c3241Smlf /* 1241507c3241Smlf * Check if this drive has the Single Sector bug 1242507c3241Smlf */ 1243507c3241Smlf 1244507c3241Smlf if (ata_check_drive_blacklist(&ata_drvp->ad_id, ATA_BL_1SECTOR)) 1245507c3241Smlf ata_drvp->ad_flags |= AD_1SECTOR; 1246507c3241Smlf else 1247507c3241Smlf ata_drvp->ad_flags &= ~AD_1SECTOR; 1248507c3241Smlf 1249507c3241Smlf /* Check if this drive has the "revert to defaults" bug */ 1250507c3241Smlf if (!ata_check_revert_to_defaults(ata_drvp)) 1251507c3241Smlf ata_drvp->ad_flags |= AD_NORVRT; 1252507c3241Smlf 1253507c3241Smlf /* Dump the drive info */ 1254507c3241Smlf (void) strncpy(buf, aidp->ai_model, sizeof (aidp->ai_model)); 1255507c3241Smlf buf[sizeof (aidp->ai_model)-1] = '\0'; 1256507c3241Smlf for (i = sizeof (aidp->ai_model) - 2; buf[i] == ' '; i--) 1257507c3241Smlf buf[i] = '\0'; 1258507c3241Smlf 1259507c3241Smlf ATAPRT(("?\t%s device at targ %d, lun %d lastlun 0x%x\n", 1260507c3241Smlf (ATAPIDRV(ata_drvp) ? "ATAPI":"IDE"), 1261507c3241Smlf ata_drvp->ad_targ, ata_drvp->ad_lun, aidp->ai_lastlun)); 1262507c3241Smlf 1263507c3241Smlf ATAPRT(("?\tmodel %s\n", buf)); 1264507c3241Smlf 1265507c3241Smlf if (aidp->ai_majorversion != 0 && aidp->ai_majorversion != 0xffff) { 1266507c3241Smlf for (i = 14; i >= 2; i--) { 1267507c3241Smlf if (aidp->ai_majorversion & (1 << i)) { 1268507c3241Smlf valid_version = i; 1269507c3241Smlf break; 1270507c3241Smlf } 1271507c3241Smlf } 1272507c3241Smlf ATAPRT(( 1273507c3241Smlf "?\tATA/ATAPI-%d supported, majver 0x%x minver 0x%x\n", 1274507c3241Smlf valid_version, 1275507c3241Smlf aidp->ai_majorversion, 1276507c3241Smlf aidp->ai_minorversion)); 1277507c3241Smlf } 1278507c3241Smlf 1279507c3241Smlf if (ata_capability_data) { 1280507c3241Smlf 1281507c3241Smlf ATAPRT(("?\t\tstat %x, err %x\n", 1282507c3241Smlf ddi_get8(ata_ctlp->ac_iohandle2, 1283507c3241Smlf ata_ctlp->ac_altstatus), 1284507c3241Smlf ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_error))); 1285507c3241Smlf 1286507c3241Smlf ATAPRT(("?\t\tcfg 0x%x, cap 0x%x\n", 1287507c3241Smlf aidp->ai_config, 1288507c3241Smlf aidp->ai_cap)); 1289507c3241Smlf 1290507c3241Smlf /* 1291507c3241Smlf * Be aware that ATA-6 and later drives may not provide valid 1292507c3241Smlf * geometry information and other obsoleted info. 1293507c3241Smlf * Select what is printed based on supported ATA model (skip 1294507c3241Smlf * anything below ATA/ATAPI-3) 1295507c3241Smlf */ 1296507c3241Smlf 1297507c3241Smlf if (valid_version == 0 || aidp->ai_majorversion < 1298507c3241Smlf ATAC_MAJVER_6) { 1299507c3241Smlf /* 1300507c3241Smlf * Supported version less then ATA-6 1301507c3241Smlf */ 1302507c3241Smlf ATAPRT(("?\t\tcyl %d, hd %d, sec/trk %d\n", 1303507c3241Smlf aidp->ai_fixcyls, 1304507c3241Smlf aidp->ai_heads, 1305507c3241Smlf aidp->ai_sectors)); 1306507c3241Smlf } 1307507c3241Smlf ATAPRT(("?\t\tmult1 0x%x, mult2 0x%x\n", 1308507c3241Smlf aidp->ai_mult1, 1309507c3241Smlf aidp->ai_mult2)); 1310507c3241Smlf if (valid_version && aidp->ai_majorversion < ATAC_MAJVER_4) { 1311507c3241Smlf ATAPRT(( 1312507c3241Smlf "?\t\tpiomode 0x%x, dmamode 0x%x, advpiomode 0x%x\n", 1313507c3241Smlf aidp->ai_piomode, 1314507c3241Smlf aidp->ai_dmamode, 1315507c3241Smlf aidp->ai_advpiomode)); 1316507c3241Smlf } else { 1317507c3241Smlf ATAPRT(("?\t\tadvpiomode 0x%x\n", 1318507c3241Smlf aidp->ai_advpiomode)); 1319507c3241Smlf } 1320507c3241Smlf ATAPRT(("?\t\tminpio %d, minpioflow %d\n", 1321507c3241Smlf aidp->ai_minpio, 1322507c3241Smlf aidp->ai_minpioflow)); 1323507c3241Smlf if (valid_version && aidp->ai_majorversion >= ATAC_MAJVER_4 && 1324507c3241Smlf (aidp->ai_validinfo & ATAC_VALIDINFO_83)) { 1325507c3241Smlf ATAPRT(("?\t\tdwdma 0x%x, ultradma 0x%x\n", 1326507c3241Smlf aidp->ai_dworddma, 1327507c3241Smlf aidp->ai_ultradma)); 1328507c3241Smlf } else { 1329507c3241Smlf ATAPRT(("?\t\tdwdma 0x%x\n", 1330507c3241Smlf aidp->ai_dworddma)); 1331507c3241Smlf } 1332507c3241Smlf } 1333507c3241Smlf 1334507c3241Smlf if (ATAPIDRV(ata_drvp)) { 1335507c3241Smlf if (!atapi_init_drive(ata_drvp)) 1336507c3241Smlf goto errout; 1337507c3241Smlf } else { 1338507c3241Smlf if (!ata_disk_init_drive(ata_drvp)) 1339507c3241Smlf goto errout; 1340507c3241Smlf } 1341507c3241Smlf 1342507c3241Smlf /* 1343507c3241Smlf * store pointer in controller struct 1344507c3241Smlf */ 1345507c3241Smlf CTL2DRV(ata_ctlp, targ, lun) = ata_drvp; 1346507c3241Smlf 1347507c3241Smlf /* 1348507c3241Smlf * lock the drive's current settings in case I have to 1349507c3241Smlf * reset the drive due to some sort of error 1350507c3241Smlf */ 13512df1fe9cSrandyf (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0); 1352507c3241Smlf 1353507c3241Smlf return (ata_drvp); 1354507c3241Smlf 1355507c3241Smlf errout: 1356507c3241Smlf ata_uninit_drive(ata_drvp); 1357507c3241Smlf return (NULL); 1358507c3241Smlf } 1359507c3241Smlf 1360507c3241Smlf /* destroy a drive */ 1361507c3241Smlf 1362507c3241Smlf static void 1363507c3241Smlf ata_uninit_drive( 1364507c3241Smlf ata_drv_t *ata_drvp) 1365507c3241Smlf { 1366507c3241Smlf #if 0 1367507c3241Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp; 1368507c3241Smlf #endif 1369507c3241Smlf 1370507c3241Smlf ADBG_TRACE(("ata_uninit_drive entered\n")); 1371507c3241Smlf 1372507c3241Smlf #if 0 1373507c3241Smlf /* 1374507c3241Smlf * DON'T DO THIS. disabling interrupts floats the IRQ line 1375507c3241Smlf * which generates spurious interrupts 1376507c3241Smlf */ 1377507c3241Smlf 1378507c3241Smlf /* 1379507c3241Smlf * Select the correct drive 1380507c3241Smlf */ 1381507c3241Smlf ddi_put8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_drvhd, 1382507c3241Smlf ata_drvp->ad_drive_bits); 13839f49ae27Smlf ata_nsecwait(400); 1384507c3241Smlf 1385507c3241Smlf /* 1386507c3241Smlf * Disable interrupts from the drive 1387507c3241Smlf */ 1388507c3241Smlf ddi_put8(ata_ctlp->ac_iohandle2, ata_ctlp->ac_devctl, 1389507c3241Smlf (ATDC_D3 | ATDC_NIEN)); 1390507c3241Smlf #endif 1391507c3241Smlf 1392507c3241Smlf /* interface specific clean-ups */ 1393507c3241Smlf 1394507c3241Smlf if (ata_drvp->ad_flags & AD_ATAPI) 1395507c3241Smlf atapi_uninit_drive(ata_drvp); 1396507c3241Smlf else if (ata_drvp->ad_flags & AD_DISK) 1397507c3241Smlf ata_disk_uninit_drive(ata_drvp); 1398507c3241Smlf 1399507c3241Smlf /* free drive struct */ 1400507c3241Smlf 1401507c3241Smlf kmem_free(ata_drvp, sizeof (ata_drv_t)); 1402507c3241Smlf } 1403507c3241Smlf 1404507c3241Smlf 1405507c3241Smlf /* 1406507c3241Smlf * ata_drive_type() 1407507c3241Smlf * 1408507c3241Smlf * The timeout values and exact sequence of checking is critical 1409507c3241Smlf * especially for atapi device detection, and should not be changed lightly. 1410507c3241Smlf * 1411507c3241Smlf */ 1412507c3241Smlf static int 1413507c3241Smlf ata_drive_type( 1414507c3241Smlf uchar_t drvhd, 1415507c3241Smlf ddi_acc_handle_t io_hdl1, 1416507c3241Smlf caddr_t ioaddr1, 1417507c3241Smlf ddi_acc_handle_t io_hdl2, 1418507c3241Smlf caddr_t ioaddr2, 1419507c3241Smlf struct ata_id *ata_id_bufp) 1420507c3241Smlf { 1421507c3241Smlf uchar_t status; 1422507c3241Smlf 1423507c3241Smlf ADBG_TRACE(("ata_drive_type entered\n")); 1424507c3241Smlf 1425507c3241Smlf /* 1426507c3241Smlf * select the appropriate drive and LUN 1427507c3241Smlf */ 1428507c3241Smlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_DRVHD, drvhd); 14299f49ae27Smlf ata_nsecwait(400); 1430507c3241Smlf 1431507c3241Smlf /* 1432507c3241Smlf * make certain the drive is selected, and wait for not busy 1433507c3241Smlf */ 1434507c3241Smlf (void) ata_wait3(io_hdl2, ioaddr2, 0, ATS_BSY, 0x7f, 0, 0x7f, 0, 1435507c3241Smlf 5 * 1000000); 1436507c3241Smlf 1437507c3241Smlf status = ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS); 1438507c3241Smlf 1439b3c0e203Smlf if (status & ATS_BSY) { 14409f49ae27Smlf ADBG_TRACE(("ata_drive_type 0x%p 0x%x\n", ioaddr1, status)); 1441507c3241Smlf return (ATA_DEV_NONE); 1442507c3241Smlf } 1443507c3241Smlf 1444507c3241Smlf if (ata_disk_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp)) 1445507c3241Smlf return (ATA_DEV_DISK); 1446507c3241Smlf 1447507c3241Smlf /* 1448507c3241Smlf * No disk, check for atapi unit. 1449507c3241Smlf */ 1450507c3241Smlf if (!atapi_signature(io_hdl1, ioaddr1)) { 1451507c3241Smlf #ifndef ATA_DISABLE_ATAPI_1_7 1452507c3241Smlf /* 1453507c3241Smlf * Check for old (but prevalent) atapi 1.7B 1454507c3241Smlf * spec device, the only known example is the 1455507c3241Smlf * NEC CDR-260 (not 260R which is (mostly) ATAPI 1.2 1456507c3241Smlf * compliant). This device has no signature 1457507c3241Smlf * and requires conversion from hex to BCD 1458507c3241Smlf * for some scsi audio commands. 1459507c3241Smlf */ 1460507c3241Smlf if (atapi_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp)) { 1461507c3241Smlf return (ATA_DEV_ATAPI); 1462507c3241Smlf } 1463507c3241Smlf #endif 1464507c3241Smlf return (ATA_DEV_NONE); 1465507c3241Smlf } 1466507c3241Smlf 1467507c3241Smlf if (atapi_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp)) { 1468507c3241Smlf return (ATA_DEV_ATAPI); 1469507c3241Smlf } 1470507c3241Smlf 1471507c3241Smlf return (ATA_DEV_NONE); 1472507c3241Smlf 1473507c3241Smlf } 1474507c3241Smlf 1475507c3241Smlf /* 14769f49ae27Smlf * nsec-granularity time delay function 14779f49ae27Smlf */ 14789f49ae27Smlf void 14799f49ae27Smlf ata_nsecwait(clock_t count) 14809f49ae27Smlf { 14819f49ae27Smlf extern int tsc_gethrtime_initted; 14829f49ae27Smlf 14839f49ae27Smlf if (tsc_gethrtime_initted) { 14849f49ae27Smlf hrtime_t end = gethrtime() + count; 14859f49ae27Smlf 14869f49ae27Smlf while (gethrtime() < end) { 14879f49ae27Smlf SMT_PAUSE(); 14889f49ae27Smlf } 14899f49ae27Smlf } else { 14909f49ae27Smlf drv_usecwait(1 + (count / 1000)); 14919f49ae27Smlf } 14929f49ae27Smlf } 14939f49ae27Smlf 14949f49ae27Smlf 14959f49ae27Smlf /* 1496507c3241Smlf * Wait for a register of a controller to achieve a specific state. 1497507c3241Smlf * To return normally, all the bits in the first sub-mask must be ON, 1498507c3241Smlf * all the bits in the second sub-mask must be OFF. 1499507c3241Smlf * If timeout_usec microseconds pass without the controller achieving 1500507c3241Smlf * the desired bit configuration, we return TRUE, else FALSE. 1501507c3241Smlf */ 1502507c3241Smlf 1503507c3241Smlf int ata_usec_delay = 10; 1504507c3241Smlf 1505507c3241Smlf int 1506507c3241Smlf ata_wait( 1507507c3241Smlf ddi_acc_handle_t io_hdl, 1508507c3241Smlf caddr_t ioaddr, 1509507c3241Smlf uchar_t onbits, 1510507c3241Smlf uchar_t offbits, 1511507c3241Smlf uint_t timeout_usec) 1512507c3241Smlf { 1513507c3241Smlf ushort_t val; 15149f49ae27Smlf hrtime_t deadline = gethrtime() + 15159f49ae27Smlf (hrtime_t)timeout_usec * (NANOSEC / MICROSEC); 15169f49ae27Smlf 1517507c3241Smlf 1518507c3241Smlf do { 1519507c3241Smlf val = ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_ALTSTATUS); 1520507c3241Smlf if ((val & onbits) == onbits && (val & offbits) == 0) 1521507c3241Smlf return (TRUE); 1522507c3241Smlf drv_usecwait(ata_usec_delay); 15239f49ae27Smlf } while (gethrtime() < deadline); 1524507c3241Smlf 1525507c3241Smlf return (FALSE); 1526507c3241Smlf } 1527507c3241Smlf 1528507c3241Smlf 1529507c3241Smlf /* 1530507c3241Smlf * 1531507c3241Smlf * This is a slightly more complicated version that checks 1532507c3241Smlf * for error conditions and bails-out rather than looping 1533507c3241Smlf * until the timeout expires 1534507c3241Smlf */ 1535507c3241Smlf int 1536507c3241Smlf ata_wait3( 1537507c3241Smlf ddi_acc_handle_t io_hdl, 1538507c3241Smlf caddr_t ioaddr, 1539507c3241Smlf uchar_t onbits1, 1540507c3241Smlf uchar_t offbits1, 1541507c3241Smlf uchar_t failure_onbits2, 1542507c3241Smlf uchar_t failure_offbits2, 1543507c3241Smlf uchar_t failure_onbits3, 1544507c3241Smlf uchar_t failure_offbits3, 1545507c3241Smlf uint_t timeout_usec) 1546507c3241Smlf { 1547507c3241Smlf ushort_t val; 15489f49ae27Smlf hrtime_t deadline = gethrtime() + 15499f49ae27Smlf (hrtime_t)timeout_usec * (NANOSEC / MICROSEC); 1550507c3241Smlf 1551507c3241Smlf do { 1552507c3241Smlf val = ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_ALTSTATUS); 1553507c3241Smlf 1554507c3241Smlf /* 1555507c3241Smlf * check for expected condition 1556507c3241Smlf */ 1557507c3241Smlf if ((val & onbits1) == onbits1 && (val & offbits1) == 0) 1558507c3241Smlf return (TRUE); 1559507c3241Smlf 1560507c3241Smlf /* 1561507c3241Smlf * check for error conditions 1562507c3241Smlf */ 1563507c3241Smlf if ((val & failure_onbits2) == failure_onbits2 && 1564507c3241Smlf (val & failure_offbits2) == 0) { 1565507c3241Smlf return (FALSE); 1566507c3241Smlf } 1567507c3241Smlf 1568507c3241Smlf if ((val & failure_onbits3) == failure_onbits3 && 1569507c3241Smlf (val & failure_offbits3) == 0) { 1570507c3241Smlf return (FALSE); 1571507c3241Smlf } 1572507c3241Smlf 1573507c3241Smlf drv_usecwait(ata_usec_delay); 15749f49ae27Smlf } while (gethrtime() < deadline); 1575507c3241Smlf 1576507c3241Smlf return (FALSE); 1577507c3241Smlf } 1578507c3241Smlf 1579507c3241Smlf 1580507c3241Smlf /* 1581507c3241Smlf * 1582507c3241Smlf * low level routine for ata_disk_id() and atapi_id() 1583507c3241Smlf * 1584507c3241Smlf */ 1585507c3241Smlf 1586507c3241Smlf int 1587507c3241Smlf ata_id_common( 1588507c3241Smlf uchar_t id_cmd, 1589507c3241Smlf int expect_drdy, 1590507c3241Smlf ddi_acc_handle_t io_hdl1, 1591507c3241Smlf caddr_t ioaddr1, 1592507c3241Smlf ddi_acc_handle_t io_hdl2, 1593507c3241Smlf caddr_t ioaddr2, 1594507c3241Smlf struct ata_id *aidp) 1595507c3241Smlf { 1596507c3241Smlf uchar_t status; 1597507c3241Smlf 1598507c3241Smlf ADBG_TRACE(("ata_id_common entered\n")); 1599507c3241Smlf 1600507c3241Smlf bzero(aidp, sizeof (struct ata_id)); 1601507c3241Smlf 1602507c3241Smlf /* 1603507c3241Smlf * clear the features register 1604507c3241Smlf */ 1605507c3241Smlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_FEATURE, 0); 1606507c3241Smlf 1607507c3241Smlf /* 1608b3c0e203Smlf * Disable interrupts from the device. When the ata 1609b3c0e203Smlf * hardware is sharing its interrupt with another 1610b3c0e203Smlf * device, the shared interrupt might have already been 1611b3c0e203Smlf * unmasked in the interrupt controller and 16129f49ae27Smlf * triggering ata device interrupts will result in an 16139f49ae27Smlf * interrupt storm and a hung system. 1614507c3241Smlf */ 16159f49ae27Smlf ddi_put8(io_hdl2, (uchar_t *)ioaddr2 + AT_DEVCTL, ATDC_D3 | ATDC_NIEN); 1616507c3241Smlf 1617507c3241Smlf /* 1618507c3241Smlf * issue IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command 1619507c3241Smlf */ 1620507c3241Smlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_CMD, id_cmd); 1621507c3241Smlf 1622507c3241Smlf /* wait for the busy bit to settle */ 16239f49ae27Smlf ata_nsecwait(400); 1624507c3241Smlf 1625507c3241Smlf /* 1626b3c0e203Smlf * read alternate status and check for conditions which 1627b3c0e203Smlf * may indicate the drive is not present, to prevent getting 1628b3c0e203Smlf * stuck in ata_wait3() below. 1629b3c0e203Smlf */ 1630b3c0e203Smlf status = ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS); 1631b3c0e203Smlf 1632b3c0e203Smlf /* 1633b3c0e203Smlf * 0x0, 0x7f, or ATS_DF can happen when no drive is present 1634b3c0e203Smlf */ 1635b3c0e203Smlf if ((status == 0x0) || (status == 0x7f) || 1636b3c0e203Smlf ((status & (ATS_BSY|ATS_DF)) == ATS_DF)) { 1637b3c0e203Smlf /* invalid status, can't be an ATA or ATAPI device */ 1638b3c0e203Smlf return (FALSE); 1639b3c0e203Smlf } 1640b3c0e203Smlf 1641b3c0e203Smlf /* 1642507c3241Smlf * According to the ATA specification, some drives may have 1643507c3241Smlf * to read the media to complete this command. We need to 1644507c3241Smlf * make sure we give them enough time to respond. 1645507c3241Smlf */ 1646507c3241Smlf (void) ata_wait3(io_hdl2, ioaddr2, 0, ATS_BSY, 1647507c3241Smlf ATS_ERR, ATS_BSY, 0x7f, 0, 5 * 1000000); 1648507c3241Smlf 1649507c3241Smlf /* 1650507c3241Smlf * read the status byte and clear the pending interrupt 1651507c3241Smlf */ 1652b3c0e203Smlf status = ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_STATUS); 1653507c3241Smlf 1654507c3241Smlf /* 1655b3c0e203Smlf * this happens if there's no drive present 1656507c3241Smlf */ 1657b3c0e203Smlf if (status == 0xff || status == 0x7f) { 1658507c3241Smlf /* invalid status, can't be an ATA or ATAPI device */ 1659507c3241Smlf return (FALSE); 1660507c3241Smlf } 1661507c3241Smlf 1662507c3241Smlf if (status & ATS_BSY) { 1663507c3241Smlf ADBG_ERROR(("ata_id_common: BUSY status 0x%x error 0x%x\n", 1664507c3241Smlf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS), 1665507c3241Smlf ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR))); 1666507c3241Smlf return (FALSE); 1667507c3241Smlf } 1668507c3241Smlf 1669507c3241Smlf if (!(status & ATS_DRQ)) { 1670507c3241Smlf if (status & (ATS_ERR | ATS_DF)) { 1671507c3241Smlf return (FALSE); 1672507c3241Smlf } 1673507c3241Smlf /* 1674507c3241Smlf * Give the drive another second to assert DRQ. Some older 1675507c3241Smlf * drives de-assert BSY before asserting DRQ. 1676507c3241Smlf */ 1677507c3241Smlf if (!ata_wait(io_hdl2, ioaddr2, ATS_DRQ, ATS_BSY, 1000000)) { 1678507c3241Smlf ADBG_WARN(("ata_id_common: !DRQ status 0x%x error 0x%x\n", 1679507c3241Smlf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS), 1680507c3241Smlf ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR))); 1681507c3241Smlf return (FALSE); 1682507c3241Smlf } 1683507c3241Smlf } 1684507c3241Smlf 1685507c3241Smlf /* 1686507c3241Smlf * transfer the data 1687507c3241Smlf */ 1688507c3241Smlf ddi_rep_get16(io_hdl1, (ushort_t *)aidp, (ushort_t *)ioaddr1 + AT_DATA, 1689507c3241Smlf NBPSCTR >> 1, DDI_DEV_NO_AUTOINCR); 1690507c3241Smlf 1691507c3241Smlf /* wait for the busy bit to settle */ 16929f49ae27Smlf ata_nsecwait(400); 1693507c3241Smlf 1694507c3241Smlf 1695507c3241Smlf /* 1696507c3241Smlf * Wait for the drive to recognize I've read all the data. 1697507c3241Smlf * Some drives have been observed to take as much as 3msec to 1698507c3241Smlf * deassert DRQ after reading the data; allow 10 msec just in case. 1699507c3241Smlf * 1700507c3241Smlf * Note: some non-compliant ATAPI drives (e.g., NEC Multispin 6V, 1701507c3241Smlf * CDR-1350A) don't assert DRDY. If we've made it this far we can 1702507c3241Smlf * safely ignore the DRDY bit since the ATAPI Packet command 1703507c3241Smlf * actually doesn't require it to ever be asserted. 1704507c3241Smlf * 1705507c3241Smlf */ 1706507c3241Smlf if (!ata_wait(io_hdl2, ioaddr2, (uchar_t)(expect_drdy ? ATS_DRDY : 0), 1707507c3241Smlf (ATS_BSY | ATS_DRQ), 1000000)) { 1708507c3241Smlf ADBG_WARN(("ata_id_common: bad status 0x%x error 0x%x\n", 1709507c3241Smlf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS), 1710507c3241Smlf ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR))); 1711507c3241Smlf return (FALSE); 1712507c3241Smlf } 1713507c3241Smlf 1714507c3241Smlf /* 1715507c3241Smlf * Check to see if the command aborted. This happens if 1716507c3241Smlf * an IDENTIFY DEVICE command is issued to an ATAPI PACKET device, 1717507c3241Smlf * or if an IDENTIFY PACKET DEVICE command is issued to an ATA 1718507c3241Smlf * (non-PACKET) device. 1719507c3241Smlf */ 1720507c3241Smlf if (status & (ATS_DF | ATS_ERR)) { 1721507c3241Smlf ADBG_WARN(("ata_id_common: status 0x%x error 0x%x \n", 1722507c3241Smlf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS), 1723507c3241Smlf ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR))); 1724507c3241Smlf return (FALSE); 1725507c3241Smlf } 1726507c3241Smlf return (TRUE); 1727507c3241Smlf } 1728507c3241Smlf 1729507c3241Smlf 1730507c3241Smlf /* 1731507c3241Smlf * Low level routine to issue a non-data command and busy wait for 1732507c3241Smlf * the completion status. 1733507c3241Smlf */ 1734507c3241Smlf 1735507c3241Smlf int 1736507c3241Smlf ata_command( 1737507c3241Smlf ata_ctl_t *ata_ctlp, 1738507c3241Smlf ata_drv_t *ata_drvp, 1739507c3241Smlf int expect_drdy, 1740507c3241Smlf int silent, 1741507c3241Smlf uint_t busy_wait, 1742507c3241Smlf uchar_t cmd, 1743507c3241Smlf uchar_t feature, 1744507c3241Smlf uchar_t count, 1745507c3241Smlf uchar_t sector, 1746507c3241Smlf uchar_t head, 1747507c3241Smlf uchar_t cyl_low, 1748507c3241Smlf uchar_t cyl_hi) 1749507c3241Smlf { 1750507c3241Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1; 1751507c3241Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2; 1752507c3241Smlf uchar_t status; 1753507c3241Smlf 1754507c3241Smlf /* select the drive */ 1755507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits); 17569f49ae27Smlf ata_nsecwait(400); 1757507c3241Smlf 1758507c3241Smlf /* make certain the drive selected */ 1759507c3241Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 1760507c3241Smlf (uchar_t)(expect_drdy ? ATS_DRDY : 0), 1761507c3241Smlf ATS_BSY, busy_wait)) { 1762507c3241Smlf ADBG_ERROR(("ata_command: select failed " 1763507c3241Smlf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x " 1764507c3241Smlf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", 1765507c3241Smlf expect_drdy, cmd, feature, count, 1766507c3241Smlf sector, head, cyl_low, cyl_hi)); 1767507c3241Smlf return (FALSE); 1768507c3241Smlf } 1769507c3241Smlf 1770507c3241Smlf /* 1771507c3241Smlf * set all the regs 1772507c3241Smlf */ 1773507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, (head | ata_drvp->ad_drive_bits)); 1774507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, sector); 1775507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, count); 1776507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, cyl_low); 1777507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, cyl_hi); 1778507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_feature, feature); 1779507c3241Smlf 1780507c3241Smlf /* send the command */ 1781507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, cmd); 1782507c3241Smlf 1783507c3241Smlf /* wait for the busy bit to settle */ 17849f49ae27Smlf ata_nsecwait(400); 1785507c3241Smlf 1786507c3241Smlf /* wait for not busy */ 1787507c3241Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, busy_wait)) { 1788507c3241Smlf ADBG_ERROR(("ata_command: BSY too long!" 1789507c3241Smlf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x " 1790507c3241Smlf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", 1791507c3241Smlf expect_drdy, cmd, feature, count, 1792507c3241Smlf sector, head, cyl_low, cyl_hi)); 1793507c3241Smlf return (FALSE); 1794507c3241Smlf } 1795507c3241Smlf 1796507c3241Smlf /* 1797507c3241Smlf * wait for DRDY before continuing 1798507c3241Smlf */ 1799507c3241Smlf (void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2, 1800507c3241Smlf ATS_DRDY, ATS_BSY, /* okay */ 1801507c3241Smlf ATS_ERR, ATS_BSY, /* cmd failed */ 1802507c3241Smlf ATS_DF, ATS_BSY, /* drive failed */ 1803507c3241Smlf busy_wait); 1804507c3241Smlf 1805507c3241Smlf /* read status to clear IRQ, and check for error */ 1806507c3241Smlf status = ddi_get8(io_hdl1, ata_ctlp->ac_status); 1807507c3241Smlf 1808507c3241Smlf if ((status & (ATS_BSY | ATS_DF | ATS_ERR)) == 0) 1809507c3241Smlf return (TRUE); 1810507c3241Smlf 1811507c3241Smlf if (!silent) { 1812507c3241Smlf ADBG_ERROR(("ata_command status 0x%x error 0x%x " 1813507c3241Smlf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x " 1814507c3241Smlf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", 1815507c3241Smlf ddi_get8(io_hdl1, ata_ctlp->ac_status), 1816507c3241Smlf ddi_get8(io_hdl1, ata_ctlp->ac_error), 1817507c3241Smlf expect_drdy, cmd, feature, count, 1818507c3241Smlf sector, head, cyl_low, cyl_hi)); 1819507c3241Smlf } 1820507c3241Smlf return (FALSE); 1821507c3241Smlf } 1822507c3241Smlf 1823507c3241Smlf 1824507c3241Smlf 1825507c3241Smlf /* 1826507c3241Smlf * 1827507c3241Smlf * Issue a SET FEATURES command 1828507c3241Smlf * 1829507c3241Smlf */ 1830507c3241Smlf 1831507c3241Smlf int 1832507c3241Smlf ata_set_feature( 1833507c3241Smlf ata_ctl_t *ata_ctlp, 1834507c3241Smlf ata_drv_t *ata_drvp, 1835507c3241Smlf uchar_t feature, 1836507c3241Smlf uchar_t value) 1837507c3241Smlf { 1838507c3241Smlf int rc; 1839507c3241Smlf 1840507c3241Smlf rc = ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, ata_set_feature_wait, 1841507c3241Smlf ATC_SET_FEAT, feature, value, 0, 0, 0, 0); 1842507c3241Smlf /* feature, count, sector, head, cyl_low, cyl_hi */ 1843507c3241Smlf 1844507c3241Smlf if (rc) { 1845507c3241Smlf return (TRUE); 1846507c3241Smlf } 1847507c3241Smlf 1848507c3241Smlf ADBG_ERROR(("?ata_set_feature: (0x%x,0x%x) failed\n", feature, value)); 1849507c3241Smlf return (FALSE); 1850507c3241Smlf } 1851507c3241Smlf 1852507c3241Smlf 1853507c3241Smlf 1854507c3241Smlf /* 1855507c3241Smlf * 1856507c3241Smlf * Issue a FLUSH CACHE command 1857507c3241Smlf * 1858507c3241Smlf */ 1859507c3241Smlf 1860507c3241Smlf static int 1861507c3241Smlf ata_flush_cache( 1862507c3241Smlf ata_ctl_t *ata_ctlp, 1863507c3241Smlf ata_drv_t *ata_drvp) 1864507c3241Smlf { 1865507c3241Smlf /* this command is optional so fail silently */ 1866507c3241Smlf return (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 1867507c3241Smlf ata_flush_cache_wait, 1868507c3241Smlf ATC_FLUSH_CACHE, 0, 0, 0, 0, 0, 0)); 1869507c3241Smlf } 1870507c3241Smlf 1871507c3241Smlf /* 1872507c3241Smlf * ata_setup_ioaddr() 1873507c3241Smlf * 1874507c3241Smlf * Map the device registers and return the handles. 1875507c3241Smlf * 1876507c3241Smlf * If this is a ISA-ATA controller then only two handles are 1877507c3241Smlf * initialized and returned. 1878507c3241Smlf * 1879507c3241Smlf * If this is a PCI-IDE controller than a third handle (for the 1880507c3241Smlf * PCI-IDE Bus Mastering registers) is initialized and returned. 1881507c3241Smlf * 1882507c3241Smlf */ 1883507c3241Smlf 1884507c3241Smlf static int 1885507c3241Smlf ata_setup_ioaddr( 1886507c3241Smlf dev_info_t *dip, 1887507c3241Smlf ddi_acc_handle_t *handle1p, 1888507c3241Smlf caddr_t *addr1p, 1889507c3241Smlf ddi_acc_handle_t *handle2p, 1890507c3241Smlf caddr_t *addr2p, 1891507c3241Smlf ddi_acc_handle_t *bm_hdlp, 1892507c3241Smlf caddr_t *bm_addrp) 1893507c3241Smlf { 1894507c3241Smlf ddi_device_acc_attr_t dev_attr; 1895507c3241Smlf int rnumber; 1896507c3241Smlf int rc; 1897507c3241Smlf off_t regsize; 1898507c3241Smlf 1899507c3241Smlf /* 1900507c3241Smlf * Make certain the controller is enabled and its regs are map-able 1901507c3241Smlf * 1902507c3241Smlf */ 1903507c3241Smlf rc = ddi_dev_regsize(dip, 0, ®size); 1904507c3241Smlf if (rc != DDI_SUCCESS || regsize <= AT_CMD) { 1905507c3241Smlf ADBG_INIT(("ata_setup_ioaddr(1): rc %d regsize %lld\n", 1906507c3241Smlf rc, (long long)regsize)); 1907507c3241Smlf return (FALSE); 1908507c3241Smlf } 1909507c3241Smlf 1910507c3241Smlf rc = ddi_dev_regsize(dip, 1, ®size); 1911507c3241Smlf if (rc != DDI_SUCCESS || regsize <= AT_ALTSTATUS) { 1912507c3241Smlf ADBG_INIT(("ata_setup_ioaddr(2): rc %d regsize %lld\n", 1913507c3241Smlf rc, (long long)regsize)); 1914507c3241Smlf return (FALSE); 1915507c3241Smlf } 1916507c3241Smlf 1917507c3241Smlf /* 1918507c3241Smlf * setup the device attribute structure for little-endian, 1919507c3241Smlf * strict ordering access. 1920507c3241Smlf */ 1921507c3241Smlf dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1922507c3241Smlf dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 1923507c3241Smlf dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1924507c3241Smlf 1925507c3241Smlf *handle1p = NULL; 1926507c3241Smlf *handle2p = NULL; 1927507c3241Smlf *bm_hdlp = NULL; 1928507c3241Smlf 1929507c3241Smlf /* 1930507c3241Smlf * Determine whether this is a ISA, PNP-ISA, or PCI-IDE device 1931507c3241Smlf */ 1932507c3241Smlf if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "pnp-csn")) { 1933507c3241Smlf /* it's PNP-ISA, skip over the extra reg tuple */ 1934507c3241Smlf rnumber = 1; 1935507c3241Smlf goto not_pciide; 1936507c3241Smlf } 1937507c3241Smlf 1938507c3241Smlf /* else, it's ISA or PCI-IDE, check further */ 1939507c3241Smlf rnumber = 0; 1940507c3241Smlf 19412df1fe9cSrandyf if (!ata_is_pci(dip)) { 1942507c3241Smlf /* 1943507c3241Smlf * If it's not a PCI-IDE, there are only two reg tuples 1944507c3241Smlf * and the first one contains the I/O base (170 or 1f0) 1945507c3241Smlf * rather than the controller instance number. 1946507c3241Smlf */ 1947507c3241Smlf ADBG_TRACE(("ata_setup_ioaddr !pci-ide\n")); 1948507c3241Smlf goto not_pciide; 1949507c3241Smlf } 1950507c3241Smlf 1951507c3241Smlf 1952507c3241Smlf /* 1953507c3241Smlf * Map the correct half of the PCI-IDE Bus Master registers. 1954507c3241Smlf * There's a single BAR that maps these registers for both 1955507c3241Smlf * controller's in a dual-controller chip and it's upto my 1956507c3241Smlf * parent nexus, pciide, to adjust which (based on my instance 1957507c3241Smlf * number) half this call maps. 1958507c3241Smlf */ 1959507c3241Smlf rc = ddi_dev_regsize(dip, 2, ®size); 1960507c3241Smlf if (rc != DDI_SUCCESS || regsize < 8) { 1961507c3241Smlf ADBG_INIT(("ata_setup_ioaddr(3): rc %d regsize %lld\n", 1962507c3241Smlf rc, (long long)regsize)); 1963507c3241Smlf goto not_pciide; 1964507c3241Smlf } 1965507c3241Smlf 1966507c3241Smlf rc = ddi_regs_map_setup(dip, 2, bm_addrp, 0, 0, &dev_attr, bm_hdlp); 1967507c3241Smlf 1968507c3241Smlf if (rc != DDI_SUCCESS) { 1969507c3241Smlf /* map failed, try to use in non-pci-ide mode */ 1970507c3241Smlf ADBG_WARN(("ata_setup_ioaddr bus master map failed, rc=0x%x\n", 1971507c3241Smlf rc)); 1972507c3241Smlf *bm_hdlp = NULL; 1973507c3241Smlf } 1974507c3241Smlf 1975507c3241Smlf not_pciide: 1976507c3241Smlf /* 1977507c3241Smlf * map the lower command block registers 1978507c3241Smlf */ 1979507c3241Smlf 1980507c3241Smlf rc = ddi_regs_map_setup(dip, rnumber, addr1p, 0, 0, &dev_attr, 1981507c3241Smlf handle1p); 1982507c3241Smlf 1983507c3241Smlf if (rc != DDI_SUCCESS) { 1984507c3241Smlf cmn_err(CE_WARN, "ata: reg tuple 0 map failed, rc=0x%x\n", rc); 1985507c3241Smlf goto out1; 1986507c3241Smlf } 1987507c3241Smlf 1988507c3241Smlf /* 1989507c3241Smlf * If the controller is being used in compatibility mode 1990507c3241Smlf * via /devices/isa/ata@1,{1f0,1f0}/..., the reg property 1991507c3241Smlf * will specify zeros for the I/O ports for the PCI 1992507c3241Smlf * instance. 1993507c3241Smlf */ 1994507c3241Smlf if (*addr1p == 0) { 1995507c3241Smlf ADBG_TRACE(("ata_setup_ioaddr ioaddr1 0\n")); 1996507c3241Smlf goto out2; 1997507c3241Smlf } 1998507c3241Smlf 1999507c3241Smlf /* 2000507c3241Smlf * map the upper control block registers 2001507c3241Smlf */ 2002507c3241Smlf rc = ddi_regs_map_setup(dip, rnumber + 1, addr2p, 0, 0, &dev_attr, 2003507c3241Smlf handle2p); 2004507c3241Smlf if (rc == DDI_SUCCESS) 2005507c3241Smlf return (TRUE); 2006507c3241Smlf 2007507c3241Smlf cmn_err(CE_WARN, "ata: reg tuple 1 map failed, rc=0x%x", rc); 2008507c3241Smlf 2009507c3241Smlf out2: 2010507c3241Smlf if (*handle1p != NULL) { 2011507c3241Smlf ddi_regs_map_free(handle1p); 2012507c3241Smlf *handle1p = NULL; 2013507c3241Smlf } 2014507c3241Smlf 2015507c3241Smlf out1: 2016507c3241Smlf if (*bm_hdlp != NULL) { 2017507c3241Smlf ddi_regs_map_free(bm_hdlp); 2018507c3241Smlf *bm_hdlp = NULL; 2019507c3241Smlf } 2020507c3241Smlf return (FALSE); 2021507c3241Smlf 2022507c3241Smlf } 2023507c3241Smlf 2024507c3241Smlf /* 2025507c3241Smlf * 2026507c3241Smlf * Currently, the only supported controllers are ones which 2027507c3241Smlf * support the SFF-8038 Bus Mastering spec. 2028507c3241Smlf * 2029507c3241Smlf * Check the parent node's IEEE 1275 class-code property to 2030507c3241Smlf * determine if it's an PCI-IDE instance which supports SFF-8038 2031507c3241Smlf * Bus Mastering. It's perfectly valid to have a PCI-IDE controller 2032507c3241Smlf * that doesn't do Bus Mastering. In that case, my interrupt handler 2033507c3241Smlf * only uses the interrupt latch bit in PCI-IDE status register. 2034507c3241Smlf * The assumption is that the programming interface byte of the 2035507c3241Smlf * class-code property reflects the bus master DMA capability of 2036507c3241Smlf * the controller. 2037507c3241Smlf * 2038507c3241Smlf * Whether the drive support supports the DMA option still needs 2039507c3241Smlf * to be checked later. Each individual request also has to be 2040507c3241Smlf * checked for alignment and size to decide whether to use the 2041507c3241Smlf * DMA transfer mode. 2042507c3241Smlf */ 2043507c3241Smlf 2044507c3241Smlf static void 2045507c3241Smlf ata_init_pciide( 2046507c3241Smlf dev_info_t *dip, 2047507c3241Smlf ata_ctl_t *ata_ctlp) 2048507c3241Smlf { 2049507c3241Smlf uint_t class_code; 2050507c3241Smlf uchar_t status; 2051507c3241Smlf 2052507c3241Smlf ata_cntrl_DMA_sel_msg = NULL; 2053507c3241Smlf 2054507c3241Smlf if (ata_ctlp->ac_bmhandle == NULL) { 2055507c3241Smlf ata_ctlp->ac_pciide = FALSE; 2056507c3241Smlf ata_ctlp->ac_pciide_bm = FALSE; 2057507c3241Smlf ata_cntrl_DMA_sel_msg = "cntrl not Bus Master DMA capable"; 2058507c3241Smlf return; 2059507c3241Smlf } 2060507c3241Smlf 2061507c3241Smlf /* 2062507c3241Smlf * check if it's a known bogus PCI-IDE chip 2063507c3241Smlf */ 2064507c3241Smlf if (ata_check_pciide_blacklist(dip, ATA_BL_BOGUS)) { 2065507c3241Smlf ADBG_WARN(("ata_setup_ioaddr pci-ide blacklist\n")); 2066507c3241Smlf ata_ctlp->ac_pciide = FALSE; 2067507c3241Smlf ata_ctlp->ac_pciide_bm = FALSE; 2068507c3241Smlf ata_cntrl_DMA_sel_msg = "cntrl blacklisted"; 2069507c3241Smlf return; 2070507c3241Smlf } 2071507c3241Smlf ata_ctlp->ac_pciide = TRUE; 2072507c3241Smlf 2073507c3241Smlf if (ata_check_pciide_blacklist(dip, ATA_BL_BMSTATREG_PIO_BROKEN)) { 2074507c3241Smlf ata_ctlp->ac_flags |= AC_BMSTATREG_PIO_BROKEN; 2075507c3241Smlf } 2076507c3241Smlf 2077507c3241Smlf /* 2078507c3241Smlf * check for a PCI-IDE chip with a broken DMA engine 2079507c3241Smlf */ 2080507c3241Smlf if (ata_check_pciide_blacklist(dip, ATA_BL_NODMA)) { 2081507c3241Smlf ata_ctlp->ac_pciide_bm = FALSE; 2082507c3241Smlf ata_cntrl_DMA_sel_msg = 2083507c3241Smlf "cntrl blacklisted/DMA engine broken"; 2084507c3241Smlf return; 2085507c3241Smlf } 2086507c3241Smlf 2087507c3241Smlf /* 2088507c3241Smlf * Check the Programming Interface register to determine 2089507c3241Smlf * if this device supports PCI-IDE Bus Mastering. Some PCI-IDE 2090507c3241Smlf * devices don't support Bus Mastering or DMA. 2091507c3241Smlf * Since we are dealing with pre-qualified pci-ide controller, 2092507c3241Smlf * check programming interface byte only. 2093507c3241Smlf */ 2094507c3241Smlf 2095507c3241Smlf class_code = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), 2096507c3241Smlf DDI_PROP_DONTPASS, "class-code", 0); 2097507c3241Smlf if ((class_code & PCIIDE_BM_CAP_MASK) != PCIIDE_BM_CAP_MASK) { 2098507c3241Smlf ata_ctlp->ac_pciide_bm = FALSE; 2099507c3241Smlf ata_cntrl_DMA_sel_msg = 2100507c3241Smlf "cntrl not Bus Master DMA capable"; 2101507c3241Smlf return; 2102507c3241Smlf } 2103507c3241Smlf 2104507c3241Smlf /* 2105507c3241Smlf * Avoid doing DMA on "simplex" chips which share hardware 2106507c3241Smlf * between channels 2107507c3241Smlf */ 2108507c3241Smlf status = ddi_get8(ata_ctlp->ac_bmhandle, 2109507c3241Smlf (uchar_t *)ata_ctlp->ac_bmaddr + PCIIDE_BMISX_REG); 2110507c3241Smlf /* 2111507c3241Smlf * Some motherboards have CSB5's that are wired "to emulate CSB4 mode". 2112507c3241Smlf * In such a mode, the simplex bit is asserted, but in fact testing 2113507c3241Smlf * on such a motherboard has shown that the devices are not simplex 2114507c3241Smlf * -- DMA can be used on both channels concurrently with no special 2115507c3241Smlf * considerations. For chips like this, we have the ATA_BL_NO_SIMPLEX 2116507c3241Smlf * flag set to indicate that the value of the simplex bit can be 2117507c3241Smlf * ignored. 2118507c3241Smlf */ 2119507c3241Smlf 2120507c3241Smlf if (status & PCIIDE_BMISX_SIMPLEX) { 2121507c3241Smlf if (ata_check_pciide_blacklist(dip, ATA_BL_NO_SIMPLEX)) { 2122507c3241Smlf cmn_err(CE_WARN, "Ignoring false simplex bit \n"); 2123d39757aaSmlf 2124507c3241Smlf } else { 2125d39757aaSmlf 2126d39757aaSmlf int simplex_dma_channel, *rp, proplen, channel; 2127d39757aaSmlf int dma_on = FALSE; 2128d39757aaSmlf 2129d39757aaSmlf /* 2130d39757aaSmlf * By default,use DMA on channel 0 and PIO on channel 2131d39757aaSmlf * 1. This can be switched by setting 2132d39757aaSmlf * ata-simplex-dma-channel to: 2133d39757aaSmlf * 0 DMA on channel 0 (default without this 2134d39757aaSmlf * property) 2135d39757aaSmlf * 1 DMA on channel 1 2136d39757aaSmlf * any other value: DMA off on both channels. 2137d39757aaSmlf */ 2138d39757aaSmlf simplex_dma_channel = ata_prop_lookup_int(DDI_DEV_T_ANY, 2139d39757aaSmlf ata_ctlp->ac_dip, 0, "ata-simplex-dma-channel", 0); 2140d39757aaSmlf 2141d39757aaSmlf if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, 2142d39757aaSmlf ata_ctlp->ac_dip, DDI_PROP_DONTPASS, "reg", &rp, 2143d39757aaSmlf (uint_t *)&proplen) == DDI_PROP_SUCCESS) { 2144d39757aaSmlf 2145d39757aaSmlf channel = *rp; 2146d39757aaSmlf ddi_prop_free(rp); 2147d39757aaSmlf 2148d39757aaSmlf if (simplex_dma_channel == channel) { 2149ab4f33c9Sml40262 cmn_err(CE_CONT, "?ata: simplex " 2150d39757aaSmlf "controller. DMA on channel" 2151ab4f33c9Sml40262 " %d PIO on channel %d", 2152d39757aaSmlf channel, channel ? 0:1); 2153d39757aaSmlf dma_on = TRUE; 2154d39757aaSmlf } else { 2155507c3241Smlf ata_cntrl_DMA_sel_msg = 2156d39757aaSmlf "simplex controller"; 2157d39757aaSmlf } 2158d39757aaSmlf } 2159d39757aaSmlf 2160d39757aaSmlf if (dma_on == FALSE) { 2161d39757aaSmlf ata_ctlp->ac_pciide_bm = FALSE; 2162d39757aaSmlf 2163507c3241Smlf return; 2164507c3241Smlf } 2165507c3241Smlf } 2166d39757aaSmlf } 2167507c3241Smlf 2168507c3241Smlf /* 2169507c3241Smlf * It's a compatible PCI-IDE Bus Mastering controller, 2170507c3241Smlf * allocate and map the DMA Scatter/Gather list (PRDE table). 2171507c3241Smlf */ 2172507c3241Smlf if (ata_pciide_alloc(dip, ata_ctlp)) 2173507c3241Smlf ata_ctlp->ac_pciide_bm = TRUE; 2174507c3241Smlf else { 2175507c3241Smlf ata_ctlp->ac_pciide_bm = FALSE; 2176507c3241Smlf ata_cntrl_DMA_sel_msg = "unable to init DMA S/G list"; 2177507c3241Smlf } 2178507c3241Smlf } 2179507c3241Smlf 2180507c3241Smlf /* 2181507c3241Smlf * 2182507c3241Smlf * Determine whether to enable DMA support for this drive. 2183507c3241Smlf * The controller and the drive both have to support DMA. 2184507c3241Smlf * The controller's capabilities were already checked in 2185507c3241Smlf * ata_init_pciide(), now just check the drive's capabilities. 2186507c3241Smlf * 2187507c3241Smlf */ 2188507c3241Smlf 2189507c3241Smlf static int 2190507c3241Smlf ata_init_drive_pcidma( 2191507c3241Smlf ata_ctl_t *ata_ctlp, 2192507c3241Smlf ata_drv_t *ata_drvp, 2193507c3241Smlf dev_info_t *tdip) 2194507c3241Smlf { 2195507c3241Smlf boolean_t dma; 2196507c3241Smlf boolean_t cd_dma; 2197507c3241Smlf boolean_t disk_dma; 2198507c3241Smlf boolean_t atapi_dma; 2199507c3241Smlf int ata_options; 2200507c3241Smlf 2201507c3241Smlf ata_dev_DMA_sel_msg = NULL; 2202507c3241Smlf 2203507c3241Smlf if (ata_ctlp->ac_pciide_bm != TRUE) { 2204507c3241Smlf ata_dev_DMA_sel_msg = 2205507c3241Smlf "controller is not Bus Master capable"; 2206507c3241Smlf 2207507c3241Smlf return (ATA_DMA_OFF); 2208507c3241Smlf } 2209507c3241Smlf 2210507c3241Smlf ata_options = ddi_prop_get_int(DDI_DEV_T_ANY, ata_ctlp->ac_dip, 2211507c3241Smlf 0, "ata-options", 0); 2212507c3241Smlf 2213507c3241Smlf if (!(ata_options & ATA_OPTIONS_DMA)) { 2214507c3241Smlf /* 2215507c3241Smlf * Either the ata-options property was not found or 2216507c3241Smlf * DMA is not enabled by this property 2217507c3241Smlf */ 2218507c3241Smlf ata_dev_DMA_sel_msg = 2219507c3241Smlf "disabled by \"ata-options\" property"; 2220507c3241Smlf 2221507c3241Smlf return (ATA_DMA_OFF); 2222507c3241Smlf } 2223507c3241Smlf 2224507c3241Smlf if (ata_check_drive_blacklist(&ata_drvp->ad_id, ATA_BL_NODMA)) { 2225507c3241Smlf ata_dev_DMA_sel_msg = "device not DMA capable; blacklisted"; 2226507c3241Smlf 2227507c3241Smlf return (ATA_DMA_OFF); 2228507c3241Smlf } 2229507c3241Smlf 2230507c3241Smlf /* 2231507c3241Smlf * DMA mode is mandatory on ATA-3 (or newer) drives but is 2232507c3241Smlf * optional on ATA-2 (or older) drives. 2233507c3241Smlf * 2234507c3241Smlf * On ATA-2 drives the ai_majorversion word will probably 2235507c3241Smlf * be 0xffff or 0x0000, check the (now obsolete) DMA bit in 2236507c3241Smlf * the capabilities word instead. The order of these tests 2237507c3241Smlf * is important since an ATA-3 drive doesn't have to set 2238507c3241Smlf * the DMA bit in the capabilities word. 2239507c3241Smlf * 2240507c3241Smlf */ 2241507c3241Smlf 2242507c3241Smlf if (!((ata_drvp->ad_id.ai_majorversion & 0x8000) == 0 && 2243507c3241Smlf ata_drvp->ad_id.ai_majorversion >= (1 << 2)) && 2244507c3241Smlf !(ata_drvp->ad_id.ai_cap & ATAC_DMA_SUPPORT)) { 2245507c3241Smlf ata_dev_DMA_sel_msg = "device not DMA capable"; 2246507c3241Smlf 2247507c3241Smlf return (ATA_DMA_OFF); 2248507c3241Smlf } 2249507c3241Smlf 2250f304523cSzhongyan gu - Sun Microsystems - Beijing China /* 2251f304523cSzhongyan gu - Sun Microsystems - Beijing China * Disable DMA for ATAPI devices on controllers known to 2252f304523cSzhongyan gu - Sun Microsystems - Beijing China * have trouble with ATAPI DMA 2253f304523cSzhongyan gu - Sun Microsystems - Beijing China */ 2254f304523cSzhongyan gu - Sun Microsystems - Beijing China 2255f304523cSzhongyan gu - Sun Microsystems - Beijing China if (ATAPIDRV(ata_drvp)) { 2256f304523cSzhongyan gu - Sun Microsystems - Beijing China if (ata_check_pciide_blacklist(ata_ctlp->ac_dip, 2257f304523cSzhongyan gu - Sun Microsystems - Beijing China ATA_BL_ATAPI_NODMA)) { 2258f304523cSzhongyan gu - Sun Microsystems - Beijing China ata_dev_DMA_sel_msg = 2259f304523cSzhongyan gu - Sun Microsystems - Beijing China "controller incapable of DMA for ATAPI device"; 2260f304523cSzhongyan gu - Sun Microsystems - Beijing China 2261f304523cSzhongyan gu - Sun Microsystems - Beijing China return (ATA_DMA_OFF); 2262f304523cSzhongyan gu - Sun Microsystems - Beijing China } 2263f304523cSzhongyan gu - Sun Microsystems - Beijing China } 2264507c3241Smlf dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip, 2265507c3241Smlf 0, "ata-dma-enabled", TRUE); 2266507c3241Smlf disk_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip, 2267507c3241Smlf 0, "ata-disk-dma-enabled", TRUE); 2268507c3241Smlf cd_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip, 2269507c3241Smlf 0, "atapi-cd-dma-enabled", FALSE); 2270507c3241Smlf atapi_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip, 2271507c3241Smlf 0, "atapi-other-dma-enabled", TRUE); 2272507c3241Smlf 2273507c3241Smlf if (dma == FALSE) { 2274507c3241Smlf cmn_err(CE_CONT, "?ata_init_drive_pcidma: " 2275507c3241Smlf "DMA disabled by \"ata-dma-enabled\" property"); 2276507c3241Smlf ata_dev_DMA_sel_msg = "disabled by prop ata-dma-enabled"; 2277507c3241Smlf 2278507c3241Smlf return (ATA_DMA_OFF); 2279507c3241Smlf } 2280507c3241Smlf 2281507c3241Smlf if (IS_CDROM(ata_drvp) == TRUE) { 2282507c3241Smlf if (cd_dma == FALSE) { 2283507c3241Smlf ata_dev_DMA_sel_msg = 2284507c3241Smlf "disabled. Control with \"atapi-cd-dma-enabled\"" 2285507c3241Smlf " property"; 2286507c3241Smlf 2287507c3241Smlf return (ATA_DMA_OFF); 2288507c3241Smlf } 2289507c3241Smlf 2290507c3241Smlf } else if (ATAPIDRV(ata_drvp) == FALSE) { 2291507c3241Smlf if (disk_dma == FALSE) { 2292507c3241Smlf ata_dev_DMA_sel_msg = 2293507c3241Smlf "disabled by \"ata-disk-dma-enabled\" property"; 2294507c3241Smlf 2295507c3241Smlf return (ATA_DMA_OFF); 2296507c3241Smlf } 2297507c3241Smlf 2298507c3241Smlf } else if (atapi_dma == FALSE) { 2299507c3241Smlf ata_dev_DMA_sel_msg = 2300507c3241Smlf "disabled by \"atapi-other-dma-enabled\" property"; 2301507c3241Smlf 2302507c3241Smlf return (ATA_DMA_OFF); 2303507c3241Smlf } 2304507c3241Smlf 2305507c3241Smlf return (ATA_DMA_ON); 2306507c3241Smlf } 2307507c3241Smlf 2308507c3241Smlf 2309507c3241Smlf 2310507c3241Smlf /* 2311507c3241Smlf * this compare routine squeezes out extra blanks and 2312507c3241Smlf * returns TRUE if p1 matches the leftmost substring of p2 2313507c3241Smlf */ 2314507c3241Smlf 2315507c3241Smlf static int 2316507c3241Smlf ata_strncmp( 2317507c3241Smlf char *p1, 2318507c3241Smlf char *p2, 2319507c3241Smlf int cnt) 2320507c3241Smlf { 2321507c3241Smlf 2322507c3241Smlf for (;;) { 2323507c3241Smlf /* 2324507c3241Smlf * skip over any extra blanks in both strings 2325507c3241Smlf */ 2326507c3241Smlf while (*p1 != '\0' && *p1 == ' ') 2327507c3241Smlf p1++; 2328507c3241Smlf 2329507c3241Smlf while (cnt != 0 && *p2 == ' ') { 2330507c3241Smlf p2++; 2331507c3241Smlf cnt--; 2332507c3241Smlf } 2333507c3241Smlf 2334507c3241Smlf /* 2335507c3241Smlf * compare the two strings 2336507c3241Smlf */ 2337507c3241Smlf 2338507c3241Smlf if (cnt == 0 || *p1 != *p2) 2339507c3241Smlf break; 2340507c3241Smlf 2341507c3241Smlf while (cnt > 0 && *p1 == *p2) { 2342507c3241Smlf p1++; 2343507c3241Smlf p2++; 2344507c3241Smlf cnt--; 2345507c3241Smlf } 2346507c3241Smlf 2347507c3241Smlf } 2348507c3241Smlf 2349507c3241Smlf /* return TRUE if both strings ended at same point */ 2350507c3241Smlf return ((*p1 == '\0') ? TRUE : FALSE); 2351507c3241Smlf } 2352507c3241Smlf 2353507c3241Smlf /* 2354507c3241Smlf * Per PSARC/1997/281 create variant="atapi" property (if necessary) 2355507c3241Smlf * on the target's dev_info node. Currently, the sd target driver 2356507c3241Smlf * is the only driver which refers to this property. 2357507c3241Smlf * 2358507c3241Smlf * If the flag ata_id_debug is set also create the 2359507c3241Smlf * the "ata" or "atapi" property on the target's dev_info node 2360507c3241Smlf * 2361507c3241Smlf */ 2362507c3241Smlf 2363507c3241Smlf int 2364507c3241Smlf ata_prop_create( 2365507c3241Smlf dev_info_t *tgt_dip, 2366507c3241Smlf ata_drv_t *ata_drvp, 2367507c3241Smlf char *name) 2368507c3241Smlf { 2369507c3241Smlf int rc; 2370507c3241Smlf 2371507c3241Smlf ADBG_TRACE(("ata_prop_create 0x%p 0x%p %s\n", tgt_dip, ata_drvp, name)); 2372507c3241Smlf 2373507c3241Smlf if (strcmp("atapi", name) == 0) { 2374507c3241Smlf rc = ndi_prop_update_string(DDI_DEV_T_NONE, tgt_dip, 2375507c3241Smlf "variant", name); 2376507c3241Smlf if (rc != DDI_PROP_SUCCESS) 2377507c3241Smlf return (FALSE); 2378507c3241Smlf } 2379507c3241Smlf 2380507c3241Smlf if (!ata_id_debug) 2381507c3241Smlf return (TRUE); 2382507c3241Smlf 2383507c3241Smlf rc = ndi_prop_update_byte_array(DDI_DEV_T_NONE, tgt_dip, name, 2384507c3241Smlf (uchar_t *)&ata_drvp->ad_id, sizeof (ata_drvp->ad_id)); 2385507c3241Smlf if (rc != DDI_PROP_SUCCESS) { 2386507c3241Smlf ADBG_ERROR(("ata_prop_create failed, rc=%d\n", rc)); 2387507c3241Smlf } 2388507c3241Smlf return (TRUE); 2389507c3241Smlf } 2390507c3241Smlf 2391507c3241Smlf 2392507c3241Smlf /* *********************************************************************** */ 2393507c3241Smlf /* *********************************************************************** */ 2394507c3241Smlf /* *********************************************************************** */ 2395507c3241Smlf 2396507c3241Smlf /* 2397507c3241Smlf * This state machine doesn't implement the ATAPI Optional Overlap 2398507c3241Smlf * feature. You need that feature to efficiently support ATAPI 2399507c3241Smlf * tape drives. See the 1394-ATA Tailgate spec (D97107), Figure 24, 2400507c3241Smlf * for an example of how to add the necessary additional NextActions 2401507c3241Smlf * and NextStates to this FSM and the atapi_fsm, in order to support 2402507c3241Smlf * the Overlap Feature. 2403507c3241Smlf */ 2404507c3241Smlf 2405507c3241Smlf 2406507c3241Smlf uchar_t ata_ctlr_fsm_NextAction[ATA_CTLR_NSTATES][ATA_CTLR_NFUNCS] = { 2407507c3241Smlf /* --------------------- next action --------------------- | - current - */ 2408507c3241Smlf /* start0 --- start1 ---- intr ------ fini --- reset --- */ 2409507c3241Smlf { AC_START, AC_START, AC_NADA, AC_NADA, AC_RESET_I }, /* idle */ 2410507c3241Smlf { AC_BUSY, AC_BUSY, AC_INTR, AC_FINI, AC_RESET_A }, /* active0 */ 2411507c3241Smlf { AC_BUSY, AC_BUSY, AC_INTR, AC_FINI, AC_RESET_A }, /* active1 */ 2412507c3241Smlf }; 2413507c3241Smlf 2414507c3241Smlf uchar_t ata_ctlr_fsm_NextState[ATA_CTLR_NSTATES][ATA_CTLR_NFUNCS] = { 2415507c3241Smlf 2416507c3241Smlf /* --------------------- next state --------------------- | - current - */ 2417507c3241Smlf /* start0 --- start1 ---- intr ------ fini --- reset --- */ 2418507c3241Smlf { AS_ACTIVE0, AS_ACTIVE1, AS_IDLE, AS_IDLE, AS_IDLE }, /* idle */ 2419507c3241Smlf { AS_ACTIVE0, AS_ACTIVE0, AS_ACTIVE0, AS_IDLE, AS_ACTIVE0 }, /* active0 */ 2420507c3241Smlf { AS_ACTIVE1, AS_ACTIVE1, AS_ACTIVE1, AS_IDLE, AS_ACTIVE1 }, /* active1 */ 2421507c3241Smlf }; 2422507c3241Smlf 2423507c3241Smlf 2424507c3241Smlf static int 2425507c3241Smlf ata_ctlr_fsm( 2426507c3241Smlf uchar_t fsm_func, 2427507c3241Smlf ata_ctl_t *ata_ctlp, 2428507c3241Smlf ata_drv_t *ata_drvp, 2429507c3241Smlf ata_pkt_t *ata_pktp, 2430507c3241Smlf int *DoneFlgp) 2431507c3241Smlf { 2432507c3241Smlf uchar_t action; 2433507c3241Smlf uchar_t current_state; 2434507c3241Smlf uchar_t next_state; 2435507c3241Smlf int rc; 2436507c3241Smlf 2437507c3241Smlf current_state = ata_ctlp->ac_state; 2438507c3241Smlf action = ata_ctlr_fsm_NextAction[current_state][fsm_func]; 2439507c3241Smlf next_state = ata_ctlr_fsm_NextState[current_state][fsm_func]; 2440507c3241Smlf 2441507c3241Smlf /* 2442507c3241Smlf * Set the controller's new state 2443507c3241Smlf */ 2444507c3241Smlf ata_ctlp->ac_state = next_state; 2445507c3241Smlf switch (action) { 2446507c3241Smlf 2447507c3241Smlf case AC_BUSY: 2448507c3241Smlf return (ATA_FSM_RC_BUSY); 2449507c3241Smlf 2450507c3241Smlf case AC_NADA: 2451507c3241Smlf return (ATA_FSM_RC_OKAY); 2452507c3241Smlf 2453507c3241Smlf case AC_START: 2454507c3241Smlf ASSERT(ata_ctlp->ac_active_pktp == NULL); 2455507c3241Smlf ASSERT(ata_ctlp->ac_active_drvp == NULL); 2456507c3241Smlf 2457507c3241Smlf ata_ctlp->ac_active_pktp = ata_pktp; 2458507c3241Smlf ata_ctlp->ac_active_drvp = ata_drvp; 2459507c3241Smlf 2460507c3241Smlf rc = (*ata_pktp->ap_start)(ata_ctlp, ata_drvp, ata_pktp); 2461507c3241Smlf 2462507c3241Smlf if (rc == ATA_FSM_RC_BUSY) { 2463507c3241Smlf /* the request didn't start, GHD will requeue it */ 2464507c3241Smlf ata_ctlp->ac_state = AS_IDLE; 2465507c3241Smlf ata_ctlp->ac_active_pktp = NULL; 2466507c3241Smlf ata_ctlp->ac_active_drvp = NULL; 2467507c3241Smlf } 2468507c3241Smlf return (rc); 2469507c3241Smlf 2470507c3241Smlf case AC_INTR: 2471507c3241Smlf ASSERT(ata_ctlp->ac_active_pktp != NULL); 2472507c3241Smlf ASSERT(ata_ctlp->ac_active_drvp != NULL); 2473507c3241Smlf 2474507c3241Smlf ata_drvp = ata_ctlp->ac_active_drvp; 2475507c3241Smlf ata_pktp = ata_ctlp->ac_active_pktp; 2476507c3241Smlf return ((*ata_pktp->ap_intr)(ata_ctlp, ata_drvp, ata_pktp)); 2477507c3241Smlf 2478507c3241Smlf case AC_RESET_A: /* Reset, controller active */ 2479507c3241Smlf ASSERT(ata_ctlp->ac_active_pktp != NULL); 2480507c3241Smlf ASSERT(ata_ctlp->ac_active_drvp != NULL); 2481507c3241Smlf 2482507c3241Smlf /* clean up the active request */ 2483507c3241Smlf ata_pktp = ata_ctlp->ac_active_pktp; 2484507c3241Smlf ata_pktp->ap_flags |= AP_DEV_RESET | AP_BUS_RESET; 2485507c3241Smlf 2486507c3241Smlf /* halt the DMA engine */ 2487507c3241Smlf if (ata_pktp->ap_pciide_dma) { 2488507c3241Smlf ata_pciide_dma_stop(ata_ctlp); 2489507c3241Smlf (void) ata_pciide_status_clear(ata_ctlp); 2490507c3241Smlf } 2491507c3241Smlf 2492507c3241Smlf /* Do a Software Reset to unwedge the bus */ 2493507c3241Smlf if (!ata_software_reset(ata_ctlp)) { 2494507c3241Smlf return (ATA_FSM_RC_BUSY); 2495507c3241Smlf } 2496507c3241Smlf 2497507c3241Smlf /* Then send a DEVICE RESET cmd to each ATAPI device */ 2498507c3241Smlf atapi_fsm_reset(ata_ctlp); 2499507c3241Smlf return (ATA_FSM_RC_FINI); 2500507c3241Smlf 2501507c3241Smlf case AC_RESET_I: /* Reset, controller idle */ 2502507c3241Smlf /* Do a Software Reset to unwedge the bus */ 2503507c3241Smlf if (!ata_software_reset(ata_ctlp)) { 2504507c3241Smlf return (ATA_FSM_RC_BUSY); 2505507c3241Smlf } 2506507c3241Smlf 2507507c3241Smlf /* Then send a DEVICE RESET cmd to each ATAPI device */ 2508507c3241Smlf atapi_fsm_reset(ata_ctlp); 2509507c3241Smlf return (ATA_FSM_RC_OKAY); 2510507c3241Smlf 2511507c3241Smlf case AC_FINI: 2512507c3241Smlf break; 2513507c3241Smlf } 2514507c3241Smlf 2515507c3241Smlf /* 2516507c3241Smlf * AC_FINI, check ARQ needs to be started or finished 2517507c3241Smlf */ 2518507c3241Smlf 2519507c3241Smlf ASSERT(action == AC_FINI); 2520507c3241Smlf ASSERT(ata_ctlp->ac_active_pktp != NULL); 2521507c3241Smlf ASSERT(ata_ctlp->ac_active_drvp != NULL); 2522507c3241Smlf 2523507c3241Smlf /* 2524507c3241Smlf * The active request is done now. 2525507c3241Smlf * Disconnect the request from the controller and 2526507c3241Smlf * add it to the done queue. 2527507c3241Smlf */ 2528507c3241Smlf ata_drvp = ata_ctlp->ac_active_drvp; 2529507c3241Smlf ata_pktp = ata_ctlp->ac_active_pktp; 2530507c3241Smlf 2531507c3241Smlf /* 2532507c3241Smlf * If ARQ pkt is done, get ptr to original pkt and wrap it up. 2533507c3241Smlf */ 2534507c3241Smlf if (ata_pktp == ata_ctlp->ac_arq_pktp) { 2535507c3241Smlf ata_pkt_t *arq_pktp; 2536507c3241Smlf 2537507c3241Smlf ADBG_ARQ(("ata_ctlr_fsm 0x%p ARQ done\n", ata_ctlp)); 2538507c3241Smlf 2539507c3241Smlf arq_pktp = ata_pktp; 2540507c3241Smlf ata_pktp = ata_ctlp->ac_fault_pktp; 2541507c3241Smlf ata_ctlp->ac_fault_pktp = NULL; 2542507c3241Smlf if (arq_pktp->ap_flags & (AP_ERROR | AP_BUS_RESET)) 2543507c3241Smlf ata_pktp->ap_flags |= AP_ARQ_ERROR; 2544507c3241Smlf else 2545507c3241Smlf ata_pktp->ap_flags |= AP_ARQ_OKAY; 2546507c3241Smlf goto all_done; 2547507c3241Smlf } 2548507c3241Smlf 2549507c3241Smlf 2550507c3241Smlf #define AP_ARQ_NEEDED (AP_ARQ_ON_ERROR | AP_GOT_STATUS | AP_ERROR) 2551507c3241Smlf 2552507c3241Smlf /* 2553507c3241Smlf * Start ARQ pkt if necessary 2554507c3241Smlf */ 2555507c3241Smlf if ((ata_pktp->ap_flags & AP_ARQ_NEEDED) == AP_ARQ_NEEDED && 2556507c3241Smlf (ata_pktp->ap_status & ATS_ERR)) { 2557507c3241Smlf 2558507c3241Smlf /* set controller state back to active */ 2559507c3241Smlf ata_ctlp->ac_state = current_state; 2560507c3241Smlf 2561507c3241Smlf /* try to start the ARQ pkt */ 2562507c3241Smlf rc = ata_start_arq(ata_ctlp, ata_drvp, ata_pktp); 2563507c3241Smlf 2564507c3241Smlf if (rc == ATA_FSM_RC_BUSY) { 2565507c3241Smlf ADBG_ARQ(("ata_ctlr_fsm 0x%p ARQ BUSY\n", ata_ctlp)); 2566507c3241Smlf /* let the target driver handle the problem */ 2567507c3241Smlf ata_ctlp->ac_state = AS_IDLE; 2568507c3241Smlf ata_ctlp->ac_active_pktp = NULL; 2569507c3241Smlf ata_ctlp->ac_active_drvp = NULL; 2570507c3241Smlf ata_ctlp->ac_fault_pktp = NULL; 2571507c3241Smlf goto all_done; 2572507c3241Smlf } 2573507c3241Smlf 2574507c3241Smlf ADBG_ARQ(("ata_ctlr_fsm 0x%p ARQ started\n", ata_ctlp)); 2575507c3241Smlf return (rc); 2576507c3241Smlf } 2577507c3241Smlf 2578507c3241Smlf /* 2579507c3241Smlf * Normal completion, no error status, and not an ARQ pkt, 2580507c3241Smlf * just fall through. 2581507c3241Smlf */ 2582507c3241Smlf 2583507c3241Smlf all_done: 2584507c3241Smlf 2585507c3241Smlf /* 2586507c3241Smlf * wrap everything up and tie a ribbon around it 2587507c3241Smlf */ 2588507c3241Smlf ata_ctlp->ac_active_pktp = NULL; 2589507c3241Smlf ata_ctlp->ac_active_drvp = NULL; 2590507c3241Smlf if (APKT2GCMD(ata_pktp) != (gcmd_t *)0) { 2591507c3241Smlf ghd_complete(&ata_ctlp->ac_ccc, APKT2GCMD(ata_pktp)); 2592507c3241Smlf if (DoneFlgp) 2593507c3241Smlf *DoneFlgp = TRUE; 2594507c3241Smlf } 2595507c3241Smlf 2596507c3241Smlf return (ATA_FSM_RC_OKAY); 2597507c3241Smlf } 2598507c3241Smlf 2599507c3241Smlf 2600507c3241Smlf static int 2601507c3241Smlf ata_start_arq( 2602507c3241Smlf ata_ctl_t *ata_ctlp, 2603507c3241Smlf ata_drv_t *ata_drvp, 2604507c3241Smlf ata_pkt_t *ata_pktp) 2605507c3241Smlf { 2606507c3241Smlf ata_pkt_t *arq_pktp; 2607507c3241Smlf int bytes; 2608507c3241Smlf uint_t senselen; 2609507c3241Smlf 2610507c3241Smlf ADBG_ARQ(("ata_start_arq 0x%p ARQ needed\n", ata_ctlp)); 2611507c3241Smlf 2612507c3241Smlf /* 2613507c3241Smlf * Determine just the size of the Request Sense Data buffer within 2614507c3241Smlf * the scsi_arq_status structure. 2615507c3241Smlf */ 2616507c3241Smlf #define SIZEOF_ARQ_HEADER (sizeof (struct scsi_arq_status) \ 2617507c3241Smlf - sizeof (struct scsi_extended_sense)) 2618507c3241Smlf senselen = ata_pktp->ap_statuslen - SIZEOF_ARQ_HEADER; 2619507c3241Smlf ASSERT(senselen > 0); 2620507c3241Smlf 2621507c3241Smlf 2622507c3241Smlf /* save ptr to original pkt */ 2623507c3241Smlf ata_ctlp->ac_fault_pktp = ata_pktp; 2624507c3241Smlf 2625507c3241Smlf /* switch the controller's active pkt to the ARQ pkt */ 2626507c3241Smlf arq_pktp = ata_ctlp->ac_arq_pktp; 2627507c3241Smlf ata_ctlp->ac_active_pktp = arq_pktp; 2628507c3241Smlf 2629507c3241Smlf /* finish initializing the ARQ CDB */ 2630507c3241Smlf ata_ctlp->ac_arq_cdb[1] = ata_drvp->ad_lun << 4; 2631f304523cSzhongyan gu - Sun Microsystems - Beijing China ata_ctlp->ac_arq_cdb[4] = (uchar_t)senselen; 2632507c3241Smlf 2633507c3241Smlf /* finish initializing the ARQ pkt */ 2634507c3241Smlf arq_pktp->ap_v_addr = (caddr_t)&ata_pktp->ap_scbp->sts_sensedata; 2635507c3241Smlf 2636507c3241Smlf arq_pktp->ap_resid = senselen; 2637507c3241Smlf arq_pktp->ap_flags = AP_ATAPI | AP_READ; 2638507c3241Smlf arq_pktp->ap_cdb_pad = 2639507c3241Smlf ((unsigned)(ata_drvp->ad_cdb_len - arq_pktp->ap_cdb_len)) >> 1; 2640507c3241Smlf 2641507c3241Smlf bytes = min(senselen, ATAPI_MAX_BYTES_PER_DRQ); 2642507c3241Smlf arq_pktp->ap_hicyl = (uchar_t)(bytes >> 8); 2643507c3241Smlf arq_pktp->ap_lwcyl = (uchar_t)bytes; 2644507c3241Smlf 2645507c3241Smlf /* 2646507c3241Smlf * This packet is shared by all drives on this controller 2647507c3241Smlf * therefore we need to init the drive number on every ARQ. 2648507c3241Smlf */ 2649507c3241Smlf arq_pktp->ap_hd = ata_drvp->ad_drive_bits; 2650507c3241Smlf 2651507c3241Smlf /* start it up */ 2652507c3241Smlf return ((*arq_pktp->ap_start)(ata_ctlp, ata_drvp, arq_pktp)); 2653507c3241Smlf } 2654507c3241Smlf 2655507c3241Smlf /* 2656507c3241Smlf * 2657507c3241Smlf * reset the bus 2658507c3241Smlf * 2659507c3241Smlf */ 2660507c3241Smlf 2661507c3241Smlf static int 2662507c3241Smlf ata_reset_bus( 2663507c3241Smlf ata_ctl_t *ata_ctlp) 2664507c3241Smlf { 2665507c3241Smlf int watchdog; 2666507c3241Smlf uchar_t drive; 2667507c3241Smlf int rc = FALSE; 2668507c3241Smlf uchar_t fsm_func; 2669507c3241Smlf int DoneFlg = FALSE; 2670507c3241Smlf 2671507c3241Smlf /* 2672507c3241Smlf * Do a Software Reset to unwedge the bus, and send 2673507c3241Smlf * ATAPI DEVICE RESET to each ATAPI drive. 2674507c3241Smlf */ 2675507c3241Smlf fsm_func = ATA_FSM_RESET; 2676507c3241Smlf for (watchdog = ata_reset_bus_watchdog; watchdog > 0; watchdog--) { 2677507c3241Smlf switch (ata_ctlr_fsm(fsm_func, ata_ctlp, NULL, NULL, 2678507c3241Smlf &DoneFlg)) { 2679507c3241Smlf case ATA_FSM_RC_OKAY: 2680507c3241Smlf rc = TRUE; 2681507c3241Smlf goto fsm_done; 2682507c3241Smlf 2683507c3241Smlf case ATA_FSM_RC_BUSY: 2684507c3241Smlf return (FALSE); 2685507c3241Smlf 2686507c3241Smlf case ATA_FSM_RC_INTR: 2687507c3241Smlf fsm_func = ATA_FSM_INTR; 2688507c3241Smlf rc = TRUE; 2689507c3241Smlf continue; 2690507c3241Smlf 2691507c3241Smlf case ATA_FSM_RC_FINI: 2692507c3241Smlf fsm_func = ATA_FSM_FINI; 2693507c3241Smlf rc = TRUE; 2694507c3241Smlf continue; 2695507c3241Smlf } 2696507c3241Smlf } 2697507c3241Smlf ADBG_WARN(("ata_reset_bus: watchdog\n")); 2698507c3241Smlf 2699507c3241Smlf fsm_done: 2700507c3241Smlf 2701507c3241Smlf /* 2702507c3241Smlf * Reinitialize the ATA drives 2703507c3241Smlf */ 2704507c3241Smlf for (drive = 0; drive < ATA_MAXTARG; drive++) { 2705507c3241Smlf ata_drv_t *ata_drvp; 2706507c3241Smlf 2707507c3241Smlf if ((ata_drvp = CTL2DRV(ata_ctlp, drive, 0)) == NULL) 2708507c3241Smlf continue; 2709507c3241Smlf 2710507c3241Smlf if (ATAPIDRV(ata_drvp)) 2711507c3241Smlf continue; 2712507c3241Smlf 2713507c3241Smlf /* 2714507c3241Smlf * Reprogram the Read/Write Multiple block factor 2715507c3241Smlf * and current geometry into the drive. 2716507c3241Smlf */ 2717507c3241Smlf if (!ata_disk_setup_parms(ata_ctlp, ata_drvp)) 2718507c3241Smlf rc = FALSE; 2719507c3241Smlf } 2720507c3241Smlf 2721507c3241Smlf /* If DoneFlg is TRUE, it means that ghd_complete() function */ 2722507c3241Smlf /* has been already called. In this case ignore any errors and */ 2723507c3241Smlf /* return TRUE to the caller, otherwise return the value of rc */ 2724507c3241Smlf /* to the caller */ 2725507c3241Smlf if (DoneFlg) 2726507c3241Smlf return (TRUE); 2727507c3241Smlf else 2728507c3241Smlf return (rc); 2729507c3241Smlf } 2730507c3241Smlf 2731507c3241Smlf 2732507c3241Smlf /* 2733507c3241Smlf * 2734507c3241Smlf * Low level routine to toggle the Software Reset bit 2735507c3241Smlf * 2736507c3241Smlf */ 2737507c3241Smlf 2738507c3241Smlf static int 2739507c3241Smlf ata_software_reset( 2740507c3241Smlf ata_ctl_t *ata_ctlp) 2741507c3241Smlf { 2742507c3241Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1; 2743507c3241Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2; 27449f49ae27Smlf hrtime_t deadline; 27459f49ae27Smlf uint_t usecs_left; 2746507c3241Smlf 2747507c3241Smlf ADBG_TRACE(("ata_reset_bus entered\n")); 2748507c3241Smlf 2749507c3241Smlf /* disable interrupts and turn the software reset bit on */ 2750507c3241Smlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3 | ATDC_SRST)); 2751507c3241Smlf 2752507c3241Smlf /* why 30 milliseconds, the ATA/ATAPI-4 spec says 5 usec. */ 2753507c3241Smlf drv_usecwait(30000); 2754507c3241Smlf 2755507c3241Smlf /* turn the software reset bit back off */ 2756507c3241Smlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, ATDC_D3); 2757507c3241Smlf 2758507c3241Smlf /* 2759507c3241Smlf * Wait for the controller to assert BUSY status. 2760507c3241Smlf * I don't think 300 msecs is correct. The ATA/ATAPI-4 2761507c3241Smlf * spec says 400 nsecs, (and 2 msecs if device 2762507c3241Smlf * was in sleep mode; but we don't put drives to sleep 2763507c3241Smlf * so it probably doesn't matter). 2764507c3241Smlf */ 2765507c3241Smlf drv_usecwait(300000); 2766507c3241Smlf 2767507c3241Smlf /* 2768507c3241Smlf * If drive 0 exists the test for completion is simple 2769507c3241Smlf */ 27709f49ae27Smlf deadline = gethrtime() + ((hrtime_t)31 * NANOSEC); 27719f49ae27Smlf 2772507c3241Smlf if (CTL2DRV(ata_ctlp, 0, 0)) { 2773507c3241Smlf goto wait_for_not_busy; 2774507c3241Smlf } 2775507c3241Smlf 2776507c3241Smlf ASSERT(CTL2DRV(ata_ctlp, 1, 0) != NULL); 2777507c3241Smlf 2778507c3241Smlf /* 2779507c3241Smlf * This must be a single device configuration, with drive 1 2780507c3241Smlf * only. This complicates the test for completion because 2781507c3241Smlf * issuing the software reset just caused drive 1 to 2782507c3241Smlf * deselect. With drive 1 deselected, if I just read the 2783507c3241Smlf * status register to test the BSY bit I get garbage, but 2784507c3241Smlf * I can't re-select drive 1 until I'm certain the BSY bit 2785507c3241Smlf * is de-asserted. Catch-22. 2786507c3241Smlf * 2787507c3241Smlf * In ATA/ATAPI-4, rev 15, section 9.16.2, it says to handle 2788507c3241Smlf * this situation like this: 2789507c3241Smlf */ 2790507c3241Smlf 2791507c3241Smlf /* give up if the drive doesn't settle within 31 seconds */ 27929f49ae27Smlf while (gethrtime() < deadline) { 2793507c3241Smlf /* 2794507c3241Smlf * delay 10msec each time around the loop 2795507c3241Smlf */ 2796507c3241Smlf drv_usecwait(10000); 2797507c3241Smlf 2798507c3241Smlf /* 2799507c3241Smlf * try to select drive 1 2800507c3241Smlf */ 2801507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ATDH_DRIVE1); 2802507c3241Smlf 2803507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, 0x55); 2804507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, 0xaa); 2805507c3241Smlf if (ddi_get8(io_hdl1, ata_ctlp->ac_sect) != 0xaa) 2806507c3241Smlf continue; 2807507c3241Smlf 2808507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, 0x55); 2809507c3241Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, 0xaa); 2810507c3241Smlf if (ddi_get8(io_hdl1, ata_ctlp->ac_count) != 0xaa) 2811507c3241Smlf continue; 2812507c3241Smlf 2813507c3241Smlf goto wait_for_not_busy; 2814507c3241Smlf } 2815507c3241Smlf return (FALSE); 2816507c3241Smlf 2817507c3241Smlf wait_for_not_busy: 2818507c3241Smlf 2819507c3241Smlf /* 2820507c3241Smlf * Now wait up to 31 seconds for BUSY to clear. 2821507c3241Smlf */ 28229f49ae27Smlf usecs_left = (deadline - gethrtime()) / 1000; 2823507c3241Smlf (void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, 28249f49ae27Smlf ATS_ERR, ATS_BSY, ATS_DF, ATS_BSY, usecs_left); 2825507c3241Smlf 2826507c3241Smlf return (TRUE); 2827507c3241Smlf } 2828507c3241Smlf 2829507c3241Smlf /* 2830507c3241Smlf * 2831507c3241Smlf * DDI interrupt handler 2832507c3241Smlf * 2833507c3241Smlf */ 2834507c3241Smlf 2835507c3241Smlf static uint_t 2836507c3241Smlf ata_intr( 2837507c3241Smlf caddr_t arg) 2838507c3241Smlf { 2839507c3241Smlf ata_ctl_t *ata_ctlp; 2840507c3241Smlf int one_shot = 1; 2841507c3241Smlf 2842507c3241Smlf ata_ctlp = (ata_ctl_t *)arg; 2843507c3241Smlf 2844507c3241Smlf return (ghd_intr(&ata_ctlp->ac_ccc, (void *)&one_shot)); 2845507c3241Smlf } 2846507c3241Smlf 2847507c3241Smlf 2848507c3241Smlf /* 2849507c3241Smlf * 2850507c3241Smlf * GHD ccc_get_status callback 2851507c3241Smlf * 2852507c3241Smlf */ 2853507c3241Smlf 2854507c3241Smlf static int 2855507c3241Smlf ata_get_status( 2856507c3241Smlf void *hba_handle, 2857507c3241Smlf void *intr_status) 2858507c3241Smlf { 2859507c3241Smlf ata_ctl_t *ata_ctlp = (ata_ctl_t *)hba_handle; 2860507c3241Smlf uchar_t status; 2861507c3241Smlf 2862507c3241Smlf ADBG_TRACE(("ata_get_status entered\n")); 2863507c3241Smlf 2864507c3241Smlf /* 2865507c3241Smlf * ignore interrupts before ata_attach completes 2866507c3241Smlf */ 2867507c3241Smlf if (!(ata_ctlp->ac_flags & AC_ATTACHED)) 2868507c3241Smlf return (FALSE); 2869507c3241Smlf 2870507c3241Smlf /* 2871507c3241Smlf * can't be interrupt pending if nothing active 2872507c3241Smlf */ 2873507c3241Smlf switch (ata_ctlp->ac_state) { 2874507c3241Smlf case AS_IDLE: 2875507c3241Smlf return (FALSE); 2876507c3241Smlf case AS_ACTIVE0: 2877507c3241Smlf case AS_ACTIVE1: 2878507c3241Smlf ASSERT(ata_ctlp->ac_active_drvp != NULL); 2879507c3241Smlf ASSERT(ata_ctlp->ac_active_pktp != NULL); 2880507c3241Smlf break; 2881507c3241Smlf } 2882507c3241Smlf 2883507c3241Smlf /* 2884507c3241Smlf * If this is a PCI-IDE controller, check the PCI-IDE controller's 2885507c3241Smlf * interrupt status latch. But don't clear it yet. 2886507c3241Smlf * 2887507c3241Smlf * AC_BMSTATREG_PIO_BROKEN flag is used currently for 2888507c3241Smlf * CMD chips with device id 0x646. Since the interrupt bit on 2889507c3241Smlf * Bus master IDE register is not usable when in PIO mode, 2890507c3241Smlf * this chip is treated as a legacy device for interrupt 2891507c3241Smlf * indication. The following code for CMD 2892507c3241Smlf * chips may need to be revisited when we enable support for dma. 2893507c3241Smlf * 2894507c3241Smlf * CHANGE: DMA is not disabled for these devices. BM intr bit is 2895507c3241Smlf * checked only if there was DMA used or BM intr is useable on PIO, 2896507c3241Smlf * else treat it as before - as legacy device. 2897507c3241Smlf */ 2898507c3241Smlf 2899507c3241Smlf if ((ata_ctlp->ac_pciide) && 2900507c3241Smlf ((ata_ctlp->ac_pciide_bm != FALSE) && 2901507c3241Smlf ((ata_ctlp->ac_active_pktp->ap_pciide_dma == TRUE) || 2902507c3241Smlf !(ata_ctlp->ac_flags & AC_BMSTATREG_PIO_BROKEN)))) { 2903507c3241Smlf 2904507c3241Smlf if (!ata_pciide_status_pending(ata_ctlp)) 2905507c3241Smlf return (FALSE); 2906507c3241Smlf } else { 2907507c3241Smlf /* 2908507c3241Smlf * Interrupts from legacy ATA/IDE controllers are 2909507c3241Smlf * edge-triggered but the dumb legacy ATA/IDE controllers 2910507c3241Smlf * and drives don't have an interrupt status bit. 2911507c3241Smlf * 2912507c3241Smlf * Use a one_shot variable to make sure we only return 2913507c3241Smlf * one status per interrupt. 2914507c3241Smlf */ 2915507c3241Smlf if (intr_status != NULL) { 2916507c3241Smlf int *one_shot = (int *)intr_status; 2917507c3241Smlf 2918507c3241Smlf if (*one_shot == 1) 2919507c3241Smlf *one_shot = 0; 2920507c3241Smlf else 2921507c3241Smlf return (FALSE); 2922507c3241Smlf } 2923507c3241Smlf } 2924507c3241Smlf 2925507c3241Smlf /* check if device is still busy */ 2926507c3241Smlf 2927507c3241Smlf status = ddi_get8(ata_ctlp->ac_iohandle2, ata_ctlp->ac_altstatus); 2928507c3241Smlf if (status & ATS_BSY) 2929507c3241Smlf return (FALSE); 2930507c3241Smlf return (TRUE); 2931507c3241Smlf } 2932507c3241Smlf 2933507c3241Smlf 2934507c3241Smlf /* 2935507c3241Smlf * 2936507c3241Smlf * get the current status and clear the IRQ 2937507c3241Smlf * 2938507c3241Smlf */ 2939507c3241Smlf 2940507c3241Smlf int 2941507c3241Smlf ata_get_status_clear_intr( 2942507c3241Smlf ata_ctl_t *ata_ctlp, 2943507c3241Smlf ata_pkt_t *ata_pktp) 2944507c3241Smlf { 2945507c3241Smlf uchar_t status; 2946507c3241Smlf 2947507c3241Smlf /* 2948507c3241Smlf * Here's where we clear the PCI-IDE interrupt latch. If this 2949507c3241Smlf * request used DMA mode then we also have to check and clear 2950507c3241Smlf * the DMA error latch at the same time. 2951507c3241Smlf */ 2952507c3241Smlf 2953507c3241Smlf if (ata_pktp->ap_pciide_dma) { 2954507c3241Smlf if (ata_pciide_status_dmacheck_clear(ata_ctlp)) 2955507c3241Smlf ata_pktp->ap_flags |= AP_ERROR | AP_TRAN_ERROR; 2956507c3241Smlf } else if ((ata_ctlp->ac_pciide) && 2957507c3241Smlf !(ata_ctlp->ac_flags & AC_BMSTATREG_PIO_BROKEN)) { 2958507c3241Smlf /* 2959507c3241Smlf * Some requests don't use DMA mode and therefore won't 2960507c3241Smlf * set the DMA error latch, but we still have to clear 2961507c3241Smlf * the interrupt latch. 2962507c3241Smlf * Controllers with broken BM intr in PIO mode do not go 2963507c3241Smlf * through this path. 2964507c3241Smlf */ 2965507c3241Smlf (void) ata_pciide_status_clear(ata_ctlp); 2966507c3241Smlf } 2967507c3241Smlf 2968507c3241Smlf /* 2969507c3241Smlf * this clears the drive's interrupt 2970507c3241Smlf */ 2971507c3241Smlf status = ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_status); 2972507c3241Smlf ADBG_TRACE(("ata_get_status_clear_intr: 0x%x\n", status)); 2973507c3241Smlf return (status); 2974507c3241Smlf } 2975507c3241Smlf 2976507c3241Smlf 2977507c3241Smlf 2978507c3241Smlf /* 2979507c3241Smlf * 2980507c3241Smlf * GHD interrupt handler 2981507c3241Smlf * 2982507c3241Smlf */ 2983507c3241Smlf 2984507c3241Smlf /* ARGSUSED */ 2985507c3241Smlf static void 2986507c3241Smlf ata_process_intr( 2987507c3241Smlf void *hba_handle, 2988507c3241Smlf void *intr_status) 2989507c3241Smlf { 2990507c3241Smlf ata_ctl_t *ata_ctlp = (ata_ctl_t *)hba_handle; 2991507c3241Smlf int watchdog; 2992507c3241Smlf uchar_t fsm_func; 2993507c3241Smlf int rc; 2994507c3241Smlf 2995507c3241Smlf ADBG_TRACE(("ata_process_intr entered\n")); 2996507c3241Smlf 2997507c3241Smlf /* 2998507c3241Smlf * process the ATA or ATAPI interrupt 2999507c3241Smlf */ 3000507c3241Smlf 3001507c3241Smlf fsm_func = ATA_FSM_INTR; 3002507c3241Smlf for (watchdog = ata_process_intr_watchdog; watchdog > 0; watchdog--) { 3003507c3241Smlf rc = ata_ctlr_fsm(fsm_func, ata_ctlp, NULL, NULL, NULL); 3004507c3241Smlf 3005507c3241Smlf switch (rc) { 3006507c3241Smlf case ATA_FSM_RC_OKAY: 3007507c3241Smlf return; 3008507c3241Smlf 3009507c3241Smlf case ATA_FSM_RC_BUSY: /* wait for the next interrupt */ 3010507c3241Smlf return; 3011507c3241Smlf 3012507c3241Smlf case ATA_FSM_RC_INTR: /* re-invoke the FSM */ 3013507c3241Smlf fsm_func = ATA_FSM_INTR; 3014507c3241Smlf break; 3015507c3241Smlf 3016507c3241Smlf case ATA_FSM_RC_FINI: /* move a request to done Q */ 3017507c3241Smlf fsm_func = ATA_FSM_FINI; 3018507c3241Smlf break; 3019507c3241Smlf } 3020507c3241Smlf } 3021507c3241Smlf ADBG_WARN(("ata_process_intr: watchdog\n")); 3022507c3241Smlf } 3023507c3241Smlf 3024507c3241Smlf 3025507c3241Smlf 3026507c3241Smlf /* 3027507c3241Smlf * 3028507c3241Smlf * GHD ccc_hba_start callback 3029507c3241Smlf * 3030507c3241Smlf */ 3031507c3241Smlf 3032507c3241Smlf static int 3033507c3241Smlf ata_hba_start( 3034507c3241Smlf void *hba_handle, 3035507c3241Smlf gcmd_t *gcmdp) 3036507c3241Smlf { 3037507c3241Smlf ata_ctl_t *ata_ctlp; 3038507c3241Smlf ata_drv_t *ata_drvp; 3039507c3241Smlf ata_pkt_t *ata_pktp; 3040507c3241Smlf uchar_t fsm_func; 3041507c3241Smlf int request_started; 3042507c3241Smlf int watchdog; 3043507c3241Smlf 3044507c3241Smlf ADBG_TRACE(("ata_hba_start entered\n")); 3045507c3241Smlf 3046507c3241Smlf ata_ctlp = (ata_ctl_t *)hba_handle; 3047507c3241Smlf 3048507c3241Smlf if (ata_ctlp->ac_active_drvp != NULL) { 3049507c3241Smlf ADBG_WARN(("ata_hba_start drvp not null\n")); 3050507c3241Smlf return (FALSE); 3051507c3241Smlf } 3052507c3241Smlf if (ata_ctlp->ac_active_pktp != NULL) { 3053507c3241Smlf ADBG_WARN(("ata_hba_start pktp not null\n")); 3054507c3241Smlf return (FALSE); 3055507c3241Smlf } 3056507c3241Smlf 3057507c3241Smlf ata_pktp = GCMD2APKT(gcmdp); 3058507c3241Smlf ata_drvp = GCMD2DRV(gcmdp); 3059507c3241Smlf 3060507c3241Smlf /* 3061507c3241Smlf * which drive? 3062507c3241Smlf */ 3063507c3241Smlf if (ata_drvp->ad_targ == 0) 3064507c3241Smlf fsm_func = ATA_FSM_START0; 3065507c3241Smlf else 3066507c3241Smlf fsm_func = ATA_FSM_START1; 3067507c3241Smlf 3068507c3241Smlf /* 3069507c3241Smlf * start the request 3070507c3241Smlf */ 3071507c3241Smlf request_started = FALSE; 3072507c3241Smlf for (watchdog = ata_hba_start_watchdog; watchdog > 0; watchdog--) { 3073507c3241Smlf switch (ata_ctlr_fsm(fsm_func, ata_ctlp, ata_drvp, ata_pktp, 3074507c3241Smlf NULL)) { 3075507c3241Smlf case ATA_FSM_RC_OKAY: 3076507c3241Smlf request_started = TRUE; 3077507c3241Smlf goto fsm_done; 3078507c3241Smlf 3079507c3241Smlf case ATA_FSM_RC_BUSY: 3080507c3241Smlf /* if first time, tell GHD to requeue the request */ 3081507c3241Smlf goto fsm_done; 3082507c3241Smlf 3083507c3241Smlf case ATA_FSM_RC_INTR: 3084507c3241Smlf /* 3085507c3241Smlf * The start function polled for the next 3086507c3241Smlf * bus phase, now fake an interrupt to process 3087507c3241Smlf * the next action. 3088507c3241Smlf */ 3089507c3241Smlf request_started = TRUE; 3090507c3241Smlf fsm_func = ATA_FSM_INTR; 3091507c3241Smlf ata_drvp = NULL; 3092507c3241Smlf ata_pktp = NULL; 3093507c3241Smlf break; 3094507c3241Smlf 3095507c3241Smlf case ATA_FSM_RC_FINI: /* move request to the done queue */ 3096507c3241Smlf request_started = TRUE; 3097507c3241Smlf fsm_func = ATA_FSM_FINI; 3098507c3241Smlf ata_drvp = NULL; 3099507c3241Smlf ata_pktp = NULL; 3100507c3241Smlf break; 3101507c3241Smlf } 3102507c3241Smlf } 3103507c3241Smlf ADBG_WARN(("ata_hba_start: watchdog\n")); 3104507c3241Smlf 3105507c3241Smlf fsm_done: 3106507c3241Smlf return (request_started); 3107507c3241Smlf 3108507c3241Smlf } 3109507c3241Smlf 3110507c3241Smlf static int 3111507c3241Smlf ata_check_pciide_blacklist( 3112507c3241Smlf dev_info_t *dip, 3113507c3241Smlf uint_t flags) 3114507c3241Smlf { 3115507c3241Smlf ushort_t vendorid; 3116507c3241Smlf ushort_t deviceid; 3117507c3241Smlf pcibl_t *blp; 3118507c3241Smlf int *propp; 3119507c3241Smlf uint_t count; 3120507c3241Smlf int rc; 3121507c3241Smlf 3122507c3241Smlf 3123507c3241Smlf vendorid = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), 3124507c3241Smlf DDI_PROP_DONTPASS, "vendor-id", 0); 3125507c3241Smlf deviceid = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), 3126507c3241Smlf DDI_PROP_DONTPASS, "device-id", 0); 3127507c3241Smlf 3128507c3241Smlf /* 3129507c3241Smlf * first check for a match in the "pci-ide-blacklist" property 3130507c3241Smlf */ 3131507c3241Smlf rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, 3132507c3241Smlf "pci-ide-blacklist", &propp, &count); 3133507c3241Smlf 3134507c3241Smlf if (rc == DDI_PROP_SUCCESS) { 3135507c3241Smlf count = (count * sizeof (uint_t)) / sizeof (pcibl_t); 3136507c3241Smlf blp = (pcibl_t *)propp; 3137507c3241Smlf while (count--) { 3138507c3241Smlf /* check for matching ID */ 3139507c3241Smlf if ((vendorid & blp->b_vmask) 3140507c3241Smlf != (blp->b_vendorid & blp->b_vmask)) { 3141507c3241Smlf blp++; 3142507c3241Smlf continue; 3143507c3241Smlf } 3144507c3241Smlf if ((deviceid & blp->b_dmask) 3145507c3241Smlf != (blp->b_deviceid & blp->b_dmask)) { 3146507c3241Smlf blp++; 3147507c3241Smlf continue; 3148507c3241Smlf } 3149507c3241Smlf 3150507c3241Smlf /* got a match */ 3151507c3241Smlf if (blp->b_flags & flags) { 3152507c3241Smlf ddi_prop_free(propp); 3153507c3241Smlf return (TRUE); 3154507c3241Smlf } else { 3155507c3241Smlf ddi_prop_free(propp); 3156507c3241Smlf return (FALSE); 3157507c3241Smlf } 3158507c3241Smlf } 3159507c3241Smlf ddi_prop_free(propp); 3160507c3241Smlf } 3161507c3241Smlf 3162507c3241Smlf /* 3163507c3241Smlf * then check the built-in blacklist 3164507c3241Smlf */ 3165507c3241Smlf for (blp = ata_pciide_blacklist; blp->b_vendorid; blp++) { 3166507c3241Smlf if ((vendorid & blp->b_vmask) != blp->b_vendorid) 3167507c3241Smlf continue; 3168507c3241Smlf if ((deviceid & blp->b_dmask) != blp->b_deviceid) 3169507c3241Smlf continue; 3170507c3241Smlf if (!(blp->b_flags & flags)) 3171507c3241Smlf continue; 3172507c3241Smlf return (TRUE); 3173507c3241Smlf } 3174507c3241Smlf return (FALSE); 3175507c3241Smlf } 3176507c3241Smlf 3177507c3241Smlf int 3178507c3241Smlf ata_check_drive_blacklist( 3179507c3241Smlf struct ata_id *aidp, 3180507c3241Smlf uint_t flags) 3181507c3241Smlf { 3182507c3241Smlf atabl_t *blp; 3183507c3241Smlf 3184507c3241Smlf for (blp = ata_drive_blacklist; blp->b_model; blp++) { 3185507c3241Smlf if (!ata_strncmp(blp->b_model, aidp->ai_model, 3186507c3241Smlf sizeof (aidp->ai_model))) 3187507c3241Smlf continue; 3188507c3241Smlf if (blp->b_flags & flags) 3189507c3241Smlf return (TRUE); 3190507c3241Smlf return (FALSE); 3191507c3241Smlf } 3192507c3241Smlf return (FALSE); 3193507c3241Smlf } 3194507c3241Smlf 3195507c3241Smlf /* 3196507c3241Smlf * Queue a request to perform some sort of internally 3197507c3241Smlf * generated command. When this request packet reaches 3198507c3241Smlf * the front of the queue (*func)() is invoked. 3199507c3241Smlf * 3200507c3241Smlf */ 3201507c3241Smlf 3202507c3241Smlf int 3203507c3241Smlf ata_queue_cmd( 3204507c3241Smlf int (*func)(ata_ctl_t *, ata_drv_t *, ata_pkt_t *), 3205507c3241Smlf void *arg, 3206507c3241Smlf ata_ctl_t *ata_ctlp, 3207507c3241Smlf ata_drv_t *ata_drvp, 3208507c3241Smlf gtgt_t *gtgtp) 3209507c3241Smlf { 3210507c3241Smlf ata_pkt_t *ata_pktp; 3211507c3241Smlf gcmd_t *gcmdp; 3212507c3241Smlf int rc; 3213507c3241Smlf 3214507c3241Smlf if (!(gcmdp = ghd_gcmd_alloc(gtgtp, sizeof (*ata_pktp), TRUE))) { 3215507c3241Smlf ADBG_ERROR(("atapi_id_update alloc failed\n")); 3216507c3241Smlf return (FALSE); 3217507c3241Smlf } 3218507c3241Smlf 3219507c3241Smlf 3220507c3241Smlf /* set the back ptr from the ata_pkt to the gcmd_t */ 3221507c3241Smlf ata_pktp = GCMD2APKT(gcmdp); 3222507c3241Smlf ata_pktp->ap_gcmdp = gcmdp; 3223507c3241Smlf ata_pktp->ap_hd = ata_drvp->ad_drive_bits; 3224507c3241Smlf ata_pktp->ap_bytes_per_block = ata_drvp->ad_bytes_per_block; 3225507c3241Smlf 3226507c3241Smlf /* 3227507c3241Smlf * over-ride the default start function 3228507c3241Smlf */ 3229507c3241Smlf ata_pktp = GCMD2APKT(gcmdp); 3230507c3241Smlf ata_pktp->ap_start = func; 3231507c3241Smlf ata_pktp->ap_complete = NULL; 3232507c3241Smlf ata_pktp->ap_v_addr = (caddr_t)arg; 3233507c3241Smlf 3234507c3241Smlf /* 3235507c3241Smlf * add it to the queue, when it gets to the front the 3236507c3241Smlf * ap_start function is called. 3237507c3241Smlf */ 3238507c3241Smlf rc = ghd_transport(&ata_ctlp->ac_ccc, gcmdp, gcmdp->cmd_gtgtp, 3239507c3241Smlf 0, TRUE, NULL); 3240507c3241Smlf 3241507c3241Smlf if (rc != TRAN_ACCEPT) { 3242507c3241Smlf /* this should never, ever happen */ 3243507c3241Smlf return (FALSE); 3244507c3241Smlf } 3245507c3241Smlf 3246507c3241Smlf if (ata_pktp->ap_flags & AP_ERROR) 3247507c3241Smlf return (FALSE); 3248507c3241Smlf return (TRUE); 3249507c3241Smlf } 3250507c3241Smlf 3251507c3241Smlf /* 3252507c3241Smlf * Check if this drive has the "revert to defaults" bug 3253507c3241Smlf * PSARC 2001/500 and 2001/xxx - check for the properties 3254507c3241Smlf * ata-revert-to-defaults and atarvrt-<diskmodel> before 3255507c3241Smlf * examining the blacklist. 3256507c3241Smlf * <diskmodel> is made from the model number reported by Identify Drive 3257507c3241Smlf * with uppercase letters converted to lowercase and all characters 3258507c3241Smlf * except letters, digits, ".", "_", and "-" deleted. 3259507c3241Smlf * Return value: 3260507c3241Smlf * TRUE: enable revert to defaults 3261507c3241Smlf * FALSE: disable revert to defaults 3262507c3241Smlf * 3263507c3241Smlf * NOTE: revert to power on defaults that includes reverting to MDMA 3264507c3241Smlf * mode is allowed by ATA-6 & ATA-7 specs. 3265507c3241Smlf * Therefore drives exhibiting this behaviour are not violating the spec. 3266507c3241Smlf * Furthermore, the spec explicitly says that after the soft reset 3267507c3241Smlf * host should check the current setting of the device features. 3268507c3241Smlf * Correctly working BIOS would therefore reprogram either the drive 3269507c3241Smlf * and/or the host controller to match transfer modes. 3270507c3241Smlf * Devices with ATA_BL_NORVRT flag will be removed from 3271507c3241Smlf * the ata_blacklist. 3272507c3241Smlf * The default behaviour will be - no revert to power-on defaults 3273507c3241Smlf * for all devices. The property is retained in case the user 3274507c3241Smlf * explicitly requests revert-to-defaults before reboot. 3275507c3241Smlf */ 3276507c3241Smlf 3277507c3241Smlf #define ATA_REVERT_PROP_PREFIX "revert-" 3278507c3241Smlf #define ATA_REVERT_PROP_GLOBAL "ata-revert-to-defaults" 3279507c3241Smlf /* room for prefix + model number + terminating NUL character */ 3280507c3241Smlf #define PROP_BUF_SIZE (sizeof (ATA_REVERT_PROP_PREFIX) + \ 3281507c3241Smlf sizeof (aidp->ai_model) + 1) 3282507c3241Smlf #define PROP_LEN_MAX (31) 3283507c3241Smlf 3284507c3241Smlf static int 3285507c3241Smlf ata_check_revert_to_defaults( 3286507c3241Smlf ata_drv_t *ata_drvp) 3287507c3241Smlf { 3288507c3241Smlf struct ata_id *aidp = &ata_drvp->ad_id; 3289507c3241Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp; 3290507c3241Smlf char prop_buf[PROP_BUF_SIZE]; 3291507c3241Smlf int i, j; 3292507c3241Smlf int propval; 3293507c3241Smlf 3294507c3241Smlf /* put prefix into the buffer */ 3295507c3241Smlf (void) strcpy(prop_buf, ATA_REVERT_PROP_PREFIX); 3296507c3241Smlf j = strlen(prop_buf); 3297507c3241Smlf 3298507c3241Smlf /* append the model number, leaving out invalid characters */ 3299507c3241Smlf for (i = 0; i < sizeof (aidp->ai_model); ++i) { 3300507c3241Smlf char c = aidp->ai_model[i]; 3301507c3241Smlf if (c >= 'A' && c <= 'Z') /* uppercase -> lower */ 3302507c3241Smlf c = c - 'A' + 'a'; 3303507c3241Smlf if (c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || 3304507c3241Smlf c == '.' || c == '_' || c == '-') 3305507c3241Smlf prop_buf[j++] = c; 3306507c3241Smlf if (c == '\0') 3307507c3241Smlf break; 3308507c3241Smlf } 3309507c3241Smlf 3310507c3241Smlf /* make sure there's a terminating NUL character */ 3311507c3241Smlf if (j >= PROP_LEN_MAX) 3312507c3241Smlf j = PROP_LEN_MAX; 3313507c3241Smlf prop_buf[j] = '\0'; 3314507c3241Smlf 3315507c3241Smlf /* look for a disk-specific "revert" property" */ 3316507c3241Smlf propval = ddi_getprop(DDI_DEV_T_ANY, ata_ctlp->ac_dip, 3317507c3241Smlf DDI_PROP_DONTPASS, prop_buf, -1); 3318507c3241Smlf if (propval == 0) 3319507c3241Smlf return (FALSE); 3320507c3241Smlf else if (propval != -1) 3321507c3241Smlf return (TRUE); 3322507c3241Smlf 3323507c3241Smlf /* look for a global "revert" property" */ 3324507c3241Smlf propval = ddi_getprop(DDI_DEV_T_ANY, ata_ctlp->ac_dip, 3325507c3241Smlf 0, ATA_REVERT_PROP_GLOBAL, -1); 3326507c3241Smlf if (propval == 0) 3327507c3241Smlf return (FALSE); 3328507c3241Smlf else if (propval != -1) 3329507c3241Smlf return (TRUE); 3330507c3241Smlf 3331507c3241Smlf return (FALSE); 3332507c3241Smlf } 3333507c3241Smlf 3334507c3241Smlf void 3335507c3241Smlf ata_show_transfer_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp) 3336507c3241Smlf { 3337507c3241Smlf int i; 3338507c3241Smlf 3339507c3241Smlf if (ata_ctlp->ac_pciide_bm == FALSE || 3340507c3241Smlf ata_drvp->ad_pciide_dma != ATA_DMA_ON) { 3341507c3241Smlf if (ata_cntrl_DMA_sel_msg) { 3342507c3241Smlf ATAPRT(( 3343507c3241Smlf "?\tATA DMA off: %s\n", ata_cntrl_DMA_sel_msg)); 3344507c3241Smlf } else if (ata_dev_DMA_sel_msg) { 3345507c3241Smlf ATAPRT(("?\tATA DMA off: %s\n", ata_dev_DMA_sel_msg)); 3346507c3241Smlf } 3347507c3241Smlf ATAPRT(("?\tPIO mode %d selected\n", 3348507c3241Smlf (ata_drvp->ad_id.ai_advpiomode & ATAC_ADVPIO_4_SUP) == 3349507c3241Smlf ATAC_ADVPIO_4_SUP ? 4 : 3)); 3350507c3241Smlf } else { 3351507c3241Smlf /* Using DMA */ 3352507c3241Smlf if (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_SEL_MASK) { 3353507c3241Smlf /* 3354507c3241Smlf * Rely on the fact that either dwdma or udma is 3355507c3241Smlf * selected, not both. 3356507c3241Smlf */ 3357507c3241Smlf ATAPRT(("?\tMultiwordDMA mode %d selected\n", 3358507c3241Smlf (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_2_SEL) == 3359507c3241Smlf ATAC_MDMA_2_SEL ? 2 : 3360507c3241Smlf (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_1_SEL) == 3361507c3241Smlf ATAC_MDMA_1_SEL ? 1 : 0)); 3362507c3241Smlf } else { 3363507c3241Smlf for (i = 0; i <= 6; i++) { 3364507c3241Smlf if (ata_drvp->ad_id.ai_ultradma & 3365507c3241Smlf (1 << (i + 8))) { 3366507c3241Smlf ATAPRT(( 3367507c3241Smlf "?\tUltraDMA mode %d selected\n", 3368507c3241Smlf i)); 3369507c3241Smlf break; 3370507c3241Smlf } 3371507c3241Smlf } 3372507c3241Smlf } 3373507c3241Smlf } 3374507c3241Smlf } 3375507c3241Smlf 3376507c3241Smlf /* 3377507c3241Smlf * Controller-specific operation pointers. 3378507c3241Smlf * Should be extended as needed - init only for now 3379507c3241Smlf */ 3380507c3241Smlf struct ata_ctl_spec_ops { 3381507c3241Smlf uint_t (*cs_init)(dev_info_t *, ushort_t, ushort_t); /* ctlr init */ 3382507c3241Smlf }; 3383507c3241Smlf 3384507c3241Smlf 3385507c3241Smlf struct ata_ctl_spec { 3386507c3241Smlf ushort_t cs_vendor_id; 3387507c3241Smlf ushort_t cs_device_id; 3388507c3241Smlf struct ata_ctl_spec_ops *cs_ops; 3389507c3241Smlf }; 3390507c3241Smlf 3391507c3241Smlf /* Sil3XXX-specific functions (init only for now) */ 3392507c3241Smlf struct ata_ctl_spec_ops sil3xxx_ops = { 3393507c3241Smlf &sil3xxx_init_controller /* Sil3XXX cntrl initialization */ 3394507c3241Smlf }; 3395507c3241Smlf 3396507c3241Smlf 3397507c3241Smlf struct ata_ctl_spec ata_cntrls_spec[] = { 3398507c3241Smlf {0x1095, 0x3114, &sil3xxx_ops}, 3399507c3241Smlf {0x1095, 0x3512, &sil3xxx_ops}, 3400507c3241Smlf {0x1095, 0x3112, &sil3xxx_ops}, 3401507c3241Smlf {0, 0, NULL} /* List must end with cs_ops set to NULL */ 3402507c3241Smlf }; 3403507c3241Smlf 3404507c3241Smlf /* 3405507c3241Smlf * Do controller specific initialization if necessary. 3406507c3241Smlf * Pick-up controller specific functions. 3407507c3241Smlf */ 3408507c3241Smlf 3409507c3241Smlf int 3410507c3241Smlf ata_spec_init_controller(dev_info_t *dip) 3411507c3241Smlf { 3412507c3241Smlf ushort_t vendor_id; 3413507c3241Smlf ushort_t device_id; 3414507c3241Smlf struct ata_ctl_spec *ctlsp; 3415507c3241Smlf 3416507c3241Smlf vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), 3417507c3241Smlf DDI_PROP_DONTPASS, "vendor-id", 0); 3418507c3241Smlf device_id = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), 3419507c3241Smlf DDI_PROP_DONTPASS, "device-id", 0); 3420507c3241Smlf 3421507c3241Smlf /* Locate controller specific ops, if they exist */ 3422507c3241Smlf ctlsp = ata_cntrls_spec; 3423507c3241Smlf while (ctlsp->cs_ops != NULL) { 3424507c3241Smlf if (ctlsp->cs_vendor_id == vendor_id && 3425507c3241Smlf ctlsp->cs_device_id == device_id) 3426507c3241Smlf break; 3427507c3241Smlf ctlsp++; 3428507c3241Smlf } 3429507c3241Smlf 3430507c3241Smlf if (ctlsp->cs_ops != NULL) { 3431507c3241Smlf if (ctlsp->cs_ops->cs_init != NULL) { 3432507c3241Smlf /* Initialize controller */ 3433507c3241Smlf if ((*(ctlsp->cs_ops->cs_init)) 3434507c3241Smlf (dip, vendor_id, device_id) != TRUE) { 3435507c3241Smlf cmn_err(CE_WARN, 3436507c3241Smlf "pci%4x,%4x cntrl specific " 3437507c3241Smlf "initialization failed", 3438507c3241Smlf vendor_id, device_id); 3439507c3241Smlf return (FALSE); 3440507c3241Smlf } 3441507c3241Smlf } 3442507c3241Smlf } 3443507c3241Smlf return (TRUE); 3444507c3241Smlf } 3445507c3241Smlf 3446507c3241Smlf /* 3447507c3241Smlf * this routine works like ddi_prop_get_int, except that it works on 3448507c3241Smlf * a string property that contains ascii representations 3449507c3241Smlf * of an integer. 3450507c3241Smlf * If the property is not found, the default value is returned. 3451507c3241Smlf */ 3452507c3241Smlf static int 3453507c3241Smlf ata_prop_lookup_int(dev_t match_dev, dev_info_t *dip, 3454507c3241Smlf uint_t flags, char *name, int defvalue) 3455507c3241Smlf { 3456507c3241Smlf 3457507c3241Smlf char *bufp, *cp; 3458507c3241Smlf int rc = defvalue; 3459507c3241Smlf int proprc; 3460507c3241Smlf 3461507c3241Smlf proprc = ddi_prop_lookup_string(match_dev, dip, 3462507c3241Smlf flags, name, &bufp); 3463507c3241Smlf 3464507c3241Smlf if (proprc == DDI_PROP_SUCCESS) { 3465507c3241Smlf cp = bufp; 3466507c3241Smlf rc = stoi(&cp); 3467507c3241Smlf ddi_prop_free(bufp); 3468507c3241Smlf } else { 3469507c3241Smlf /* 3470507c3241Smlf * see if property is encoded as an int instead of string. 3471507c3241Smlf */ 3472507c3241Smlf rc = ddi_prop_get_int(match_dev, dip, flags, name, defvalue); 3473507c3241Smlf } 3474507c3241Smlf 3475507c3241Smlf return (rc); 3476507c3241Smlf } 34772df1fe9cSrandyf 34782df1fe9cSrandyf /* 34792df1fe9cSrandyf * Initialize the power management components 34802df1fe9cSrandyf */ 34812df1fe9cSrandyf static void 34822df1fe9cSrandyf ata_init_pm(dev_info_t *dip) 34832df1fe9cSrandyf { 34842df1fe9cSrandyf char pmc_name[16]; 34852df1fe9cSrandyf char *pmc[] = { 34862df1fe9cSrandyf NULL, 34872df1fe9cSrandyf "0=Sleep (PCI D3 State)", 34882df1fe9cSrandyf "3=PowerOn (PCI D0 State)", 34892df1fe9cSrandyf NULL 34902df1fe9cSrandyf }; 34912df1fe9cSrandyf int instance; 34922df1fe9cSrandyf ata_ctl_t *ata_ctlp; 34932df1fe9cSrandyf 34942df1fe9cSrandyf 34952df1fe9cSrandyf instance = ddi_get_instance(dip); 34962df1fe9cSrandyf ata_ctlp = ddi_get_soft_state(ata_state, instance); 34972df1fe9cSrandyf ata_ctlp->ac_pm_support = 0; 34982df1fe9cSrandyf 34992df1fe9cSrandyf /* check PCI capabilities */ 35002df1fe9cSrandyf if (!ata_is_pci(dip)) 35012df1fe9cSrandyf return; 35022df1fe9cSrandyf 35032df1fe9cSrandyf (void) sprintf(pmc_name, "NAME=ata%d", instance); 35042df1fe9cSrandyf pmc[0] = pmc_name; 35052df1fe9cSrandyf 35062df1fe9cSrandyf #ifdef ATA_USE_AUTOPM 35072df1fe9cSrandyf if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip, 35082df1fe9cSrandyf "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { 35092df1fe9cSrandyf return; 35102df1fe9cSrandyf } 35112df1fe9cSrandyf #endif 35122df1fe9cSrandyf 35132df1fe9cSrandyf ata_ctlp->ac_pm_support = 1; 35142df1fe9cSrandyf ata_ctlp->ac_pm_level = PM_LEVEL_D0; 35152df1fe9cSrandyf 35162df1fe9cSrandyf ATA_BUSY_COMPONENT(dip, 0); 35172df1fe9cSrandyf if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { 35182df1fe9cSrandyf (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components"); 35192df1fe9cSrandyf } 35202df1fe9cSrandyf ATA_IDLE_COMPONENT(dip, 0); 35212df1fe9cSrandyf } 35222df1fe9cSrandyf 35232df1fe9cSrandyf /* 35242df1fe9cSrandyf * resume the hard drive 35252df1fe9cSrandyf */ 35262df1fe9cSrandyf static void 35272df1fe9cSrandyf ata_resume_drive(ata_drv_t *ata_drvp) 35282df1fe9cSrandyf { 35292df1fe9cSrandyf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp; 35302df1fe9cSrandyf int drive_type; 35312df1fe9cSrandyf struct ata_id id; 35322df1fe9cSrandyf 35332df1fe9cSrandyf ADBG_TRACE(("ata_resume_drive entered\n")); 35342df1fe9cSrandyf 35352df1fe9cSrandyf drive_type = ata_drive_type(ata_drvp->ad_drive_bits, 35362df1fe9cSrandyf ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1, 35372df1fe9cSrandyf ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, 35382df1fe9cSrandyf &id); 35392df1fe9cSrandyf if (drive_type == ATA_DEV_NONE) 35402df1fe9cSrandyf return; 35412df1fe9cSrandyf 35422df1fe9cSrandyf if (!ATAPIDRV(ata_drvp)) { 354362c8caf3SAda /* Reset Ultra DMA mode */ 354462c8caf3SAda (void) ata_set_dma_mode(ata_ctlp, ata_drvp); 35452df1fe9cSrandyf if (!ata_disk_setup_parms(ata_ctlp, ata_drvp)) 35462df1fe9cSrandyf return; 354762c8caf3SAda } else { 3548b44e05abSAda (void) atapi_init_drive(ata_drvp); 3549*8c97a06bSAda (void) atapi_reset_dma_mode(ata_drvp); 35502df1fe9cSrandyf } 355162c8caf3SAda (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0); 355262c8caf3SAda 35532df1fe9cSrandyf } 35542df1fe9cSrandyf 35552df1fe9cSrandyf /* 35562df1fe9cSrandyf * resume routine, it will be run when get the command 35572df1fe9cSrandyf * DDI_RESUME at attach(9E) from system power management 35582df1fe9cSrandyf */ 35592df1fe9cSrandyf static int 35602df1fe9cSrandyf ata_resume(dev_info_t *dip) 35612df1fe9cSrandyf { 35622df1fe9cSrandyf int instance; 35632df1fe9cSrandyf ata_ctl_t *ata_ctlp; 35642df1fe9cSrandyf ddi_acc_handle_t io_hdl2; 35652df1fe9cSrandyf caddr_t ioaddr2; 35662df1fe9cSrandyf 35672df1fe9cSrandyf instance = ddi_get_instance(dip); 35682df1fe9cSrandyf ata_ctlp = ddi_get_soft_state(ata_state, instance); 35692df1fe9cSrandyf 35702df1fe9cSrandyf if (!ata_ctlp->ac_pm_support) 35712df1fe9cSrandyf return (DDI_FAILURE); 35722df1fe9cSrandyf if (ata_ctlp->ac_pm_level == PM_LEVEL_D0) 35732df1fe9cSrandyf return (DDI_SUCCESS); 35742df1fe9cSrandyf 35752df1fe9cSrandyf ATA_BUSY_COMPONENT(dip, 0); 35762df1fe9cSrandyf if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) == DDI_FAILURE) 35772df1fe9cSrandyf return (DDI_FAILURE); 35782df1fe9cSrandyf ATA_IDLE_COMPONENT(dip, 0); 35792df1fe9cSrandyf 35802df1fe9cSrandyf /* enable interrupts from the device */ 35812df1fe9cSrandyf io_hdl2 = ata_ctlp->ac_iohandle2; 35822df1fe9cSrandyf ioaddr2 = ata_ctlp->ac_ioaddr2; 35832df1fe9cSrandyf ddi_put8(io_hdl2, (uchar_t *)ioaddr2 + AT_DEVCTL, ATDC_D3); 35842df1fe9cSrandyf ata_ctlp->ac_pm_level = PM_LEVEL_D0; 35852df1fe9cSrandyf 35862df1fe9cSrandyf return (DDI_SUCCESS); 35872df1fe9cSrandyf } 35882df1fe9cSrandyf 35892df1fe9cSrandyf /* 35902df1fe9cSrandyf * suspend routine, it will be run when get the command 35912df1fe9cSrandyf * DDI_SUSPEND at detach(9E) from system power management 35922df1fe9cSrandyf */ 35932df1fe9cSrandyf static int 35942df1fe9cSrandyf ata_suspend(dev_info_t *dip) 35952df1fe9cSrandyf { 35962df1fe9cSrandyf int instance; 35972df1fe9cSrandyf ata_ctl_t *ata_ctlp; 35982df1fe9cSrandyf ddi_acc_handle_t io_hdl2; 35992df1fe9cSrandyf 36002df1fe9cSrandyf instance = ddi_get_instance(dip); 36012df1fe9cSrandyf ata_ctlp = ddi_get_soft_state(ata_state, instance); 36022df1fe9cSrandyf 36032df1fe9cSrandyf if (!ata_ctlp->ac_pm_support) 36042df1fe9cSrandyf return (DDI_FAILURE); 36052df1fe9cSrandyf if (ata_ctlp->ac_pm_level == PM_LEVEL_D3) 36062df1fe9cSrandyf return (DDI_SUCCESS); 36072df1fe9cSrandyf 36082df1fe9cSrandyf /* disable interrupts and turn the software reset bit on */ 36092df1fe9cSrandyf io_hdl2 = ata_ctlp->ac_iohandle2; 36102df1fe9cSrandyf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3 | ATDC_SRST)); 36112df1fe9cSrandyf 36122df1fe9cSrandyf (void) ata_reset_bus(ata_ctlp); 36132df1fe9cSrandyf (void) ata_change_power(dip, ATC_SLEEP); 36142df1fe9cSrandyf ata_ctlp->ac_pm_level = PM_LEVEL_D3; 36152df1fe9cSrandyf return (DDI_SUCCESS); 36162df1fe9cSrandyf } 36172df1fe9cSrandyf 36182df1fe9cSrandyf int ata_save_pci_config = 0; 36192df1fe9cSrandyf /* 36202df1fe9cSrandyf * ata specific power management entry point, it was 36212df1fe9cSrandyf * used to change the power management component 36222df1fe9cSrandyf */ 36232df1fe9cSrandyf static int 36242df1fe9cSrandyf ata_power(dev_info_t *dip, int component, int level) 36252df1fe9cSrandyf { 36262df1fe9cSrandyf int instance; 36272df1fe9cSrandyf ata_ctl_t *ata_ctlp; 36282df1fe9cSrandyf uint8_t cmd; 36292df1fe9cSrandyf 36302df1fe9cSrandyf ADBG_TRACE(("ata_power entered, component = %d, level = %d\n", 36312df1fe9cSrandyf component, level)); 36322df1fe9cSrandyf 36332df1fe9cSrandyf instance = ddi_get_instance(dip); 36342df1fe9cSrandyf ata_ctlp = ddi_get_soft_state(ata_state, instance); 36352df1fe9cSrandyf if (ata_ctlp == NULL || component != 0) 36362df1fe9cSrandyf return (DDI_FAILURE); 36372df1fe9cSrandyf 36382df1fe9cSrandyf if (!ata_ctlp->ac_pm_support) 36392df1fe9cSrandyf return (DDI_FAILURE); 36402df1fe9cSrandyf 3641*8c97a06bSAda if (ata_ctlp->ac_pm_level == level) 3642*8c97a06bSAda return (DDI_SUCCESS); 3643*8c97a06bSAda 36442df1fe9cSrandyf switch (level) { 36452df1fe9cSrandyf case PM_LEVEL_D0: 36462df1fe9cSrandyf if (ata_save_pci_config) 36472df1fe9cSrandyf (void) pci_restore_config_regs(dip); 36482df1fe9cSrandyf ata_ctlp->ac_pm_level = PM_LEVEL_D0; 3649dcafa541Srandyf cmd = ATC_IDLE_IMMED; 36502df1fe9cSrandyf break; 36512df1fe9cSrandyf case PM_LEVEL_D3: 36522df1fe9cSrandyf if (ata_save_pci_config) 36532df1fe9cSrandyf (void) pci_save_config_regs(dip); 36542df1fe9cSrandyf ata_ctlp->ac_pm_level = PM_LEVEL_D3; 36552df1fe9cSrandyf cmd = ATC_SLEEP; 36562df1fe9cSrandyf break; 36572df1fe9cSrandyf default: 36582df1fe9cSrandyf return (DDI_FAILURE); 36592df1fe9cSrandyf } 36602df1fe9cSrandyf return (ata_change_power(dip, cmd)); 36612df1fe9cSrandyf } 36622df1fe9cSrandyf 36632df1fe9cSrandyf /* 36642df1fe9cSrandyf * sent commands to ata controller to change the power level 36652df1fe9cSrandyf */ 36662df1fe9cSrandyf static int 36672df1fe9cSrandyf ata_change_power(dev_info_t *dip, uint8_t cmd) 36682df1fe9cSrandyf { 36692df1fe9cSrandyf int instance; 36702df1fe9cSrandyf ata_ctl_t *ata_ctlp; 36712df1fe9cSrandyf ata_drv_t *ata_drvp; 36722df1fe9cSrandyf uchar_t targ; 36732df1fe9cSrandyf struct ata_id id; 36742df1fe9cSrandyf uchar_t lun; 36752df1fe9cSrandyf uchar_t lastlun; 3676*8c97a06bSAda struct ata_id *aidp; 36772df1fe9cSrandyf 36782df1fe9cSrandyf ADBG_TRACE(("ata_change_power entered, cmd = %d\n", cmd)); 36792df1fe9cSrandyf 36802df1fe9cSrandyf instance = ddi_get_instance(dip); 36812df1fe9cSrandyf ata_ctlp = ddi_get_soft_state(ata_state, instance); 3682*8c97a06bSAda 36832df1fe9cSrandyf /* 36842df1fe9cSrandyf * Issue command on each disk device on the bus. 36852df1fe9cSrandyf */ 368662c8caf3SAda if (cmd == ATC_SLEEP) { 36872df1fe9cSrandyf for (targ = 0; targ < ATA_MAXTARG; targ++) { 36882df1fe9cSrandyf ata_drvp = CTL2DRV(ata_ctlp, targ, 0); 36892df1fe9cSrandyf if (ata_drvp == NULL) 36902df1fe9cSrandyf continue; 3691*8c97a06bSAda aidp = &ata_drvp->ad_id; 3692*8c97a06bSAda if ((aidp->ai_validinfo & ATAC_VALIDINFO_83) && 3693*8c97a06bSAda (aidp->ai_ultradma & ATAC_UDMA_SEL_MASK)) { 3694*8c97a06bSAda ata_drvp->ad_dma_cap = ATA_DMA_ULTRAMODE; 3695*8c97a06bSAda ata_drvp->ad_dma_mode = aidp->ai_ultradma; 3696*8c97a06bSAda } else if (aidp->ai_dworddma & ATAC_MDMA_SEL_MASK) { 3697*8c97a06bSAda ata_drvp->ad_dma_cap = ATA_DMA_MWORDMODE; 3698*8c97a06bSAda ata_drvp->ad_dma_mode = aidp->ai_dworddma; 3699*8c97a06bSAda } 37002df1fe9cSrandyf if (ata_drive_type(ata_drvp->ad_drive_bits, 37012df1fe9cSrandyf ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1, 37022df1fe9cSrandyf ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, 37032df1fe9cSrandyf &id) != ATA_DEV_DISK) 37042df1fe9cSrandyf continue; 37052df1fe9cSrandyf (void) ata_flush_cache(ata_ctlp, ata_drvp); 370662c8caf3SAda if (!ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 370762c8caf3SAda 5 * 1000000, cmd, 0, 0, 0, 0, 0, 0)) { 370862c8caf3SAda cmn_err(CE_WARN, "!ata_controller - Can not " 370962c8caf3SAda "put drive %d in to power mode %u", 371062c8caf3SAda targ, cmd); 37112df1fe9cSrandyf (void) ata_devo_reset(dip, DDI_RESET_FORCE); 37122df1fe9cSrandyf return (DDI_FAILURE); 37132df1fe9cSrandyf } 37142df1fe9cSrandyf } 37152df1fe9cSrandyf return (DDI_SUCCESS); 371662c8caf3SAda } 37172df1fe9cSrandyf 371862c8caf3SAda (void) ata_software_reset(ata_ctlp); 37192df1fe9cSrandyf for (targ = 0; targ < ATA_MAXTARG; targ++) { 37202df1fe9cSrandyf ata_drvp = CTL2DRV(ata_ctlp, targ, 0); 372162c8caf3SAda if (ata_drvp == NULL) 37222df1fe9cSrandyf continue; 37232df1fe9cSrandyf ata_resume_drive(ata_drvp); 37242df1fe9cSrandyf 37252df1fe9cSrandyf if (ATAPIDRV(ata_drvp)) 37262df1fe9cSrandyf lastlun = ata_drvp->ad_id.ai_lastlun; 37272df1fe9cSrandyf else 37282df1fe9cSrandyf lastlun = 0; 37292df1fe9cSrandyf if (!ata_enable_atapi_luns) 37302df1fe9cSrandyf lastlun = 0; 37312df1fe9cSrandyf for (lun = 1; lun <= lastlun && lun < ATA_MAXLUN; lun++) { 37322df1fe9cSrandyf ata_drvp = CTL2DRV(ata_ctlp, targ, lun); 37332df1fe9cSrandyf if (ata_drvp != NULL) 37342df1fe9cSrandyf ata_resume_drive(ata_drvp); 37352df1fe9cSrandyf } 37362df1fe9cSrandyf } 37372df1fe9cSrandyf 37382df1fe9cSrandyf return (DDI_SUCCESS); 37392df1fe9cSrandyf } 37402df1fe9cSrandyf 37412df1fe9cSrandyf /* 37422df1fe9cSrandyf * return 1 when ata controller is a pci device, 37432df1fe9cSrandyf * otherwise return 0 37442df1fe9cSrandyf */ 37452df1fe9cSrandyf static int 37462df1fe9cSrandyf ata_is_pci(dev_info_t *dip) 37472df1fe9cSrandyf { 37482df1fe9cSrandyf int rc; 37492df1fe9cSrandyf char *bufp; 37502df1fe9cSrandyf int ispci; 37512df1fe9cSrandyf 37522df1fe9cSrandyf rc = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(dip), 37532df1fe9cSrandyf DDI_PROP_DONTPASS, "device_type", &bufp); 37542df1fe9cSrandyf 37552df1fe9cSrandyf if (rc != DDI_PROP_SUCCESS) { 37562df1fe9cSrandyf ADBG_ERROR(("ata_is_pci !device_type\n")); 37572df1fe9cSrandyf return (0); 37582df1fe9cSrandyf } 37592df1fe9cSrandyf 37602df1fe9cSrandyf ispci = (strcmp(bufp, "pci-ide") == 0); 37612df1fe9cSrandyf 37622df1fe9cSrandyf ddi_prop_free(bufp); 37632df1fe9cSrandyf 37642df1fe9cSrandyf return (ispci); 37652df1fe9cSrandyf } 37665fb86baeSml40262 37675fb86baeSml40262 /* 37685fb86baeSml40262 * Disable DMA for this drive 37695fb86baeSml40262 */ 37705fb86baeSml40262 static void 37715fb86baeSml40262 ata_disable_DMA(ata_drv_t *ata_drvp) 37725fb86baeSml40262 { 37735fb86baeSml40262 struct ata_id *aidp; 37745fb86baeSml40262 char buf[sizeof (aidp->ai_model) +2]; 37755fb86baeSml40262 int i; 37765fb86baeSml40262 37775fb86baeSml40262 if (ata_drvp == NULL) 37785fb86baeSml40262 return; 37795fb86baeSml40262 37805fb86baeSml40262 if (ata_drvp->ad_pciide_dma == ATA_DMA_OFF) 37815fb86baeSml40262 return; 37825fb86baeSml40262 37835fb86baeSml40262 ata_drvp->ad_pciide_dma = ATA_DMA_OFF; 37845fb86baeSml40262 37855fb86baeSml40262 /* Print the message */ 37865fb86baeSml40262 buf[0] = '\0'; 37875fb86baeSml40262 aidp = &ata_drvp->ad_id; 37885fb86baeSml40262 if (aidp != NULL) { 37895fb86baeSml40262 (void) strncpy(buf, aidp->ai_model, sizeof (aidp->ai_model)); 37905fb86baeSml40262 buf[sizeof (aidp->ai_model) -1] = '\0'; 37915fb86baeSml40262 for (i = sizeof (aidp->ai_model) - 2; buf[i] == ' '; i--) 37925fb86baeSml40262 buf[i] = '\0'; 37935fb86baeSml40262 } 37945fb86baeSml40262 cmn_err(CE_CONT, 37955fb86baeSml40262 "?DMA disabled on %s target=%d, lun=%d due to DMA errors,", 37965fb86baeSml40262 buf, ata_drvp->ad_targ, ata_drvp->ad_lun); 37975fb86baeSml40262 cmn_err(CE_CONT, "?most likely due to the CF-to-IDE adapter."); 37985fb86baeSml40262 } 3799c8531848Syt160523 3800c8531848Syt160523 /* 3801c8531848Syt160523 * Check and select DMA mode 3802c8531848Syt160523 * 3803c8531848Syt160523 * TRUE is returned when set feature is called successfully, 3804c8531848Syt160523 * otherwise return FALSE 3805c8531848Syt160523 */ 3806c8531848Syt160523 int 3807c8531848Syt160523 ata_set_dma_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp) 3808c8531848Syt160523 { 3809c8531848Syt160523 struct ata_id *aidp; 3810c8531848Syt160523 int mode, rval = FALSE; 3811c8531848Syt160523 uint8_t subcmd; 3812c8531848Syt160523 3813c8531848Syt160523 aidp = &ata_drvp->ad_id; 3814c8531848Syt160523 3815c8531848Syt160523 /* Return directly if DMA is not supported */ 3816c8531848Syt160523 if (!(aidp->ai_cap & ATAC_DMA_SUPPORT)) 3817c8531848Syt160523 return (rval); 3818c8531848Syt160523 3819*8c97a06bSAda /* Return if DMA mode is already selected */ 3820*8c97a06bSAda if (((aidp->ai_validinfo & ATAC_VALIDINFO_83) && 3821*8c97a06bSAda (aidp->ai_ultradma & ATAC_UDMA_SEL_MASK)) || 3822*8c97a06bSAda (aidp->ai_dworddma & ATAC_MDMA_SEL_MASK)) 3823*8c97a06bSAda return (rval); 3824*8c97a06bSAda 3825c8531848Syt160523 /* First check Ultra DMA mode if no DMA is selected */ 3826c8531848Syt160523 if ((aidp->ai_validinfo & ATAC_VALIDINFO_83) && 3827c8531848Syt160523 (aidp->ai_ultradma & ATAC_UDMA_SUP_MASK)) { 3828c8531848Syt160523 for (mode = 6; mode >= 0; --mode) { 3829c8531848Syt160523 if (aidp->ai_ultradma & (1 << mode)) 3830c8531848Syt160523 break; 3831c8531848Syt160523 } 3832c8531848Syt160523 subcmd = ATF_XFRMOD_UDMA; 3833c8531848Syt160523 3834c8531848Syt160523 } else if (aidp->ai_dworddma & ATAC_MDMA_SUP_MASK) { 3835c8531848Syt160523 /* Then check multi-word DMA mode */ 3836c8531848Syt160523 for (mode = 2; mode >= 0; --mode) { 3837c8531848Syt160523 if (aidp->ai_dworddma & (1 << mode)) 3838c8531848Syt160523 break; 3839c8531848Syt160523 } 3840c8531848Syt160523 subcmd = ATF_XFRMOD_MDMA; 3841c8531848Syt160523 3842c8531848Syt160523 } else { 3843c8531848Syt160523 return (rval); 3844c8531848Syt160523 } 3845c8531848Syt160523 3846c8531848Syt160523 rval = ata_set_feature(ata_ctlp, ata_drvp, ATSF_SET_XFRMOD, 3847c8531848Syt160523 subcmd|mode); 3848c8531848Syt160523 3849c8531848Syt160523 return (rval); 3850c8531848Syt160523 } 3851