1507c3241Smlf /*
2507c3241Smlf  * CDDL HEADER START
3507c3241Smlf  *
4507c3241Smlf  * The contents of this file are subject to the terms of the
59f49ae27Smlf  * Common Development and Distribution License (the "License").
6507c3241Smlf  * You may not use this file except in compliance with the License.
7507c3241Smlf  *
8507c3241Smlf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9507c3241Smlf  * or http://www.opensolaris.org/os/licensing.
10507c3241Smlf  * See the License for the specific language governing permissions
11507c3241Smlf  * and limitations under the License.
12507c3241Smlf  *
13507c3241Smlf  * When distributing Covered Code, include this CDDL HEADER in each
14507c3241Smlf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15507c3241Smlf  * If applicable, add the following below this CDDL HEADER, with the
16507c3241Smlf  * fields enclosed by brackets "[]" replaced with your own identifying
17507c3241Smlf  * information: Portions Copyright [yyyy] [name of copyright owner]
18507c3241Smlf  *
19507c3241Smlf  * CDDL HEADER END
20507c3241Smlf  */
21507c3241Smlf 
22507c3241Smlf /*
23*8793b36bSNick Todd  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24507c3241Smlf  * Use is subject to license terms.
25507c3241Smlf  */
26507c3241Smlf 
27507c3241Smlf /*
28507c3241Smlf  * Finite State Machines for ATA controller and ATAPI devices
29507c3241Smlf  */
30507c3241Smlf 
31507c3241Smlf #include <sys/types.h>
32507c3241Smlf 
33507c3241Smlf #include "ata_common.h"
34507c3241Smlf #include "atapi.h"
35507c3241Smlf 
36507c3241Smlf /*
37507c3241Smlf  * Local functions
38507c3241Smlf  */
39507c3241Smlf static	int	atapi_start_cmd(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
40507c3241Smlf 				ata_pkt_t *ata_pktp);
41507c3241Smlf static	void	atapi_send_cdb(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
42507c3241Smlf static	void	atapi_start_dma(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
43507c3241Smlf 				ata_pkt_t *ata_pktp);
44507c3241Smlf static	void	atapi_pio_data_in(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
45507c3241Smlf static	void	atapi_pio_data_out(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
46507c3241Smlf static	void	atapi_status(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp,
47507c3241Smlf 				uchar_t status, int dma_complete);
48507c3241Smlf static	void	atapi_fsm_error(ata_ctl_t *ata_ctlp, uchar_t state,
49507c3241Smlf 				uchar_t event);
50507c3241Smlf 
51507c3241Smlf 
52507c3241Smlf 
53507c3241Smlf 
54507c3241Smlf static void
atapi_fsm_error(ata_ctl_t * ata_ctlp,uchar_t state,uchar_t event)55507c3241Smlf atapi_fsm_error(
56507c3241Smlf 	ata_ctl_t *ata_ctlp,
57507c3241Smlf 	uchar_t	   state,
58507c3241Smlf 	uchar_t	   event)
59507c3241Smlf {
60507c3241Smlf 	ADBG_ERROR(("atapi protocol error: 0x%p 0x%x 0x%x\n",
61*8793b36bSNick Todd 	    (void *)ata_ctlp->ac_data, state, event));
62507c3241Smlf }
63507c3241Smlf 
64507c3241Smlf 
65507c3241Smlf /*
66507c3241Smlf  *
67507c3241Smlf  *  IO  CoD  DRQ
68507c3241Smlf  *  --  ---  ---
69507c3241Smlf  *   0    0    0  == 0 invalid
70507c3241Smlf  *   0    0    1  == 1 Data to device
71507c3241Smlf  *   0    1    0  == 2 Idle
72507c3241Smlf  *   0    1    1  == 3 Send ATAPI CDB to device
73507c3241Smlf  *   1    0    0  == 4 invalid
74507c3241Smlf  *   1    0    1  == 5 Data from device
75507c3241Smlf  *   1    1    0  == 6 Status ready
76507c3241Smlf  *   1    1    1  == 7 Future use
77507c3241Smlf  *
78507c3241Smlf  */
79507c3241Smlf 
80507c3241Smlf /*
81507c3241Smlf  * Given the current state and the current event this
82507c3241Smlf  * table determines what action to take. Note, in the actual
83507c3241Smlf  * table I've left room for the invalid event codes: 0, 2, and 7.
84507c3241Smlf  *
85507c3241Smlf  *		+-----------------------------------------------------
86507c3241Smlf  *		|		Current Event
87507c3241Smlf  *		|
88507c3241Smlf  *	State	|	dataout	idle	cdb	datain	status
89507c3241Smlf  *		|	1	2	3	5	6
90507c3241Smlf  *		|-----------------------------------------------------
91507c3241Smlf  *	idle	|	sendcmd	sendcmd	sendcmd	sendcmd	sendcmd
92507c3241Smlf  *	cmd	|	*	 *	sendcdb	*	read-err-code
93507c3241Smlf  *	cdb	|	xfer-out nada	nada	xfer-in read-err-code
94507c3241Smlf  *	datain	|	*	 *	*	xfer-in	read-err-code
95507c3241Smlf  *	dataout	|	xfer-out *	*	*	read-err-code
96507c3241Smlf  *	DMA	|	*	 *	*	*	read-err-code
97507c3241Smlf  *
98507c3241Smlf  */
99507c3241Smlf 
100507c3241Smlf uchar_t	atapi_PioAction[ATAPI_NSTATES][ATAPI_NEVENTS] = {
101507c3241Smlf /* invalid dataout idle	  cdb	  invalid datain  status  future */
102507c3241Smlf { A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA }, /* Idle */
103507c3241Smlf { A_NADA, A_NADA, A_NADA, A_CDB,  A_NADA, A_NADA, A_RE,   A_NADA }, /* Cmd */
104507c3241Smlf { A_REX,  A_OUT,  A_NADA, A_NADA, A_IDLE, A_IN,   A_RE,   A_UNK  }, /* Cdb */
105507c3241Smlf { A_REX,  A_UNK,  A_IDLE, A_UNK,  A_IDLE, A_IN,   A_RE,   A_UNK  }, /* DtaIn */
106507c3241Smlf { A_REX,  A_OUT,  A_IDLE, A_UNK,  A_IDLE, A_UNK,  A_RE,   A_UNK  }, /* DtaOut */
107507c3241Smlf { A_REX,  A_UNK,  A_UNK,  A_UNK,  A_UNK,  A_UNK,  A_RE,   A_UNK  }  /* DmaAct */
108507c3241Smlf };
109507c3241Smlf 
110507c3241Smlf /*
111507c3241Smlf  *
112507c3241Smlf  * Give the current state and the current event this table
113507c3241Smlf  * determines the new state of the device.
114507c3241Smlf  *
115507c3241Smlf  *		+----------------------------------------------
116507c3241Smlf  *		|		Current Event
117507c3241Smlf  *		|
118507c3241Smlf  *	State	|	dataout	idle	cdb	datain	status
119507c3241Smlf  *		|----------------------------------------------
120507c3241Smlf  *	idle	|	cmd	cmd	cmd	cmd	cmd
121507c3241Smlf  *	cmd	|	*	*	cdb	*	*
122507c3241Smlf  *	cdb	|	dataout	cdb	cdb	datain	(idle)
123507c3241Smlf  *	datain	|	*	*	*	datain	(idle)
124507c3241Smlf  *	dataout	|	dataout	*	*	*	(idle)
125507c3241Smlf  *	DMA	|	DMA	DMA	DMA	DMA	(idle)
126507c3241Smlf  *
127507c3241Smlf  *
128507c3241Smlf  * Note: the states enclosed in parens "(state)", are the accept states
129507c3241Smlf  * for this FSM. A separate table is used to encode the done
130507c3241Smlf  * states rather than extra state codes.
131507c3241Smlf  *
132507c3241Smlf  */
133507c3241Smlf 
134507c3241Smlf uchar_t	atapi_PioNextState[ATAPI_NSTATES][ATAPI_NEVENTS] = {
135507c3241Smlf /* invalid dataout idle	  cdb	  invalid datain  status  future */
136507c3241Smlf { S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE}, /* idle */
137507c3241Smlf { S_CDB,  S_CDB,  S_CDB,  S_CDB,  S_CDB,  S_CDB,  S_IDLE, S_X   }, /* cmd */
138507c3241Smlf { S_IDLE, S_OUT,  S_CDB,  S_CDB,  S_CDB,  S_IN,   S_IDLE, S_X   }, /* cdb */
139507c3241Smlf { S_IDLE, S_X,    S_IN,   S_X,    S_IN,   S_IN,   S_IDLE, S_X   }, /* datain */
140507c3241Smlf { S_IDLE, S_OUT,  S_OUT,  S_X,    S_OUT,  S_X,    S_IDLE, S_X   }, /* dataout */
141507c3241Smlf { S_IDLE, S_DMA,  S_DMA,  S_DMA,  S_DMA,  S_DMA,  S_IDLE, S_DMA }  /* dmaActv */
142507c3241Smlf };
143507c3241Smlf 
144507c3241Smlf 
145507c3241Smlf static int
atapi_start_cmd(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)146507c3241Smlf atapi_start_cmd(
147507c3241Smlf 	ata_ctl_t	*ata_ctlp,
148507c3241Smlf 	ata_drv_t	*ata_drvp,
149507c3241Smlf 	ata_pkt_t	*ata_pktp)
150507c3241Smlf {
151507c3241Smlf 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
152507c3241Smlf 	ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
153507c3241Smlf 
154507c3241Smlf 	/*
155507c3241Smlf 	 * Bug 1256489:
156507c3241Smlf 	 *
157507c3241Smlf 	 * If AC_BSY_WAIT is set, wait for controller to be not busy,
158507c3241Smlf 	 * before issuing a command.  If AC_BSY_WAIT is not set,
159507c3241Smlf 	 * skip the wait.  This is important for laptops that do
160507c3241Smlf 	 * suspend/resume but do not correctly wait for the busy bit to
161507c3241Smlf 	 * drop after a resume.
162507c3241Smlf 	 */
163507c3241Smlf 
164507c3241Smlf 	if (ata_ctlp->ac_timing_flags & AC_BSY_WAIT) {
165507c3241Smlf 		if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2,
166507c3241Smlf 			0, ATS_BSY, 5000000)) {
167507c3241Smlf 			ADBG_WARN(("atapi_start: BSY too long!\n"));
168507c3241Smlf 			ata_pktp->ap_flags |= AP_ERROR;
169507c3241Smlf 			return (ATA_FSM_RC_BUSY);
170507c3241Smlf 		}
171507c3241Smlf 	}
172507c3241Smlf 
173507c3241Smlf 	/*
174507c3241Smlf 	 * Select the drive
175507c3241Smlf 	 */
176507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_pktp->ap_hd);
1779f49ae27Smlf 	ata_nsecwait(400);
178507c3241Smlf 
179507c3241Smlf 	/*
180507c3241Smlf 	 * make certain the drive selected
181507c3241Smlf 	 */
182507c3241Smlf 	if (!ata_wait(io_hdl2,  ata_ctlp->ac_ioaddr2, 0, ATS_BSY, 5000000)) {
183507c3241Smlf 		ADBG_ERROR(("atapi_start_cmd: drive select failed\n"));
184507c3241Smlf 		return (ATA_FSM_RC_BUSY);
185507c3241Smlf 	}
186507c3241Smlf 
187507c3241Smlf 	/*
188507c3241Smlf 	 * Always make certain interrupts are enabled. It's been reported
189507c3241Smlf 	 * (but not confirmed) that some notebook computers don't
190507c3241Smlf 	 * clear the interrupt disable bit after being resumed. The
191507c3241Smlf 	 * easiest way to fix this is to always clear the disable bit
192507c3241Smlf 	 * before every command.
193507c3241Smlf 	 */
194507c3241Smlf 	ddi_put8(io_hdl2, ata_ctlp->ac_devctl, ATDC_D3);
195507c3241Smlf 
196507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, ata_pktp->ap_lwcyl);
197507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, ata_pktp->ap_hicyl);
198507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_sect, ata_pktp->ap_sec);
199507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_count, ata_pktp->ap_count);
200507c3241Smlf 
201507c3241Smlf 	if (ata_pktp->ap_pciide_dma) {
202507c3241Smlf 
203507c3241Smlf 		ASSERT((ata_pktp->ap_flags & (AP_READ | AP_WRITE)) != 0);
204507c3241Smlf 
205507c3241Smlf 		/*
206507c3241Smlf 		 * DMA but no Overlap
207507c3241Smlf 		 */
208507c3241Smlf 		ddi_put8(io_hdl1, ata_ctlp->ac_feature, ATF_ATAPI_DMA);
209507c3241Smlf 
210507c3241Smlf 		/*
211507c3241Smlf 		 * copy the Scatter/Gather list to the controller's
212507c3241Smlf 		 * Physical Region Descriptor Table
213507c3241Smlf 		 */
214507c3241Smlf 		ata_pciide_dma_setup(ata_ctlp, ata_pktp->ap_sg_list,
215507c3241Smlf 			ata_pktp->ap_sg_cnt);
216507c3241Smlf 	} else {
217507c3241Smlf 		/*
218507c3241Smlf 		 * no DMA and no Overlap
219507c3241Smlf 		 */
220507c3241Smlf 		ddi_put8(io_hdl1, ata_ctlp->ac_feature, 0);
221507c3241Smlf 	}
222507c3241Smlf 
223507c3241Smlf 	/*
224507c3241Smlf 	 * This next one sets the device in motion
225507c3241Smlf 	 */
226507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ata_pktp->ap_cmd);
227507c3241Smlf 
228507c3241Smlf 	/* wait for the busy bit to settle */
2299f49ae27Smlf 	ata_nsecwait(400);
230507c3241Smlf 
231507c3241Smlf 	if (!(ata_drvp->ad_flags & AD_NO_CDB_INTR)) {
232507c3241Smlf 		/*
233507c3241Smlf 		 * the device will send me an interrupt when it's
234507c3241Smlf 		 * ready for the packet
235507c3241Smlf 		 */
236507c3241Smlf 		return (ATA_FSM_RC_OKAY);
237507c3241Smlf 	}
238507c3241Smlf 
239507c3241Smlf 	/* else */
240507c3241Smlf 
241507c3241Smlf 	/*
242507c3241Smlf 	 * If we don't receive an interrupt requesting the scsi CDB,
243507c3241Smlf 	 * we must poll for DRQ, and then send out the CDB.
244507c3241Smlf 	 */
245507c3241Smlf 
246507c3241Smlf 	/*
247507c3241Smlf 	 * Wait for DRQ before sending the CDB. Bailout early
248507c3241Smlf 	 * if an error occurs.
249507c3241Smlf 	 *
250507c3241Smlf 	 * I'm not certain what the correct timeout should be.
251507c3241Smlf 	 */
252507c3241Smlf 	if (ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2,
253507c3241Smlf 		ATS_DRQ, ATS_BSY, /* okay */
254507c3241Smlf 		ATS_ERR, ATS_BSY, /* cmd failed */
255507c3241Smlf 		ATS_DF,  ATS_BSY, /* cmd failed */
256507c3241Smlf 		4000000)) {
257507c3241Smlf 		/* got good status */
258507c3241Smlf 		return (ATA_FSM_RC_INTR);
259507c3241Smlf 	}
260507c3241Smlf 
261507c3241Smlf 	ADBG_WARN(("atapi_start_cmd: 0x%x status 0x%x error 0x%x\n",
262507c3241Smlf 		ata_pktp->ap_cmd,
263507c3241Smlf 		ddi_get8(io_hdl2,  ata_ctlp->ac_altstatus),
264507c3241Smlf 		ddi_get8(io_hdl1, ata_ctlp->ac_error)));
265507c3241Smlf 
266507c3241Smlf 	return (ATA_FSM_RC_INTR);
267507c3241Smlf }
268507c3241Smlf 
269507c3241Smlf 
270507c3241Smlf /*
271507c3241Smlf  *
272507c3241Smlf  * Send the SCSI CDB to the ATAPI device
273507c3241Smlf  *
274507c3241Smlf  */
275507c3241Smlf 
276507c3241Smlf static void
atapi_send_cdb(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)277507c3241Smlf atapi_send_cdb(
278507c3241Smlf 	ata_ctl_t	*ata_ctlp,
279507c3241Smlf 	ata_pkt_t	*ata_pktp)
280507c3241Smlf {
281507c3241Smlf 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
282507c3241Smlf 	int		 padding;
283507c3241Smlf 
284507c3241Smlf 	ADBG_TRACE(("atapi_send_cdb entered\n"));
285507c3241Smlf 
286507c3241Smlf 	/*
287507c3241Smlf 	 * send the CDB to the drive
288507c3241Smlf 	 */
289507c3241Smlf 	ddi_rep_put16(io_hdl1, (ushort_t *)ata_pktp->ap_cdbp, ata_ctlp->ac_data,
290507c3241Smlf 		ata_pktp->ap_cdb_len >> 1, DDI_DEV_NO_AUTOINCR);
291507c3241Smlf 
292507c3241Smlf 	/*
293507c3241Smlf 	 * pad to ad_cdb_len bytes
294507c3241Smlf 	 */
295507c3241Smlf 
296507c3241Smlf 	padding = ata_pktp->ap_cdb_pad;
297507c3241Smlf 
298507c3241Smlf 	while (padding) {
299507c3241Smlf 		ddi_put16(io_hdl1, ata_ctlp->ac_data, 0);
300507c3241Smlf 		padding--;
301507c3241Smlf 	}
302507c3241Smlf 
303507c3241Smlf 	/* wait for the busy bit to settle */
3049f49ae27Smlf 	ata_nsecwait(400);
305507c3241Smlf 
306507c3241Smlf #ifdef ATA_DEBUG_XXX
307507c3241Smlf 	{
308507c3241Smlf 		uchar_t	*cp = ata_pktp->ap_cdbp;
309507c3241Smlf 
310507c3241Smlf 		ADBG_TRANSPORT(("\tatapi scsi cmd (%d bytes):\n ",
311507c3241Smlf 				ata_pktp->ap_cdb_len));
312507c3241Smlf 		ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
313507c3241Smlf 			cp[0], cp[1], cp[2], cp[3]));
314507c3241Smlf 		ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
315507c3241Smlf 			cp[4], cp[5], cp[6], cp[7]));
316507c3241Smlf 		ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
317507c3241Smlf 			cp[8], cp[9], cp[10], cp[11]));
318507c3241Smlf 	}
319507c3241Smlf #endif
320507c3241Smlf 
321507c3241Smlf 	ata_pktp->ap_flags |= AP_SENT_CMD;
322507c3241Smlf }
323507c3241Smlf 
324507c3241Smlf 
325507c3241Smlf 
326507c3241Smlf /*
327507c3241Smlf  * Start the DMA engine
328507c3241Smlf  */
329507c3241Smlf 
330507c3241Smlf /* ARGSUSED */
331507c3241Smlf static void
atapi_start_dma(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)332507c3241Smlf atapi_start_dma(
333507c3241Smlf 	ata_ctl_t	*ata_ctlp,
334507c3241Smlf 	ata_drv_t	*ata_drvp,
335507c3241Smlf 	ata_pkt_t	*ata_pktp)
336507c3241Smlf {
337507c3241Smlf 	uchar_t		 rd_wr;
338507c3241Smlf 
339507c3241Smlf 	/*
340507c3241Smlf 	 * Determine the direction. This may look backwards
341507c3241Smlf 	 * but the command bit programmed into the DMA engine
342507c3241Smlf 	 * specifies the type of operation the engine performs
343507c3241Smlf 	 * on the PCI bus (not the ATA bus). Therefore when
344507c3241Smlf 	 * transferring data from the device to system memory, the
345507c3241Smlf 	 * DMA engine performs PCI Write operations.
346507c3241Smlf 	 */
347507c3241Smlf 	if (ata_pktp->ap_flags & AP_READ)
348507c3241Smlf 		rd_wr = PCIIDE_BMICX_RWCON_WRITE_TO_MEMORY;
349507c3241Smlf 	else
350507c3241Smlf 		rd_wr = PCIIDE_BMICX_RWCON_READ_FROM_MEMORY;
351507c3241Smlf 
352507c3241Smlf 	/*
353507c3241Smlf 	 * Start the DMA engine
354507c3241Smlf 	 */
355507c3241Smlf 	ata_pciide_dma_start(ata_ctlp, rd_wr);
356507c3241Smlf }
357507c3241Smlf 
358507c3241Smlf 
359507c3241Smlf 
360507c3241Smlf /*
361507c3241Smlf  * Transfer the data from the device
362507c3241Smlf  *
363507c3241Smlf  * Note: the atapi_pio_data_in() and atapi_pio_data_out() functions
364507c3241Smlf  * are complicated a lot by the requirement to handle an odd byte count.
365507c3241Smlf  * The only device we've seen which does this is the Hitachi CDR-7730.
366507c3241Smlf  * See bug ID 1214595. It's my understanding that Dell stopped shipping
367507c3241Smlf  * that drive after discovering all the problems it caused, so it may
368507c3241Smlf  * be impossible to find one for any sort of regression test.
369507c3241Smlf  *
370507c3241Smlf  * In the future, ATAPI tape drives will also probably support odd byte
371507c3241Smlf  * counts so this code will be excersized more often.
372507c3241Smlf  *
373507c3241Smlf  */
374507c3241Smlf 
375507c3241Smlf static void
atapi_pio_data_in(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)376507c3241Smlf atapi_pio_data_in(
377507c3241Smlf 	ata_ctl_t	*ata_ctlp,
378507c3241Smlf 	ata_pkt_t	*ata_pktp)
379507c3241Smlf {
380507c3241Smlf 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
381507c3241Smlf 	int		 drive_bytes;
382507c3241Smlf 	int		 xfer_bytes;
383507c3241Smlf 	int		 xfer_words;
384507c3241Smlf 
385507c3241Smlf 	ata_pktp->ap_flags |= AP_XFERRED_DATA;
386507c3241Smlf 
387507c3241Smlf 	/*
388507c3241Smlf 	 * Get the device's byte count for this transfer
389507c3241Smlf 	 */
390507c3241Smlf 	drive_bytes = ((int)ddi_get8(io_hdl1, ata_ctlp->ac_hcyl) << 8)
391507c3241Smlf 			+ ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
392507c3241Smlf 
393507c3241Smlf 	/*
394507c3241Smlf 	 * Determine actual number I'm going to transfer. My
395507c3241Smlf 	 * buffer might have fewer bytes than what the device
396507c3241Smlf 	 * expects or handles on each interrupt.
397507c3241Smlf 	 */
398507c3241Smlf 	xfer_bytes = min(ata_pktp->ap_resid, drive_bytes);
399507c3241Smlf 
400507c3241Smlf 	ASSERT(xfer_bytes >= 0);
401507c3241Smlf 
402507c3241Smlf 	/*
403507c3241Smlf 	 * Round down my transfer count to whole words so that
404507c3241Smlf 	 * if the transfer count is odd it's still handled correctly.
405507c3241Smlf 	 */
406507c3241Smlf 	xfer_words = xfer_bytes / 2;
407507c3241Smlf 
408507c3241Smlf 	if (xfer_words) {
409507c3241Smlf 		int	byte_count = xfer_words * 2;
410507c3241Smlf 
411507c3241Smlf 		ddi_rep_get16(io_hdl1, (ushort_t *)ata_pktp->ap_v_addr,
412507c3241Smlf 			ata_ctlp->ac_data, xfer_words, DDI_DEV_NO_AUTOINCR);
413507c3241Smlf 
414507c3241Smlf 		ata_pktp->ap_v_addr += byte_count;
415507c3241Smlf 		drive_bytes -= byte_count;
416507c3241Smlf 	}
417507c3241Smlf 
418507c3241Smlf 	/*
419507c3241Smlf 	 * Handle possible odd byte at end. Read a 16-bit
420507c3241Smlf 	 * word but discard the high-order byte.
421507c3241Smlf 	 */
422507c3241Smlf 	if (xfer_bytes & 1) {
423507c3241Smlf 		ushort_t tmp_word;
424507c3241Smlf 
425507c3241Smlf 		tmp_word = ddi_get16(io_hdl1, ata_ctlp->ac_data);
426507c3241Smlf 		*ata_pktp->ap_v_addr++ = tmp_word & 0xff;
427507c3241Smlf 		drive_bytes -= 2;
428507c3241Smlf 	}
429507c3241Smlf 
430507c3241Smlf 	ata_pktp->ap_resid -= xfer_bytes;
431507c3241Smlf 
432507c3241Smlf 	ADBG_TRANSPORT(("atapi_pio_data_in: read 0x%x bytes\n", xfer_bytes));
433507c3241Smlf 
434507c3241Smlf 	/*
435507c3241Smlf 	 * Discard any unwanted data.
436507c3241Smlf 	 */
437507c3241Smlf 	if (drive_bytes > 0) {
438507c3241Smlf 		ADBG_TRANSPORT(("atapi_pio_data_in: dump 0x%x bytes\n",
439507c3241Smlf 				drive_bytes));
440507c3241Smlf 
441507c3241Smlf 		/* rounded up if the drive_bytes count is odd */
442507c3241Smlf 		for (; drive_bytes > 0; drive_bytes -= 2)
443507c3241Smlf 			(void) ddi_get16(io_hdl1, ata_ctlp->ac_data);
444507c3241Smlf 	}
445507c3241Smlf 
446507c3241Smlf 	/* wait for the busy bit to settle */
4479f49ae27Smlf 	ata_nsecwait(400);
448507c3241Smlf }
449507c3241Smlf 
450507c3241Smlf 
451507c3241Smlf /*
452507c3241Smlf  * Transfer the data to the device
453507c3241Smlf  */
454507c3241Smlf 
455507c3241Smlf static void
atapi_pio_data_out(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)456507c3241Smlf atapi_pio_data_out(
457507c3241Smlf 	ata_ctl_t	*ata_ctlp,
458507c3241Smlf 	ata_pkt_t	*ata_pktp)
459507c3241Smlf {
460507c3241Smlf 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
461507c3241Smlf 	int		 drive_bytes;
462507c3241Smlf 	int		 xfer_bytes;
463507c3241Smlf 	int		 xfer_words;
464507c3241Smlf 
465507c3241Smlf 	ata_pktp->ap_flags |= AP_XFERRED_DATA;
466507c3241Smlf 
467507c3241Smlf 	/*
468507c3241Smlf 	 * Get the device's byte count for this transfer
469507c3241Smlf 	 */
470507c3241Smlf 	drive_bytes = ((int)ddi_get8(io_hdl1, ata_ctlp->ac_hcyl) << 8)
471507c3241Smlf 			+ ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
472507c3241Smlf 
473507c3241Smlf 	/*
474507c3241Smlf 	 * Determine actual number I'm going to transfer. My
475507c3241Smlf 	 * buffer might have fewer bytes than what the device
476507c3241Smlf 	 * expects or handles on each interrupt.
477507c3241Smlf 	 */
478507c3241Smlf 	xfer_bytes = min(ata_pktp->ap_resid, drive_bytes);
479507c3241Smlf 
480507c3241Smlf 	/*
481507c3241Smlf 	 * Round down my transfer count to whole words so that
482507c3241Smlf 	 * if the transfer count is odd it's handled correctly.
483507c3241Smlf 	 */
484507c3241Smlf 	xfer_words = xfer_bytes / 2;
485507c3241Smlf 
486507c3241Smlf 	if (xfer_words) {
487507c3241Smlf 		int	byte_count = xfer_words * 2;
488507c3241Smlf 
489507c3241Smlf 		ddi_rep_put16(io_hdl1, (ushort_t *)ata_pktp->ap_v_addr,
490507c3241Smlf 			ata_ctlp->ac_data, xfer_words, DDI_DEV_NO_AUTOINCR);
491507c3241Smlf 		ata_pktp->ap_v_addr += byte_count;
492507c3241Smlf 	}
493507c3241Smlf 
494507c3241Smlf 	/*
495507c3241Smlf 	 * If odd byte count, transfer the last
496507c3241Smlf 	 * byte. Use a tmp so that I don't run off
497507c3241Smlf 	 * the end off the buffer and possibly page
498507c3241Smlf 	 * fault.
499507c3241Smlf 	 */
500507c3241Smlf 	if (xfer_bytes & 1) {
501507c3241Smlf 		ushort_t tmp_word;
502507c3241Smlf 
503507c3241Smlf 		/* grab the last unsigned byte and widen it to 16-bits */
504507c3241Smlf 		tmp_word = *ata_pktp->ap_v_addr++;
505507c3241Smlf 		ddi_put16(io_hdl1, ata_ctlp->ac_data, tmp_word);
506507c3241Smlf 	}
507507c3241Smlf 
508507c3241Smlf 	ata_pktp->ap_resid -= xfer_bytes;
509507c3241Smlf 
510507c3241Smlf 	ADBG_TRANSPORT(("atapi_pio_data_out: wrote 0x%x bytes\n", xfer_bytes));
511507c3241Smlf 
512507c3241Smlf 	/* wait for the busy bit to settle */
5139f49ae27Smlf 	ata_nsecwait(400);
514507c3241Smlf }
515507c3241Smlf 
516507c3241Smlf 
517507c3241Smlf /*
518507c3241Smlf  *
519507c3241Smlf  * check status of completed command
520507c3241Smlf  *
521507c3241Smlf  */
522507c3241Smlf static void
atapi_status(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp,uchar_t status,int dma_completion)523507c3241Smlf atapi_status(
524507c3241Smlf 	ata_ctl_t	*ata_ctlp,
525507c3241Smlf 	ata_pkt_t	*ata_pktp,
526507c3241Smlf 	uchar_t		 status,
527507c3241Smlf 	int		 dma_completion)
528507c3241Smlf {
529507c3241Smlf 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
530507c3241Smlf 
531507c3241Smlf 	ata_pktp->ap_flags |= AP_GOT_STATUS;
532507c3241Smlf 
533507c3241Smlf 	if (status & (ATS_DF | ATS_ERR)) {
534507c3241Smlf 		ata_pktp->ap_flags |= AP_ERROR;
535507c3241Smlf 	}
536507c3241Smlf 
537507c3241Smlf 	if (ata_pktp->ap_flags & AP_ERROR) {
538507c3241Smlf 		ata_pktp->ap_status = status;
539507c3241Smlf 		ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
540507c3241Smlf 	}
541507c3241Smlf 
542507c3241Smlf 
543507c3241Smlf 	/*
544507c3241Smlf 	 * If the DMA transfer failed leave the resid set to
545507c3241Smlf 	 * the original byte count. The target driver has
546507c3241Smlf 	 * to do a REQUEST SENSE to get the true residual
547507c3241Smlf 	 * byte count. Otherwise, it all transferred so update
548507c3241Smlf 	 * the flags and residual byte count.
549507c3241Smlf 	 */
550507c3241Smlf 	if (dma_completion && !(ata_pktp->ap_flags & AP_TRAN_ERROR)) {
551507c3241Smlf 		ata_pktp->ap_flags |= AP_XFERRED_DATA;
552507c3241Smlf 		ata_pktp->ap_resid = 0;
553507c3241Smlf 	}
554507c3241Smlf }
555507c3241Smlf 
556507c3241Smlf 
557507c3241Smlf static void
atapi_device_reset(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)558507c3241Smlf atapi_device_reset(
559507c3241Smlf 	ata_ctl_t	*ata_ctlp,
560507c3241Smlf 	ata_drv_t	*ata_drvp)
561507c3241Smlf {
562507c3241Smlf 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
563507c3241Smlf 	ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
564507c3241Smlf 
565507c3241Smlf 	/* select the drive */
566507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
5679f49ae27Smlf 	ata_nsecwait(400);
568507c3241Smlf 
569507c3241Smlf 	/* issue atapi DEVICE RESET */
570507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ATC_DEVICE_RESET);
571507c3241Smlf 
572507c3241Smlf 	/* wait for the busy bit to settle */
5739f49ae27Smlf 	ata_nsecwait(400);
574507c3241Smlf 
575507c3241Smlf 	/*
576507c3241Smlf 	 * Re-select the drive (this is probably only necessary
577507c3241Smlf 	 * when resetting drive 1).
578507c3241Smlf 	 */
579507c3241Smlf 	ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
5809f49ae27Smlf 	ata_nsecwait(400);
581507c3241Smlf 
582507c3241Smlf 	/* allow the drive the full 6 seconds to respond */
583507c3241Smlf 	/* LINTED */
584507c3241Smlf 	if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, 6 * 1000000)) {
585507c3241Smlf 		ADBG_WARN(("atapi_device_reset: still busy\n"));
586507c3241Smlf 		/*
587507c3241Smlf 		 * It's not clear to me what to do at this point,
588507c3241Smlf 		 * the drive might be dead or might eventually
589507c3241Smlf 		 * recover. For now just ignore it and continue
590507c3241Smlf 		 * to attempt to use the drive.
591507c3241Smlf 		 */
592507c3241Smlf 	}
593507c3241Smlf }
594507c3241Smlf 
595507c3241Smlf 
596507c3241Smlf 
597507c3241Smlf void
atapi_fsm_reset(ata_ctl_t * ata_ctlp)598507c3241Smlf atapi_fsm_reset(ata_ctl_t *ata_ctlp)
599507c3241Smlf {
600507c3241Smlf 	ata_drv_t *ata_drvp;
601507c3241Smlf 	int	   drive;
602507c3241Smlf 
603507c3241Smlf 	/*
604507c3241Smlf 	 * reset drive drive 0 and the drive 1
605507c3241Smlf 	 */
606507c3241Smlf 	for (drive = 0; drive <= 1; drive++) {
607507c3241Smlf 		ata_drvp = CTL2DRV(ata_ctlp, drive, 0);
608507c3241Smlf 		if (ata_drvp && ATAPIDRV(ata_drvp)) {
609507c3241Smlf 			ata_drvp->ad_state = S_IDLE;
610507c3241Smlf 			atapi_device_reset(ata_ctlp, ata_drvp);
611507c3241Smlf 		}
612507c3241Smlf 	}
613507c3241Smlf }
614507c3241Smlf 
615507c3241Smlf 
616507c3241Smlf int
atapi_fsm_start(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)617507c3241Smlf atapi_fsm_start(
618507c3241Smlf 	ata_ctl_t	*ata_ctlp,
619507c3241Smlf 	ata_drv_t	*ata_drvp,
620507c3241Smlf 	ata_pkt_t	*ata_pktp)
621507c3241Smlf {
622507c3241Smlf 	int		 rc;
623507c3241Smlf 
624507c3241Smlf 	ADBG_TRACE(("atapi_start entered\n"));
625507c3241Smlf 	ADBG_TRANSPORT(("atapi_start: pkt = 0x%p\n", ata_pktp));
626507c3241Smlf 
627507c3241Smlf 	/*
628507c3241Smlf 	 * check for valid state
629507c3241Smlf 	 */
630507c3241Smlf 	if (ata_drvp->ad_state != S_IDLE) {
631507c3241Smlf 		ADBG_ERROR(("atapi_fsm_start not idle 0x%x\n",
632507c3241Smlf 			    ata_drvp->ad_state));
633507c3241Smlf 		return (ATA_FSM_RC_BUSY);
634507c3241Smlf 	} else {
635507c3241Smlf 		ata_drvp->ad_state = S_CMD;
636507c3241Smlf 	}
637507c3241Smlf 
638507c3241Smlf 	rc = atapi_start_cmd(ata_ctlp, ata_drvp, ata_pktp);
639507c3241Smlf 
640507c3241Smlf 	switch (rc) {
641507c3241Smlf 	case ATA_FSM_RC_OKAY:
642507c3241Smlf 		/*
643507c3241Smlf 		 * The command started okay. Just return.
644507c3241Smlf 		 */
645507c3241Smlf 		break;
646507c3241Smlf 	case ATA_FSM_RC_INTR:
647507c3241Smlf 		/*
648507c3241Smlf 		 * Got Command Phase. The upper layer will send
649507c3241Smlf 		 * the cdb by faking an interrupt.
650507c3241Smlf 		 */
651507c3241Smlf 		break;
652507c3241Smlf 	case ATA_FSM_RC_FINI:
653507c3241Smlf 		/*
654507c3241Smlf 		 * command completed immediately, stick on done q
655507c3241Smlf 		 */
656507c3241Smlf 		break;
657507c3241Smlf 	case ATA_FSM_RC_BUSY:
658507c3241Smlf 		/*
659507c3241Smlf 		 * The command wouldn't start, tell the upper layer to
660507c3241Smlf 		 * stick this request on the done queue.
661507c3241Smlf 		 */
662507c3241Smlf 		ata_drvp->ad_state = S_IDLE;
663507c3241Smlf 		return (ATA_FSM_RC_BUSY);
664507c3241Smlf 	}
665507c3241Smlf 	return (rc);
666507c3241Smlf }
667507c3241Smlf 
668507c3241Smlf /*
669507c3241Smlf  *
670507c3241Smlf  * All interrupts on an ATAPI device come through here.
671507c3241Smlf  * This function determines what to do next, based on
672507c3241Smlf  * the current state of the request and the drive's current
673507c3241Smlf  * status bits.  See the FSM tables at the top of this file.
674507c3241Smlf  *
675507c3241Smlf  */
676507c3241Smlf 
677507c3241Smlf int
atapi_fsm_intr(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)678507c3241Smlf atapi_fsm_intr(
679507c3241Smlf 	ata_ctl_t	*ata_ctlp,
680507c3241Smlf 	ata_drv_t	*ata_drvp,
681507c3241Smlf 	ata_pkt_t	*ata_pktp)
682507c3241Smlf {
683507c3241Smlf 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
684507c3241Smlf 	uchar_t		 status;
685507c3241Smlf 	uchar_t		 intr_reason;
686507c3241Smlf 	uchar_t		 state;
687507c3241Smlf 	uchar_t		 event;
688507c3241Smlf 	uchar_t		 action;
689507c3241Smlf 
690507c3241Smlf 
691507c3241Smlf 	/*
692507c3241Smlf 	 * get the prior state
693507c3241Smlf 	 */
694507c3241Smlf 	state = ata_drvp->ad_state;
695507c3241Smlf 
696507c3241Smlf 	/*
697507c3241Smlf 	 * If doing DMA, then:
698507c3241Smlf 	 *
699507c3241Smlf 	 *	1. halt the DMA engine
700507c3241Smlf 	 *	2. reset the interrupt and error latches
701507c3241Smlf 	 *	3. reset the drive's IRQ.
702507c3241Smlf 	 *
703507c3241Smlf 	 * I think the order of these operations must be
704507c3241Smlf 	 * exactly as listed. Otherwise we the PCI-IDE
705507c3241Smlf 	 * controller can hang or we can miss the next interrupt
706507c3241Smlf 	 * edge.
707507c3241Smlf 	 *
708507c3241Smlf 	 */
709507c3241Smlf 	switch (state) {
710507c3241Smlf 	case S_DMA:
711507c3241Smlf 		ASSERT(ata_pktp->ap_pciide_dma == TRUE);
712507c3241Smlf 		/*
713507c3241Smlf 		 * Halt the DMA engine. When we reach this point
714507c3241Smlf 		 * we already know for certain that the device has
715507c3241Smlf 		 * an interrupt pending since the ata_get_status()
716507c3241Smlf 		 * function already checked the PCI-IDE interrupt
717507c3241Smlf 		 * status bit.
718507c3241Smlf 		 */
719507c3241Smlf 		ata_pciide_dma_stop(ata_ctlp);
720507c3241Smlf 		/*FALLTHRU*/
721507c3241Smlf 	case S_IDLE:
722507c3241Smlf 	case S_CMD:
723507c3241Smlf 	case S_CDB:
724507c3241Smlf 	case S_IN:
725507c3241Smlf 	case S_OUT:
726507c3241Smlf 		break;
727507c3241Smlf 	}
728507c3241Smlf 
729507c3241Smlf 
730507c3241Smlf 	/*
731507c3241Smlf 	 * Clear the PCI-IDE latches and the drive's IRQ
732507c3241Smlf 	 */
733507c3241Smlf 	status = ata_get_status_clear_intr(ata_ctlp, ata_pktp);
734507c3241Smlf 
735507c3241Smlf 	/*
736507c3241Smlf 	 * some non-compliant (i.e., NEC) drives don't
737507c3241Smlf 	 * set ATS_BSY within 400 nsec. and/or don't keep
738507c3241Smlf 	 * it asserted until they're actually non-busy.
739507c3241Smlf 	 * There's a small window between reading the alt_status
740507c3241Smlf 	 * and status registers where the drive might "bounce"
741507c3241Smlf 	 * the ATS_BSY bit.
742507c3241Smlf 	 */
743507c3241Smlf 	if (status & ATS_BSY)
744507c3241Smlf 		return (ATA_FSM_RC_BUSY);
745507c3241Smlf 
746507c3241Smlf 	/*
747507c3241Smlf 	 * get the interrupt reason code
748507c3241Smlf 	 */
749507c3241Smlf 	intr_reason = ddi_get8(io_hdl1, ata_ctlp->ac_count);
750507c3241Smlf 
751507c3241Smlf 	/*
752507c3241Smlf 	 * encode the status and interrupt reason bits
753507c3241Smlf 	 * into an event code which is used to index the
754507c3241Smlf 	 * FSM tables
755507c3241Smlf 	 */
756507c3241Smlf 	event = ATAPI_EVENT(status, intr_reason);
757507c3241Smlf 
758507c3241Smlf 	/*
759507c3241Smlf 	 * determine the action for this event
760507c3241Smlf 	 */
761507c3241Smlf 	action = atapi_PioAction[state][event];
762507c3241Smlf 
763507c3241Smlf 	/*
764507c3241Smlf 	 * determine the new state
765507c3241Smlf 	 */
766507c3241Smlf 	ata_drvp->ad_state = atapi_PioNextState[state][event];
767507c3241Smlf 
768507c3241Smlf 	switch (action) {
769507c3241Smlf 	default:
770507c3241Smlf 	case A_UNK:
771507c3241Smlf 		/*
772507c3241Smlf 		 * invalid state
773507c3241Smlf 		 */
774507c3241Smlf /*
775507c3241Smlf  * ??? this shouldn't happen. ???
776507c3241Smlf  *	if there's an active command on
777507c3241Smlf  *	this device, the pkt timer should eventually clear the
778507c3241Smlf  *	device. I might try sending a DEVICE-RESET here to speed
779507c3241Smlf  *	up the error recovery except that DEVICE-RESET is kind of
780507c3241Smlf  *	complicated to implement correctly because if I send a
781507c3241Smlf  *	DEVICE-RESET to drive 1 it deselects itself.
782507c3241Smlf  */
783507c3241Smlf 		ADBG_WARN(("atapi_fsm_intr: Unsupported intr\n"));
784507c3241Smlf 		break;
785507c3241Smlf 
786507c3241Smlf 	case A_NADA:
787507c3241Smlf 		drv_usecwait(100);
788507c3241Smlf 		break;
789507c3241Smlf 
790507c3241Smlf 	case A_CDB:
791507c3241Smlf 		/*
792507c3241Smlf 		 * send out atapi pkt
793507c3241Smlf 		 */
794507c3241Smlf 		atapi_send_cdb(ata_ctlp, ata_pktp);
795507c3241Smlf 
796507c3241Smlf 		/*
797507c3241Smlf 		 * start the DMA engine if necessary and change
798507c3241Smlf 		 * the state variable to reflect not doing PIO
799507c3241Smlf 		 */
800507c3241Smlf 		if (ata_pktp->ap_pciide_dma) {
801507c3241Smlf 			atapi_start_dma(ata_ctlp, ata_drvp, ata_pktp);
802507c3241Smlf 			ata_drvp->ad_state = S_DMA;
803507c3241Smlf 		}
804507c3241Smlf 		break;
805507c3241Smlf 
806507c3241Smlf 	case A_IN:
807507c3241Smlf 		if (!(ata_pktp->ap_flags & AP_READ)) {
808507c3241Smlf 			/*
809507c3241Smlf 			 * maybe this was a spurious interrupt, just
810507c3241Smlf 			 * spin for a bit and see if the drive
811507c3241Smlf 			 * recovers
812507c3241Smlf 			 */
813507c3241Smlf 			atapi_fsm_error(ata_ctlp, state, event);
814507c3241Smlf 			drv_usecwait(100);
815507c3241Smlf 			break;
816507c3241Smlf 		}
817507c3241Smlf 		/*
818507c3241Smlf 		 * read in the data
819507c3241Smlf 		 */
820507c3241Smlf 		if (!ata_pktp->ap_pciide_dma) {
821507c3241Smlf 			atapi_pio_data_in(ata_ctlp, ata_pktp);
822507c3241Smlf 		}
823507c3241Smlf 		break;
824507c3241Smlf 
825507c3241Smlf 	case A_OUT:
826507c3241Smlf 		if (!(ata_pktp->ap_flags & AP_WRITE)) {
827507c3241Smlf 			/* spin for a bit and see if the drive recovers */
828507c3241Smlf 			atapi_fsm_error(ata_ctlp, state, event);
829507c3241Smlf 			drv_usecwait(100);
830507c3241Smlf 			break;
831507c3241Smlf 		}
832507c3241Smlf 		/*
833507c3241Smlf 		 * send out data
834507c3241Smlf 		 */
835507c3241Smlf 		if (!ata_pktp->ap_pciide_dma) {
836507c3241Smlf 			atapi_pio_data_out(ata_ctlp, ata_pktp);
837507c3241Smlf 		}
838507c3241Smlf 		break;
839507c3241Smlf 
840507c3241Smlf 	case A_IDLE:
841507c3241Smlf 		/*
842507c3241Smlf 		 * The DRQ bit deasserted before or between the data
843507c3241Smlf 		 * transfer phases.
844507c3241Smlf 		 */
845507c3241Smlf 		if (!ata_drvp->ad_bogus_drq) {
846507c3241Smlf 			ata_drvp->ad_bogus_drq = TRUE;
847507c3241Smlf 			atapi_fsm_error(ata_ctlp, state, event);
848507c3241Smlf 		}
849507c3241Smlf 		drv_usecwait(100);
850507c3241Smlf 		break;
851507c3241Smlf 
852507c3241Smlf 	case A_RE:
853507c3241Smlf 		/*
854507c3241Smlf 		 * If we get here, a command has completed!
855507c3241Smlf 		 *
856507c3241Smlf 		 * check status of completed command
857507c3241Smlf 		 */
858507c3241Smlf 		atapi_status(ata_ctlp, ata_pktp, status,
859507c3241Smlf 			(state == S_DMA) ? TRUE : FALSE);
860507c3241Smlf 
861507c3241Smlf 		return (ATA_FSM_RC_FINI);
862507c3241Smlf 
863507c3241Smlf 	case A_REX:
864507c3241Smlf 		/*
865507c3241Smlf 		 * some NEC drives don't report the right interrupt
866507c3241Smlf 		 * reason code for the status phase
867507c3241Smlf 		 */
868507c3241Smlf 		if (!ata_drvp->ad_nec_bad_status) {
869507c3241Smlf 			ata_drvp->ad_nec_bad_status = TRUE;
870507c3241Smlf 			atapi_fsm_error(ata_ctlp, state, event);
871507c3241Smlf 			drv_usecwait(100);
872507c3241Smlf 		}
873507c3241Smlf 		atapi_status(ata_ctlp, ata_pktp, status,
874507c3241Smlf 			(state == S_DMA) ? TRUE : FALSE);
875507c3241Smlf 		return (ATA_FSM_RC_FINI);
876507c3241Smlf 
877507c3241Smlf 	}
878507c3241Smlf 	return (ATA_FSM_RC_OKAY);
879507c3241Smlf }
880