xref: /onnv-gate/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c (revision 11310:853217c5f53e)
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, &regsize);
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, &regsize);
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, &regsize);
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