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