11709Smlf /*
21709Smlf * CDDL HEADER START
31709Smlf *
41709Smlf * The contents of this file are subject to the terms of the
52100Smlf * Common Development and Distribution License (the "License").
61709Smlf * You may not use this file except in compliance with the License.
71709Smlf *
81709Smlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91709Smlf * or http://www.opensolaris.org/os/licensing.
101709Smlf * See the License for the specific language governing permissions
111709Smlf * and limitations under the License.
121709Smlf *
131709Smlf * When distributing Covered Code, include this CDDL HEADER in each
141709Smlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151709Smlf * If applicable, add the following below this CDDL HEADER, with the
161709Smlf * fields enclosed by brackets "[]" replaced with your own identifying
171709Smlf * information: Portions Copyright [yyyy] [name of copyright owner]
181709Smlf *
191709Smlf * CDDL HEADER END
201709Smlf */
211709Smlf
221709Smlf /*
238550SSeth.Goldberg@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
241709Smlf * Use is subject to license terms.
251709Smlf */
261709Smlf
271709Smlf #include <sys/types.h>
281709Smlf #include <sys/modctl.h>
291709Smlf #include <sys/debug.h>
301709Smlf #include <sys/promif.h>
311709Smlf #include <sys/pci.h>
321709Smlf #include <sys/errno.h>
331709Smlf #include <sys/open.h>
341709Smlf #include <sys/uio.h>
351709Smlf #include <sys/cred.h>
364852Smlf #include <sys/cpu.h>
371709Smlf #include "ata_common.h"
381709Smlf #include "ata_disk.h"
391709Smlf #include "atapi.h"
401709Smlf #include "ata_blacklist.h"
411709Smlf #include "sil3xxx.h"
421709Smlf
431709Smlf /*
441709Smlf * Solaris Entry Points.
451709Smlf */
461709Smlf
471709Smlf static int ata_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
481709Smlf static int ata_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
491709Smlf static int ata_bus_ctl(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t o,
501709Smlf void *a, void *v);
511709Smlf static uint_t ata_intr(caddr_t arg);
521709Smlf
531709Smlf /*
541709Smlf * GHD Entry points
551709Smlf */
561709Smlf
571709Smlf static int ata_get_status(void *hba_handle, void *intr_status);
581709Smlf static void ata_process_intr(void *hba_handle, void *intr_status);
591709Smlf static int ata_hba_start(void *handle, gcmd_t *gcmdp);
601709Smlf static void ata_hba_complete(void *handle, gcmd_t *gcmdp, int do_callback);
611709Smlf static int ata_timeout_func(void *hba_handle, gcmd_t *gcmdp,
621709Smlf gtgt_t *gtgtp, gact_t action, int calltype);
631709Smlf
641709Smlf /*
651709Smlf * Local Function Prototypes
661709Smlf */
671709Smlf static int ata_prop_lookup_int(dev_t match_dev, dev_info_t *dip,
681709Smlf uint_t flags, char *name, int defvalue);
691709Smlf static int ata_ctlr_fsm(uchar_t fsm_func, ata_ctl_t *ata_ctlp,
701709Smlf ata_drv_t *ata_drvp, ata_pkt_t *ata_pktp,
711709Smlf int *DoneFlgp);
721709Smlf static void ata_destroy_controller(dev_info_t *dip);
731709Smlf static int ata_drive_type(uchar_t drvhd,
741709Smlf ddi_acc_handle_t io_hdl1, caddr_t ioaddr1,
751709Smlf ddi_acc_handle_t io_hdl2, caddr_t ioaddr2,
761709Smlf struct ata_id *ata_id_bufp);
771709Smlf static ata_ctl_t *ata_init_controller(dev_info_t *dip);
781709Smlf static ata_drv_t *ata_init_drive(ata_ctl_t *ata_ctlp,
791709Smlf uchar_t targ, uchar_t lun);
801709Smlf static int ata_init_drive_pcidma(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
811709Smlf dev_info_t *tdip);
821709Smlf static int ata_flush_cache(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp);
831709Smlf static void ata_init_pciide(dev_info_t *dip, ata_ctl_t *ata_ctlp);
841709Smlf static int ata_reset_bus(ata_ctl_t *ata_ctlp);
851709Smlf static int ata_setup_ioaddr(dev_info_t *dip,
861709Smlf ddi_acc_handle_t *iohandle1, caddr_t *ioaddr1p,
871709Smlf ddi_acc_handle_t *iohandle2, caddr_t *ioaddr2p,
881709Smlf ddi_acc_handle_t *bm_hdlp, caddr_t *bm_addrp);
891709Smlf static int ata_software_reset(ata_ctl_t *ata_ctlp);
901709Smlf static int ata_start_arq(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
911709Smlf ata_pkt_t *ata_pktp);
921709Smlf static int ata_strncmp(char *p1, char *p2, int cnt);
931709Smlf static void ata_uninit_drive(ata_drv_t *ata_drvp);
941709Smlf
951709Smlf static int ata_check_pciide_blacklist(dev_info_t *dip, uint_t flags);
961709Smlf static int ata_check_revert_to_defaults(ata_drv_t *ata_drvp);
971709Smlf static void ata_show_transfer_mode(ata_ctl_t *, ata_drv_t *);
981709Smlf static int ata_spec_init_controller(dev_info_t *dip);
991709Smlf
1005295Srandyf static void ata_init_pm(dev_info_t *);
1015295Srandyf static int ata_suspend(dev_info_t *);
1025295Srandyf static int ata_resume(dev_info_t *);
1035295Srandyf static int ata_power(dev_info_t *, int, int);
1045295Srandyf static int ata_change_power(dev_info_t *, uint8_t);
1055295Srandyf static int ata_is_pci(dev_info_t *);
1065603Sml40262 static void ata_disable_DMA(ata_drv_t *ata_drvp);
10710452SAda.Feng@Sun.COM static int ata_check_dma_mode(ata_drv_t *ata_drvp);
1081709Smlf
1091709Smlf /*
1101709Smlf * Local static data
1111709Smlf */
1121709Smlf static void *ata_state;
1131709Smlf
1141709Smlf static tmr_t ata_timer_conf; /* single timeout list for all instances */
1151709Smlf static int ata_watchdog_usec = 100000; /* check timeouts every 100 ms */
1161709Smlf
1171709Smlf int ata_hba_start_watchdog = 1000;
1181709Smlf int ata_process_intr_watchdog = 1000;
1191709Smlf int ata_reset_bus_watchdog = 1000;
1201709Smlf
1211709Smlf
1221709Smlf /*
1235295Srandyf * Use local or framework power management
1245295Srandyf */
1255295Srandyf
1265295Srandyf #ifdef ATA_USE_AUTOPM
1275295Srandyf #define ATA_BUSY_COMPONENT(d, c) ((void)pm_busy_component(d, c))
1285295Srandyf #define ATA_IDLE_COMPONENT(d, c) ((void)pm_idle_component(d, c))
1295295Srandyf #define ATA_RAISE_POWER(d, c, l) pm_raise_power(d, c, l)
1305295Srandyf #define ATA_LOWER_POWER(d, c, l) pm_lower_power(d, c, l)
1315295Srandyf #else
1325295Srandyf #define ATA_BUSY_COMPONENT(d, c)
1335295Srandyf #define ATA_IDLE_COMPONENT(d, c)
1345295Srandyf #define ATA_RAISE_POWER(d, c, l) ata_power(d, c, l)
1355295Srandyf #define ATA_LOWER_POWER(d, c, l) ata_power(d, c, l)
1365295Srandyf #endif
1375295Srandyf /*
1381709Smlf * number of seconds to wait during various operations
1391709Smlf */
1401709Smlf int ata_flush_delay = 5 * 1000000;
1411709Smlf uint_t ata_set_feature_wait = 4 * 1000000;
1421709Smlf uint_t ata_flush_cache_wait = 60 * 1000000; /* may take a long time */
1431709Smlf
1441709Smlf /*
1451709Smlf * Change this for SFF-8070i support. Currently SFF-8070i is
1461709Smlf * using a field in the IDENTIFY PACKET DEVICE response which
1471709Smlf * already seems to be in use by some vendor's drives. I suspect
1481709Smlf * SFF will either move their laslun field or provide a reliable
1491709Smlf * way to validate it.
1501709Smlf */
1511709Smlf int ata_enable_atapi_luns = FALSE;
1521709Smlf
1531709Smlf /*
1541709Smlf * set this to disable all DMA requests
1551709Smlf */
1561709Smlf int ata_dma_disabled = FALSE;
1571709Smlf
1581709Smlf /*
1591709Smlf * set this to TRUE to enable storing the IDENTIFY DEVICE result in the
1601709Smlf * "ata" or "atapi" property.
1611709Smlf */
1621709Smlf int ata_id_debug = FALSE;
1631709Smlf
1641709Smlf /*
1651709Smlf * set this to TRUE to enable logging device-capability data
1661709Smlf */
1671709Smlf int ata_capability_data = FALSE;
1681709Smlf
1691709Smlf /*
1701709Smlf * DMA selection message pointers
1711709Smlf */
1721709Smlf char *ata_cntrl_DMA_sel_msg;
1731709Smlf char *ata_dev_DMA_sel_msg;
1741709Smlf
1751709Smlf /*
1761709Smlf * bus nexus operations
1771709Smlf */
1781709Smlf static struct bus_ops ata_bus_ops;
1791709Smlf static struct bus_ops *scsa_bus_ops_p;
1801709Smlf
1811709Smlf /* ARGSUSED */
1821709Smlf static int
ata_open(dev_t * devp,int flag,int otyp,cred_t * cred_p)1831709Smlf ata_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
1841709Smlf {
1851709Smlf if (ddi_get_soft_state(ata_state, getminor(*devp)) == NULL)
1861709Smlf return (ENXIO);
1871709Smlf
1881709Smlf return (0);
1891709Smlf }
1901709Smlf
1911709Smlf /*
1921709Smlf * The purpose of this function is to pass the ioaddress of the controller
1931709Smlf * to the caller, specifically used for upgrade from pre-pciide
1941709Smlf * to pciide nodes
1951709Smlf */
1961709Smlf /* ARGSUSED */
1971709Smlf static int
ata_read(dev_t dev,struct uio * uio_p,cred_t * cred_p)1981709Smlf ata_read(dev_t dev, struct uio *uio_p, cred_t *cred_p)
1991709Smlf {
2001709Smlf ata_ctl_t *ata_ctlp;
2011709Smlf char buf[18];
2021709Smlf long len;
2031709Smlf
2041709Smlf ata_ctlp = ddi_get_soft_state(ata_state, getminor(dev));
2051709Smlf
2061709Smlf if (ata_ctlp == NULL)
2071709Smlf return (ENXIO);
2081709Smlf
2091709Smlf (void) sprintf(buf, "%p\n", (void *) ata_ctlp->ac_ioaddr1);
2101709Smlf
2111709Smlf len = strlen(buf) - uio_p->uio_offset;
2121709Smlf len = min(uio_p->uio_resid, len);
2131709Smlf if (len <= 0)
2141709Smlf return (0);
2151709Smlf
2161709Smlf return (uiomove((caddr_t)(buf + uio_p->uio_offset), len,
2171709Smlf UIO_READ, uio_p));
2181709Smlf }
2191709Smlf
2201709Smlf int
ata_devo_reset(dev_info_t * dip,ddi_reset_cmd_t cmd)2211709Smlf ata_devo_reset(
2221709Smlf dev_info_t *dip,
2231709Smlf ddi_reset_cmd_t cmd)
2241709Smlf {
2251709Smlf ata_ctl_t *ata_ctlp;
2261709Smlf ata_drv_t *ata_drvp;
2271709Smlf int instance;
2281709Smlf int i;
2291709Smlf int rc;
2301709Smlf int flush_okay;
2311709Smlf
2321709Smlf if (cmd != DDI_RESET_FORCE)
2331709Smlf return (0);
2341709Smlf
2351709Smlf instance = ddi_get_instance(dip);
2361709Smlf ata_ctlp = ddi_get_soft_state(ata_state, instance);
2371709Smlf
2381709Smlf if (!ata_ctlp)
2391709Smlf return (0);
2401709Smlf
2411709Smlf /*
2421709Smlf * reset ATA drives and flush the write cache of any drives
2431709Smlf */
2441709Smlf flush_okay = TRUE;
2451709Smlf for (i = 0; i < ATA_MAXTARG; i++) {
2461709Smlf if ((ata_drvp = CTL2DRV(ata_ctlp, i, 0)) == 0)
2471709Smlf continue;
2481709Smlf /* Don't revert to defaults for certain IBM drives */
2491709Smlf if ((ata_drvp->ad_flags & AD_DISK) != 0 &&
2501709Smlf ((ata_drvp->ad_flags & AD_NORVRT) == 0)) {
2511709Smlf /* Enable revert to defaults when reset */
2525295Srandyf (void) ata_set_feature(ata_ctlp, ata_drvp,
2535295Srandyf ATSF_ENA_REVPOD, 0);
2541709Smlf }
2551709Smlf
2561709Smlf /*
2571709Smlf * skip flush cache if device type is cdrom
2581709Smlf *
2591709Smlf * notes: the structure definitions for ata_drvp->ad_id are
2601709Smlf * defined for the ATA IDENTIFY_DEVICE, but if AD_ATAPI is set
2611709Smlf * the struct holds data for the ATAPI IDENTIFY_PACKET_DEVICE
2621709Smlf */
2631709Smlf if (!IS_CDROM(ata_drvp)) {
2641709Smlf
2651709Smlf /*
2661709Smlf * Try the ATA/ATAPI flush write cache command
2671709Smlf */
2681709Smlf rc = ata_flush_cache(ata_ctlp, ata_drvp);
2691709Smlf ADBG_WARN(("ata_flush_cache %s\n",
2705295Srandyf rc ? "okay" : "failed"));
2711709Smlf
2721709Smlf if (!rc)
2731709Smlf flush_okay = FALSE;
2741709Smlf }
2751709Smlf
2761709Smlf
2771709Smlf /*
2781709Smlf * do something else if flush cache not supported
2791709Smlf */
2801709Smlf }
2811709Smlf
2821709Smlf /*
2831709Smlf * just busy wait if any drive doesn't support FLUSH CACHE
2841709Smlf */
2851709Smlf if (!flush_okay)
2861709Smlf drv_usecwait(ata_flush_delay);
2871709Smlf return (0);
2881709Smlf }
2891709Smlf
2907656SSherry.Moore@Sun.COM /*
2917656SSherry.Moore@Sun.COM * quiesce(9E) entry point.
2927656SSherry.Moore@Sun.COM *
2937656SSherry.Moore@Sun.COM * This function is called when the system is single-threaded at high
2947656SSherry.Moore@Sun.COM * PIL with preemption disabled. Therefore, this function must not be
2957656SSherry.Moore@Sun.COM * blocked.
2967656SSherry.Moore@Sun.COM *
2977656SSherry.Moore@Sun.COM * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
2987656SSherry.Moore@Sun.COM * DDI_FAILURE indicates an error condition and should almost never happen.
2997656SSherry.Moore@Sun.COM */
3007656SSherry.Moore@Sun.COM int
ata_quiesce(dev_info_t * dip)3017656SSherry.Moore@Sun.COM ata_quiesce(dev_info_t *dip)
3027656SSherry.Moore@Sun.COM {
3037656SSherry.Moore@Sun.COM #ifdef ATA_DEBUG
3047656SSherry.Moore@Sun.COM /*
3057656SSherry.Moore@Sun.COM * Turn off debugging
3067656SSherry.Moore@Sun.COM */
3077656SSherry.Moore@Sun.COM ata_debug = 0;
3087656SSherry.Moore@Sun.COM #endif
3097656SSherry.Moore@Sun.COM
3107656SSherry.Moore@Sun.COM return (ata_devo_reset(dip, DDI_RESET_FORCE));
3117656SSherry.Moore@Sun.COM }
3127656SSherry.Moore@Sun.COM
3131709Smlf
3141709Smlf static struct cb_ops ata_cb_ops = {
3151709Smlf ata_open, /* open */
3161709Smlf nulldev, /* close */
3171709Smlf nodev, /* strategy */
3181709Smlf nodev, /* print */
3191709Smlf nodev, /* dump */
3201709Smlf ata_read, /* read */
3211709Smlf nodev, /* write */
3221709Smlf nodev, /* ioctl */
3231709Smlf nodev, /* devmap */
3241709Smlf nodev, /* mmap */
3251709Smlf nodev, /* segmap */
3261709Smlf nochpoll, /* chpoll */
3271709Smlf ddi_prop_op, /* prop_op */
3281709Smlf NULL, /* stream info */
3291709Smlf D_MP, /* driver compatibility flag */
3301709Smlf CB_REV, /* cb_ops revision */
3311709Smlf nodev, /* aread */
3321709Smlf nodev /* awrite */
3331709Smlf };
3341709Smlf
3351709Smlf static struct dev_ops ata_ops = {
3361709Smlf DEVO_REV, /* devo_rev, */
3371709Smlf 0, /* refcnt */
3381709Smlf ddi_getinfo_1to1, /* info */
3391709Smlf nulldev, /* identify */
3405162Smlf NULL, /* probe */
3411709Smlf ata_attach, /* attach */
3421709Smlf ata_detach, /* detach */
3431709Smlf ata_devo_reset, /* reset */
3441709Smlf &ata_cb_ops, /* driver operations */
3455295Srandyf NULL, /* bus operations */
3467656SSherry.Moore@Sun.COM ata_power, /* power */
3477656SSherry.Moore@Sun.COM ata_quiesce /* quiesce */
3481709Smlf };
3491709Smlf
3501709Smlf /* driver loadable module wrapper */
3511709Smlf static struct modldrv modldrv = {
3521709Smlf &mod_driverops, /* Type of module. This one is a driver */
3531709Smlf "ATA AT-bus attachment disk controller Driver", /* module name */
3541709Smlf &ata_ops, /* driver ops */
3551709Smlf };
3561709Smlf
3571709Smlf static struct modlinkage modlinkage = {
3581709Smlf MODREV_1, (void *)&modldrv, NULL
3591709Smlf };
3601709Smlf
3611709Smlf #ifdef ATA_DEBUG
3621709Smlf int ata_debug_init = FALSE;
3631709Smlf int ata_debug_attach = FALSE;
3641709Smlf
3651709Smlf int ata_debug = ADBG_FLAG_ERROR
3661709Smlf /* | ADBG_FLAG_ARQ */
3671709Smlf /* | ADBG_FLAG_INIT */
3681709Smlf /* | ADBG_FLAG_TRACE */
3691709Smlf /* | ADBG_FLAG_TRANSPORT */
3701709Smlf /* | ADBG_FLAG_WARN */
3711709Smlf ;
3721709Smlf #endif
3731709Smlf
3741709Smlf int
_init(void)3751709Smlf _init(void)
3761709Smlf {
3771709Smlf int err;
3781709Smlf
3791709Smlf #ifdef ATA_DEBUG
3801709Smlf if (ata_debug_init)
3811709Smlf debug_enter("\nATA _INIT\n");
3821709Smlf #endif
3831709Smlf
3841709Smlf if ((err = ddi_soft_state_init(&ata_state, sizeof (ata_ctl_t), 0)) != 0)
3851709Smlf return (err);
3861709Smlf
3871709Smlf if ((err = scsi_hba_init(&modlinkage)) != 0) {
3881709Smlf ddi_soft_state_fini(&ata_state);
3891709Smlf return (err);
3901709Smlf }
3911709Smlf
3921709Smlf /* save pointer to SCSA provided bus_ops struct */
3931709Smlf scsa_bus_ops_p = ata_ops.devo_bus_ops;
3941709Smlf
3951709Smlf /* make a copy of SCSA bus_ops */
3961709Smlf ata_bus_ops = *(ata_ops.devo_bus_ops);
3971709Smlf
3981709Smlf /*
3991709Smlf * Modify our bus_ops to call our routines. Our implementation
4001709Smlf * will determine if the device is ATA or ATAPI/SCSA and react
4011709Smlf * accordingly.
4021709Smlf */
4031709Smlf ata_bus_ops.bus_ctl = ata_bus_ctl;
4041709Smlf
4051709Smlf /* patch our bus_ops into the dev_ops struct */
4061709Smlf ata_ops.devo_bus_ops = &ata_bus_ops;
4071709Smlf
4081709Smlf if ((err = mod_install(&modlinkage)) != 0) {
4091709Smlf scsi_hba_fini(&modlinkage);
4101709Smlf ddi_soft_state_fini(&ata_state);
4111709Smlf }
4121709Smlf
4131709Smlf /*
4141709Smlf * Initialize the per driver timer info.
4151709Smlf */
4161709Smlf
4171709Smlf ghd_timer_init(&ata_timer_conf, drv_usectohz(ata_watchdog_usec));
4181709Smlf
4191709Smlf return (err);
4201709Smlf }
4211709Smlf
4221709Smlf int
_fini(void)4231709Smlf _fini(void)
4241709Smlf {
4251709Smlf int err;
4261709Smlf
4271709Smlf if ((err = mod_remove(&modlinkage)) == 0) {
4281709Smlf ghd_timer_fini(&ata_timer_conf);
4291709Smlf scsi_hba_fini(&modlinkage);
4301709Smlf ddi_soft_state_fini(&ata_state);
4311709Smlf }
4321709Smlf
4331709Smlf return (err);
4341709Smlf }
4351709Smlf
4361709Smlf int
_info(struct modinfo * modinfop)4371709Smlf _info(struct modinfo *modinfop)
4381709Smlf {
4391709Smlf return (mod_info(&modlinkage, modinfop));
4401709Smlf }
4411709Smlf
4421709Smlf
4431709Smlf /*
4441709Smlf *
4451709Smlf * driver attach entry point
4461709Smlf *
4471709Smlf */
4481709Smlf
4491709Smlf static int
ata_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)4501709Smlf ata_attach(
4511709Smlf dev_info_t *dip,
4521709Smlf ddi_attach_cmd_t cmd)
4531709Smlf {
4541709Smlf ata_ctl_t *ata_ctlp;
4551709Smlf ata_drv_t *ata_drvp;
4561709Smlf ata_drv_t *first_drvp = NULL;
4571709Smlf uchar_t targ;
4581709Smlf uchar_t lun;
4591709Smlf uchar_t lastlun;
4601709Smlf int atapi_count = 0;
4611709Smlf int disk_count = 0;
4621709Smlf
4631709Smlf ADBG_TRACE(("ata_attach entered\n"));
4641709Smlf #ifdef ATA_DEBUG
4651709Smlf if (ata_debug_attach)
4661709Smlf debug_enter("\nATA_ATTACH\n\n");
4671709Smlf #endif
4681709Smlf
4695295Srandyf switch (cmd) {
4705295Srandyf case DDI_ATTACH:
4715295Srandyf break;
4725295Srandyf case DDI_RESUME:
4735295Srandyf return (ata_resume(dip));
4745295Srandyf default:
4751709Smlf return (DDI_FAILURE);
4765295Srandyf }
4771709Smlf
4781709Smlf /* initialize controller */
4791709Smlf ata_ctlp = ata_init_controller(dip);
4801709Smlf
4811709Smlf if (ata_ctlp == NULL)
4821709Smlf goto errout;
4831709Smlf
4841709Smlf mutex_enter(&ata_ctlp->ac_ccc.ccc_hba_mutex);
4851709Smlf
4861709Smlf /* initialize drives */
4871709Smlf
4881709Smlf for (targ = 0; targ < ATA_MAXTARG; targ++) {
4891709Smlf
4901709Smlf ata_drvp = ata_init_drive(ata_ctlp, targ, 0);
4911709Smlf if (ata_drvp == NULL)
4921709Smlf continue;
4931709Smlf
4941709Smlf if (first_drvp == NULL)
4951709Smlf first_drvp = ata_drvp;
4961709Smlf
4971709Smlf if (ATAPIDRV(ata_drvp)) {
4981709Smlf atapi_count++;
4991709Smlf lastlun = ata_drvp->ad_id.ai_lastlun;
5001709Smlf } else {
5011709Smlf disk_count++;
5021709Smlf lastlun = 0;
5031709Smlf }
5041709Smlf
5051709Smlf /*
5061709Smlf * LUN support is currently disabled. Check with SFF-8070i
5071709Smlf * before enabling.
5081709Smlf */
5091709Smlf if (!ata_enable_atapi_luns)
5101709Smlf lastlun = 0;
5111709Smlf
5121709Smlf /* Initialize higher LUNs, if there are any */
5131709Smlf for (lun = 1; lun <= lastlun && lun < ATA_MAXLUN; lun++) {
5141709Smlf if ((ata_drvp =
5151709Smlf ata_init_drive(ata_ctlp, targ, lun)) != NULL) {
5161709Smlf ata_show_transfer_mode(ata_ctlp, ata_drvp);
5171709Smlf }
5181709Smlf }
5191709Smlf }
5201709Smlf
5211709Smlf if ((atapi_count == 0) && (disk_count == 0)) {
5221709Smlf ADBG_WARN(("ata_attach: no drives detected\n"));
5231709Smlf goto errout1;
5241709Smlf }
5251709Smlf
5261709Smlf /*
5271709Smlf * Always make certain that a valid drive is selected so
5281709Smlf * that routines which poll the status register don't get
5291709Smlf * confused by non-existent drives.
5301709Smlf */
5311709Smlf ddi_put8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_drvhd,
5325295Srandyf first_drvp->ad_drive_bits);
5334852Smlf ata_nsecwait(400);
5341709Smlf
5351709Smlf /*
5361709Smlf * make certain the drive selected
5371709Smlf */
5381709Smlf if (!ata_wait(ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2,
5395295Srandyf 0, ATS_BSY, 5000000)) {
5401709Smlf ADBG_ERROR(("ata_attach: select failed\n"));
5411709Smlf }
5421709Smlf
5431709Smlf /*
5441709Smlf * initialize atapi/ata_dsk modules if we have at least
5451709Smlf * one drive of that type.
5461709Smlf */
5471709Smlf
5481709Smlf if (atapi_count) {
5491709Smlf if (!atapi_attach(ata_ctlp))
5501709Smlf goto errout1;
5511709Smlf ata_ctlp->ac_flags |= AC_ATAPI_INIT;
5521709Smlf }
5531709Smlf
5541709Smlf if (disk_count) {
5551709Smlf if (!ata_disk_attach(ata_ctlp))
5561709Smlf goto errout1;
5571709Smlf ata_ctlp->ac_flags |= AC_DISK_INIT;
5581709Smlf }
5591709Smlf
5601709Smlf /*
5611709Smlf * make certain the interrupt and error latches are clear
5621709Smlf */
5631709Smlf if (ata_ctlp->ac_pciide) {
5641709Smlf
5651709Smlf int instance = ddi_get_instance(dip);
5661709Smlf if (ddi_create_minor_node(dip, "control", S_IFCHR, instance,
5671709Smlf DDI_PSEUDO, 0) != DDI_SUCCESS) {
5681709Smlf goto errout1;
5691709Smlf }
5701709Smlf
5711709Smlf (void) ata_pciide_status_clear(ata_ctlp);
5721709Smlf
5731709Smlf }
5741709Smlf
5751709Smlf /*
5761709Smlf * enable the interrupt handler and drop the mutex
5771709Smlf */
5781709Smlf ata_ctlp->ac_flags |= AC_ATTACHED;
5791709Smlf mutex_exit(&ata_ctlp->ac_ccc.ccc_hba_mutex);
5801709Smlf
5815295Srandyf ata_init_pm(dip);
5825295Srandyf
5831709Smlf ddi_report_dev(dip);
5841709Smlf return (DDI_SUCCESS);
5851709Smlf
5861709Smlf errout1:
5871709Smlf mutex_exit(&ata_ctlp->ac_ccc.ccc_hba_mutex);
5881709Smlf errout:
5891709Smlf (void) ata_detach(dip, DDI_DETACH);
5901709Smlf return (DDI_FAILURE);
5911709Smlf }
5921709Smlf
5931709Smlf /* driver detach entry point */
5941709Smlf
5951709Smlf static int
ata_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)5961709Smlf ata_detach(
5971709Smlf dev_info_t *dip,
5981709Smlf ddi_detach_cmd_t cmd)
5991709Smlf {
6001709Smlf ata_ctl_t *ata_ctlp;
6011709Smlf ata_drv_t *ata_drvp;
6021709Smlf int instance;
6031709Smlf int i;
6041709Smlf int j;
6051709Smlf
6061709Smlf ADBG_TRACE(("ata_detach entered\n"));
6071709Smlf
6085295Srandyf switch (cmd) {
6095295Srandyf case DDI_DETACH:
6105295Srandyf break;
6115295Srandyf case DDI_SUSPEND:
6125295Srandyf return (ata_suspend(dip));
6135295Srandyf default:
6141709Smlf return (DDI_FAILURE);
6155295Srandyf }
6161709Smlf
6171709Smlf instance = ddi_get_instance(dip);
6181709Smlf ata_ctlp = ddi_get_soft_state(ata_state, instance);
6191709Smlf
6201709Smlf if (!ata_ctlp)
6211709Smlf return (DDI_SUCCESS);
6221709Smlf
6235295Srandyf if (ata_ctlp->ac_pm_support) {
6245295Srandyf ATA_BUSY_COMPONENT(dip, 0);
6255295Srandyf if (ata_ctlp->ac_pm_level != PM_LEVEL_D0) {
6265295Srandyf if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) !=
6275295Srandyf DDI_SUCCESS) {
6285295Srandyf ATA_IDLE_COMPONENT(dip, 0);
6295295Srandyf return (DDI_FAILURE);
6305295Srandyf }
6315295Srandyf }
6325295Srandyf (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components");
6335295Srandyf }
6341709Smlf ata_ctlp->ac_flags &= ~AC_ATTACHED;
6351709Smlf
6361709Smlf /* destroy ata module */
6371709Smlf if (ata_ctlp->ac_flags & AC_DISK_INIT)
6381709Smlf ata_disk_detach(ata_ctlp);
6391709Smlf
6401709Smlf /* destroy atapi module */
6411709Smlf if (ata_ctlp->ac_flags & AC_ATAPI_INIT)
6421709Smlf atapi_detach(ata_ctlp);
6431709Smlf
6441709Smlf ddi_remove_minor_node(dip, NULL);
6451709Smlf
6461709Smlf /* destroy drives */
6471709Smlf for (i = 0; i < ATA_MAXTARG; i++) {
6481709Smlf for (j = 0; j < ATA_MAXLUN; j++) {
6491709Smlf ata_drvp = CTL2DRV(ata_ctlp, i, j);
6501709Smlf if (ata_drvp != NULL)
6511709Smlf ata_uninit_drive(ata_drvp);
6521709Smlf }
6531709Smlf }
6541709Smlf
6551709Smlf if (ata_ctlp->ac_iohandle1)
6561709Smlf ddi_regs_map_free(&ata_ctlp->ac_iohandle1);
6571709Smlf if (ata_ctlp->ac_iohandle2)
6581709Smlf ddi_regs_map_free(&ata_ctlp->ac_iohandle2);
6591709Smlf if (ata_ctlp->ac_bmhandle)
6601709Smlf ddi_regs_map_free(&ata_ctlp->ac_bmhandle);
6611709Smlf
6621709Smlf /* destroy controller */
6631709Smlf ata_destroy_controller(dip);
6641709Smlf
6655162Smlf ddi_prop_remove_all(dip);
6665162Smlf
6671709Smlf return (DDI_SUCCESS);
6681709Smlf }
6691709Smlf
6701709Smlf /*
6711709Smlf * Nexus driver bus_ctl entry point
6721709Smlf */
6731709Smlf /*ARGSUSED*/
6741709Smlf static int
ata_bus_ctl(dev_info_t * d,dev_info_t * r,ddi_ctl_enum_t o,void * a,void * v)6751709Smlf ata_bus_ctl(
6761709Smlf dev_info_t *d,
6771709Smlf dev_info_t *r,
6781709Smlf ddi_ctl_enum_t o,
6791709Smlf void *a,
6801709Smlf void *v)
6811709Smlf {
6821709Smlf dev_info_t *tdip;
6831709Smlf int target_type;
6841709Smlf int rc;
6851709Smlf char *bufp;
6861709Smlf
6871709Smlf ADBG_TRACE(("ata_bus_ctl entered\n"));
6881709Smlf
6891709Smlf switch (o) {
6901709Smlf
6911709Smlf case DDI_CTLOPS_SIDDEV:
6921709Smlf return (DDI_FAILURE);
6931709Smlf
6941709Smlf case DDI_CTLOPS_IOMIN:
6951709Smlf
6961709Smlf /*
6971709Smlf * Since we use PIO, we return a minimum I/O size of
6981709Smlf * one byte. This will need to be updated when we
6991709Smlf * implement DMA support
7001709Smlf */
7011709Smlf
7021709Smlf *((int *)v) = 1;
7031709Smlf return (DDI_SUCCESS);
7041709Smlf
7051709Smlf case DDI_CTLOPS_DMAPMAPC:
7061709Smlf case DDI_CTLOPS_REPORTINT:
7071709Smlf case DDI_CTLOPS_REGSIZE:
7081709Smlf case DDI_CTLOPS_NREGS:
7091709Smlf case DDI_CTLOPS_SLAVEONLY:
7101709Smlf case DDI_CTLOPS_AFFINITY:
7111709Smlf case DDI_CTLOPS_POKE:
7121709Smlf case DDI_CTLOPS_PEEK:
7131709Smlf
7141709Smlf /* These ops shouldn't be called by a target driver */
7151709Smlf ADBG_ERROR(("ata_bus_ctl: %s%d: invalid op (%d) from %s%d\n",
7165295Srandyf ddi_driver_name(d), ddi_get_instance(d), o,
7175295Srandyf ddi_driver_name(r), ddi_get_instance(r)));
7181709Smlf
7191709Smlf return (DDI_FAILURE);
7201709Smlf
7211709Smlf case DDI_CTLOPS_REPORTDEV:
7221709Smlf case DDI_CTLOPS_INITCHILD:
7231709Smlf case DDI_CTLOPS_UNINITCHILD:
7241709Smlf
7251709Smlf /* these require special handling below */
7261709Smlf break;
7271709Smlf
7281709Smlf default:
7291709Smlf return (ddi_ctlops(d, r, o, a, v));
7301709Smlf }
7311709Smlf
7321709Smlf /* get targets dip */
7331709Smlf
7341709Smlf if (o == DDI_CTLOPS_INITCHILD || o == DDI_CTLOPS_UNINITCHILD)
7351709Smlf tdip = (dev_info_t *)a;
7361709Smlf else
7371709Smlf tdip = r;
7381709Smlf
7391709Smlf /*
7401709Smlf * XXX - Get class of target
7411709Smlf * Before the "class" entry in a conf file becomes
7421709Smlf * a real property, we use an additional property
7431709Smlf * tentatively called "class_prop". We will require that
7441709Smlf * new classes (ie. direct) export "class_prop".
7451709Smlf * SCSA target drivers will not have this property, so
7461709Smlf * no property implies SCSA.
7471709Smlf */
7481709Smlf if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS,
7491709Smlf "class", &bufp) == DDI_PROP_SUCCESS) ||
7501709Smlf (ddi_prop_lookup_string(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS,
7511709Smlf "class_prop", &bufp) == DDI_PROP_SUCCESS)) {
7521709Smlf if (strcmp(bufp, "dada") == 0)
7531709Smlf target_type = ATA_DEV_DISK;
7541709Smlf else if (strcmp(bufp, "scsi") == 0)
7551709Smlf target_type = ATA_DEV_ATAPI;
7561709Smlf else {
7571709Smlf ADBG_WARN(("ata_bus_ctl: invalid target class %s\n",
7585295Srandyf bufp));
7591709Smlf ddi_prop_free(bufp);
7601709Smlf return (DDI_FAILURE);
7611709Smlf }
7621709Smlf ddi_prop_free(bufp);
7631709Smlf } else {
7641709Smlf target_type = ATA_DEV_ATAPI; /* no class prop, assume SCSI */
7651709Smlf }
7661709Smlf
7671709Smlf if (o == DDI_CTLOPS_INITCHILD) {
7681709Smlf int instance = ddi_get_instance(d);
7691709Smlf ata_ctl_t *ata_ctlp = ddi_get_soft_state(ata_state, instance);
7701709Smlf ata_drv_t *ata_drvp;
7711709Smlf int targ;
7721709Smlf int lun;
7731709Smlf int drive_type;
7741709Smlf char *disk_prop;
7751709Smlf char *class_prop;
7761709Smlf
7771709Smlf if (ata_ctlp == NULL) {
7781709Smlf ADBG_WARN(("ata_bus_ctl: failed to find ctl struct\n"));
7791709Smlf return (DDI_FAILURE);
7801709Smlf }
7811709Smlf
7821709Smlf /* get (target,lun) of child device */
7831709Smlf
7841709Smlf targ = ddi_prop_get_int(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS,
7855295Srandyf "target", -1);
7861709Smlf if (targ == -1) {
7871709Smlf ADBG_WARN(("ata_bus_ctl: failed to get targ num\n"));
7881709Smlf return (DDI_FAILURE);
7891709Smlf }
7901709Smlf
7911709Smlf lun = ddi_prop_get_int(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS,
7925295Srandyf "lun", 0);
7931709Smlf
7941709Smlf if ((targ < 0) || (targ >= ATA_MAXTARG) ||
7955295Srandyf (lun < 0) || (lun >= ATA_MAXLUN)) {
7961709Smlf return (DDI_FAILURE);
7971709Smlf }
7981709Smlf
7991709Smlf ata_drvp = CTL2DRV(ata_ctlp, targ, lun);
8001709Smlf
8011709Smlf if (ata_drvp == NULL)
8021709Smlf return (DDI_FAILURE); /* no drive */
8031709Smlf
8041709Smlf /* get type of device */
8051709Smlf
8061709Smlf if (ATAPIDRV(ata_drvp))
8071709Smlf drive_type = ATA_DEV_ATAPI;
8081709Smlf else
8091709Smlf drive_type = ATA_DEV_DISK;
8101709Smlf
8111709Smlf /*
8121709Smlf * Check for special handling when child driver is
8131709Smlf * cmdk (which morphs to the correct interface)
8141709Smlf */
8151709Smlf if (strcmp(ddi_get_name(tdip), "cmdk") == 0) {
8161709Smlf
8171709Smlf if ((target_type == ATA_DEV_DISK) &&
8185295Srandyf (target_type != drive_type))
8191709Smlf return (DDI_FAILURE);
8201709Smlf
8211709Smlf target_type = drive_type;
8221709Smlf
8231709Smlf if (drive_type == ATA_DEV_ATAPI) {
8241709Smlf class_prop = "scsi";
8251709Smlf } else {
8261709Smlf disk_prop = "dadk";
8271709Smlf class_prop = "dada";
8281709Smlf
8291709Smlf if (ndi_prop_update_string(DDI_DEV_T_NONE, tdip,
8301709Smlf "disk", disk_prop) != DDI_PROP_SUCCESS) {
8311709Smlf ADBG_WARN(("ata_bus_ctl: failed to "
8325295Srandyf "create disk prop\n"));
8331709Smlf return (DDI_FAILURE);
8345295Srandyf }
8351709Smlf }
8361709Smlf
8371709Smlf if (ndi_prop_update_string(DDI_DEV_T_NONE, tdip,
8381709Smlf "class_prop", class_prop) != DDI_PROP_SUCCESS) {
8391709Smlf ADBG_WARN(("ata_bus_ctl: failed to "
8401709Smlf "create class prop\n"));
8411709Smlf return (DDI_FAILURE);
8421709Smlf }
8431709Smlf }
8441709Smlf
8451709Smlf /* Check that target class matches the device */
8461709Smlf
8471709Smlf if (target_type != drive_type)
8481709Smlf return (DDI_FAILURE);
8491709Smlf
8501709Smlf /* save pointer to drive struct for ata_disk_bus_ctl */
8511709Smlf ddi_set_driver_private(tdip, ata_drvp);
8521709Smlf
8531709Smlf /*
8541709Smlf * Determine whether to enable DMA support for this drive. This
8551709Smlf * check is deferred to this point so that the various dma
8561709Smlf * properties could reside on the devinfo node should finer
8571709Smlf * grained dma control be required.
8581709Smlf */
8595603Sml40262 if (ata_drvp->ad_pciide_dma == ATA_DMA_UNINITIALIZED) {
8605603Sml40262 ata_drvp->ad_pciide_dma =
8615603Sml40262 ata_init_drive_pcidma(ata_ctlp, ata_drvp, tdip);
8625603Sml40262 ata_show_transfer_mode(ata_ctlp, ata_drvp);
8635603Sml40262 }
8641709Smlf }
8651709Smlf
8661709Smlf if (target_type == ATA_DEV_ATAPI) {
8671709Smlf rc = scsa_bus_ops_p->bus_ctl(d, r, o, a, v);
8681709Smlf } else {
8691709Smlf rc = ata_disk_bus_ctl(d, r, o, a, v);
8701709Smlf }
8711709Smlf
8721709Smlf return (rc);
8731709Smlf }
8741709Smlf
8751709Smlf /*
8761709Smlf *
8771709Smlf * GHD ccc_hba_complete callback
8781709Smlf *
8791709Smlf */
8801709Smlf
8811709Smlf /* ARGSUSED */
8821709Smlf static void
ata_hba_complete(void * hba_handle,gcmd_t * gcmdp,int do_callback)8831709Smlf ata_hba_complete(
8841709Smlf void *hba_handle,
8851709Smlf gcmd_t *gcmdp,
8861709Smlf int do_callback)
8871709Smlf {
8881709Smlf ata_drv_t *ata_drvp;
8891709Smlf ata_pkt_t *ata_pktp;
8901709Smlf
8911709Smlf ADBG_TRACE(("ata_hba_complete entered\n"));
8921709Smlf
8931709Smlf ata_drvp = GCMD2DRV(gcmdp);
8941709Smlf ata_pktp = GCMD2APKT(gcmdp);
8951709Smlf if (ata_pktp->ap_complete)
8961709Smlf (*ata_pktp->ap_complete)(ata_drvp, ata_pktp,
8975295Srandyf do_callback);
8981709Smlf }
8991709Smlf
9001709Smlf /* GHD ccc_timeout_func callback */
9011709Smlf
9021709Smlf /* ARGSUSED */
9031709Smlf static int
ata_timeout_func(void * hba_handle,gcmd_t * gcmdp,gtgt_t * gtgtp,gact_t action,int calltype)9041709Smlf ata_timeout_func(
9051709Smlf void *hba_handle,
9061709Smlf gcmd_t *gcmdp,
9071709Smlf gtgt_t *gtgtp,
9081709Smlf gact_t action,
9091709Smlf int calltype)
9101709Smlf {
9111709Smlf ata_ctl_t *ata_ctlp;
9121709Smlf ata_pkt_t *ata_pktp;
9135603Sml40262 ata_drv_t *ata_drvp;
9141709Smlf
9151709Smlf ADBG_TRACE(("ata_timeout_func entered\n"));
9161709Smlf
9171709Smlf ata_ctlp = (ata_ctl_t *)hba_handle;
9181709Smlf
9191709Smlf if (gcmdp != NULL)
9201709Smlf ata_pktp = GCMD2APKT(gcmdp);
9211709Smlf else
9221709Smlf ata_pktp = NULL;
9231709Smlf
9241709Smlf switch (action) {
9251709Smlf case GACTION_EARLY_ABORT:
9261709Smlf /* abort before request was started */
9271709Smlf if (ata_pktp != NULL) {
9281709Smlf ata_pktp->ap_flags |= AP_ABORT;
9291709Smlf }
9301709Smlf ghd_complete(&ata_ctlp->ac_ccc, gcmdp);
9311709Smlf return (TRUE);
9321709Smlf
9331709Smlf case GACTION_EARLY_TIMEOUT:
9341709Smlf /* timeout before request was started */
9351709Smlf if (ata_pktp != NULL) {
9361709Smlf ata_pktp->ap_flags |= AP_TIMEOUT;
9371709Smlf }
9381709Smlf ghd_complete(&ata_ctlp->ac_ccc, gcmdp);
9391709Smlf return (TRUE);
9401709Smlf
9411709Smlf case GACTION_RESET_TARGET:
9421709Smlf /*
9431709Smlf * Reset a device is not supported. Resetting a specific
9441709Smlf * device can't be done at all to an ATA device and if
9451709Smlf * you send a RESET to an ATAPI device you have to
9461709Smlf * reset the whole bus to make certain both devices
9471709Smlf * on the bus stay in sync regarding which device is
9481709Smlf * the currently selected one.
9491709Smlf */
9501709Smlf return (FALSE);
9511709Smlf
9521709Smlf case GACTION_RESET_BUS:
9531709Smlf /*
9541709Smlf * Issue bus reset and reinitialize both drives.
9551709Smlf * But only if this is a timed-out request. Target
9561709Smlf * driver reset requests are ignored because ATA
9571709Smlf * and ATAPI devices shouldn't be gratuitously reset.
9585603Sml40262 * Also disable DMA if it is a CF device.
9591709Smlf */
9601709Smlf if (gcmdp == NULL)
9611709Smlf break;
9625603Sml40262 ata_drvp = GCMD2DRV(gcmdp);
9635603Sml40262 if (ata_drvp != NULL)
9645603Sml40262 if (ata_drvp->ad_id.ai_config == ATA_ID_CF_TO_ATA)
9655603Sml40262 ata_disable_DMA(ata_drvp);
9661709Smlf return (ata_reset_bus(ata_ctlp));
9671709Smlf default:
9681709Smlf break;
9691709Smlf }
9701709Smlf return (FALSE);
9711709Smlf }
9721709Smlf
9731709Smlf /*
9741709Smlf *
9751709Smlf * Initialize controller's soft-state structure
9761709Smlf *
9771709Smlf */
9781709Smlf
9791709Smlf static ata_ctl_t *
ata_init_controller(dev_info_t * dip)9801709Smlf ata_init_controller(
9811709Smlf dev_info_t *dip)
9821709Smlf {
9831709Smlf ata_ctl_t *ata_ctlp;
9841709Smlf int instance;
9851709Smlf caddr_t ioaddr1;
9861709Smlf caddr_t ioaddr2;
9871709Smlf
9881709Smlf ADBG_TRACE(("ata_init_controller entered\n"));
9891709Smlf
9901709Smlf instance = ddi_get_instance(dip);
9911709Smlf
9921709Smlf /* allocate controller structure */
9931709Smlf if (ddi_soft_state_zalloc(ata_state, instance) != DDI_SUCCESS) {
9941709Smlf ADBG_WARN(("ata_init_controller: soft_state_zalloc failed\n"));
9951709Smlf return (NULL);
9961709Smlf }
9971709Smlf
9981709Smlf ata_ctlp = ddi_get_soft_state(ata_state, instance);
9991709Smlf
10001709Smlf if (ata_ctlp == NULL) {
10011709Smlf ADBG_WARN(("ata_init_controller: failed to find "
10025295Srandyf "controller struct\n"));
10031709Smlf return (NULL);
10041709Smlf }
10051709Smlf
10061709Smlf /*
10071709Smlf * initialize per-controller data
10081709Smlf */
10091709Smlf ata_ctlp->ac_dip = dip;
10101709Smlf ata_ctlp->ac_arq_pktp = kmem_zalloc(sizeof (ata_pkt_t), KM_SLEEP);
10111709Smlf
10121709Smlf /*
10131709Smlf * map the device registers
10141709Smlf */
10151709Smlf if (!ata_setup_ioaddr(dip, &ata_ctlp->ac_iohandle1, &ioaddr1,
10165295Srandyf &ata_ctlp->ac_iohandle2, &ioaddr2,
10175295Srandyf &ata_ctlp->ac_bmhandle, &ata_ctlp->ac_bmaddr)) {
10181709Smlf (void) ata_detach(dip, DDI_DETACH);
10191709Smlf return (NULL);
10201709Smlf }
10211709Smlf
10221709Smlf ADBG_INIT(("ata_init_controller: ioaddr1 = 0x%p, ioaddr2 = 0x%p\n",
10235295Srandyf ioaddr1, ioaddr2));
10241709Smlf
10251709Smlf /*
10261709Smlf * Do ARQ setup
10271709Smlf */
10281709Smlf atapi_init_arq(ata_ctlp);
10291709Smlf
10301709Smlf /*
10311709Smlf * Do PCI-IDE setup
10321709Smlf */
10331709Smlf ata_init_pciide(dip, ata_ctlp);
10341709Smlf
10351709Smlf /*
10361709Smlf * port addresses associated with ioaddr1
10371709Smlf */
10381709Smlf ata_ctlp->ac_ioaddr1 = ioaddr1;
10391709Smlf ata_ctlp->ac_data = (ushort_t *)ioaddr1 + AT_DATA;
10401709Smlf ata_ctlp->ac_error = (uchar_t *)ioaddr1 + AT_ERROR;
10411709Smlf ata_ctlp->ac_feature = (uchar_t *)ioaddr1 + AT_FEATURE;
10421709Smlf ata_ctlp->ac_count = (uchar_t *)ioaddr1 + AT_COUNT;
10431709Smlf ata_ctlp->ac_sect = (uchar_t *)ioaddr1 + AT_SECT;
10441709Smlf ata_ctlp->ac_lcyl = (uchar_t *)ioaddr1 + AT_LCYL;
10451709Smlf ata_ctlp->ac_hcyl = (uchar_t *)ioaddr1 + AT_HCYL;
10461709Smlf ata_ctlp->ac_drvhd = (uchar_t *)ioaddr1 + AT_DRVHD;
10471709Smlf ata_ctlp->ac_status = (uchar_t *)ioaddr1 + AT_STATUS;
10481709Smlf ata_ctlp->ac_cmd = (uchar_t *)ioaddr1 + AT_CMD;
10491709Smlf
10501709Smlf /*
10511709Smlf * port addresses associated with ioaddr2
10521709Smlf */
10531709Smlf ata_ctlp->ac_ioaddr2 = ioaddr2;
10541709Smlf ata_ctlp->ac_altstatus = (uchar_t *)ioaddr2 + AT_ALTSTATUS;
10551709Smlf ata_ctlp->ac_devctl = (uchar_t *)ioaddr2 + AT_DEVCTL;
10561709Smlf
10571709Smlf /*
10581709Smlf * If AC_BSY_WAIT needs to be set for laptops that do
10591709Smlf * suspend/resume but do not correctly wait for the busy bit to
10601709Smlf * drop after a resume.
10611709Smlf */
10621709Smlf ata_ctlp->ac_timing_flags = ddi_prop_get_int(DDI_DEV_T_ANY,
10635295Srandyf dip, DDI_PROP_DONTPASS, "timing_flags", 0);
10641709Smlf /*
10651709Smlf * get max transfer size, default to 256 sectors
10661709Smlf */
10671709Smlf ata_ctlp->ac_max_transfer = ddi_prop_get_int(DDI_DEV_T_ANY,
10685295Srandyf dip, DDI_PROP_DONTPASS, "max_transfer", 0x100);
10691709Smlf if (ata_ctlp->ac_max_transfer < 1)
10701709Smlf ata_ctlp->ac_max_transfer = 1;
10711709Smlf if (ata_ctlp->ac_max_transfer > 0x100)
10721709Smlf ata_ctlp->ac_max_transfer = 0x100;
10731709Smlf
10741709Smlf /*
10751709Smlf * Get the standby timer value
10761709Smlf */
10771709Smlf ata_ctlp->ac_standby_time = ddi_prop_get_int(DDI_DEV_T_ANY,
10785295Srandyf dip, DDI_PROP_DONTPASS, "standby", -1);
10791709Smlf
10801709Smlf /*
10811709Smlf * If this is a /pci/pci-ide instance check to see if
10821709Smlf * it's supposed to be attached as an /isa/ata
10831709Smlf */
10841709Smlf if (ata_ctlp->ac_pciide) {
10851709Smlf static char prop_buf[] = "SUNW-ata-ffff-isa";
10861709Smlf int addr1 = (intptr_t)ioaddr1;
10871709Smlf
10881709Smlf
10891709Smlf if (addr1 < 0 || addr1 > 0xffff) {
10901709Smlf (void) ata_detach(dip, DDI_DETACH);
10911709Smlf return (NULL);
10921709Smlf }
10931709Smlf (void) sprintf(prop_buf, "SUNW-ata-%04x-isa",
10945295Srandyf addr1);
10951709Smlf if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(),
10965295Srandyf DDI_PROP_DONTPASS, prop_buf)) {
10971709Smlf (void) ata_detach(dip, DDI_DETACH);
10981709Smlf return (NULL);
10991709Smlf }
11001709Smlf }
11011709Smlf
11021709Smlf /* Init controller specific stuff */
11031709Smlf (void) ata_spec_init_controller(dip);
11041709Smlf
11051709Smlf /*
11061709Smlf * initialize GHD
11071709Smlf */
11081709Smlf
11091709Smlf GHD_WAITQ_INIT(&ata_ctlp->ac_ccc.ccc_waitq, NULL, 1);
11101709Smlf
11111709Smlf if (!ghd_register("ata", &ata_ctlp->ac_ccc, dip, 0, ata_ctlp,
11125295Srandyf atapi_ccballoc, atapi_ccbfree,
11135295Srandyf ata_pciide_dma_sg_func, ata_hba_start,
11145295Srandyf ata_hba_complete, ata_intr,
11155295Srandyf ata_get_status, ata_process_intr, ata_timeout_func,
11165295Srandyf &ata_timer_conf, NULL)) {
11171709Smlf (void) ata_detach(dip, DDI_DETACH);
11181709Smlf return (NULL);
11191709Smlf }
11201709Smlf
11211709Smlf ata_ctlp->ac_flags |= AC_GHD_INIT;
11221709Smlf return (ata_ctlp);
11231709Smlf }
11241709Smlf
11251709Smlf /* destroy a controller */
11261709Smlf
11271709Smlf static void
ata_destroy_controller(dev_info_t * dip)11281709Smlf ata_destroy_controller(
11291709Smlf dev_info_t *dip)
11301709Smlf {
11311709Smlf ata_ctl_t *ata_ctlp;
11321709Smlf int instance;
11331709Smlf
11341709Smlf ADBG_TRACE(("ata_destroy_controller entered\n"));
11351709Smlf
11361709Smlf instance = ddi_get_instance(dip);
11371709Smlf ata_ctlp = ddi_get_soft_state(ata_state, instance);
11381709Smlf
11391709Smlf if (ata_ctlp == NULL)
11401709Smlf return;
11411709Smlf
11421709Smlf /* destroy ghd */
11431709Smlf if (ata_ctlp->ac_flags & AC_GHD_INIT)
11441709Smlf ghd_unregister(&ata_ctlp->ac_ccc);
11451709Smlf
11461709Smlf /* free the pciide buffer (if any) */
11471709Smlf ata_pciide_free(ata_ctlp);
11481709Smlf
11491709Smlf /* destroy controller struct */
11501709Smlf kmem_free(ata_ctlp->ac_arq_pktp, sizeof (ata_pkt_t));
11511709Smlf ddi_soft_state_free(ata_state, instance);
11521709Smlf
11531709Smlf }
11541709Smlf
11551709Smlf
11561709Smlf /*
11571709Smlf *
11581709Smlf * initialize a drive
11591709Smlf *
11601709Smlf */
11611709Smlf
11621709Smlf static ata_drv_t *
ata_init_drive(ata_ctl_t * ata_ctlp,uchar_t targ,uchar_t lun)11631709Smlf ata_init_drive(
11641709Smlf ata_ctl_t *ata_ctlp,
11651709Smlf uchar_t targ,
11661709Smlf uchar_t lun)
11671709Smlf {
11681709Smlf static char nec_260[] = "NEC CD-ROM DRIVE";
11691709Smlf ata_drv_t *ata_drvp;
11701709Smlf struct ata_id *aidp;
11711709Smlf char buf[80];
11721709Smlf int drive_type;
11731709Smlf int i;
11741709Smlf int valid_version = 0;
11751709Smlf
11761709Smlf ADBG_TRACE(("ata_init_drive entered, targ = %d, lun = %d\n",
11775295Srandyf targ, lun));
11781709Smlf
11791709Smlf /* check if device already exists */
11801709Smlf
11811709Smlf ata_drvp = CTL2DRV(ata_ctlp, targ, lun);
11821709Smlf
11831709Smlf if (ata_drvp != NULL)
11841709Smlf return (ata_drvp);
11851709Smlf
11861709Smlf /* allocate new device structure */
11871709Smlf
11881709Smlf ata_drvp = kmem_zalloc(sizeof (ata_drv_t), KM_SLEEP);
11891709Smlf aidp = &ata_drvp->ad_id;
11901709Smlf
11911709Smlf /*
11921709Smlf * set up drive struct
11931709Smlf */
11941709Smlf ata_drvp->ad_ctlp = ata_ctlp;
11955603Sml40262 ata_drvp->ad_pciide_dma = ATA_DMA_UNINITIALIZED;
11961709Smlf ata_drvp->ad_targ = targ;
11971709Smlf ata_drvp->ad_drive_bits =
11985295Srandyf (ata_drvp->ad_targ == 0 ? ATDH_DRIVE0 : ATDH_DRIVE1);
11991709Smlf /*
12001709Smlf * Add the LUN for SFF-8070i support
12011709Smlf */
12021709Smlf ata_drvp->ad_lun = lun;
12031709Smlf ata_drvp->ad_drive_bits |= ata_drvp->ad_lun;
12041709Smlf
12051709Smlf /*
12061709Smlf * get drive type, side effect is to collect
12071709Smlf * IDENTIFY DRIVE data
12081709Smlf */
12091709Smlf
12101709Smlf drive_type = ata_drive_type(ata_drvp->ad_drive_bits,
12115295Srandyf ata_ctlp->ac_iohandle1,
12125295Srandyf ata_ctlp->ac_ioaddr1,
12135295Srandyf ata_ctlp->ac_iohandle2,
12145295Srandyf ata_ctlp->ac_ioaddr2,
12155295Srandyf aidp);
12161709Smlf
12171709Smlf switch (drive_type) {
12181709Smlf case ATA_DEV_NONE:
12191709Smlf /* no drive found */
12201709Smlf goto errout;
12211709Smlf case ATA_DEV_ATAPI:
12221709Smlf ata_drvp->ad_flags |= AD_ATAPI;
12231709Smlf break;
12241709Smlf case ATA_DEV_DISK:
12251709Smlf ata_drvp->ad_flags |= AD_DISK;
12261709Smlf break;
12271709Smlf }
12281709Smlf
12291709Smlf /*
12301709Smlf * swap bytes of all text fields
12311709Smlf */
12321709Smlf if (!ata_strncmp(nec_260, aidp->ai_model, sizeof (aidp->ai_model))) {
12331709Smlf swab(aidp->ai_drvser, aidp->ai_drvser,
12345295Srandyf sizeof (aidp->ai_drvser));
12351709Smlf swab(aidp->ai_fw, aidp->ai_fw,
12365295Srandyf sizeof (aidp->ai_fw));
12371709Smlf swab(aidp->ai_model, aidp->ai_model,
12385295Srandyf sizeof (aidp->ai_model));
12391709Smlf }
12401709Smlf
12411709Smlf /*
12421709Smlf * Check if this drive has the Single Sector bug
12431709Smlf */
12441709Smlf
12451709Smlf if (ata_check_drive_blacklist(&ata_drvp->ad_id, ATA_BL_1SECTOR))
12461709Smlf ata_drvp->ad_flags |= AD_1SECTOR;
12471709Smlf else
12481709Smlf ata_drvp->ad_flags &= ~AD_1SECTOR;
12491709Smlf
12507963SColin.Yi@Sun.COM if (ata_check_drive_blacklist(&ata_drvp->ad_id, ATA_BL_LBA48))
12517963SColin.Yi@Sun.COM ata_drvp->ad_flags |= AD_BLLBA48;
12527963SColin.Yi@Sun.COM else
12537963SColin.Yi@Sun.COM ata_drvp->ad_flags &= ~AD_BLLBA48;
12547963SColin.Yi@Sun.COM
12551709Smlf /* Check if this drive has the "revert to defaults" bug */
12561709Smlf if (!ata_check_revert_to_defaults(ata_drvp))
12571709Smlf ata_drvp->ad_flags |= AD_NORVRT;
12581709Smlf
12591709Smlf /* Dump the drive info */
12601709Smlf (void) strncpy(buf, aidp->ai_model, sizeof (aidp->ai_model));
12611709Smlf buf[sizeof (aidp->ai_model)-1] = '\0';
12621709Smlf for (i = sizeof (aidp->ai_model) - 2; buf[i] == ' '; i--)
12631709Smlf buf[i] = '\0';
12641709Smlf
12651709Smlf ATAPRT(("?\t%s device at targ %d, lun %d lastlun 0x%x\n",
12665295Srandyf (ATAPIDRV(ata_drvp) ? "ATAPI":"IDE"),
12675295Srandyf ata_drvp->ad_targ, ata_drvp->ad_lun, aidp->ai_lastlun));
12681709Smlf
12691709Smlf ATAPRT(("?\tmodel %s\n", buf));
12701709Smlf
12711709Smlf if (aidp->ai_majorversion != 0 && aidp->ai_majorversion != 0xffff) {
12721709Smlf for (i = 14; i >= 2; i--) {
12731709Smlf if (aidp->ai_majorversion & (1 << i)) {
12741709Smlf valid_version = i;
12751709Smlf break;
12761709Smlf }
12771709Smlf }
12781709Smlf ATAPRT((
12791709Smlf "?\tATA/ATAPI-%d supported, majver 0x%x minver 0x%x\n",
12805295Srandyf valid_version,
12815295Srandyf aidp->ai_majorversion,
12825295Srandyf aidp->ai_minorversion));
12831709Smlf }
12841709Smlf
12851709Smlf if (ata_capability_data) {
12861709Smlf
12871709Smlf ATAPRT(("?\t\tstat %x, err %x\n",
12885295Srandyf ddi_get8(ata_ctlp->ac_iohandle2,
12895295Srandyf ata_ctlp->ac_altstatus),
12905295Srandyf ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_error)));
12911709Smlf
12921709Smlf ATAPRT(("?\t\tcfg 0x%x, cap 0x%x\n",
12935295Srandyf aidp->ai_config,
12945295Srandyf aidp->ai_cap));
12951709Smlf
12961709Smlf /*
12971709Smlf * Be aware that ATA-6 and later drives may not provide valid
12981709Smlf * geometry information and other obsoleted info.
12991709Smlf * Select what is printed based on supported ATA model (skip
13001709Smlf * anything below ATA/ATAPI-3)
13011709Smlf */
13021709Smlf
13031709Smlf if (valid_version == 0 || aidp->ai_majorversion <
13041709Smlf ATAC_MAJVER_6) {
13051709Smlf /*
13061709Smlf * Supported version less then ATA-6
13071709Smlf */
13081709Smlf ATAPRT(("?\t\tcyl %d, hd %d, sec/trk %d\n",
13095295Srandyf aidp->ai_fixcyls,
13105295Srandyf aidp->ai_heads,
13115295Srandyf aidp->ai_sectors));
13121709Smlf }
13131709Smlf ATAPRT(("?\t\tmult1 0x%x, mult2 0x%x\n",
13145295Srandyf aidp->ai_mult1,
13155295Srandyf aidp->ai_mult2));
13161709Smlf if (valid_version && aidp->ai_majorversion < ATAC_MAJVER_4) {
13171709Smlf ATAPRT((
13181709Smlf "?\t\tpiomode 0x%x, dmamode 0x%x, advpiomode 0x%x\n",
13195295Srandyf aidp->ai_piomode,
13205295Srandyf aidp->ai_dmamode,
13215295Srandyf aidp->ai_advpiomode));
13221709Smlf } else {
13231709Smlf ATAPRT(("?\t\tadvpiomode 0x%x\n",
13245295Srandyf aidp->ai_advpiomode));
13251709Smlf }
13261709Smlf ATAPRT(("?\t\tminpio %d, minpioflow %d\n",
13275295Srandyf aidp->ai_minpio,
13285295Srandyf aidp->ai_minpioflow));
13291709Smlf if (valid_version && aidp->ai_majorversion >= ATAC_MAJVER_4 &&
13301709Smlf (aidp->ai_validinfo & ATAC_VALIDINFO_83)) {
13311709Smlf ATAPRT(("?\t\tdwdma 0x%x, ultradma 0x%x\n",
13325295Srandyf aidp->ai_dworddma,
13335295Srandyf aidp->ai_ultradma));
13341709Smlf } else {
13351709Smlf ATAPRT(("?\t\tdwdma 0x%x\n",
13365295Srandyf aidp->ai_dworddma));
13371709Smlf }
13381709Smlf }
13391709Smlf
13401709Smlf if (ATAPIDRV(ata_drvp)) {
13411709Smlf if (!atapi_init_drive(ata_drvp))
13421709Smlf goto errout;
13431709Smlf } else {
13441709Smlf if (!ata_disk_init_drive(ata_drvp))
13451709Smlf goto errout;
13461709Smlf }
13471709Smlf
13481709Smlf /*
13491709Smlf * store pointer in controller struct
13501709Smlf */
13511709Smlf CTL2DRV(ata_ctlp, targ, lun) = ata_drvp;
13521709Smlf
13531709Smlf /*
13541709Smlf * lock the drive's current settings in case I have to
13551709Smlf * reset the drive due to some sort of error
13561709Smlf */
13575295Srandyf (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0);
13581709Smlf
13591709Smlf return (ata_drvp);
13601709Smlf
13611709Smlf errout:
13621709Smlf ata_uninit_drive(ata_drvp);
13631709Smlf return (NULL);
13641709Smlf }
13651709Smlf
13661709Smlf /* destroy a drive */
13671709Smlf
13681709Smlf static void
ata_uninit_drive(ata_drv_t * ata_drvp)13691709Smlf ata_uninit_drive(
13701709Smlf ata_drv_t *ata_drvp)
13711709Smlf {
13721709Smlf #if 0
13731709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
13741709Smlf #endif
13751709Smlf
13761709Smlf ADBG_TRACE(("ata_uninit_drive entered\n"));
13771709Smlf
13781709Smlf #if 0
13791709Smlf /*
13801709Smlf * DON'T DO THIS. disabling interrupts floats the IRQ line
13811709Smlf * which generates spurious interrupts
13821709Smlf */
13831709Smlf
13841709Smlf /*
13851709Smlf * Select the correct drive
13861709Smlf */
13871709Smlf ddi_put8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_drvhd,
13885295Srandyf ata_drvp->ad_drive_bits);
13894852Smlf ata_nsecwait(400);
13901709Smlf
13911709Smlf /*
13921709Smlf * Disable interrupts from the drive
13931709Smlf */
13941709Smlf ddi_put8(ata_ctlp->ac_iohandle2, ata_ctlp->ac_devctl,
13955295Srandyf (ATDC_D3 | ATDC_NIEN));
13961709Smlf #endif
13971709Smlf
13981709Smlf /* interface specific clean-ups */
13991709Smlf
14001709Smlf if (ata_drvp->ad_flags & AD_ATAPI)
14011709Smlf atapi_uninit_drive(ata_drvp);
14021709Smlf else if (ata_drvp->ad_flags & AD_DISK)
14031709Smlf ata_disk_uninit_drive(ata_drvp);
14041709Smlf
14051709Smlf /* free drive struct */
14061709Smlf
14071709Smlf kmem_free(ata_drvp, sizeof (ata_drv_t));
14081709Smlf }
14091709Smlf
14101709Smlf
14111709Smlf /*
14121709Smlf * ata_drive_type()
14131709Smlf *
14141709Smlf * The timeout values and exact sequence of checking is critical
14151709Smlf * especially for atapi device detection, and should not be changed lightly.
14161709Smlf *
14171709Smlf */
14181709Smlf static int
ata_drive_type(uchar_t drvhd,ddi_acc_handle_t io_hdl1,caddr_t ioaddr1,ddi_acc_handle_t io_hdl2,caddr_t ioaddr2,struct ata_id * ata_id_bufp)14191709Smlf ata_drive_type(
14201709Smlf uchar_t drvhd,
14211709Smlf ddi_acc_handle_t io_hdl1,
14221709Smlf caddr_t ioaddr1,
14231709Smlf ddi_acc_handle_t io_hdl2,
14241709Smlf caddr_t ioaddr2,
14251709Smlf struct ata_id *ata_id_bufp)
14261709Smlf {
14271709Smlf uchar_t status;
14281709Smlf
14291709Smlf ADBG_TRACE(("ata_drive_type entered\n"));
14301709Smlf
14311709Smlf /*
14321709Smlf * select the appropriate drive and LUN
14331709Smlf */
14341709Smlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_DRVHD, drvhd);
14354852Smlf ata_nsecwait(400);
14361709Smlf
14371709Smlf /*
14381709Smlf * make certain the drive is selected, and wait for not busy
14391709Smlf */
14401709Smlf (void) ata_wait3(io_hdl2, ioaddr2, 0, ATS_BSY, 0x7f, 0, 0x7f, 0,
14415295Srandyf 5 * 1000000);
14421709Smlf
14431709Smlf status = ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS);
14441709Smlf
14455162Smlf if (status & ATS_BSY) {
14464852Smlf ADBG_TRACE(("ata_drive_type 0x%p 0x%x\n", ioaddr1, status));
14471709Smlf return (ATA_DEV_NONE);
14481709Smlf }
14491709Smlf
14501709Smlf if (ata_disk_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp))
14511709Smlf return (ATA_DEV_DISK);
14521709Smlf
14531709Smlf /*
14541709Smlf * No disk, check for atapi unit.
14551709Smlf */
14561709Smlf if (!atapi_signature(io_hdl1, ioaddr1)) {
14571709Smlf #ifndef ATA_DISABLE_ATAPI_1_7
14581709Smlf /*
14591709Smlf * Check for old (but prevalent) atapi 1.7B
14601709Smlf * spec device, the only known example is the
14611709Smlf * NEC CDR-260 (not 260R which is (mostly) ATAPI 1.2
14621709Smlf * compliant). This device has no signature
14631709Smlf * and requires conversion from hex to BCD
14641709Smlf * for some scsi audio commands.
14651709Smlf */
14661709Smlf if (atapi_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp)) {
14671709Smlf return (ATA_DEV_ATAPI);
14681709Smlf }
14691709Smlf #endif
14701709Smlf return (ATA_DEV_NONE);
14711709Smlf }
14721709Smlf
14731709Smlf if (atapi_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp)) {
14741709Smlf return (ATA_DEV_ATAPI);
14751709Smlf }
14761709Smlf
14771709Smlf return (ATA_DEV_NONE);
14781709Smlf
14791709Smlf }
14801709Smlf
14811709Smlf /*
14824852Smlf * nsec-granularity time delay function
14834852Smlf */
14844852Smlf void
ata_nsecwait(clock_t count)14854852Smlf ata_nsecwait(clock_t count)
14864852Smlf {
14874852Smlf extern int tsc_gethrtime_initted;
14884852Smlf
14894852Smlf if (tsc_gethrtime_initted) {
14904852Smlf hrtime_t end = gethrtime() + count;
14914852Smlf
14924852Smlf while (gethrtime() < end) {
14934852Smlf SMT_PAUSE();
14944852Smlf }
14954852Smlf } else {
14964852Smlf drv_usecwait(1 + (count / 1000));
14974852Smlf }
14984852Smlf }
14994852Smlf
15004852Smlf
15014852Smlf /*
15021709Smlf * Wait for a register of a controller to achieve a specific state.
15031709Smlf * To return normally, all the bits in the first sub-mask must be ON,
15041709Smlf * all the bits in the second sub-mask must be OFF.
15051709Smlf * If timeout_usec microseconds pass without the controller achieving
15061709Smlf * the desired bit configuration, we return TRUE, else FALSE.
15071709Smlf */
15081709Smlf
15091709Smlf int ata_usec_delay = 10;
15101709Smlf
15111709Smlf int
ata_wait(ddi_acc_handle_t io_hdl,caddr_t ioaddr,uchar_t onbits,uchar_t offbits,uint_t timeout_usec)15121709Smlf ata_wait(
15131709Smlf ddi_acc_handle_t io_hdl,
15141709Smlf caddr_t ioaddr,
15151709Smlf uchar_t onbits,
15161709Smlf uchar_t offbits,
15171709Smlf uint_t timeout_usec)
15181709Smlf {
15191709Smlf ushort_t val;
15204852Smlf hrtime_t deadline = gethrtime() +
15214852Smlf (hrtime_t)timeout_usec * (NANOSEC / MICROSEC);
15224852Smlf
15231709Smlf
15241709Smlf do {
15251709Smlf val = ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_ALTSTATUS);
15261709Smlf if ((val & onbits) == onbits && (val & offbits) == 0)
15271709Smlf return (TRUE);
15281709Smlf drv_usecwait(ata_usec_delay);
15294852Smlf } while (gethrtime() < deadline);
15301709Smlf
15311709Smlf return (FALSE);
15321709Smlf }
15331709Smlf
15341709Smlf
15351709Smlf /*
15361709Smlf *
15371709Smlf * This is a slightly more complicated version that checks
15381709Smlf * for error conditions and bails-out rather than looping
15391709Smlf * until the timeout expires
15401709Smlf */
15411709Smlf int
ata_wait3(ddi_acc_handle_t io_hdl,caddr_t ioaddr,uchar_t onbits1,uchar_t offbits1,uchar_t failure_onbits2,uchar_t failure_offbits2,uchar_t failure_onbits3,uchar_t failure_offbits3,uint_t timeout_usec)15421709Smlf ata_wait3(
15431709Smlf ddi_acc_handle_t io_hdl,
15441709Smlf caddr_t ioaddr,
15451709Smlf uchar_t onbits1,
15461709Smlf uchar_t offbits1,
15471709Smlf uchar_t failure_onbits2,
15481709Smlf uchar_t failure_offbits2,
15491709Smlf uchar_t failure_onbits3,
15501709Smlf uchar_t failure_offbits3,
15511709Smlf uint_t timeout_usec)
15521709Smlf {
15531709Smlf ushort_t val;
15544852Smlf hrtime_t deadline = gethrtime() +
15554852Smlf (hrtime_t)timeout_usec * (NANOSEC / MICROSEC);
15561709Smlf
15571709Smlf do {
15581709Smlf val = ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_ALTSTATUS);
15591709Smlf
15601709Smlf /*
15611709Smlf * check for expected condition
15621709Smlf */
15631709Smlf if ((val & onbits1) == onbits1 && (val & offbits1) == 0)
15641709Smlf return (TRUE);
15651709Smlf
15661709Smlf /*
15671709Smlf * check for error conditions
15681709Smlf */
15691709Smlf if ((val & failure_onbits2) == failure_onbits2 &&
15705295Srandyf (val & failure_offbits2) == 0) {
15711709Smlf return (FALSE);
15721709Smlf }
15731709Smlf
15741709Smlf if ((val & failure_onbits3) == failure_onbits3 &&
15755295Srandyf (val & failure_offbits3) == 0) {
15761709Smlf return (FALSE);
15771709Smlf }
15781709Smlf
15791709Smlf drv_usecwait(ata_usec_delay);
15804852Smlf } while (gethrtime() < deadline);
15811709Smlf
15821709Smlf return (FALSE);
15831709Smlf }
15841709Smlf
15851709Smlf
15861709Smlf /*
15871709Smlf *
15881709Smlf * low level routine for ata_disk_id() and atapi_id()
15891709Smlf *
15901709Smlf */
15911709Smlf
15921709Smlf int
ata_id_common(uchar_t id_cmd,int expect_drdy,ddi_acc_handle_t io_hdl1,caddr_t ioaddr1,ddi_acc_handle_t io_hdl2,caddr_t ioaddr2,struct ata_id * aidp)15931709Smlf ata_id_common(
15941709Smlf uchar_t id_cmd,
15951709Smlf int expect_drdy,
15961709Smlf ddi_acc_handle_t io_hdl1,
15971709Smlf caddr_t ioaddr1,
15981709Smlf ddi_acc_handle_t io_hdl2,
15991709Smlf caddr_t ioaddr2,
16001709Smlf struct ata_id *aidp)
16011709Smlf {
16021709Smlf uchar_t status;
16031709Smlf
16041709Smlf ADBG_TRACE(("ata_id_common entered\n"));
16051709Smlf
16061709Smlf bzero(aidp, sizeof (struct ata_id));
16071709Smlf
16081709Smlf /*
16091709Smlf * clear the features register
16101709Smlf */
16111709Smlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_FEATURE, 0);
16121709Smlf
16131709Smlf /*
16145162Smlf * Disable interrupts from the device. When the ata
16155162Smlf * hardware is sharing its interrupt with another
16165162Smlf * device, the shared interrupt might have already been
16175162Smlf * unmasked in the interrupt controller and
16184852Smlf * triggering ata device interrupts will result in an
16194852Smlf * interrupt storm and a hung system.
16201709Smlf */
16214852Smlf ddi_put8(io_hdl2, (uchar_t *)ioaddr2 + AT_DEVCTL, ATDC_D3 | ATDC_NIEN);
16221709Smlf
16231709Smlf /*
16241709Smlf * issue IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command
16251709Smlf */
16261709Smlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_CMD, id_cmd);
16271709Smlf
16281709Smlf /* wait for the busy bit to settle */
16294852Smlf ata_nsecwait(400);
16301709Smlf
16311709Smlf /*
16325162Smlf * read alternate status and check for conditions which
16335162Smlf * may indicate the drive is not present, to prevent getting
16345162Smlf * stuck in ata_wait3() below.
16355162Smlf */
16365162Smlf status = ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS);
16375162Smlf
16385162Smlf /*
16395162Smlf * 0x0, 0x7f, or ATS_DF can happen when no drive is present
16405162Smlf */
16415162Smlf if ((status == 0x0) || (status == 0x7f) ||
16425162Smlf ((status & (ATS_BSY|ATS_DF)) == ATS_DF)) {
16435162Smlf /* invalid status, can't be an ATA or ATAPI device */
16445162Smlf return (FALSE);
16455162Smlf }
16465162Smlf
16475162Smlf /*
16481709Smlf * According to the ATA specification, some drives may have
16491709Smlf * to read the media to complete this command. We need to
16501709Smlf * make sure we give them enough time to respond.
16511709Smlf */
16521709Smlf (void) ata_wait3(io_hdl2, ioaddr2, 0, ATS_BSY,
16535295Srandyf ATS_ERR, ATS_BSY, 0x7f, 0, 5 * 1000000);
16541709Smlf
16551709Smlf /*
16561709Smlf * read the status byte and clear the pending interrupt
16571709Smlf */
16585162Smlf status = ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_STATUS);
16591709Smlf
16601709Smlf /*
16615162Smlf * this happens if there's no drive present
16621709Smlf */
16635162Smlf if (status == 0xff || status == 0x7f) {
16641709Smlf /* invalid status, can't be an ATA or ATAPI device */
16651709Smlf return (FALSE);
16661709Smlf }
16671709Smlf
16681709Smlf if (status & ATS_BSY) {
16691709Smlf ADBG_ERROR(("ata_id_common: BUSY status 0x%x error 0x%x\n",
16705295Srandyf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS),
16715295Srandyf ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));
16721709Smlf return (FALSE);
16731709Smlf }
16741709Smlf
16751709Smlf if (!(status & ATS_DRQ)) {
16761709Smlf if (status & (ATS_ERR | ATS_DF)) {
16771709Smlf return (FALSE);
16781709Smlf }
16791709Smlf /*
16801709Smlf * Give the drive another second to assert DRQ. Some older
1681*11310SVitezslav.Batrla@Sun.COM * drives de-assert BSY before asserting DRQ. Bail out
1682*11310SVitezslav.Batrla@Sun.COM * immediately if the status becomes 0x7f, which is invalid
1683*11310SVitezslav.Batrla@Sun.COM * value. It can happen when no drive is present.
16841709Smlf */
1685*11310SVitezslav.Batrla@Sun.COM if (!ata_wait3(io_hdl2, ioaddr2, ATS_DRQ, ATS_BSY, 0x7f,
1686*11310SVitezslav.Batrla@Sun.COM ATS_BSY, 0x7f, ATS_BSY, 1000000)) {
1687*11310SVitezslav.Batrla@Sun.COM ADBG_WARN(("ata_id_common: "
1688*11310SVitezslav.Batrla@Sun.COM "!DRQ status 0x%x error 0x%x\n",
1689*11310SVitezslav.Batrla@Sun.COM ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS),
1690*11310SVitezslav.Batrla@Sun.COM ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));
1691*11310SVitezslav.Batrla@Sun.COM return (FALSE);
16921709Smlf }
16931709Smlf }
16941709Smlf
16951709Smlf /*
16961709Smlf * transfer the data
16971709Smlf */
16981709Smlf ddi_rep_get16(io_hdl1, (ushort_t *)aidp, (ushort_t *)ioaddr1 + AT_DATA,
16995295Srandyf NBPSCTR >> 1, DDI_DEV_NO_AUTOINCR);
17001709Smlf
17011709Smlf /* wait for the busy bit to settle */
17024852Smlf ata_nsecwait(400);
17031709Smlf
17041709Smlf
17051709Smlf /*
17061709Smlf * Wait for the drive to recognize I've read all the data.
17071709Smlf * Some drives have been observed to take as much as 3msec to
1708*11310SVitezslav.Batrla@Sun.COM * deassert DRQ after reading the data; allow 1 sec just in case.
17091709Smlf *
17101709Smlf * Note: some non-compliant ATAPI drives (e.g., NEC Multispin 6V,
17111709Smlf * CDR-1350A) don't assert DRDY. If we've made it this far we can
17121709Smlf * safely ignore the DRDY bit since the ATAPI Packet command
17131709Smlf * actually doesn't require it to ever be asserted.
17141709Smlf *
1715*11310SVitezslav.Batrla@Sun.COM * Bail out immediately if the status becomes 0x7f, which is invalid
1716*11310SVitezslav.Batrla@Sun.COM * value. It can happen when no drive is present.
1717*11310SVitezslav.Batrla@Sun.COM *
17181709Smlf */
1719*11310SVitezslav.Batrla@Sun.COM if (!ata_wait3(io_hdl2, ioaddr2, (uchar_t)(expect_drdy ? ATS_DRDY : 0),
1720*11310SVitezslav.Batrla@Sun.COM (ATS_BSY | ATS_DRQ), 0x7f, ATS_BSY, 0x7f, ATS_BSY, 1000000)) {
17211709Smlf ADBG_WARN(("ata_id_common: bad status 0x%x error 0x%x\n",
17225295Srandyf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS),
17235295Srandyf ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));
17241709Smlf return (FALSE);
17251709Smlf }
17261709Smlf
17271709Smlf /*
17281709Smlf * Check to see if the command aborted. This happens if
17291709Smlf * an IDENTIFY DEVICE command is issued to an ATAPI PACKET device,
17301709Smlf * or if an IDENTIFY PACKET DEVICE command is issued to an ATA
17311709Smlf * (non-PACKET) device.
17321709Smlf */
17331709Smlf if (status & (ATS_DF | ATS_ERR)) {
17341709Smlf ADBG_WARN(("ata_id_common: status 0x%x error 0x%x \n",
17355295Srandyf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS),
17365295Srandyf ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));
17371709Smlf return (FALSE);
17381709Smlf }
17391709Smlf return (TRUE);
17401709Smlf }
17411709Smlf
17421709Smlf
17431709Smlf /*
17441709Smlf * Low level routine to issue a non-data command and busy wait for
17451709Smlf * the completion status.
17461709Smlf */
17471709Smlf
17481709Smlf int
ata_command(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,int expect_drdy,int silent,uint_t busy_wait,uchar_t cmd,uchar_t feature,uchar_t count,uchar_t sector,uchar_t head,uchar_t cyl_low,uchar_t cyl_hi)17491709Smlf ata_command(
17501709Smlf ata_ctl_t *ata_ctlp,
17511709Smlf ata_drv_t *ata_drvp,
17521709Smlf int expect_drdy,
17531709Smlf int silent,
17541709Smlf uint_t busy_wait,
17551709Smlf uchar_t cmd,
17561709Smlf uchar_t feature,
17571709Smlf uchar_t count,
17581709Smlf uchar_t sector,
17591709Smlf uchar_t head,
17601709Smlf uchar_t cyl_low,
17611709Smlf uchar_t cyl_hi)
17621709Smlf {
17631709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
17641709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
17651709Smlf uchar_t status;
17661709Smlf
17671709Smlf /* select the drive */
17681709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
17694852Smlf ata_nsecwait(400);
17701709Smlf
17711709Smlf /* make certain the drive selected */
17721709Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2,
17735295Srandyf (uchar_t)(expect_drdy ? ATS_DRDY : 0),
17745295Srandyf ATS_BSY, busy_wait)) {
17751709Smlf ADBG_ERROR(("ata_command: select failed "
17765295Srandyf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x "
17775295Srandyf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n",
17785295Srandyf expect_drdy, cmd, feature, count,
17795295Srandyf sector, head, cyl_low, cyl_hi));
17801709Smlf return (FALSE);
17811709Smlf }
17821709Smlf
17831709Smlf /*
17841709Smlf * set all the regs
17851709Smlf */
17861709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, (head | ata_drvp->ad_drive_bits));
17871709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, sector);
17881709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, count);
17891709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, cyl_low);
17901709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, cyl_hi);
17911709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_feature, feature);
17921709Smlf
17931709Smlf /* send the command */
17941709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, cmd);
17951709Smlf
17961709Smlf /* wait for the busy bit to settle */
17974852Smlf ata_nsecwait(400);
17981709Smlf
17991709Smlf /* wait for not busy */
18001709Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, busy_wait)) {
18011709Smlf ADBG_ERROR(("ata_command: BSY too long!"
18025295Srandyf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x "
18035295Srandyf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n",
18045295Srandyf expect_drdy, cmd, feature, count,
18055295Srandyf sector, head, cyl_low, cyl_hi));
18061709Smlf return (FALSE);
18071709Smlf }
18081709Smlf
18091709Smlf /*
18101709Smlf * wait for DRDY before continuing
18111709Smlf */
18121709Smlf (void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2,
18135295Srandyf ATS_DRDY, ATS_BSY, /* okay */
18145295Srandyf ATS_ERR, ATS_BSY, /* cmd failed */
18155295Srandyf ATS_DF, ATS_BSY, /* drive failed */
18165295Srandyf busy_wait);
18171709Smlf
18181709Smlf /* read status to clear IRQ, and check for error */
18191709Smlf status = ddi_get8(io_hdl1, ata_ctlp->ac_status);
18201709Smlf
18211709Smlf if ((status & (ATS_BSY | ATS_DF | ATS_ERR)) == 0)
18221709Smlf return (TRUE);
18231709Smlf
18241709Smlf if (!silent) {
18251709Smlf ADBG_ERROR(("ata_command status 0x%x error 0x%x "
18265295Srandyf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x "
18275295Srandyf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n",
18285295Srandyf ddi_get8(io_hdl1, ata_ctlp->ac_status),
18295295Srandyf ddi_get8(io_hdl1, ata_ctlp->ac_error),
18305295Srandyf expect_drdy, cmd, feature, count,
18315295Srandyf sector, head, cyl_low, cyl_hi));
18321709Smlf }
18331709Smlf return (FALSE);
18341709Smlf }
18351709Smlf
18361709Smlf
18371709Smlf
18381709Smlf /*
18391709Smlf *
18401709Smlf * Issue a SET FEATURES command
18411709Smlf *
18421709Smlf */
18431709Smlf
18441709Smlf int
ata_set_feature(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,uchar_t feature,uchar_t value)18451709Smlf ata_set_feature(
18461709Smlf ata_ctl_t *ata_ctlp,
18471709Smlf ata_drv_t *ata_drvp,
18481709Smlf uchar_t feature,
18491709Smlf uchar_t value)
18501709Smlf {
18511709Smlf int rc;
18521709Smlf
18531709Smlf rc = ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, ata_set_feature_wait,
18545295Srandyf ATC_SET_FEAT, feature, value, 0, 0, 0, 0);
18555295Srandyf /* feature, count, sector, head, cyl_low, cyl_hi */
18561709Smlf
18571709Smlf if (rc) {
18581709Smlf return (TRUE);
18591709Smlf }
18601709Smlf
18611709Smlf ADBG_ERROR(("?ata_set_feature: (0x%x,0x%x) failed\n", feature, value));
18621709Smlf return (FALSE);
18631709Smlf }
18641709Smlf
18651709Smlf
18661709Smlf
18671709Smlf /*
18681709Smlf *
18691709Smlf * Issue a FLUSH CACHE command
18701709Smlf *
18711709Smlf */
18721709Smlf
18731709Smlf static int
ata_flush_cache(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)18741709Smlf ata_flush_cache(
18751709Smlf ata_ctl_t *ata_ctlp,
18761709Smlf ata_drv_t *ata_drvp)
18771709Smlf {
18781709Smlf /* this command is optional so fail silently */
18791709Smlf return (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE,
18805295Srandyf ata_flush_cache_wait,
18815295Srandyf ATC_FLUSH_CACHE, 0, 0, 0, 0, 0, 0));
18821709Smlf }
18831709Smlf
18841709Smlf /*
18851709Smlf * ata_setup_ioaddr()
18861709Smlf *
18871709Smlf * Map the device registers and return the handles.
18881709Smlf *
18891709Smlf * If this is a ISA-ATA controller then only two handles are
18901709Smlf * initialized and returned.
18911709Smlf *
18921709Smlf * If this is a PCI-IDE controller than a third handle (for the
18931709Smlf * PCI-IDE Bus Mastering registers) is initialized and returned.
18941709Smlf *
18951709Smlf */
18961709Smlf
18971709Smlf static int
ata_setup_ioaddr(dev_info_t * dip,ddi_acc_handle_t * handle1p,caddr_t * addr1p,ddi_acc_handle_t * handle2p,caddr_t * addr2p,ddi_acc_handle_t * bm_hdlp,caddr_t * bm_addrp)18981709Smlf ata_setup_ioaddr(
18991709Smlf dev_info_t *dip,
19001709Smlf ddi_acc_handle_t *handle1p,
19011709Smlf caddr_t *addr1p,
19021709Smlf ddi_acc_handle_t *handle2p,
19031709Smlf caddr_t *addr2p,
19041709Smlf ddi_acc_handle_t *bm_hdlp,
19051709Smlf caddr_t *bm_addrp)
19061709Smlf {
19071709Smlf ddi_device_acc_attr_t dev_attr;
19081709Smlf int rnumber;
19091709Smlf int rc;
19101709Smlf off_t regsize;
19111709Smlf
19121709Smlf /*
19131709Smlf * Make certain the controller is enabled and its regs are map-able
19141709Smlf *
19151709Smlf */
19161709Smlf rc = ddi_dev_regsize(dip, 0, ®size);
19171709Smlf if (rc != DDI_SUCCESS || regsize <= AT_CMD) {
19181709Smlf ADBG_INIT(("ata_setup_ioaddr(1): rc %d regsize %lld\n",
19195295Srandyf rc, (long long)regsize));
19201709Smlf return (FALSE);
19211709Smlf }
19221709Smlf
19231709Smlf rc = ddi_dev_regsize(dip, 1, ®size);
19241709Smlf if (rc != DDI_SUCCESS || regsize <= AT_ALTSTATUS) {
19251709Smlf ADBG_INIT(("ata_setup_ioaddr(2): rc %d regsize %lld\n",
19265295Srandyf rc, (long long)regsize));
19271709Smlf return (FALSE);
19281709Smlf }
19291709Smlf
19301709Smlf /*
19311709Smlf * setup the device attribute structure for little-endian,
19321709Smlf * strict ordering access.
19331709Smlf */
19341709Smlf dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
19351709Smlf dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
19361709Smlf dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
19371709Smlf
19381709Smlf *handle1p = NULL;
19391709Smlf *handle2p = NULL;
19401709Smlf *bm_hdlp = NULL;
19411709Smlf
19421709Smlf /*
19431709Smlf * Determine whether this is a ISA, PNP-ISA, or PCI-IDE device
19441709Smlf */
19451709Smlf if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "pnp-csn")) {
19461709Smlf /* it's PNP-ISA, skip over the extra reg tuple */
19471709Smlf rnumber = 1;
19481709Smlf goto not_pciide;
19491709Smlf }
19501709Smlf
19511709Smlf /* else, it's ISA or PCI-IDE, check further */
19521709Smlf rnumber = 0;
19531709Smlf
19545295Srandyf if (!ata_is_pci(dip)) {
19551709Smlf /*
19561709Smlf * If it's not a PCI-IDE, there are only two reg tuples
19571709Smlf * and the first one contains the I/O base (170 or 1f0)
19581709Smlf * rather than the controller instance number.
19591709Smlf */
19601709Smlf ADBG_TRACE(("ata_setup_ioaddr !pci-ide\n"));
19611709Smlf goto not_pciide;
19621709Smlf }
19631709Smlf
19641709Smlf
19651709Smlf /*
19661709Smlf * Map the correct half of the PCI-IDE Bus Master registers.
19671709Smlf * There's a single BAR that maps these registers for both
19681709Smlf * controller's in a dual-controller chip and it's upto my
19691709Smlf * parent nexus, pciide, to adjust which (based on my instance
19701709Smlf * number) half this call maps.
19711709Smlf */
19721709Smlf rc = ddi_dev_regsize(dip, 2, ®size);
19731709Smlf if (rc != DDI_SUCCESS || regsize < 8) {
19741709Smlf ADBG_INIT(("ata_setup_ioaddr(3): rc %d regsize %lld\n",
19755295Srandyf rc, (long long)regsize));
19761709Smlf goto not_pciide;
19771709Smlf }
19781709Smlf
19791709Smlf rc = ddi_regs_map_setup(dip, 2, bm_addrp, 0, 0, &dev_attr, bm_hdlp);
19801709Smlf
19811709Smlf if (rc != DDI_SUCCESS) {
19821709Smlf /* map failed, try to use in non-pci-ide mode */
19831709Smlf ADBG_WARN(("ata_setup_ioaddr bus master map failed, rc=0x%x\n",
19845295Srandyf rc));
19851709Smlf *bm_hdlp = NULL;
19861709Smlf }
19871709Smlf
19881709Smlf not_pciide:
19891709Smlf /*
19901709Smlf * map the lower command block registers
19911709Smlf */
19921709Smlf
19931709Smlf rc = ddi_regs_map_setup(dip, rnumber, addr1p, 0, 0, &dev_attr,
19945295Srandyf handle1p);
19951709Smlf
19961709Smlf if (rc != DDI_SUCCESS) {
19971709Smlf cmn_err(CE_WARN, "ata: reg tuple 0 map failed, rc=0x%x\n", rc);
19981709Smlf goto out1;
19991709Smlf }
20001709Smlf
20011709Smlf /*
20021709Smlf * If the controller is being used in compatibility mode
20031709Smlf * via /devices/isa/ata@1,{1f0,1f0}/..., the reg property
20041709Smlf * will specify zeros for the I/O ports for the PCI
20051709Smlf * instance.
20061709Smlf */
20071709Smlf if (*addr1p == 0) {
20081709Smlf ADBG_TRACE(("ata_setup_ioaddr ioaddr1 0\n"));
20091709Smlf goto out2;
20101709Smlf }
20111709Smlf
20121709Smlf /*
20131709Smlf * map the upper control block registers
20141709Smlf */
20151709Smlf rc = ddi_regs_map_setup(dip, rnumber + 1, addr2p, 0, 0, &dev_attr,
20165295Srandyf handle2p);
20171709Smlf if (rc == DDI_SUCCESS)
20181709Smlf return (TRUE);
20191709Smlf
20201709Smlf cmn_err(CE_WARN, "ata: reg tuple 1 map failed, rc=0x%x", rc);
20211709Smlf
20221709Smlf out2:
20231709Smlf if (*handle1p != NULL) {
20241709Smlf ddi_regs_map_free(handle1p);
20251709Smlf *handle1p = NULL;
20261709Smlf }
20271709Smlf
20281709Smlf out1:
20291709Smlf if (*bm_hdlp != NULL) {
20301709Smlf ddi_regs_map_free(bm_hdlp);
20311709Smlf *bm_hdlp = NULL;
20321709Smlf }
20331709Smlf return (FALSE);
20341709Smlf
20351709Smlf }
20361709Smlf
20371709Smlf /*
20381709Smlf *
20391709Smlf * Currently, the only supported controllers are ones which
20401709Smlf * support the SFF-8038 Bus Mastering spec.
20411709Smlf *
20421709Smlf * Check the parent node's IEEE 1275 class-code property to
20431709Smlf * determine if it's an PCI-IDE instance which supports SFF-8038
20441709Smlf * Bus Mastering. It's perfectly valid to have a PCI-IDE controller
20451709Smlf * that doesn't do Bus Mastering. In that case, my interrupt handler
20461709Smlf * only uses the interrupt latch bit in PCI-IDE status register.
20471709Smlf * The assumption is that the programming interface byte of the
20481709Smlf * class-code property reflects the bus master DMA capability of
20491709Smlf * the controller.
20501709Smlf *
20511709Smlf * Whether the drive support supports the DMA option still needs
20521709Smlf * to be checked later. Each individual request also has to be
20531709Smlf * checked for alignment and size to decide whether to use the
20541709Smlf * DMA transfer mode.
20551709Smlf */
20561709Smlf
20571709Smlf static void
ata_init_pciide(dev_info_t * dip,ata_ctl_t * ata_ctlp)20581709Smlf ata_init_pciide(
20591709Smlf dev_info_t *dip,
20601709Smlf ata_ctl_t *ata_ctlp)
20611709Smlf {
20621709Smlf uint_t class_code;
20631709Smlf uchar_t status;
20641709Smlf
20651709Smlf ata_cntrl_DMA_sel_msg = NULL;
20661709Smlf
20671709Smlf if (ata_ctlp->ac_bmhandle == NULL) {
20681709Smlf ata_ctlp->ac_pciide = FALSE;
20691709Smlf ata_ctlp->ac_pciide_bm = FALSE;
20701709Smlf ata_cntrl_DMA_sel_msg = "cntrl not Bus Master DMA capable";
20711709Smlf return;
20721709Smlf }
20731709Smlf
20741709Smlf /*
20751709Smlf * check if it's a known bogus PCI-IDE chip
20761709Smlf */
20771709Smlf if (ata_check_pciide_blacklist(dip, ATA_BL_BOGUS)) {
20781709Smlf ADBG_WARN(("ata_setup_ioaddr pci-ide blacklist\n"));
20791709Smlf ata_ctlp->ac_pciide = FALSE;
20801709Smlf ata_ctlp->ac_pciide_bm = FALSE;
20811709Smlf ata_cntrl_DMA_sel_msg = "cntrl blacklisted";
20821709Smlf return;
20831709Smlf }
20841709Smlf ata_ctlp->ac_pciide = TRUE;
20851709Smlf
20861709Smlf if (ata_check_pciide_blacklist(dip, ATA_BL_BMSTATREG_PIO_BROKEN)) {
20871709Smlf ata_ctlp->ac_flags |= AC_BMSTATREG_PIO_BROKEN;
20881709Smlf }
20891709Smlf
20901709Smlf /*
20911709Smlf * check for a PCI-IDE chip with a broken DMA engine
20921709Smlf */
20931709Smlf if (ata_check_pciide_blacklist(dip, ATA_BL_NODMA)) {
20941709Smlf ata_ctlp->ac_pciide_bm = FALSE;
20951709Smlf ata_cntrl_DMA_sel_msg =
20965295Srandyf "cntrl blacklisted/DMA engine broken";
20971709Smlf return;
20981709Smlf }
20991709Smlf
21001709Smlf /*
21011709Smlf * Check the Programming Interface register to determine
21021709Smlf * if this device supports PCI-IDE Bus Mastering. Some PCI-IDE
21031709Smlf * devices don't support Bus Mastering or DMA.
21041709Smlf * Since we are dealing with pre-qualified pci-ide controller,
21051709Smlf * check programming interface byte only.
21061709Smlf */
21071709Smlf
21081709Smlf class_code = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
21095295Srandyf DDI_PROP_DONTPASS, "class-code", 0);
21101709Smlf if ((class_code & PCIIDE_BM_CAP_MASK) != PCIIDE_BM_CAP_MASK) {
21111709Smlf ata_ctlp->ac_pciide_bm = FALSE;
21121709Smlf ata_cntrl_DMA_sel_msg =
21135295Srandyf "cntrl not Bus Master DMA capable";
21141709Smlf return;
21151709Smlf }
21161709Smlf
21171709Smlf /*
21181709Smlf * Avoid doing DMA on "simplex" chips which share hardware
21191709Smlf * between channels
21201709Smlf */
21211709Smlf status = ddi_get8(ata_ctlp->ac_bmhandle,
21225295Srandyf (uchar_t *)ata_ctlp->ac_bmaddr + PCIIDE_BMISX_REG);
21231709Smlf /*
21241709Smlf * Some motherboards have CSB5's that are wired "to emulate CSB4 mode".
21251709Smlf * In such a mode, the simplex bit is asserted, but in fact testing
21261709Smlf * on such a motherboard has shown that the devices are not simplex
21271709Smlf * -- DMA can be used on both channels concurrently with no special
21281709Smlf * considerations. For chips like this, we have the ATA_BL_NO_SIMPLEX
21291709Smlf * flag set to indicate that the value of the simplex bit can be
21301709Smlf * ignored.
21311709Smlf */
21321709Smlf
21331709Smlf if (status & PCIIDE_BMISX_SIMPLEX) {
21342100Smlf if (ata_check_pciide_blacklist(dip, ATA_BL_NO_SIMPLEX)) {
21351709Smlf cmn_err(CE_WARN, "Ignoring false simplex bit \n");
21362100Smlf
21371709Smlf } else {
21382100Smlf
21392100Smlf int simplex_dma_channel, *rp, proplen, channel;
21402100Smlf int dma_on = FALSE;
21412100Smlf
21422100Smlf /*
21432100Smlf * By default,use DMA on channel 0 and PIO on channel
21442100Smlf * 1. This can be switched by setting
21452100Smlf * ata-simplex-dma-channel to:
21462100Smlf * 0 DMA on channel 0 (default without this
21472100Smlf * property)
21482100Smlf * 1 DMA on channel 1
21492100Smlf * any other value: DMA off on both channels.
21502100Smlf */
21512100Smlf simplex_dma_channel = ata_prop_lookup_int(DDI_DEV_T_ANY,
21522100Smlf ata_ctlp->ac_dip, 0, "ata-simplex-dma-channel", 0);
21532100Smlf
21542100Smlf if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
21552100Smlf ata_ctlp->ac_dip, DDI_PROP_DONTPASS, "reg", &rp,
21562100Smlf (uint_t *)&proplen) == DDI_PROP_SUCCESS) {
21572100Smlf
21582100Smlf channel = *rp;
21592100Smlf ddi_prop_free(rp);
21602100Smlf
21612100Smlf if (simplex_dma_channel == channel) {
21625721Sml40262 cmn_err(CE_CONT, "?ata: simplex "
21632100Smlf "controller. DMA on channel"
21645721Sml40262 " %d PIO on channel %d",
21652100Smlf channel, channel ? 0:1);
21662100Smlf dma_on = TRUE;
21672100Smlf } else {
21682100Smlf ata_cntrl_DMA_sel_msg =
21692100Smlf "simplex controller";
21702100Smlf }
21712100Smlf }
21722100Smlf
21732100Smlf if (dma_on == FALSE) {
21742100Smlf ata_ctlp->ac_pciide_bm = FALSE;
21752100Smlf
21762100Smlf return;
21772100Smlf }
21781709Smlf }
21791709Smlf }
21801709Smlf
21811709Smlf /*
21821709Smlf * It's a compatible PCI-IDE Bus Mastering controller,
21831709Smlf * allocate and map the DMA Scatter/Gather list (PRDE table).
21841709Smlf */
21851709Smlf if (ata_pciide_alloc(dip, ata_ctlp))
21861709Smlf ata_ctlp->ac_pciide_bm = TRUE;
21871709Smlf else {
21881709Smlf ata_ctlp->ac_pciide_bm = FALSE;
21891709Smlf ata_cntrl_DMA_sel_msg = "unable to init DMA S/G list";
21901709Smlf }
21911709Smlf }
21921709Smlf
21931709Smlf /*
21941709Smlf *
21951709Smlf * Determine whether to enable DMA support for this drive.
21961709Smlf * The controller and the drive both have to support DMA.
21971709Smlf * The controller's capabilities were already checked in
21981709Smlf * ata_init_pciide(), now just check the drive's capabilities.
21991709Smlf *
22001709Smlf */
22011709Smlf
22021709Smlf static int
ata_init_drive_pcidma(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,dev_info_t * tdip)22031709Smlf ata_init_drive_pcidma(
22041709Smlf ata_ctl_t *ata_ctlp,
22051709Smlf ata_drv_t *ata_drvp,
22061709Smlf dev_info_t *tdip)
22071709Smlf {
22081709Smlf boolean_t dma;
22091709Smlf boolean_t cd_dma;
22101709Smlf boolean_t disk_dma;
22111709Smlf boolean_t atapi_dma;
22121709Smlf int ata_options;
22131709Smlf
22141709Smlf ata_dev_DMA_sel_msg = NULL;
22151709Smlf
22161709Smlf if (ata_ctlp->ac_pciide_bm != TRUE) {
22171709Smlf ata_dev_DMA_sel_msg =
22181709Smlf "controller is not Bus Master capable";
22191709Smlf
22201709Smlf return (ATA_DMA_OFF);
22211709Smlf }
22221709Smlf
22231709Smlf ata_options = ddi_prop_get_int(DDI_DEV_T_ANY, ata_ctlp->ac_dip,
22245295Srandyf 0, "ata-options", 0);
22251709Smlf
22261709Smlf if (!(ata_options & ATA_OPTIONS_DMA)) {
22271709Smlf /*
22281709Smlf * Either the ata-options property was not found or
22291709Smlf * DMA is not enabled by this property
22301709Smlf */
22311709Smlf ata_dev_DMA_sel_msg =
22325295Srandyf "disabled by \"ata-options\" property";
22331709Smlf
22341709Smlf return (ATA_DMA_OFF);
22351709Smlf }
22361709Smlf
22371709Smlf if (ata_check_drive_blacklist(&ata_drvp->ad_id, ATA_BL_NODMA)) {
22381709Smlf ata_dev_DMA_sel_msg = "device not DMA capable; blacklisted";
22391709Smlf
22401709Smlf return (ATA_DMA_OFF);
22411709Smlf }
22421709Smlf
22431709Smlf /*
22441709Smlf * DMA mode is mandatory on ATA-3 (or newer) drives but is
22451709Smlf * optional on ATA-2 (or older) drives.
22461709Smlf *
22471709Smlf * On ATA-2 drives the ai_majorversion word will probably
22481709Smlf * be 0xffff or 0x0000, check the (now obsolete) DMA bit in
22491709Smlf * the capabilities word instead. The order of these tests
22501709Smlf * is important since an ATA-3 drive doesn't have to set
22511709Smlf * the DMA bit in the capabilities word.
22521709Smlf *
22531709Smlf */
22541709Smlf
22551709Smlf if (!((ata_drvp->ad_id.ai_majorversion & 0x8000) == 0 &&
22561709Smlf ata_drvp->ad_id.ai_majorversion >= (1 << 2)) &&
22571709Smlf !(ata_drvp->ad_id.ai_cap & ATAC_DMA_SUPPORT)) {
22581709Smlf ata_dev_DMA_sel_msg = "device not DMA capable";
22591709Smlf
22601709Smlf return (ATA_DMA_OFF);
22611709Smlf }
22621709Smlf
22637671SZhongyan.Gu@Sun.COM /*
22647671SZhongyan.Gu@Sun.COM * Disable DMA for ATAPI devices on controllers known to
22657671SZhongyan.Gu@Sun.COM * have trouble with ATAPI DMA
22667671SZhongyan.Gu@Sun.COM */
22677671SZhongyan.Gu@Sun.COM
22687671SZhongyan.Gu@Sun.COM if (ATAPIDRV(ata_drvp)) {
22697671SZhongyan.Gu@Sun.COM if (ata_check_pciide_blacklist(ata_ctlp->ac_dip,
22707671SZhongyan.Gu@Sun.COM ATA_BL_ATAPI_NODMA)) {
22717671SZhongyan.Gu@Sun.COM ata_dev_DMA_sel_msg =
22727671SZhongyan.Gu@Sun.COM "controller incapable of DMA for ATAPI device";
22737671SZhongyan.Gu@Sun.COM
22747671SZhongyan.Gu@Sun.COM return (ATA_DMA_OFF);
22757671SZhongyan.Gu@Sun.COM }
22767671SZhongyan.Gu@Sun.COM }
22771709Smlf dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip,
22785295Srandyf 0, "ata-dma-enabled", TRUE);
22791709Smlf disk_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip,
22805295Srandyf 0, "ata-disk-dma-enabled", TRUE);
22811709Smlf cd_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip,
22825295Srandyf 0, "atapi-cd-dma-enabled", FALSE);
22831709Smlf atapi_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip,
22845295Srandyf 0, "atapi-other-dma-enabled", TRUE);
22851709Smlf
22861709Smlf if (dma == FALSE) {
22871709Smlf cmn_err(CE_CONT, "?ata_init_drive_pcidma: "
22881709Smlf "DMA disabled by \"ata-dma-enabled\" property");
22891709Smlf ata_dev_DMA_sel_msg = "disabled by prop ata-dma-enabled";
22901709Smlf
22911709Smlf return (ATA_DMA_OFF);
22921709Smlf }
22931709Smlf
22941709Smlf if (IS_CDROM(ata_drvp) == TRUE) {
22951709Smlf if (cd_dma == FALSE) {
22961709Smlf ata_dev_DMA_sel_msg =
22971709Smlf "disabled. Control with \"atapi-cd-dma-enabled\""
22981709Smlf " property";
22991709Smlf
23001709Smlf return (ATA_DMA_OFF);
23011709Smlf }
23021709Smlf
23031709Smlf } else if (ATAPIDRV(ata_drvp) == FALSE) {
23041709Smlf if (disk_dma == FALSE) {
23051709Smlf ata_dev_DMA_sel_msg =
23061709Smlf "disabled by \"ata-disk-dma-enabled\" property";
23071709Smlf
23081709Smlf return (ATA_DMA_OFF);
23091709Smlf }
23101709Smlf
23111709Smlf } else if (atapi_dma == FALSE) {
23121709Smlf ata_dev_DMA_sel_msg =
23131709Smlf "disabled by \"atapi-other-dma-enabled\" property";
23141709Smlf
23151709Smlf return (ATA_DMA_OFF);
23161709Smlf }
23171709Smlf
23181709Smlf return (ATA_DMA_ON);
23191709Smlf }
23201709Smlf
23211709Smlf
23221709Smlf
23231709Smlf /*
23241709Smlf * this compare routine squeezes out extra blanks and
23251709Smlf * returns TRUE if p1 matches the leftmost substring of p2
23261709Smlf */
23271709Smlf
23281709Smlf static int
ata_strncmp(char * p1,char * p2,int cnt)23291709Smlf ata_strncmp(
23301709Smlf char *p1,
23311709Smlf char *p2,
23321709Smlf int cnt)
23331709Smlf {
23341709Smlf
23351709Smlf for (;;) {
23361709Smlf /*
23371709Smlf * skip over any extra blanks in both strings
23381709Smlf */
23391709Smlf while (*p1 != '\0' && *p1 == ' ')
23401709Smlf p1++;
23411709Smlf
23421709Smlf while (cnt != 0 && *p2 == ' ') {
23431709Smlf p2++;
23441709Smlf cnt--;
23451709Smlf }
23461709Smlf
23471709Smlf /*
23481709Smlf * compare the two strings
23491709Smlf */
23501709Smlf
23511709Smlf if (cnt == 0 || *p1 != *p2)
23521709Smlf break;
23531709Smlf
23541709Smlf while (cnt > 0 && *p1 == *p2) {
23551709Smlf p1++;
23561709Smlf p2++;
23571709Smlf cnt--;
23581709Smlf }
23591709Smlf
23601709Smlf }
23611709Smlf
23621709Smlf /* return TRUE if both strings ended at same point */
23631709Smlf return ((*p1 == '\0') ? TRUE : FALSE);
23641709Smlf }
23651709Smlf
23661709Smlf /*
23671709Smlf * Per PSARC/1997/281 create variant="atapi" property (if necessary)
23681709Smlf * on the target's dev_info node. Currently, the sd target driver
23691709Smlf * is the only driver which refers to this property.
23701709Smlf *
23711709Smlf * If the flag ata_id_debug is set also create the
23721709Smlf * the "ata" or "atapi" property on the target's dev_info node
23731709Smlf *
23741709Smlf */
23751709Smlf
23761709Smlf int
ata_prop_create(dev_info_t * tgt_dip,ata_drv_t * ata_drvp,char * name)23771709Smlf ata_prop_create(
23781709Smlf dev_info_t *tgt_dip,
23791709Smlf ata_drv_t *ata_drvp,
23801709Smlf char *name)
23811709Smlf {
23821709Smlf int rc;
23831709Smlf
23841709Smlf ADBG_TRACE(("ata_prop_create 0x%p 0x%p %s\n", tgt_dip, ata_drvp, name));
23851709Smlf
23861709Smlf if (strcmp("atapi", name) == 0) {
23871709Smlf rc = ndi_prop_update_string(DDI_DEV_T_NONE, tgt_dip,
23885295Srandyf "variant", name);
23891709Smlf if (rc != DDI_PROP_SUCCESS)
23901709Smlf return (FALSE);
23911709Smlf }
23921709Smlf
23931709Smlf if (!ata_id_debug)
23941709Smlf return (TRUE);
23951709Smlf
23961709Smlf rc = ndi_prop_update_byte_array(DDI_DEV_T_NONE, tgt_dip, name,
23975295Srandyf (uchar_t *)&ata_drvp->ad_id, sizeof (ata_drvp->ad_id));
23981709Smlf if (rc != DDI_PROP_SUCCESS) {
23991709Smlf ADBG_ERROR(("ata_prop_create failed, rc=%d\n", rc));
24001709Smlf }
24011709Smlf return (TRUE);
24021709Smlf }
24031709Smlf
24041709Smlf
24051709Smlf /* *********************************************************************** */
24061709Smlf /* *********************************************************************** */
24071709Smlf /* *********************************************************************** */
24081709Smlf
24091709Smlf /*
24101709Smlf * This state machine doesn't implement the ATAPI Optional Overlap
24111709Smlf * feature. You need that feature to efficiently support ATAPI
24121709Smlf * tape drives. See the 1394-ATA Tailgate spec (D97107), Figure 24,
24131709Smlf * for an example of how to add the necessary additional NextActions
24141709Smlf * and NextStates to this FSM and the atapi_fsm, in order to support
24151709Smlf * the Overlap Feature.
24161709Smlf */
24171709Smlf
24181709Smlf
24191709Smlf uchar_t ata_ctlr_fsm_NextAction[ATA_CTLR_NSTATES][ATA_CTLR_NFUNCS] = {
24201709Smlf /* --------------------- next action --------------------- | - current - */
24211709Smlf /* start0 --- start1 ---- intr ------ fini --- reset --- */
24221709Smlf { AC_START, AC_START, AC_NADA, AC_NADA, AC_RESET_I }, /* idle */
24231709Smlf { AC_BUSY, AC_BUSY, AC_INTR, AC_FINI, AC_RESET_A }, /* active0 */
24241709Smlf { AC_BUSY, AC_BUSY, AC_INTR, AC_FINI, AC_RESET_A }, /* active1 */
24251709Smlf };
24261709Smlf
24271709Smlf uchar_t ata_ctlr_fsm_NextState[ATA_CTLR_NSTATES][ATA_CTLR_NFUNCS] = {
24281709Smlf
24291709Smlf /* --------------------- next state --------------------- | - current - */
24301709Smlf /* start0 --- start1 ---- intr ------ fini --- reset --- */
24311709Smlf { AS_ACTIVE0, AS_ACTIVE1, AS_IDLE, AS_IDLE, AS_IDLE }, /* idle */
24321709Smlf { AS_ACTIVE0, AS_ACTIVE0, AS_ACTIVE0, AS_IDLE, AS_ACTIVE0 }, /* active0 */
24331709Smlf { AS_ACTIVE1, AS_ACTIVE1, AS_ACTIVE1, AS_IDLE, AS_ACTIVE1 }, /* active1 */
24341709Smlf };
24351709Smlf
24361709Smlf
24371709Smlf static int
ata_ctlr_fsm(uchar_t fsm_func,ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp,int * DoneFlgp)24381709Smlf ata_ctlr_fsm(
24391709Smlf uchar_t fsm_func,
24401709Smlf ata_ctl_t *ata_ctlp,
24411709Smlf ata_drv_t *ata_drvp,
24421709Smlf ata_pkt_t *ata_pktp,
24431709Smlf int *DoneFlgp)
24441709Smlf {
24451709Smlf uchar_t action;
24461709Smlf uchar_t current_state;
24471709Smlf uchar_t next_state;
24481709Smlf int rc;
24491709Smlf
24501709Smlf current_state = ata_ctlp->ac_state;
24511709Smlf action = ata_ctlr_fsm_NextAction[current_state][fsm_func];
24521709Smlf next_state = ata_ctlr_fsm_NextState[current_state][fsm_func];
24531709Smlf
24541709Smlf /*
24551709Smlf * Set the controller's new state
24561709Smlf */
24571709Smlf ata_ctlp->ac_state = next_state;
24581709Smlf switch (action) {
24591709Smlf
24601709Smlf case AC_BUSY:
24611709Smlf return (ATA_FSM_RC_BUSY);
24621709Smlf
24631709Smlf case AC_NADA:
24641709Smlf return (ATA_FSM_RC_OKAY);
24651709Smlf
24661709Smlf case AC_START:
24671709Smlf ASSERT(ata_ctlp->ac_active_pktp == NULL);
24681709Smlf ASSERT(ata_ctlp->ac_active_drvp == NULL);
24691709Smlf
24701709Smlf ata_ctlp->ac_active_pktp = ata_pktp;
24711709Smlf ata_ctlp->ac_active_drvp = ata_drvp;
24721709Smlf
24731709Smlf rc = (*ata_pktp->ap_start)(ata_ctlp, ata_drvp, ata_pktp);
24741709Smlf
24751709Smlf if (rc == ATA_FSM_RC_BUSY) {
24761709Smlf /* the request didn't start, GHD will requeue it */
24771709Smlf ata_ctlp->ac_state = AS_IDLE;
24781709Smlf ata_ctlp->ac_active_pktp = NULL;
24791709Smlf ata_ctlp->ac_active_drvp = NULL;
24801709Smlf }
24811709Smlf return (rc);
24821709Smlf
24831709Smlf case AC_INTR:
24841709Smlf ASSERT(ata_ctlp->ac_active_pktp != NULL);
24851709Smlf ASSERT(ata_ctlp->ac_active_drvp != NULL);
24861709Smlf
24871709Smlf ata_drvp = ata_ctlp->ac_active_drvp;
24881709Smlf ata_pktp = ata_ctlp->ac_active_pktp;
24891709Smlf return ((*ata_pktp->ap_intr)(ata_ctlp, ata_drvp, ata_pktp));
24901709Smlf
24911709Smlf case AC_RESET_A: /* Reset, controller active */
24921709Smlf ASSERT(ata_ctlp->ac_active_pktp != NULL);
24931709Smlf ASSERT(ata_ctlp->ac_active_drvp != NULL);
24941709Smlf
24951709Smlf /* clean up the active request */
24961709Smlf ata_pktp = ata_ctlp->ac_active_pktp;
24971709Smlf ata_pktp->ap_flags |= AP_DEV_RESET | AP_BUS_RESET;
24981709Smlf
24991709Smlf /* halt the DMA engine */
25001709Smlf if (ata_pktp->ap_pciide_dma) {
25011709Smlf ata_pciide_dma_stop(ata_ctlp);
25021709Smlf (void) ata_pciide_status_clear(ata_ctlp);
25031709Smlf }
25041709Smlf
25051709Smlf /* Do a Software Reset to unwedge the bus */
25061709Smlf if (!ata_software_reset(ata_ctlp)) {
25071709Smlf return (ATA_FSM_RC_BUSY);
25081709Smlf }
25091709Smlf
25101709Smlf /* Then send a DEVICE RESET cmd to each ATAPI device */
25111709Smlf atapi_fsm_reset(ata_ctlp);
25121709Smlf return (ATA_FSM_RC_FINI);
25131709Smlf
25141709Smlf case AC_RESET_I: /* Reset, controller idle */
25151709Smlf /* Do a Software Reset to unwedge the bus */
25161709Smlf if (!ata_software_reset(ata_ctlp)) {
25171709Smlf return (ATA_FSM_RC_BUSY);
25181709Smlf }
25191709Smlf
25201709Smlf /* Then send a DEVICE RESET cmd to each ATAPI device */
25211709Smlf atapi_fsm_reset(ata_ctlp);
25221709Smlf return (ATA_FSM_RC_OKAY);
25231709Smlf
25241709Smlf case AC_FINI:
25251709Smlf break;
25261709Smlf }
25271709Smlf
25281709Smlf /*
25291709Smlf * AC_FINI, check ARQ needs to be started or finished
25301709Smlf */
25311709Smlf
25321709Smlf ASSERT(action == AC_FINI);
25331709Smlf ASSERT(ata_ctlp->ac_active_pktp != NULL);
25341709Smlf ASSERT(ata_ctlp->ac_active_drvp != NULL);
25351709Smlf
25361709Smlf /*
25371709Smlf * The active request is done now.
25381709Smlf * Disconnect the request from the controller and
25391709Smlf * add it to the done queue.
25401709Smlf */
25411709Smlf ata_drvp = ata_ctlp->ac_active_drvp;
25421709Smlf ata_pktp = ata_ctlp->ac_active_pktp;
25431709Smlf
25441709Smlf /*
25451709Smlf * If ARQ pkt is done, get ptr to original pkt and wrap it up.
25461709Smlf */
25471709Smlf if (ata_pktp == ata_ctlp->ac_arq_pktp) {
25481709Smlf ata_pkt_t *arq_pktp;
25491709Smlf
25501709Smlf ADBG_ARQ(("ata_ctlr_fsm 0x%p ARQ done\n", ata_ctlp));
25511709Smlf
25521709Smlf arq_pktp = ata_pktp;
25531709Smlf ata_pktp = ata_ctlp->ac_fault_pktp;
25541709Smlf ata_ctlp->ac_fault_pktp = NULL;
25551709Smlf if (arq_pktp->ap_flags & (AP_ERROR | AP_BUS_RESET))
25561709Smlf ata_pktp->ap_flags |= AP_ARQ_ERROR;
25571709Smlf else
25581709Smlf ata_pktp->ap_flags |= AP_ARQ_OKAY;
25591709Smlf goto all_done;
25601709Smlf }
25611709Smlf
25621709Smlf
25631709Smlf #define AP_ARQ_NEEDED (AP_ARQ_ON_ERROR | AP_GOT_STATUS | AP_ERROR)
25641709Smlf
25651709Smlf /*
25661709Smlf * Start ARQ pkt if necessary
25671709Smlf */
25681709Smlf if ((ata_pktp->ap_flags & AP_ARQ_NEEDED) == AP_ARQ_NEEDED &&
25695295Srandyf (ata_pktp->ap_status & ATS_ERR)) {
25701709Smlf
25711709Smlf /* set controller state back to active */
25721709Smlf ata_ctlp->ac_state = current_state;
25731709Smlf
25741709Smlf /* try to start the ARQ pkt */
25751709Smlf rc = ata_start_arq(ata_ctlp, ata_drvp, ata_pktp);
25761709Smlf
25771709Smlf if (rc == ATA_FSM_RC_BUSY) {
25781709Smlf ADBG_ARQ(("ata_ctlr_fsm 0x%p ARQ BUSY\n", ata_ctlp));
25791709Smlf /* let the target driver handle the problem */
25801709Smlf ata_ctlp->ac_state = AS_IDLE;
25811709Smlf ata_ctlp->ac_active_pktp = NULL;
25821709Smlf ata_ctlp->ac_active_drvp = NULL;
25831709Smlf ata_ctlp->ac_fault_pktp = NULL;
25841709Smlf goto all_done;
25851709Smlf }
25861709Smlf
25871709Smlf ADBG_ARQ(("ata_ctlr_fsm 0x%p ARQ started\n", ata_ctlp));
25881709Smlf return (rc);
25891709Smlf }
25901709Smlf
25911709Smlf /*
25921709Smlf * Normal completion, no error status, and not an ARQ pkt,
25931709Smlf * just fall through.
25941709Smlf */
25951709Smlf
25961709Smlf all_done:
25971709Smlf
25981709Smlf /*
25991709Smlf * wrap everything up and tie a ribbon around it
26001709Smlf */
26011709Smlf ata_ctlp->ac_active_pktp = NULL;
26021709Smlf ata_ctlp->ac_active_drvp = NULL;
26031709Smlf if (APKT2GCMD(ata_pktp) != (gcmd_t *)0) {
26041709Smlf ghd_complete(&ata_ctlp->ac_ccc, APKT2GCMD(ata_pktp));
26051709Smlf if (DoneFlgp)
26061709Smlf *DoneFlgp = TRUE;
26071709Smlf }
26081709Smlf
26091709Smlf return (ATA_FSM_RC_OKAY);
26101709Smlf }
26111709Smlf
26121709Smlf
26131709Smlf static int
ata_start_arq(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)26141709Smlf ata_start_arq(
26151709Smlf ata_ctl_t *ata_ctlp,
26161709Smlf ata_drv_t *ata_drvp,
26171709Smlf ata_pkt_t *ata_pktp)
26181709Smlf {
26191709Smlf ata_pkt_t *arq_pktp;
26201709Smlf int bytes;
26211709Smlf uint_t senselen;
26221709Smlf
26231709Smlf ADBG_ARQ(("ata_start_arq 0x%p ARQ needed\n", ata_ctlp));
26241709Smlf
26251709Smlf /*
26261709Smlf * Determine just the size of the Request Sense Data buffer within
26271709Smlf * the scsi_arq_status structure.
26281709Smlf */
26291709Smlf #define SIZEOF_ARQ_HEADER (sizeof (struct scsi_arq_status) \
26301709Smlf - sizeof (struct scsi_extended_sense))
26311709Smlf senselen = ata_pktp->ap_statuslen - SIZEOF_ARQ_HEADER;
26321709Smlf ASSERT(senselen > 0);
26331709Smlf
26341709Smlf
26351709Smlf /* save ptr to original pkt */
26361709Smlf ata_ctlp->ac_fault_pktp = ata_pktp;
26371709Smlf
26381709Smlf /* switch the controller's active pkt to the ARQ pkt */
26391709Smlf arq_pktp = ata_ctlp->ac_arq_pktp;
26401709Smlf ata_ctlp->ac_active_pktp = arq_pktp;
26411709Smlf
26421709Smlf /* finish initializing the ARQ CDB */
26431709Smlf ata_ctlp->ac_arq_cdb[1] = ata_drvp->ad_lun << 4;
26447671SZhongyan.Gu@Sun.COM ata_ctlp->ac_arq_cdb[4] = (uchar_t)senselen;
26451709Smlf
26461709Smlf /* finish initializing the ARQ pkt */
26471709Smlf arq_pktp->ap_v_addr = (caddr_t)&ata_pktp->ap_scbp->sts_sensedata;
26481709Smlf
26491709Smlf arq_pktp->ap_resid = senselen;
26501709Smlf arq_pktp->ap_flags = AP_ATAPI | AP_READ;
26511709Smlf arq_pktp->ap_cdb_pad =
26525295Srandyf ((unsigned)(ata_drvp->ad_cdb_len - arq_pktp->ap_cdb_len)) >> 1;
26531709Smlf
26541709Smlf bytes = min(senselen, ATAPI_MAX_BYTES_PER_DRQ);
26551709Smlf arq_pktp->ap_hicyl = (uchar_t)(bytes >> 8);
26561709Smlf arq_pktp->ap_lwcyl = (uchar_t)bytes;
26571709Smlf
26581709Smlf /*
26591709Smlf * This packet is shared by all drives on this controller
26601709Smlf * therefore we need to init the drive number on every ARQ.
26611709Smlf */
26621709Smlf arq_pktp->ap_hd = ata_drvp->ad_drive_bits;
26631709Smlf
26641709Smlf /* start it up */
26651709Smlf return ((*arq_pktp->ap_start)(ata_ctlp, ata_drvp, arq_pktp));
26661709Smlf }
26671709Smlf
26681709Smlf /*
26691709Smlf *
26701709Smlf * reset the bus
26711709Smlf *
26721709Smlf */
26731709Smlf
26741709Smlf static int
ata_reset_bus(ata_ctl_t * ata_ctlp)26751709Smlf ata_reset_bus(
26761709Smlf ata_ctl_t *ata_ctlp)
26771709Smlf {
26781709Smlf int watchdog;
26791709Smlf uchar_t drive;
26801709Smlf int rc = FALSE;
26811709Smlf uchar_t fsm_func;
26821709Smlf int DoneFlg = FALSE;
26831709Smlf
26841709Smlf /*
26851709Smlf * Do a Software Reset to unwedge the bus, and send
26861709Smlf * ATAPI DEVICE RESET to each ATAPI drive.
26871709Smlf */
26881709Smlf fsm_func = ATA_FSM_RESET;
26891709Smlf for (watchdog = ata_reset_bus_watchdog; watchdog > 0; watchdog--) {
26901709Smlf switch (ata_ctlr_fsm(fsm_func, ata_ctlp, NULL, NULL,
26915295Srandyf &DoneFlg)) {
26921709Smlf case ATA_FSM_RC_OKAY:
26931709Smlf rc = TRUE;
26941709Smlf goto fsm_done;
26951709Smlf
26961709Smlf case ATA_FSM_RC_BUSY:
26971709Smlf return (FALSE);
26981709Smlf
26991709Smlf case ATA_FSM_RC_INTR:
27001709Smlf fsm_func = ATA_FSM_INTR;
27011709Smlf rc = TRUE;
27021709Smlf continue;
27031709Smlf
27041709Smlf case ATA_FSM_RC_FINI:
27051709Smlf fsm_func = ATA_FSM_FINI;
27061709Smlf rc = TRUE;
27071709Smlf continue;
27081709Smlf }
27091709Smlf }
27101709Smlf ADBG_WARN(("ata_reset_bus: watchdog\n"));
27111709Smlf
27121709Smlf fsm_done:
27131709Smlf
27141709Smlf /*
27151709Smlf * Reinitialize the ATA drives
27161709Smlf */
27171709Smlf for (drive = 0; drive < ATA_MAXTARG; drive++) {
27181709Smlf ata_drv_t *ata_drvp;
27191709Smlf
27201709Smlf if ((ata_drvp = CTL2DRV(ata_ctlp, drive, 0)) == NULL)
27211709Smlf continue;
27221709Smlf
27231709Smlf if (ATAPIDRV(ata_drvp))
27241709Smlf continue;
27251709Smlf
27261709Smlf /*
27271709Smlf * Reprogram the Read/Write Multiple block factor
27281709Smlf * and current geometry into the drive.
27291709Smlf */
27301709Smlf if (!ata_disk_setup_parms(ata_ctlp, ata_drvp))
27311709Smlf rc = FALSE;
27321709Smlf }
27331709Smlf
27341709Smlf /* If DoneFlg is TRUE, it means that ghd_complete() function */
27351709Smlf /* has been already called. In this case ignore any errors and */
27361709Smlf /* return TRUE to the caller, otherwise return the value of rc */
27371709Smlf /* to the caller */
27381709Smlf if (DoneFlg)
27391709Smlf return (TRUE);
27401709Smlf else
27411709Smlf return (rc);
27421709Smlf }
27431709Smlf
27441709Smlf
27451709Smlf /*
27461709Smlf *
27471709Smlf * Low level routine to toggle the Software Reset bit
27481709Smlf *
27491709Smlf */
27501709Smlf
27511709Smlf static int
ata_software_reset(ata_ctl_t * ata_ctlp)27521709Smlf ata_software_reset(
27531709Smlf ata_ctl_t *ata_ctlp)
27541709Smlf {
27551709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
27561709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
27574852Smlf hrtime_t deadline;
27584852Smlf uint_t usecs_left;
27591709Smlf
27601709Smlf ADBG_TRACE(("ata_reset_bus entered\n"));
27611709Smlf
27621709Smlf /* disable interrupts and turn the software reset bit on */
27631709Smlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3 | ATDC_SRST));
27641709Smlf
27651709Smlf /* why 30 milliseconds, the ATA/ATAPI-4 spec says 5 usec. */
27661709Smlf drv_usecwait(30000);
27671709Smlf
27681709Smlf /* turn the software reset bit back off */
27691709Smlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, ATDC_D3);
27701709Smlf
27711709Smlf /*
27721709Smlf * Wait for the controller to assert BUSY status.
27731709Smlf * I don't think 300 msecs is correct. The ATA/ATAPI-4
27741709Smlf * spec says 400 nsecs, (and 2 msecs if device
27751709Smlf * was in sleep mode; but we don't put drives to sleep
27761709Smlf * so it probably doesn't matter).
27771709Smlf */
27781709Smlf drv_usecwait(300000);
27791709Smlf
27801709Smlf /*
27811709Smlf * If drive 0 exists the test for completion is simple
27821709Smlf */
27834852Smlf deadline = gethrtime() + ((hrtime_t)31 * NANOSEC);
27844852Smlf
27851709Smlf if (CTL2DRV(ata_ctlp, 0, 0)) {
27861709Smlf goto wait_for_not_busy;
27871709Smlf }
27881709Smlf
27891709Smlf ASSERT(CTL2DRV(ata_ctlp, 1, 0) != NULL);
27901709Smlf
27911709Smlf /*
27921709Smlf * This must be a single device configuration, with drive 1
27931709Smlf * only. This complicates the test for completion because
27941709Smlf * issuing the software reset just caused drive 1 to
27951709Smlf * deselect. With drive 1 deselected, if I just read the
27961709Smlf * status register to test the BSY bit I get garbage, but
27971709Smlf * I can't re-select drive 1 until I'm certain the BSY bit
27981709Smlf * is de-asserted. Catch-22.
27991709Smlf *
28001709Smlf * In ATA/ATAPI-4, rev 15, section 9.16.2, it says to handle
28011709Smlf * this situation like this:
28021709Smlf */
28031709Smlf
28041709Smlf /* give up if the drive doesn't settle within 31 seconds */
28054852Smlf while (gethrtime() < deadline) {
28061709Smlf /*
28071709Smlf * delay 10msec each time around the loop
28081709Smlf */
28091709Smlf drv_usecwait(10000);
28101709Smlf
28111709Smlf /*
28121709Smlf * try to select drive 1
28131709Smlf */
28141709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ATDH_DRIVE1);
28151709Smlf
28161709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, 0x55);
28171709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, 0xaa);
28181709Smlf if (ddi_get8(io_hdl1, ata_ctlp->ac_sect) != 0xaa)
28191709Smlf continue;
28201709Smlf
28211709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, 0x55);
28221709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, 0xaa);
28231709Smlf if (ddi_get8(io_hdl1, ata_ctlp->ac_count) != 0xaa)
28241709Smlf continue;
28251709Smlf
28261709Smlf goto wait_for_not_busy;
28271709Smlf }
28281709Smlf return (FALSE);
28291709Smlf
28301709Smlf wait_for_not_busy:
28311709Smlf
28321709Smlf /*
28334852Smlf * Now wait up to 31 seconds for BUSY to clear.
28341709Smlf */
28354852Smlf usecs_left = (deadline - gethrtime()) / 1000;
28361709Smlf (void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY,
28375295Srandyf ATS_ERR, ATS_BSY, ATS_DF, ATS_BSY, usecs_left);
28381709Smlf
28391709Smlf return (TRUE);
28401709Smlf }
28411709Smlf
28421709Smlf /*
28431709Smlf *
28441709Smlf * DDI interrupt handler
28451709Smlf *
28461709Smlf */
28471709Smlf
28481709Smlf static uint_t
ata_intr(caddr_t arg)28491709Smlf ata_intr(
28501709Smlf caddr_t arg)
28511709Smlf {
28521709Smlf ata_ctl_t *ata_ctlp;
28531709Smlf int one_shot = 1;
28541709Smlf
28551709Smlf ata_ctlp = (ata_ctl_t *)arg;
28561709Smlf
28571709Smlf return (ghd_intr(&ata_ctlp->ac_ccc, (void *)&one_shot));
28581709Smlf }
28591709Smlf
28601709Smlf
28611709Smlf /*
28621709Smlf *
28631709Smlf * GHD ccc_get_status callback
28641709Smlf *
28651709Smlf */
28661709Smlf
28671709Smlf static int
ata_get_status(void * hba_handle,void * intr_status)28681709Smlf ata_get_status(
28691709Smlf void *hba_handle,
28701709Smlf void *intr_status)
28711709Smlf {
28721709Smlf ata_ctl_t *ata_ctlp = (ata_ctl_t *)hba_handle;
28731709Smlf uchar_t status;
28741709Smlf
28751709Smlf ADBG_TRACE(("ata_get_status entered\n"));
28761709Smlf
28771709Smlf /*
28781709Smlf * ignore interrupts before ata_attach completes
28791709Smlf */
28801709Smlf if (!(ata_ctlp->ac_flags & AC_ATTACHED))
28811709Smlf return (FALSE);
28821709Smlf
28831709Smlf /*
28841709Smlf * can't be interrupt pending if nothing active
28851709Smlf */
28861709Smlf switch (ata_ctlp->ac_state) {
28871709Smlf case AS_IDLE:
28881709Smlf return (FALSE);
28891709Smlf case AS_ACTIVE0:
28901709Smlf case AS_ACTIVE1:
28911709Smlf ASSERT(ata_ctlp->ac_active_drvp != NULL);
28921709Smlf ASSERT(ata_ctlp->ac_active_pktp != NULL);
28931709Smlf break;
28941709Smlf }
28951709Smlf
28961709Smlf /*
28971709Smlf * If this is a PCI-IDE controller, check the PCI-IDE controller's
28981709Smlf * interrupt status latch. But don't clear it yet.
28991709Smlf *
29001709Smlf * AC_BMSTATREG_PIO_BROKEN flag is used currently for
29011709Smlf * CMD chips with device id 0x646. Since the interrupt bit on
29021709Smlf * Bus master IDE register is not usable when in PIO mode,
29031709Smlf * this chip is treated as a legacy device for interrupt
29041709Smlf * indication. The following code for CMD
29051709Smlf * chips may need to be revisited when we enable support for dma.
29061709Smlf *
29071709Smlf * CHANGE: DMA is not disabled for these devices. BM intr bit is
29081709Smlf * checked only if there was DMA used or BM intr is useable on PIO,
29091709Smlf * else treat it as before - as legacy device.
29101709Smlf */
29111709Smlf
29121709Smlf if ((ata_ctlp->ac_pciide) &&
29131709Smlf ((ata_ctlp->ac_pciide_bm != FALSE) &&
29141709Smlf ((ata_ctlp->ac_active_pktp->ap_pciide_dma == TRUE) ||
29151709Smlf !(ata_ctlp->ac_flags & AC_BMSTATREG_PIO_BROKEN)))) {
29161709Smlf
29171709Smlf if (!ata_pciide_status_pending(ata_ctlp))
29181709Smlf return (FALSE);
29191709Smlf } else {
29201709Smlf /*
29211709Smlf * Interrupts from legacy ATA/IDE controllers are
29221709Smlf * edge-triggered but the dumb legacy ATA/IDE controllers
29231709Smlf * and drives don't have an interrupt status bit.
29241709Smlf *
29251709Smlf * Use a one_shot variable to make sure we only return
29261709Smlf * one status per interrupt.
29271709Smlf */
29281709Smlf if (intr_status != NULL) {
29291709Smlf int *one_shot = (int *)intr_status;
29301709Smlf
29311709Smlf if (*one_shot == 1)
29321709Smlf *one_shot = 0;
29331709Smlf else
29341709Smlf return (FALSE);
29351709Smlf }
29361709Smlf }
29371709Smlf
29381709Smlf /* check if device is still busy */
29391709Smlf
29401709Smlf status = ddi_get8(ata_ctlp->ac_iohandle2, ata_ctlp->ac_altstatus);
29411709Smlf if (status & ATS_BSY)
29421709Smlf return (FALSE);
29431709Smlf return (TRUE);
29441709Smlf }
29451709Smlf
29461709Smlf
29471709Smlf /*
29481709Smlf *
29491709Smlf * get the current status and clear the IRQ
29501709Smlf *
29511709Smlf */
29521709Smlf
29531709Smlf int
ata_get_status_clear_intr(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)29541709Smlf ata_get_status_clear_intr(
29551709Smlf ata_ctl_t *ata_ctlp,
29561709Smlf ata_pkt_t *ata_pktp)
29571709Smlf {
29581709Smlf uchar_t status;
29591709Smlf
29601709Smlf /*
29611709Smlf * Here's where we clear the PCI-IDE interrupt latch. If this
29621709Smlf * request used DMA mode then we also have to check and clear
29631709Smlf * the DMA error latch at the same time.
29641709Smlf */
29651709Smlf
29661709Smlf if (ata_pktp->ap_pciide_dma) {
29671709Smlf if (ata_pciide_status_dmacheck_clear(ata_ctlp))
29681709Smlf ata_pktp->ap_flags |= AP_ERROR | AP_TRAN_ERROR;
29691709Smlf } else if ((ata_ctlp->ac_pciide) &&
29701709Smlf !(ata_ctlp->ac_flags & AC_BMSTATREG_PIO_BROKEN)) {
29711709Smlf /*
29721709Smlf * Some requests don't use DMA mode and therefore won't
29731709Smlf * set the DMA error latch, but we still have to clear
29741709Smlf * the interrupt latch.
29751709Smlf * Controllers with broken BM intr in PIO mode do not go
29761709Smlf * through this path.
29771709Smlf */
29781709Smlf (void) ata_pciide_status_clear(ata_ctlp);
29791709Smlf }
29801709Smlf
29811709Smlf /*
29821709Smlf * this clears the drive's interrupt
29831709Smlf */
29841709Smlf status = ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_status);
29851709Smlf ADBG_TRACE(("ata_get_status_clear_intr: 0x%x\n", status));
29861709Smlf return (status);
29871709Smlf }
29881709Smlf
29891709Smlf
29901709Smlf
29911709Smlf /*
29921709Smlf *
29931709Smlf * GHD interrupt handler
29941709Smlf *
29951709Smlf */
29961709Smlf
29971709Smlf /* ARGSUSED */
29981709Smlf static void
ata_process_intr(void * hba_handle,void * intr_status)29991709Smlf ata_process_intr(
30001709Smlf void *hba_handle,
30011709Smlf void *intr_status)
30021709Smlf {
30031709Smlf ata_ctl_t *ata_ctlp = (ata_ctl_t *)hba_handle;
30041709Smlf int watchdog;
30051709Smlf uchar_t fsm_func;
30061709Smlf int rc;
30071709Smlf
30081709Smlf ADBG_TRACE(("ata_process_intr entered\n"));
30091709Smlf
30101709Smlf /*
30111709Smlf * process the ATA or ATAPI interrupt
30121709Smlf */
30131709Smlf
30141709Smlf fsm_func = ATA_FSM_INTR;
30151709Smlf for (watchdog = ata_process_intr_watchdog; watchdog > 0; watchdog--) {
30161709Smlf rc = ata_ctlr_fsm(fsm_func, ata_ctlp, NULL, NULL, NULL);
30171709Smlf
30181709Smlf switch (rc) {
30191709Smlf case ATA_FSM_RC_OKAY:
30201709Smlf return;
30211709Smlf
30221709Smlf case ATA_FSM_RC_BUSY: /* wait for the next interrupt */
30231709Smlf return;
30241709Smlf
30251709Smlf case ATA_FSM_RC_INTR: /* re-invoke the FSM */
30261709Smlf fsm_func = ATA_FSM_INTR;
30271709Smlf break;
30281709Smlf
30291709Smlf case ATA_FSM_RC_FINI: /* move a request to done Q */
30301709Smlf fsm_func = ATA_FSM_FINI;
30311709Smlf break;
30321709Smlf }
30331709Smlf }
30341709Smlf ADBG_WARN(("ata_process_intr: watchdog\n"));
30351709Smlf }
30361709Smlf
30371709Smlf
30381709Smlf
30391709Smlf /*
30401709Smlf *
30411709Smlf * GHD ccc_hba_start callback
30421709Smlf *
30431709Smlf */
30441709Smlf
30451709Smlf static int
ata_hba_start(void * hba_handle,gcmd_t * gcmdp)30461709Smlf ata_hba_start(
30471709Smlf void *hba_handle,
30481709Smlf gcmd_t *gcmdp)
30491709Smlf {
30501709Smlf ata_ctl_t *ata_ctlp;
30511709Smlf ata_drv_t *ata_drvp;
30521709Smlf ata_pkt_t *ata_pktp;
30531709Smlf uchar_t fsm_func;
30541709Smlf int request_started;
30551709Smlf int watchdog;
30561709Smlf
30571709Smlf ADBG_TRACE(("ata_hba_start entered\n"));
30581709Smlf
30591709Smlf ata_ctlp = (ata_ctl_t *)hba_handle;
30601709Smlf
30611709Smlf if (ata_ctlp->ac_active_drvp != NULL) {
30621709Smlf ADBG_WARN(("ata_hba_start drvp not null\n"));
30631709Smlf return (FALSE);
30641709Smlf }
30651709Smlf if (ata_ctlp->ac_active_pktp != NULL) {
30661709Smlf ADBG_WARN(("ata_hba_start pktp not null\n"));
30671709Smlf return (FALSE);
30681709Smlf }
30691709Smlf
30701709Smlf ata_pktp = GCMD2APKT(gcmdp);
30711709Smlf ata_drvp = GCMD2DRV(gcmdp);
30721709Smlf
30731709Smlf /*
30741709Smlf * which drive?
30751709Smlf */
30761709Smlf if (ata_drvp->ad_targ == 0)
30771709Smlf fsm_func = ATA_FSM_START0;
30781709Smlf else
30791709Smlf fsm_func = ATA_FSM_START1;
30801709Smlf
30811709Smlf /*
30821709Smlf * start the request
30831709Smlf */
30841709Smlf request_started = FALSE;
30851709Smlf for (watchdog = ata_hba_start_watchdog; watchdog > 0; watchdog--) {
30861709Smlf switch (ata_ctlr_fsm(fsm_func, ata_ctlp, ata_drvp, ata_pktp,
30875295Srandyf NULL)) {
30881709Smlf case ATA_FSM_RC_OKAY:
30891709Smlf request_started = TRUE;
30901709Smlf goto fsm_done;
30911709Smlf
30921709Smlf case ATA_FSM_RC_BUSY:
30931709Smlf /* if first time, tell GHD to requeue the request */
30941709Smlf goto fsm_done;
30951709Smlf
30961709Smlf case ATA_FSM_RC_INTR:
30971709Smlf /*
30981709Smlf * The start function polled for the next
30991709Smlf * bus phase, now fake an interrupt to process
31001709Smlf * the next action.
31011709Smlf */
31021709Smlf request_started = TRUE;
31031709Smlf fsm_func = ATA_FSM_INTR;
31041709Smlf ata_drvp = NULL;
31051709Smlf ata_pktp = NULL;
31061709Smlf break;
31071709Smlf
31081709Smlf case ATA_FSM_RC_FINI: /* move request to the done queue */
31091709Smlf request_started = TRUE;
31101709Smlf fsm_func = ATA_FSM_FINI;
31111709Smlf ata_drvp = NULL;
31121709Smlf ata_pktp = NULL;
31131709Smlf break;
31141709Smlf }
31151709Smlf }
31161709Smlf ADBG_WARN(("ata_hba_start: watchdog\n"));
31171709Smlf
31181709Smlf fsm_done:
31191709Smlf return (request_started);
31201709Smlf
31211709Smlf }
31221709Smlf
31231709Smlf static int
ata_check_pciide_blacklist(dev_info_t * dip,uint_t flags)31241709Smlf ata_check_pciide_blacklist(
31251709Smlf dev_info_t *dip,
31261709Smlf uint_t flags)
31271709Smlf {
31281709Smlf ushort_t vendorid;
31291709Smlf ushort_t deviceid;
31301709Smlf pcibl_t *blp;
31311709Smlf int *propp;
31321709Smlf uint_t count;
31331709Smlf int rc;
31341709Smlf
31351709Smlf
31361709Smlf vendorid = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
31375295Srandyf DDI_PROP_DONTPASS, "vendor-id", 0);
31381709Smlf deviceid = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
31395295Srandyf DDI_PROP_DONTPASS, "device-id", 0);
31401709Smlf
31411709Smlf /*
31421709Smlf * first check for a match in the "pci-ide-blacklist" property
31431709Smlf */
31441709Smlf rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0,
31455295Srandyf "pci-ide-blacklist", &propp, &count);
31461709Smlf
31471709Smlf if (rc == DDI_PROP_SUCCESS) {
31481709Smlf count = (count * sizeof (uint_t)) / sizeof (pcibl_t);
31491709Smlf blp = (pcibl_t *)propp;
31501709Smlf while (count--) {
31511709Smlf /* check for matching ID */
31521709Smlf if ((vendorid & blp->b_vmask)
31535295Srandyf != (blp->b_vendorid & blp->b_vmask)) {
31541709Smlf blp++;
31551709Smlf continue;
31561709Smlf }
31571709Smlf if ((deviceid & blp->b_dmask)
31585295Srandyf != (blp->b_deviceid & blp->b_dmask)) {
31591709Smlf blp++;
31601709Smlf continue;
31611709Smlf }
31621709Smlf
31631709Smlf /* got a match */
31641709Smlf if (blp->b_flags & flags) {
31651709Smlf ddi_prop_free(propp);
31661709Smlf return (TRUE);
31671709Smlf } else {
31681709Smlf ddi_prop_free(propp);
31691709Smlf return (FALSE);
31701709Smlf }
31711709Smlf }
31721709Smlf ddi_prop_free(propp);
31731709Smlf }
31741709Smlf
31751709Smlf /*
31761709Smlf * then check the built-in blacklist
31771709Smlf */
31781709Smlf for (blp = ata_pciide_blacklist; blp->b_vendorid; blp++) {
31791709Smlf if ((vendorid & blp->b_vmask) != blp->b_vendorid)
31801709Smlf continue;
31811709Smlf if ((deviceid & blp->b_dmask) != blp->b_deviceid)
31821709Smlf continue;
31831709Smlf if (!(blp->b_flags & flags))
31841709Smlf continue;
31851709Smlf return (TRUE);
31861709Smlf }
31871709Smlf return (FALSE);
31881709Smlf }
31891709Smlf
31901709Smlf int
ata_check_drive_blacklist(struct ata_id * aidp,uint_t flags)31911709Smlf ata_check_drive_blacklist(
31921709Smlf struct ata_id *aidp,
31931709Smlf uint_t flags)
31941709Smlf {
31951709Smlf atabl_t *blp;
31961709Smlf
31977841SLing.Ke@Sun.COM for (blp = ata_drive_blacklist; blp->b_model != NULL; blp++) {
31981709Smlf if (!ata_strncmp(blp->b_model, aidp->ai_model,
31995295Srandyf sizeof (aidp->ai_model)))
32001709Smlf continue;
32017841SLing.Ke@Sun.COM if (blp->b_fw != NULL) {
32027841SLing.Ke@Sun.COM if (!ata_strncmp(blp->b_fw, aidp->ai_fw,
32037841SLing.Ke@Sun.COM sizeof (aidp->ai_fw)))
32047841SLing.Ke@Sun.COM continue;
32057841SLing.Ke@Sun.COM }
32061709Smlf if (blp->b_flags & flags)
32071709Smlf return (TRUE);
32081709Smlf return (FALSE);
32091709Smlf }
32101709Smlf return (FALSE);
32111709Smlf }
32121709Smlf
32131709Smlf /*
32141709Smlf * Queue a request to perform some sort of internally
32151709Smlf * generated command. When this request packet reaches
32161709Smlf * the front of the queue (*func)() is invoked.
32171709Smlf *
32181709Smlf */
32191709Smlf
32201709Smlf int
ata_queue_cmd(int (* func)(ata_ctl_t *,ata_drv_t *,ata_pkt_t *),void * arg,ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,gtgt_t * gtgtp)32211709Smlf ata_queue_cmd(
32221709Smlf int (*func)(ata_ctl_t *, ata_drv_t *, ata_pkt_t *),
32231709Smlf void *arg,
32241709Smlf ata_ctl_t *ata_ctlp,
32251709Smlf ata_drv_t *ata_drvp,
32261709Smlf gtgt_t *gtgtp)
32271709Smlf {
32281709Smlf ata_pkt_t *ata_pktp;
32291709Smlf gcmd_t *gcmdp;
32301709Smlf int rc;
32311709Smlf
32321709Smlf if (!(gcmdp = ghd_gcmd_alloc(gtgtp, sizeof (*ata_pktp), TRUE))) {
32331709Smlf ADBG_ERROR(("atapi_id_update alloc failed\n"));
32341709Smlf return (FALSE);
32351709Smlf }
32361709Smlf
32371709Smlf
32381709Smlf /* set the back ptr from the ata_pkt to the gcmd_t */
32391709Smlf ata_pktp = GCMD2APKT(gcmdp);
32401709Smlf ata_pktp->ap_gcmdp = gcmdp;
32411709Smlf ata_pktp->ap_hd = ata_drvp->ad_drive_bits;
32421709Smlf ata_pktp->ap_bytes_per_block = ata_drvp->ad_bytes_per_block;
32431709Smlf
32441709Smlf /*
32451709Smlf * over-ride the default start function
32461709Smlf */
32471709Smlf ata_pktp = GCMD2APKT(gcmdp);
32481709Smlf ata_pktp->ap_start = func;
32491709Smlf ata_pktp->ap_complete = NULL;
32501709Smlf ata_pktp->ap_v_addr = (caddr_t)arg;
32511709Smlf
32521709Smlf /*
32531709Smlf * add it to the queue, when it gets to the front the
32541709Smlf * ap_start function is called.
32551709Smlf */
32561709Smlf rc = ghd_transport(&ata_ctlp->ac_ccc, gcmdp, gcmdp->cmd_gtgtp,
32575295Srandyf 0, TRUE, NULL);
32581709Smlf
32591709Smlf if (rc != TRAN_ACCEPT) {
32601709Smlf /* this should never, ever happen */
32611709Smlf return (FALSE);
32621709Smlf }
32631709Smlf
32641709Smlf if (ata_pktp->ap_flags & AP_ERROR)
32651709Smlf return (FALSE);
32661709Smlf return (TRUE);
32671709Smlf }
32681709Smlf
32691709Smlf /*
32701709Smlf * Check if this drive has the "revert to defaults" bug
32711709Smlf * PSARC 2001/500 and 2001/xxx - check for the properties
32721709Smlf * ata-revert-to-defaults and atarvrt-<diskmodel> before
32731709Smlf * examining the blacklist.
32741709Smlf * <diskmodel> is made from the model number reported by Identify Drive
32751709Smlf * with uppercase letters converted to lowercase and all characters
32761709Smlf * except letters, digits, ".", "_", and "-" deleted.
32771709Smlf * Return value:
32781709Smlf * TRUE: enable revert to defaults
32791709Smlf * FALSE: disable revert to defaults
32801709Smlf *
32811709Smlf * NOTE: revert to power on defaults that includes reverting to MDMA
32821709Smlf * mode is allowed by ATA-6 & ATA-7 specs.
32831709Smlf * Therefore drives exhibiting this behaviour are not violating the spec.
32841709Smlf * Furthermore, the spec explicitly says that after the soft reset
32851709Smlf * host should check the current setting of the device features.
32861709Smlf * Correctly working BIOS would therefore reprogram either the drive
32871709Smlf * and/or the host controller to match transfer modes.
32881709Smlf * Devices with ATA_BL_NORVRT flag will be removed from
32891709Smlf * the ata_blacklist.
32901709Smlf * The default behaviour will be - no revert to power-on defaults
32911709Smlf * for all devices. The property is retained in case the user
32921709Smlf * explicitly requests revert-to-defaults before reboot.
32931709Smlf */
32941709Smlf
32951709Smlf #define ATA_REVERT_PROP_PREFIX "revert-"
32961709Smlf #define ATA_REVERT_PROP_GLOBAL "ata-revert-to-defaults"
32971709Smlf /* room for prefix + model number + terminating NUL character */
32981709Smlf #define PROP_BUF_SIZE (sizeof (ATA_REVERT_PROP_PREFIX) + \
32991709Smlf sizeof (aidp->ai_model) + 1)
33001709Smlf #define PROP_LEN_MAX (31)
33011709Smlf
33021709Smlf static int
ata_check_revert_to_defaults(ata_drv_t * ata_drvp)33031709Smlf ata_check_revert_to_defaults(
33041709Smlf ata_drv_t *ata_drvp)
33051709Smlf {
33061709Smlf struct ata_id *aidp = &ata_drvp->ad_id;
33071709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
33081709Smlf char prop_buf[PROP_BUF_SIZE];
33091709Smlf int i, j;
33101709Smlf int propval;
33111709Smlf
33121709Smlf /* put prefix into the buffer */
33131709Smlf (void) strcpy(prop_buf, ATA_REVERT_PROP_PREFIX);
33141709Smlf j = strlen(prop_buf);
33151709Smlf
33161709Smlf /* append the model number, leaving out invalid characters */
33171709Smlf for (i = 0; i < sizeof (aidp->ai_model); ++i) {
33181709Smlf char c = aidp->ai_model[i];
33191709Smlf if (c >= 'A' && c <= 'Z') /* uppercase -> lower */
33201709Smlf c = c - 'A' + 'a';
33211709Smlf if (c >= 'a' && c <= 'z' || c >= '0' && c <= '9' ||
33221709Smlf c == '.' || c == '_' || c == '-')
33231709Smlf prop_buf[j++] = c;
33241709Smlf if (c == '\0')
33251709Smlf break;
33261709Smlf }
33271709Smlf
33281709Smlf /* make sure there's a terminating NUL character */
33291709Smlf if (j >= PROP_LEN_MAX)
33301709Smlf j = PROP_LEN_MAX;
33311709Smlf prop_buf[j] = '\0';
33321709Smlf
33331709Smlf /* look for a disk-specific "revert" property" */
33341709Smlf propval = ddi_getprop(DDI_DEV_T_ANY, ata_ctlp->ac_dip,
33355295Srandyf DDI_PROP_DONTPASS, prop_buf, -1);
33361709Smlf if (propval == 0)
33371709Smlf return (FALSE);
33381709Smlf else if (propval != -1)
33391709Smlf return (TRUE);
33401709Smlf
33411709Smlf /* look for a global "revert" property" */
33421709Smlf propval = ddi_getprop(DDI_DEV_T_ANY, ata_ctlp->ac_dip,
33435295Srandyf 0, ATA_REVERT_PROP_GLOBAL, -1);
33441709Smlf if (propval == 0)
33451709Smlf return (FALSE);
33461709Smlf else if (propval != -1)
33471709Smlf return (TRUE);
33481709Smlf
33491709Smlf return (FALSE);
33501709Smlf }
33511709Smlf
33521709Smlf void
ata_show_transfer_mode(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)33531709Smlf ata_show_transfer_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp)
33541709Smlf {
33551709Smlf int i;
33561709Smlf
33571709Smlf if (ata_ctlp->ac_pciide_bm == FALSE ||
33581709Smlf ata_drvp->ad_pciide_dma != ATA_DMA_ON) {
33591709Smlf if (ata_cntrl_DMA_sel_msg) {
33601709Smlf ATAPRT((
33611709Smlf "?\tATA DMA off: %s\n", ata_cntrl_DMA_sel_msg));
33621709Smlf } else if (ata_dev_DMA_sel_msg) {
33631709Smlf ATAPRT(("?\tATA DMA off: %s\n", ata_dev_DMA_sel_msg));
33641709Smlf }
33651709Smlf ATAPRT(("?\tPIO mode %d selected\n",
33661709Smlf (ata_drvp->ad_id.ai_advpiomode & ATAC_ADVPIO_4_SUP) ==
33675295Srandyf ATAC_ADVPIO_4_SUP ? 4 : 3));
33681709Smlf } else {
33691709Smlf /* Using DMA */
33701709Smlf if (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_SEL_MASK) {
33711709Smlf /*
33721709Smlf * Rely on the fact that either dwdma or udma is
33731709Smlf * selected, not both.
33741709Smlf */
33751709Smlf ATAPRT(("?\tMultiwordDMA mode %d selected\n",
33765295Srandyf (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_2_SEL) ==
33771709Smlf ATAC_MDMA_2_SEL ? 2 :
33781709Smlf (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_1_SEL) ==
33795295Srandyf ATAC_MDMA_1_SEL ? 1 : 0));
33801709Smlf } else {
33811709Smlf for (i = 0; i <= 6; i++) {
33821709Smlf if (ata_drvp->ad_id.ai_ultradma &
33831709Smlf (1 << (i + 8))) {
33841709Smlf ATAPRT((
33851709Smlf "?\tUltraDMA mode %d selected\n",
33861709Smlf i));
33871709Smlf break;
33881709Smlf }
33891709Smlf }
33901709Smlf }
33911709Smlf }
33921709Smlf }
33931709Smlf
33941709Smlf /*
33951709Smlf * Controller-specific operation pointers.
33961709Smlf * Should be extended as needed - init only for now
33971709Smlf */
33981709Smlf struct ata_ctl_spec_ops {
33991709Smlf uint_t (*cs_init)(dev_info_t *, ushort_t, ushort_t); /* ctlr init */
34001709Smlf };
34011709Smlf
34021709Smlf
34031709Smlf struct ata_ctl_spec {
34041709Smlf ushort_t cs_vendor_id;
34051709Smlf ushort_t cs_device_id;
34061709Smlf struct ata_ctl_spec_ops *cs_ops;
34071709Smlf };
34081709Smlf
34091709Smlf /* Sil3XXX-specific functions (init only for now) */
34101709Smlf struct ata_ctl_spec_ops sil3xxx_ops = {
34111709Smlf &sil3xxx_init_controller /* Sil3XXX cntrl initialization */
34121709Smlf };
34131709Smlf
34141709Smlf
34151709Smlf struct ata_ctl_spec ata_cntrls_spec[] = {
34161709Smlf {0x1095, 0x3114, &sil3xxx_ops},
34171709Smlf {0x1095, 0x3512, &sil3xxx_ops},
34181709Smlf {0x1095, 0x3112, &sil3xxx_ops},
34191709Smlf {0, 0, NULL} /* List must end with cs_ops set to NULL */
34201709Smlf };
34211709Smlf
34221709Smlf /*
34231709Smlf * Do controller specific initialization if necessary.
34241709Smlf * Pick-up controller specific functions.
34251709Smlf */
34261709Smlf
34271709Smlf int
ata_spec_init_controller(dev_info_t * dip)34281709Smlf ata_spec_init_controller(dev_info_t *dip)
34291709Smlf {
34301709Smlf ushort_t vendor_id;
34311709Smlf ushort_t device_id;
34321709Smlf struct ata_ctl_spec *ctlsp;
34331709Smlf
34341709Smlf vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
34355295Srandyf DDI_PROP_DONTPASS, "vendor-id", 0);
34361709Smlf device_id = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
34375295Srandyf DDI_PROP_DONTPASS, "device-id", 0);
34381709Smlf
34391709Smlf /* Locate controller specific ops, if they exist */
34401709Smlf ctlsp = ata_cntrls_spec;
34411709Smlf while (ctlsp->cs_ops != NULL) {
34421709Smlf if (ctlsp->cs_vendor_id == vendor_id &&
34431709Smlf ctlsp->cs_device_id == device_id)
34441709Smlf break;
34451709Smlf ctlsp++;
34461709Smlf }
34471709Smlf
34481709Smlf if (ctlsp->cs_ops != NULL) {
34491709Smlf if (ctlsp->cs_ops->cs_init != NULL) {
34501709Smlf /* Initialize controller */
34511709Smlf if ((*(ctlsp->cs_ops->cs_init))
34521709Smlf (dip, vendor_id, device_id) != TRUE) {
34531709Smlf cmn_err(CE_WARN,
34541709Smlf "pci%4x,%4x cntrl specific "
34551709Smlf "initialization failed",
34561709Smlf vendor_id, device_id);
34571709Smlf return (FALSE);
34581709Smlf }
34591709Smlf }
34601709Smlf }
34611709Smlf return (TRUE);
34621709Smlf }
34631709Smlf
34641709Smlf /*
34651709Smlf * this routine works like ddi_prop_get_int, except that it works on
34661709Smlf * a string property that contains ascii representations
34671709Smlf * of an integer.
34681709Smlf * If the property is not found, the default value is returned.
34691709Smlf */
34701709Smlf static int
ata_prop_lookup_int(dev_t match_dev,dev_info_t * dip,uint_t flags,char * name,int defvalue)34711709Smlf ata_prop_lookup_int(dev_t match_dev, dev_info_t *dip,
34721709Smlf uint_t flags, char *name, int defvalue)
34731709Smlf {
34741709Smlf
34751709Smlf char *bufp, *cp;
34761709Smlf int rc = defvalue;
34771709Smlf int proprc;
34781709Smlf
34791709Smlf proprc = ddi_prop_lookup_string(match_dev, dip,
34805295Srandyf flags, name, &bufp);
34811709Smlf
34821709Smlf if (proprc == DDI_PROP_SUCCESS) {
34831709Smlf cp = bufp;
34841709Smlf rc = stoi(&cp);
34851709Smlf ddi_prop_free(bufp);
34861709Smlf } else {
34871709Smlf /*
34881709Smlf * see if property is encoded as an int instead of string.
34891709Smlf */
34901709Smlf rc = ddi_prop_get_int(match_dev, dip, flags, name, defvalue);
34911709Smlf }
34921709Smlf
34931709Smlf return (rc);
34941709Smlf }
34955295Srandyf
34965295Srandyf /*
34975295Srandyf * Initialize the power management components
34985295Srandyf */
34995295Srandyf static void
ata_init_pm(dev_info_t * dip)35005295Srandyf ata_init_pm(dev_info_t *dip)
35015295Srandyf {
35025295Srandyf char pmc_name[16];
35035295Srandyf char *pmc[] = {
35045295Srandyf NULL,
35055295Srandyf "0=Sleep (PCI D3 State)",
35065295Srandyf "3=PowerOn (PCI D0 State)",
35075295Srandyf NULL
35085295Srandyf };
35095295Srandyf int instance;
35105295Srandyf ata_ctl_t *ata_ctlp;
35115295Srandyf
35125295Srandyf
35135295Srandyf instance = ddi_get_instance(dip);
35145295Srandyf ata_ctlp = ddi_get_soft_state(ata_state, instance);
35155295Srandyf ata_ctlp->ac_pm_support = 0;
35165295Srandyf
35175295Srandyf /* check PCI capabilities */
35185295Srandyf if (!ata_is_pci(dip))
35195295Srandyf return;
35205295Srandyf
35215295Srandyf (void) sprintf(pmc_name, "NAME=ata%d", instance);
35225295Srandyf pmc[0] = pmc_name;
35235295Srandyf
35245295Srandyf #ifdef ATA_USE_AUTOPM
35255295Srandyf if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip,
35265295Srandyf "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
35275295Srandyf return;
35285295Srandyf }
35295295Srandyf #endif
35305295Srandyf
35315295Srandyf ata_ctlp->ac_pm_support = 1;
35325295Srandyf ata_ctlp->ac_pm_level = PM_LEVEL_D0;
35335295Srandyf
35345295Srandyf ATA_BUSY_COMPONENT(dip, 0);
35355295Srandyf if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
35365295Srandyf (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components");
35375295Srandyf }
35385295Srandyf ATA_IDLE_COMPONENT(dip, 0);
35395295Srandyf }
35405295Srandyf
35415295Srandyf /*
35425295Srandyf * resume the hard drive
35435295Srandyf */
35445295Srandyf static void
ata_resume_drive(ata_drv_t * ata_drvp)35455295Srandyf ata_resume_drive(ata_drv_t *ata_drvp)
35465295Srandyf {
35475295Srandyf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
35485295Srandyf int drive_type;
35495295Srandyf struct ata_id id;
35505295Srandyf
35515295Srandyf ADBG_TRACE(("ata_resume_drive entered\n"));
35525295Srandyf
35535295Srandyf drive_type = ata_drive_type(ata_drvp->ad_drive_bits,
35545295Srandyf ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1,
35555295Srandyf ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2,
35565295Srandyf &id);
35575295Srandyf if (drive_type == ATA_DEV_NONE)
35585295Srandyf return;
35595295Srandyf
35605295Srandyf if (!ATAPIDRV(ata_drvp)) {
35617554SAda.Feng@Sun.COM /* Reset Ultra DMA mode */
35628550SSeth.Goldberg@Sun.COM ata_reset_dma_mode(ata_drvp);
35635295Srandyf if (!ata_disk_setup_parms(ata_ctlp, ata_drvp))
35645295Srandyf return;
35657554SAda.Feng@Sun.COM } else {
35667565SAda.Feng@Sun.COM (void) atapi_init_drive(ata_drvp);
356710452SAda.Feng@Sun.COM if (ata_drvp->ad_dma_mode != 0) {
356810452SAda.Feng@Sun.COM (void) atapi_reset_dma_mode(ata_drvp, FALSE);
356910452SAda.Feng@Sun.COM if (!ata_check_dma_mode(ata_drvp))
357010452SAda.Feng@Sun.COM atapi_reset_dma_mode(ata_drvp, TRUE);
357110452SAda.Feng@Sun.COM if (ata_drvp->ad_id.ai_ultradma !=
357210452SAda.Feng@Sun.COM ata_drvp->ad_dma_mode) {
357310452SAda.Feng@Sun.COM ata_drvp->ad_pciide_dma = ATA_DMA_OFF;
357410452SAda.Feng@Sun.COM } else {
357510452SAda.Feng@Sun.COM ata_drvp->ad_pciide_dma = ATA_DMA_ON;
357610452SAda.Feng@Sun.COM }
357710452SAda.Feng@Sun.COM }
35785295Srandyf }
35797554SAda.Feng@Sun.COM (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0);
35807554SAda.Feng@Sun.COM
35815295Srandyf }
35825295Srandyf
35835295Srandyf /*
35845295Srandyf * resume routine, it will be run when get the command
35855295Srandyf * DDI_RESUME at attach(9E) from system power management
35865295Srandyf */
35875295Srandyf static int
ata_resume(dev_info_t * dip)35885295Srandyf ata_resume(dev_info_t *dip)
35895295Srandyf {
35905295Srandyf int instance;
35915295Srandyf ata_ctl_t *ata_ctlp;
35925295Srandyf ddi_acc_handle_t io_hdl2;
35935295Srandyf caddr_t ioaddr2;
35945295Srandyf
35955295Srandyf instance = ddi_get_instance(dip);
35965295Srandyf ata_ctlp = ddi_get_soft_state(ata_state, instance);
35975295Srandyf
35985295Srandyf if (!ata_ctlp->ac_pm_support)
35995295Srandyf return (DDI_FAILURE);
36005295Srandyf if (ata_ctlp->ac_pm_level == PM_LEVEL_D0)
36015295Srandyf return (DDI_SUCCESS);
36025295Srandyf
36035295Srandyf ATA_BUSY_COMPONENT(dip, 0);
36045295Srandyf if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) == DDI_FAILURE)
36055295Srandyf return (DDI_FAILURE);
36065295Srandyf ATA_IDLE_COMPONENT(dip, 0);
36075295Srandyf
36085295Srandyf /* enable interrupts from the device */
36095295Srandyf io_hdl2 = ata_ctlp->ac_iohandle2;
36105295Srandyf ioaddr2 = ata_ctlp->ac_ioaddr2;
36115295Srandyf ddi_put8(io_hdl2, (uchar_t *)ioaddr2 + AT_DEVCTL, ATDC_D3);
36125295Srandyf ata_ctlp->ac_pm_level = PM_LEVEL_D0;
36135295Srandyf
36145295Srandyf return (DDI_SUCCESS);
36155295Srandyf }
36165295Srandyf
36175295Srandyf /*
36185295Srandyf * suspend routine, it will be run when get the command
36195295Srandyf * DDI_SUSPEND at detach(9E) from system power management
36205295Srandyf */
36215295Srandyf static int
ata_suspend(dev_info_t * dip)36225295Srandyf ata_suspend(dev_info_t *dip)
36235295Srandyf {
36245295Srandyf int instance;
36255295Srandyf ata_ctl_t *ata_ctlp;
36265295Srandyf ddi_acc_handle_t io_hdl2;
36275295Srandyf
36285295Srandyf instance = ddi_get_instance(dip);
36295295Srandyf ata_ctlp = ddi_get_soft_state(ata_state, instance);
36305295Srandyf
36315295Srandyf if (!ata_ctlp->ac_pm_support)
36325295Srandyf return (DDI_FAILURE);
36335295Srandyf if (ata_ctlp->ac_pm_level == PM_LEVEL_D3)
36345295Srandyf return (DDI_SUCCESS);
36355295Srandyf
36365295Srandyf /* disable interrupts and turn the software reset bit on */
36375295Srandyf io_hdl2 = ata_ctlp->ac_iohandle2;
36385295Srandyf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3 | ATDC_SRST));
36395295Srandyf
36405295Srandyf (void) ata_reset_bus(ata_ctlp);
36415295Srandyf (void) ata_change_power(dip, ATC_SLEEP);
36425295Srandyf ata_ctlp->ac_pm_level = PM_LEVEL_D3;
36435295Srandyf return (DDI_SUCCESS);
36445295Srandyf }
36455295Srandyf
36465295Srandyf int ata_save_pci_config = 0;
36475295Srandyf /*
36485295Srandyf * ata specific power management entry point, it was
36495295Srandyf * used to change the power management component
36505295Srandyf */
36515295Srandyf static int
ata_power(dev_info_t * dip,int component,int level)36525295Srandyf ata_power(dev_info_t *dip, int component, int level)
36535295Srandyf {
36545295Srandyf int instance;
36555295Srandyf ata_ctl_t *ata_ctlp;
36565295Srandyf uint8_t cmd;
36575295Srandyf
36585295Srandyf ADBG_TRACE(("ata_power entered, component = %d, level = %d\n",
36595295Srandyf component, level));
36605295Srandyf
36615295Srandyf instance = ddi_get_instance(dip);
36625295Srandyf ata_ctlp = ddi_get_soft_state(ata_state, instance);
36635295Srandyf if (ata_ctlp == NULL || component != 0)
36645295Srandyf return (DDI_FAILURE);
36655295Srandyf
36665295Srandyf if (!ata_ctlp->ac_pm_support)
36675295Srandyf return (DDI_FAILURE);
36685295Srandyf
36697787SAda.Feng@Sun.COM if (ata_ctlp->ac_pm_level == level)
36707787SAda.Feng@Sun.COM return (DDI_SUCCESS);
36717787SAda.Feng@Sun.COM
36725295Srandyf switch (level) {
36735295Srandyf case PM_LEVEL_D0:
36745295Srandyf if (ata_save_pci_config)
36755295Srandyf (void) pci_restore_config_regs(dip);
36765295Srandyf ata_ctlp->ac_pm_level = PM_LEVEL_D0;
36776907Srandyf cmd = ATC_IDLE_IMMED;
36785295Srandyf break;
36795295Srandyf case PM_LEVEL_D3:
36805295Srandyf if (ata_save_pci_config)
36815295Srandyf (void) pci_save_config_regs(dip);
36825295Srandyf ata_ctlp->ac_pm_level = PM_LEVEL_D3;
36835295Srandyf cmd = ATC_SLEEP;
36845295Srandyf break;
36855295Srandyf default:
36865295Srandyf return (DDI_FAILURE);
36875295Srandyf }
36885295Srandyf return (ata_change_power(dip, cmd));
36895295Srandyf }
36905295Srandyf
36915295Srandyf /*
36925295Srandyf * sent commands to ata controller to change the power level
36935295Srandyf */
36945295Srandyf static int
ata_change_power(dev_info_t * dip,uint8_t cmd)36955295Srandyf ata_change_power(dev_info_t *dip, uint8_t cmd)
36965295Srandyf {
36975295Srandyf int instance;
369810452SAda.Feng@Sun.COM ata_ctl_t *ata_ctlp;
36995295Srandyf ata_drv_t *ata_drvp;
37005295Srandyf uchar_t targ;
370110452SAda.Feng@Sun.COM struct ata_id id;
37025295Srandyf uchar_t lun;
37035295Srandyf uchar_t lastlun;
37047787SAda.Feng@Sun.COM struct ata_id *aidp;
37055295Srandyf
37065295Srandyf ADBG_TRACE(("ata_change_power entered, cmd = %d\n", cmd));
37075295Srandyf
37085295Srandyf instance = ddi_get_instance(dip);
37095295Srandyf ata_ctlp = ddi_get_soft_state(ata_state, instance);
37107787SAda.Feng@Sun.COM
37115295Srandyf /*
37125295Srandyf * Issue command on each disk device on the bus.
37135295Srandyf */
37147554SAda.Feng@Sun.COM if (cmd == ATC_SLEEP) {
37157554SAda.Feng@Sun.COM for (targ = 0; targ < ATA_MAXTARG; targ++) {
37167554SAda.Feng@Sun.COM ata_drvp = CTL2DRV(ata_ctlp, targ, 0);
37177554SAda.Feng@Sun.COM if (ata_drvp == NULL)
37187554SAda.Feng@Sun.COM continue;
371910452SAda.Feng@Sun.COM if (ata_drvp->ad_dma_cap == 0 &&
372010452SAda.Feng@Sun.COM ata_drvp->ad_pciide_dma == ATA_DMA_ON) {
372110452SAda.Feng@Sun.COM aidp = &ata_drvp->ad_id;
372210452SAda.Feng@Sun.COM if ((aidp->ai_validinfo & ATAC_VALIDINFO_83) &&
372310452SAda.Feng@Sun.COM (aidp->ai_ultradma & ATAC_UDMA_SEL_MASK)) {
372410452SAda.Feng@Sun.COM ata_drvp->ad_dma_cap =
372510452SAda.Feng@Sun.COM ATA_DMA_ULTRAMODE;
372610452SAda.Feng@Sun.COM ata_drvp->ad_dma_mode =
372710452SAda.Feng@Sun.COM aidp->ai_ultradma;
372810452SAda.Feng@Sun.COM } else if (aidp->ai_dworddma &
372910452SAda.Feng@Sun.COM ATAC_MDMA_SEL_MASK) {
373010452SAda.Feng@Sun.COM ata_drvp->ad_dma_cap =
373110452SAda.Feng@Sun.COM ATA_DMA_MWORDMODE;
373210452SAda.Feng@Sun.COM ata_drvp->ad_dma_mode =
373310452SAda.Feng@Sun.COM aidp->ai_dworddma;
373410452SAda.Feng@Sun.COM }
37357787SAda.Feng@Sun.COM }
37367554SAda.Feng@Sun.COM if (ata_drive_type(ata_drvp->ad_drive_bits,
37377554SAda.Feng@Sun.COM ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1,
37387554SAda.Feng@Sun.COM ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2,
37397554SAda.Feng@Sun.COM &id) != ATA_DEV_DISK)
37407554SAda.Feng@Sun.COM continue;
37417554SAda.Feng@Sun.COM (void) ata_flush_cache(ata_ctlp, ata_drvp);
37427554SAda.Feng@Sun.COM if (!ata_command(ata_ctlp, ata_drvp, TRUE, TRUE,
37437554SAda.Feng@Sun.COM 5 * 1000000, cmd, 0, 0, 0, 0, 0, 0)) {
37447554SAda.Feng@Sun.COM cmn_err(CE_WARN, "!ata_controller - Can not "
37457554SAda.Feng@Sun.COM "put drive %d in to power mode %u",
37467554SAda.Feng@Sun.COM targ, cmd);
37477554SAda.Feng@Sun.COM (void) ata_devo_reset(dip, DDI_RESET_FORCE);
37487554SAda.Feng@Sun.COM return (DDI_FAILURE);
37497554SAda.Feng@Sun.COM }
37507554SAda.Feng@Sun.COM }
37517554SAda.Feng@Sun.COM return (DDI_SUCCESS);
37527554SAda.Feng@Sun.COM }
37537554SAda.Feng@Sun.COM
37547554SAda.Feng@Sun.COM (void) ata_software_reset(ata_ctlp);
37555295Srandyf for (targ = 0; targ < ATA_MAXTARG; targ++) {
37565295Srandyf ata_drvp = CTL2DRV(ata_ctlp, targ, 0);
37575295Srandyf if (ata_drvp == NULL)
37585295Srandyf continue;
37595295Srandyf ata_resume_drive(ata_drvp);
37605295Srandyf
37615295Srandyf if (ATAPIDRV(ata_drvp))
37625295Srandyf lastlun = ata_drvp->ad_id.ai_lastlun;
37635295Srandyf else
37645295Srandyf lastlun = 0;
37655295Srandyf if (!ata_enable_atapi_luns)
37665295Srandyf lastlun = 0;
37675295Srandyf for (lun = 1; lun <= lastlun && lun < ATA_MAXLUN; lun++) {
37685295Srandyf ata_drvp = CTL2DRV(ata_ctlp, targ, lun);
37695295Srandyf if (ata_drvp != NULL)
37705295Srandyf ata_resume_drive(ata_drvp);
37715295Srandyf }
37725295Srandyf }
37735295Srandyf
37745295Srandyf return (DDI_SUCCESS);
37755295Srandyf }
37765295Srandyf
37775295Srandyf /*
37785295Srandyf * return 1 when ata controller is a pci device,
37795295Srandyf * otherwise return 0
37805295Srandyf */
37815295Srandyf static int
ata_is_pci(dev_info_t * dip)37825295Srandyf ata_is_pci(dev_info_t *dip)
37835295Srandyf {
37845295Srandyf int rc;
37855295Srandyf char *bufp;
37865295Srandyf int ispci;
37875295Srandyf
37885295Srandyf rc = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(dip),
37895295Srandyf DDI_PROP_DONTPASS, "device_type", &bufp);
37905295Srandyf
37915295Srandyf if (rc != DDI_PROP_SUCCESS) {
37925295Srandyf ADBG_ERROR(("ata_is_pci !device_type\n"));
37935295Srandyf return (0);
37945295Srandyf }
37955295Srandyf
37965295Srandyf ispci = (strcmp(bufp, "pci-ide") == 0);
37975295Srandyf
37985295Srandyf ddi_prop_free(bufp);
37995295Srandyf
38005295Srandyf return (ispci);
38015295Srandyf }
38025603Sml40262
38035603Sml40262 /*
38045603Sml40262 * Disable DMA for this drive
38055603Sml40262 */
38065603Sml40262 static void
ata_disable_DMA(ata_drv_t * ata_drvp)38075603Sml40262 ata_disable_DMA(ata_drv_t *ata_drvp)
38085603Sml40262 {
38095603Sml40262 struct ata_id *aidp;
38105603Sml40262 char buf[sizeof (aidp->ai_model) +2];
38115603Sml40262 int i;
38125603Sml40262
38135603Sml40262 if (ata_drvp == NULL)
38145603Sml40262 return;
38155603Sml40262
38165603Sml40262 if (ata_drvp->ad_pciide_dma == ATA_DMA_OFF)
38175603Sml40262 return;
38185603Sml40262
38195603Sml40262 ata_drvp->ad_pciide_dma = ATA_DMA_OFF;
38205603Sml40262
38215603Sml40262 /* Print the message */
38225603Sml40262 buf[0] = '\0';
38235603Sml40262 aidp = &ata_drvp->ad_id;
38245603Sml40262 if (aidp != NULL) {
38255603Sml40262 (void) strncpy(buf, aidp->ai_model, sizeof (aidp->ai_model));
38265603Sml40262 buf[sizeof (aidp->ai_model) -1] = '\0';
38275603Sml40262 for (i = sizeof (aidp->ai_model) - 2; buf[i] == ' '; i--)
38285603Sml40262 buf[i] = '\0';
38295603Sml40262 }
38305603Sml40262 cmn_err(CE_CONT,
38315603Sml40262 "?DMA disabled on %s target=%d, lun=%d due to DMA errors,",
38325603Sml40262 buf, ata_drvp->ad_targ, ata_drvp->ad_lun);
38335603Sml40262 cmn_err(CE_CONT, "?most likely due to the CF-to-IDE adapter.");
38345603Sml40262 }
38356412Syt160523
38366412Syt160523 /*
38376412Syt160523 * Check and select DMA mode
38386412Syt160523 *
38396412Syt160523 * TRUE is returned when set feature is called successfully,
38406412Syt160523 * otherwise return FALSE
38416412Syt160523 */
38426412Syt160523 int
ata_set_dma_mode(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)38436412Syt160523 ata_set_dma_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp)
38446412Syt160523 {
38456412Syt160523 struct ata_id *aidp;
38466412Syt160523 int mode, rval = FALSE;
38476412Syt160523 uint8_t subcmd;
38486412Syt160523
38496412Syt160523 aidp = &ata_drvp->ad_id;
38506412Syt160523
38516412Syt160523 /* Return directly if DMA is not supported */
38526412Syt160523 if (!(aidp->ai_cap & ATAC_DMA_SUPPORT))
38536412Syt160523 return (rval);
38546412Syt160523
38557787SAda.Feng@Sun.COM /* Return if DMA mode is already selected */
38567787SAda.Feng@Sun.COM if (((aidp->ai_validinfo & ATAC_VALIDINFO_83) &&
38577787SAda.Feng@Sun.COM (aidp->ai_ultradma & ATAC_UDMA_SEL_MASK)) ||
38587787SAda.Feng@Sun.COM (aidp->ai_dworddma & ATAC_MDMA_SEL_MASK))
38597787SAda.Feng@Sun.COM return (rval);
38607787SAda.Feng@Sun.COM
38616412Syt160523 /* First check Ultra DMA mode if no DMA is selected */
38626412Syt160523 if ((aidp->ai_validinfo & ATAC_VALIDINFO_83) &&
38636412Syt160523 (aidp->ai_ultradma & ATAC_UDMA_SUP_MASK)) {
38646412Syt160523 for (mode = 6; mode >= 0; --mode) {
38656412Syt160523 if (aidp->ai_ultradma & (1 << mode))
38666412Syt160523 break;
38676412Syt160523 }
38686412Syt160523 subcmd = ATF_XFRMOD_UDMA;
38696412Syt160523
38706412Syt160523 } else if (aidp->ai_dworddma & ATAC_MDMA_SUP_MASK) {
38716412Syt160523 /* Then check multi-word DMA mode */
38726412Syt160523 for (mode = 2; mode >= 0; --mode) {
38736412Syt160523 if (aidp->ai_dworddma & (1 << mode))
38746412Syt160523 break;
38756412Syt160523 }
38766412Syt160523 subcmd = ATF_XFRMOD_MDMA;
38776412Syt160523
38786412Syt160523 } else {
38796412Syt160523 return (rval);
38806412Syt160523 }
38816412Syt160523
38826412Syt160523 rval = ata_set_feature(ata_ctlp, ata_drvp, ATSF_SET_XFRMOD,
38836412Syt160523 subcmd|mode);
38846412Syt160523
38856412Syt160523 return (rval);
38866412Syt160523 }
38878550SSeth.Goldberg@Sun.COM
38888550SSeth.Goldberg@Sun.COM /*
38898550SSeth.Goldberg@Sun.COM * Reset Ultra DMA mode / MWDMA mode
38908550SSeth.Goldberg@Sun.COM */
38918550SSeth.Goldberg@Sun.COM void
ata_reset_dma_mode(ata_drv_t * ata_drvp)38928550SSeth.Goldberg@Sun.COM ata_reset_dma_mode(ata_drv_t *ata_drvp)
38938550SSeth.Goldberg@Sun.COM {
38948550SSeth.Goldberg@Sun.COM uint8_t subcmd;
38958550SSeth.Goldberg@Sun.COM int mode;
38968550SSeth.Goldberg@Sun.COM ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
38978550SSeth.Goldberg@Sun.COM
38988550SSeth.Goldberg@Sun.COM switch (ata_drvp->ad_dma_cap) {
38998550SSeth.Goldberg@Sun.COM case ATA_DMA_ULTRAMODE:
39008550SSeth.Goldberg@Sun.COM subcmd = ATF_XFRMOD_UDMA;
39018550SSeth.Goldberg@Sun.COM for (mode = 0; mode <= 6; mode++) {
39028550SSeth.Goldberg@Sun.COM if (ata_drvp->ad_dma_mode & (1 << (mode + 8)))
39038550SSeth.Goldberg@Sun.COM break;
39048550SSeth.Goldberg@Sun.COM }
39058550SSeth.Goldberg@Sun.COM break;
39068550SSeth.Goldberg@Sun.COM case ATA_DMA_MWORDMODE:
39078550SSeth.Goldberg@Sun.COM subcmd = ATF_XFRMOD_MDMA;
39088550SSeth.Goldberg@Sun.COM mode = ((ata_drvp->ad_dma_mode & ATAC_MDMA_2_SEL) ==
39098550SSeth.Goldberg@Sun.COM ATAC_MDMA_2_SEL ? 2 :
39108550SSeth.Goldberg@Sun.COM (ata_drvp->ad_dma_mode & ATAC_MDMA_1_SEL) ==
39118550SSeth.Goldberg@Sun.COM ATAC_MDMA_1_SEL ? 1 : 0);
39128550SSeth.Goldberg@Sun.COM break;
39138550SSeth.Goldberg@Sun.COM default:
39148550SSeth.Goldberg@Sun.COM return;
39158550SSeth.Goldberg@Sun.COM }
39168550SSeth.Goldberg@Sun.COM
39178550SSeth.Goldberg@Sun.COM (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_SET_XFRMOD,
39188550SSeth.Goldberg@Sun.COM (subcmd | mode));
39198550SSeth.Goldberg@Sun.COM }
392010452SAda.Feng@Sun.COM
392110452SAda.Feng@Sun.COM /*
392210452SAda.Feng@Sun.COM * Check DMA mode is the same with saved info
392310452SAda.Feng@Sun.COM * return value: 0 - not same
392410452SAda.Feng@Sun.COM * 1 - same
392510452SAda.Feng@Sun.COM */
392610452SAda.Feng@Sun.COM static int
ata_check_dma_mode(ata_drv_t * ata_drvp)392710452SAda.Feng@Sun.COM ata_check_dma_mode(ata_drv_t *ata_drvp)
392810452SAda.Feng@Sun.COM {
392910452SAda.Feng@Sun.COM struct ata_id *aidp;
393010452SAda.Feng@Sun.COM
393110452SAda.Feng@Sun.COM aidp = &ata_drvp->ad_id;
393210452SAda.Feng@Sun.COM switch (ata_drvp->ad_dma_cap) {
393310452SAda.Feng@Sun.COM case ATA_DMA_ULTRAMODE:
393410452SAda.Feng@Sun.COM if ((aidp->ai_validinfo & ATAC_VALIDINFO_83) &&
393510452SAda.Feng@Sun.COM (aidp->ai_ultradma & ATAC_UDMA_SEL_MASK) &&
393610452SAda.Feng@Sun.COM (aidp->ai_ultradma == ata_drvp->ad_dma_mode))
393710452SAda.Feng@Sun.COM break;
393810452SAda.Feng@Sun.COM else
393910452SAda.Feng@Sun.COM return (0);
394010452SAda.Feng@Sun.COM case ATA_DMA_MWORDMODE:
394110452SAda.Feng@Sun.COM if ((aidp->ai_dworddma & ATAC_MDMA_SEL_MASK) &&
394210452SAda.Feng@Sun.COM (aidp->ai_dworddma == ata_drvp->ad_dma_mode))
394310452SAda.Feng@Sun.COM break;
394410452SAda.Feng@Sun.COM else
394510452SAda.Feng@Sun.COM return (0);
394610452SAda.Feng@Sun.COM default:
394710452SAda.Feng@Sun.COM return (0);
394810452SAda.Feng@Sun.COM }
394910452SAda.Feng@Sun.COM return (1);
395010452SAda.Feng@Sun.COM }
3951