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