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