xref: /illumos-gate/usr/src/uts/intel/io/dktp/controller/ata/atapi_fsm.c (revision bea83d026ee1bd1b2a2419e1d0232f107a5d7d9b)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Finite State Machines for ATA controller and ATAPI devices
31  */
32 
33 #include <sys/types.h>
34 
35 #include "ata_common.h"
36 #include "atapi.h"
37 
38 /*
39  * Local functions
40  */
41 static	int	atapi_start_cmd(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
42 				ata_pkt_t *ata_pktp);
43 static	void	atapi_send_cdb(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
44 static	void	atapi_start_dma(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
45 				ata_pkt_t *ata_pktp);
46 static	void	atapi_pio_data_in(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
47 static	void	atapi_pio_data_out(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
48 static	void	atapi_status(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp,
49 				uchar_t status, int dma_complete);
50 static	void	atapi_fsm_error(ata_ctl_t *ata_ctlp, uchar_t state,
51 				uchar_t event);
52 
53 
54 
55 
56 static void
57 atapi_fsm_error(
58 	ata_ctl_t *ata_ctlp,
59 	uchar_t	   state,
60 	uchar_t	   event)
61 {
62 	ADBG_ERROR(("atapi protocol error: 0x%p 0x%x 0x%x\n",
63 	    ata_ctlp->ac_data, state, event));
64 }
65 
66 
67 /*
68  *
69  *  IO  CoD  DRQ
70  *  --  ---  ---
71  *   0    0    0  == 0 invalid
72  *   0    0    1  == 1 Data to device
73  *   0    1    0  == 2 Idle
74  *   0    1    1  == 3 Send ATAPI CDB to device
75  *   1    0    0  == 4 invalid
76  *   1    0    1  == 5 Data from device
77  *   1    1    0  == 6 Status ready
78  *   1    1    1  == 7 Future use
79  *
80  */
81 
82 /*
83  * Given the current state and the current event this
84  * table determines what action to take. Note, in the actual
85  * table I've left room for the invalid event codes: 0, 2, and 7.
86  *
87  *		+-----------------------------------------------------
88  *		|		Current Event
89  *		|
90  *	State	|	dataout	idle	cdb	datain	status
91  *		|	1	2	3	5	6
92  *		|-----------------------------------------------------
93  *	idle	|	sendcmd	sendcmd	sendcmd	sendcmd	sendcmd
94  *	cmd	|	*	 *	sendcdb	*	read-err-code
95  *	cdb	|	xfer-out nada	nada	xfer-in read-err-code
96  *	datain	|	*	 *	*	xfer-in	read-err-code
97  *	dataout	|	xfer-out *	*	*	read-err-code
98  *	DMA	|	*	 *	*	*	read-err-code
99  *
100  */
101 
102 uchar_t	atapi_PioAction[ATAPI_NSTATES][ATAPI_NEVENTS] = {
103 /* invalid dataout idle	  cdb	  invalid datain  status  future */
104 { A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA }, /* Idle */
105 { A_NADA, A_NADA, A_NADA, A_CDB,  A_NADA, A_NADA, A_RE,   A_NADA }, /* Cmd */
106 { A_REX,  A_OUT,  A_NADA, A_NADA, A_IDLE, A_IN,   A_RE,   A_UNK  }, /* Cdb */
107 { A_REX,  A_UNK,  A_IDLE, A_UNK,  A_IDLE, A_IN,   A_RE,   A_UNK  }, /* DtaIn */
108 { A_REX,  A_OUT,  A_IDLE, A_UNK,  A_IDLE, A_UNK,  A_RE,   A_UNK  }, /* DtaOut */
109 { A_REX,  A_UNK,  A_UNK,  A_UNK,  A_UNK,  A_UNK,  A_RE,   A_UNK  }  /* DmaAct */
110 };
111 
112 /*
113  *
114  * Give the current state and the current event this table
115  * determines the new state of the device.
116  *
117  *		+----------------------------------------------
118  *		|		Current Event
119  *		|
120  *	State	|	dataout	idle	cdb	datain	status
121  *		|----------------------------------------------
122  *	idle	|	cmd	cmd	cmd	cmd	cmd
123  *	cmd	|	*	*	cdb	*	*
124  *	cdb	|	dataout	cdb	cdb	datain	(idle)
125  *	datain	|	*	*	*	datain	(idle)
126  *	dataout	|	dataout	*	*	*	(idle)
127  *	DMA	|	DMA	DMA	DMA	DMA	(idle)
128  *
129  *
130  * Note: the states enclosed in parens "(state)", are the accept states
131  * for this FSM. A separate table is used to encode the done
132  * states rather than extra state codes.
133  *
134  */
135 
136 uchar_t	atapi_PioNextState[ATAPI_NSTATES][ATAPI_NEVENTS] = {
137 /* invalid dataout idle	  cdb	  invalid datain  status  future */
138 { S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE}, /* idle */
139 { S_CDB,  S_CDB,  S_CDB,  S_CDB,  S_CDB,  S_CDB,  S_IDLE, S_X   }, /* cmd */
140 { S_IDLE, S_OUT,  S_CDB,  S_CDB,  S_CDB,  S_IN,   S_IDLE, S_X   }, /* cdb */
141 { S_IDLE, S_X,    S_IN,   S_X,    S_IN,   S_IN,   S_IDLE, S_X   }, /* datain */
142 { S_IDLE, S_OUT,  S_OUT,  S_X,    S_OUT,  S_X,    S_IDLE, S_X   }, /* dataout */
143 { S_IDLE, S_DMA,  S_DMA,  S_DMA,  S_DMA,  S_DMA,  S_IDLE, S_DMA }  /* dmaActv */
144 };
145 
146 
147 static int
148 atapi_start_cmd(
149 	ata_ctl_t	*ata_ctlp,
150 	ata_drv_t	*ata_drvp,
151 	ata_pkt_t	*ata_pktp)
152 {
153 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
154 	ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
155 
156 	/*
157 	 * Bug 1256489:
158 	 *
159 	 * If AC_BSY_WAIT is set, wait for controller to be not busy,
160 	 * before issuing a command.  If AC_BSY_WAIT is not set,
161 	 * skip the wait.  This is important for laptops that do
162 	 * suspend/resume but do not correctly wait for the busy bit to
163 	 * drop after a resume.
164 	 */
165 
166 	if (ata_ctlp->ac_timing_flags & AC_BSY_WAIT) {
167 		if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2,
168 			0, ATS_BSY, 5000000)) {
169 			ADBG_WARN(("atapi_start: BSY too long!\n"));
170 			ata_pktp->ap_flags |= AP_ERROR;
171 			return (ATA_FSM_RC_BUSY);
172 		}
173 	}
174 
175 	/*
176 	 * Select the drive
177 	 */
178 	ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_pktp->ap_hd);
179 	ata_nsecwait(400);
180 
181 	/*
182 	 * make certain the drive selected
183 	 */
184 	if (!ata_wait(io_hdl2,  ata_ctlp->ac_ioaddr2, 0, ATS_BSY, 5000000)) {
185 		ADBG_ERROR(("atapi_start_cmd: drive select failed\n"));
186 		return (ATA_FSM_RC_BUSY);
187 	}
188 
189 	/*
190 	 * Always make certain interrupts are enabled. It's been reported
191 	 * (but not confirmed) that some notebook computers don't
192 	 * clear the interrupt disable bit after being resumed. The
193 	 * easiest way to fix this is to always clear the disable bit
194 	 * before every command.
195 	 */
196 	ddi_put8(io_hdl2, ata_ctlp->ac_devctl, ATDC_D3);
197 
198 	ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, ata_pktp->ap_lwcyl);
199 	ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, ata_pktp->ap_hicyl);
200 	ddi_put8(io_hdl1, ata_ctlp->ac_sect, ata_pktp->ap_sec);
201 	ddi_put8(io_hdl1, ata_ctlp->ac_count, ata_pktp->ap_count);
202 
203 	if (ata_pktp->ap_pciide_dma) {
204 
205 		ASSERT((ata_pktp->ap_flags & (AP_READ | AP_WRITE)) != 0);
206 
207 		/*
208 		 * DMA but no Overlap
209 		 */
210 		ddi_put8(io_hdl1, ata_ctlp->ac_feature, ATF_ATAPI_DMA);
211 
212 		/*
213 		 * copy the Scatter/Gather list to the controller's
214 		 * Physical Region Descriptor Table
215 		 */
216 		ata_pciide_dma_setup(ata_ctlp, ata_pktp->ap_sg_list,
217 			ata_pktp->ap_sg_cnt);
218 	} else {
219 		/*
220 		 * no DMA and no Overlap
221 		 */
222 		ddi_put8(io_hdl1, ata_ctlp->ac_feature, 0);
223 	}
224 
225 	/*
226 	 * This next one sets the device in motion
227 	 */
228 	ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ata_pktp->ap_cmd);
229 
230 	/* wait for the busy bit to settle */
231 	ata_nsecwait(400);
232 
233 	if (!(ata_drvp->ad_flags & AD_NO_CDB_INTR)) {
234 		/*
235 		 * the device will send me an interrupt when it's
236 		 * ready for the packet
237 		 */
238 		return (ATA_FSM_RC_OKAY);
239 	}
240 
241 	/* else */
242 
243 	/*
244 	 * If we don't receive an interrupt requesting the scsi CDB,
245 	 * we must poll for DRQ, and then send out the CDB.
246 	 */
247 
248 	/*
249 	 * Wait for DRQ before sending the CDB. Bailout early
250 	 * if an error occurs.
251 	 *
252 	 * I'm not certain what the correct timeout should be.
253 	 */
254 	if (ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2,
255 		ATS_DRQ, ATS_BSY, /* okay */
256 		ATS_ERR, ATS_BSY, /* cmd failed */
257 		ATS_DF,  ATS_BSY, /* cmd failed */
258 		4000000)) {
259 		/* got good status */
260 		return (ATA_FSM_RC_INTR);
261 	}
262 
263 	ADBG_WARN(("atapi_start_cmd: 0x%x status 0x%x error 0x%x\n",
264 		ata_pktp->ap_cmd,
265 		ddi_get8(io_hdl2,  ata_ctlp->ac_altstatus),
266 		ddi_get8(io_hdl1, ata_ctlp->ac_error)));
267 
268 	return (ATA_FSM_RC_INTR);
269 }
270 
271 
272 /*
273  *
274  * Send the SCSI CDB to the ATAPI device
275  *
276  */
277 
278 static void
279 atapi_send_cdb(
280 	ata_ctl_t	*ata_ctlp,
281 	ata_pkt_t	*ata_pktp)
282 {
283 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
284 	int		 padding;
285 
286 	ADBG_TRACE(("atapi_send_cdb entered\n"));
287 
288 	/*
289 	 * send the CDB to the drive
290 	 */
291 	ddi_rep_put16(io_hdl1, (ushort_t *)ata_pktp->ap_cdbp, ata_ctlp->ac_data,
292 		ata_pktp->ap_cdb_len >> 1, DDI_DEV_NO_AUTOINCR);
293 
294 	/*
295 	 * pad to ad_cdb_len bytes
296 	 */
297 
298 	padding = ata_pktp->ap_cdb_pad;
299 
300 	while (padding) {
301 		ddi_put16(io_hdl1, ata_ctlp->ac_data, 0);
302 		padding--;
303 	}
304 
305 	/* wait for the busy bit to settle */
306 	ata_nsecwait(400);
307 
308 #ifdef ATA_DEBUG_XXX
309 	{
310 		uchar_t	*cp = ata_pktp->ap_cdbp;
311 
312 		ADBG_TRANSPORT(("\tatapi scsi cmd (%d bytes):\n ",
313 				ata_pktp->ap_cdb_len));
314 		ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
315 			cp[0], cp[1], cp[2], cp[3]));
316 		ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
317 			cp[4], cp[5], cp[6], cp[7]));
318 		ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
319 			cp[8], cp[9], cp[10], cp[11]));
320 	}
321 #endif
322 
323 	ata_pktp->ap_flags |= AP_SENT_CMD;
324 }
325 
326 
327 
328 /*
329  * Start the DMA engine
330  */
331 
332 /* ARGSUSED */
333 static void
334 atapi_start_dma(
335 	ata_ctl_t	*ata_ctlp,
336 	ata_drv_t	*ata_drvp,
337 	ata_pkt_t	*ata_pktp)
338 {
339 	uchar_t		 rd_wr;
340 
341 	/*
342 	 * Determine the direction. This may look backwards
343 	 * but the command bit programmed into the DMA engine
344 	 * specifies the type of operation the engine performs
345 	 * on the PCI bus (not the ATA bus). Therefore when
346 	 * transferring data from the device to system memory, the
347 	 * DMA engine performs PCI Write operations.
348 	 */
349 	if (ata_pktp->ap_flags & AP_READ)
350 		rd_wr = PCIIDE_BMICX_RWCON_WRITE_TO_MEMORY;
351 	else
352 		rd_wr = PCIIDE_BMICX_RWCON_READ_FROM_MEMORY;
353 
354 	/*
355 	 * Start the DMA engine
356 	 */
357 	ata_pciide_dma_start(ata_ctlp, rd_wr);
358 }
359 
360 
361 
362 /*
363  * Transfer the data from the device
364  *
365  * Note: the atapi_pio_data_in() and atapi_pio_data_out() functions
366  * are complicated a lot by the requirement to handle an odd byte count.
367  * The only device we've seen which does this is the Hitachi CDR-7730.
368  * See bug ID 1214595. It's my understanding that Dell stopped shipping
369  * that drive after discovering all the problems it caused, so it may
370  * be impossible to find one for any sort of regression test.
371  *
372  * In the future, ATAPI tape drives will also probably support odd byte
373  * counts so this code will be excersized more often.
374  *
375  */
376 
377 static void
378 atapi_pio_data_in(
379 	ata_ctl_t	*ata_ctlp,
380 	ata_pkt_t	*ata_pktp)
381 {
382 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
383 	int		 drive_bytes;
384 	int		 xfer_bytes;
385 	int		 xfer_words;
386 
387 	ata_pktp->ap_flags |= AP_XFERRED_DATA;
388 
389 	/*
390 	 * Get the device's byte count for this transfer
391 	 */
392 	drive_bytes = ((int)ddi_get8(io_hdl1, ata_ctlp->ac_hcyl) << 8)
393 			+ ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
394 
395 	/*
396 	 * Determine actual number I'm going to transfer. My
397 	 * buffer might have fewer bytes than what the device
398 	 * expects or handles on each interrupt.
399 	 */
400 	xfer_bytes = min(ata_pktp->ap_resid, drive_bytes);
401 
402 	ASSERT(xfer_bytes >= 0);
403 
404 	/*
405 	 * Round down my transfer count to whole words so that
406 	 * if the transfer count is odd it's still handled correctly.
407 	 */
408 	xfer_words = xfer_bytes / 2;
409 
410 	if (xfer_words) {
411 		int	byte_count = xfer_words * 2;
412 
413 		ddi_rep_get16(io_hdl1, (ushort_t *)ata_pktp->ap_v_addr,
414 			ata_ctlp->ac_data, xfer_words, DDI_DEV_NO_AUTOINCR);
415 
416 		ata_pktp->ap_v_addr += byte_count;
417 		drive_bytes -= byte_count;
418 	}
419 
420 	/*
421 	 * Handle possible odd byte at end. Read a 16-bit
422 	 * word but discard the high-order byte.
423 	 */
424 	if (xfer_bytes & 1) {
425 		ushort_t tmp_word;
426 
427 		tmp_word = ddi_get16(io_hdl1, ata_ctlp->ac_data);
428 		*ata_pktp->ap_v_addr++ = tmp_word & 0xff;
429 		drive_bytes -= 2;
430 	}
431 
432 	ata_pktp->ap_resid -= xfer_bytes;
433 
434 	ADBG_TRANSPORT(("atapi_pio_data_in: read 0x%x bytes\n", xfer_bytes));
435 
436 	/*
437 	 * Discard any unwanted data.
438 	 */
439 	if (drive_bytes > 0) {
440 		ADBG_TRANSPORT(("atapi_pio_data_in: dump 0x%x bytes\n",
441 				drive_bytes));
442 
443 		/* rounded up if the drive_bytes count is odd */
444 		for (; drive_bytes > 0; drive_bytes -= 2)
445 			(void) ddi_get16(io_hdl1, ata_ctlp->ac_data);
446 	}
447 
448 	/* wait for the busy bit to settle */
449 	ata_nsecwait(400);
450 }
451 
452 
453 /*
454  * Transfer the data to the device
455  */
456 
457 static void
458 atapi_pio_data_out(
459 	ata_ctl_t	*ata_ctlp,
460 	ata_pkt_t	*ata_pktp)
461 {
462 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
463 	int		 drive_bytes;
464 	int		 xfer_bytes;
465 	int		 xfer_words;
466 
467 	ata_pktp->ap_flags |= AP_XFERRED_DATA;
468 
469 	/*
470 	 * Get the device's byte count for this transfer
471 	 */
472 	drive_bytes = ((int)ddi_get8(io_hdl1, ata_ctlp->ac_hcyl) << 8)
473 			+ ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
474 
475 	/*
476 	 * Determine actual number I'm going to transfer. My
477 	 * buffer might have fewer bytes than what the device
478 	 * expects or handles on each interrupt.
479 	 */
480 	xfer_bytes = min(ata_pktp->ap_resid, drive_bytes);
481 
482 	/*
483 	 * Round down my transfer count to whole words so that
484 	 * if the transfer count is odd it's handled correctly.
485 	 */
486 	xfer_words = xfer_bytes / 2;
487 
488 	if (xfer_words) {
489 		int	byte_count = xfer_words * 2;
490 
491 		ddi_rep_put16(io_hdl1, (ushort_t *)ata_pktp->ap_v_addr,
492 			ata_ctlp->ac_data, xfer_words, DDI_DEV_NO_AUTOINCR);
493 		ata_pktp->ap_v_addr += byte_count;
494 	}
495 
496 	/*
497 	 * If odd byte count, transfer the last
498 	 * byte. Use a tmp so that I don't run off
499 	 * the end off the buffer and possibly page
500 	 * fault.
501 	 */
502 	if (xfer_bytes & 1) {
503 		ushort_t tmp_word;
504 
505 		/* grab the last unsigned byte and widen it to 16-bits */
506 		tmp_word = *ata_pktp->ap_v_addr++;
507 		ddi_put16(io_hdl1, ata_ctlp->ac_data, tmp_word);
508 	}
509 
510 	ata_pktp->ap_resid -= xfer_bytes;
511 
512 	ADBG_TRANSPORT(("atapi_pio_data_out: wrote 0x%x bytes\n", xfer_bytes));
513 
514 	/* wait for the busy bit to settle */
515 	ata_nsecwait(400);
516 }
517 
518 
519 /*
520  *
521  * check status of completed command
522  *
523  */
524 static void
525 atapi_status(
526 	ata_ctl_t	*ata_ctlp,
527 	ata_pkt_t	*ata_pktp,
528 	uchar_t		 status,
529 	int		 dma_completion)
530 {
531 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
532 
533 	ata_pktp->ap_flags |= AP_GOT_STATUS;
534 
535 	if (status & (ATS_DF | ATS_ERR)) {
536 		ata_pktp->ap_flags |= AP_ERROR;
537 	}
538 
539 	if (ata_pktp->ap_flags & AP_ERROR) {
540 		ata_pktp->ap_status = status;
541 		ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
542 	}
543 
544 
545 	/*
546 	 * If the DMA transfer failed leave the resid set to
547 	 * the original byte count. The target driver has
548 	 * to do a REQUEST SENSE to get the true residual
549 	 * byte count. Otherwise, it all transferred so update
550 	 * the flags and residual byte count.
551 	 */
552 	if (dma_completion && !(ata_pktp->ap_flags & AP_TRAN_ERROR)) {
553 		ata_pktp->ap_flags |= AP_XFERRED_DATA;
554 		ata_pktp->ap_resid = 0;
555 	}
556 }
557 
558 
559 static void
560 atapi_device_reset(
561 	ata_ctl_t	*ata_ctlp,
562 	ata_drv_t	*ata_drvp)
563 {
564 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
565 	ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
566 
567 	/* select the drive */
568 	ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
569 	ata_nsecwait(400);
570 
571 	/* issue atapi DEVICE RESET */
572 	ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ATC_DEVICE_RESET);
573 
574 	/* wait for the busy bit to settle */
575 	ata_nsecwait(400);
576 
577 	/*
578 	 * Re-select the drive (this is probably only necessary
579 	 * when resetting drive 1).
580 	 */
581 	ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
582 	ata_nsecwait(400);
583 
584 	/* allow the drive the full 6 seconds to respond */
585 	/* LINTED */
586 	if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, 6 * 1000000)) {
587 		ADBG_WARN(("atapi_device_reset: still busy\n"));
588 		/*
589 		 * It's not clear to me what to do at this point,
590 		 * the drive might be dead or might eventually
591 		 * recover. For now just ignore it and continue
592 		 * to attempt to use the drive.
593 		 */
594 	}
595 }
596 
597 
598 
599 void
600 atapi_fsm_reset(ata_ctl_t *ata_ctlp)
601 {
602 	ata_drv_t *ata_drvp;
603 	int	   drive;
604 
605 	/*
606 	 * reset drive drive 0 and the drive 1
607 	 */
608 	for (drive = 0; drive <= 1; drive++) {
609 		ata_drvp = CTL2DRV(ata_ctlp, drive, 0);
610 		if (ata_drvp && ATAPIDRV(ata_drvp)) {
611 			ata_drvp->ad_state = S_IDLE;
612 			atapi_device_reset(ata_ctlp, ata_drvp);
613 		}
614 	}
615 }
616 
617 
618 int
619 atapi_fsm_start(
620 	ata_ctl_t	*ata_ctlp,
621 	ata_drv_t	*ata_drvp,
622 	ata_pkt_t	*ata_pktp)
623 {
624 	int		 rc;
625 
626 	ADBG_TRACE(("atapi_start entered\n"));
627 	ADBG_TRANSPORT(("atapi_start: pkt = 0x%p\n", ata_pktp));
628 
629 	/*
630 	 * check for valid state
631 	 */
632 	if (ata_drvp->ad_state != S_IDLE) {
633 		ADBG_ERROR(("atapi_fsm_start not idle 0x%x\n",
634 			    ata_drvp->ad_state));
635 		return (ATA_FSM_RC_BUSY);
636 	} else {
637 		ata_drvp->ad_state = S_CMD;
638 	}
639 
640 	rc = atapi_start_cmd(ata_ctlp, ata_drvp, ata_pktp);
641 
642 	switch (rc) {
643 	case ATA_FSM_RC_OKAY:
644 		/*
645 		 * The command started okay. Just return.
646 		 */
647 		break;
648 	case ATA_FSM_RC_INTR:
649 		/*
650 		 * Got Command Phase. The upper layer will send
651 		 * the cdb by faking an interrupt.
652 		 */
653 		break;
654 	case ATA_FSM_RC_FINI:
655 		/*
656 		 * command completed immediately, stick on done q
657 		 */
658 		break;
659 	case ATA_FSM_RC_BUSY:
660 		/*
661 		 * The command wouldn't start, tell the upper layer to
662 		 * stick this request on the done queue.
663 		 */
664 		ata_drvp->ad_state = S_IDLE;
665 		return (ATA_FSM_RC_BUSY);
666 	}
667 	return (rc);
668 }
669 
670 /*
671  *
672  * All interrupts on an ATAPI device come through here.
673  * This function determines what to do next, based on
674  * the current state of the request and the drive's current
675  * status bits.  See the FSM tables at the top of this file.
676  *
677  */
678 
679 int
680 atapi_fsm_intr(
681 	ata_ctl_t	*ata_ctlp,
682 	ata_drv_t	*ata_drvp,
683 	ata_pkt_t	*ata_pktp)
684 {
685 	ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
686 	uchar_t		 status;
687 	uchar_t		 intr_reason;
688 	uchar_t		 state;
689 	uchar_t		 event;
690 	uchar_t		 action;
691 
692 
693 	/*
694 	 * get the prior state
695 	 */
696 	state = ata_drvp->ad_state;
697 
698 	/*
699 	 * If doing DMA, then:
700 	 *
701 	 *	1. halt the DMA engine
702 	 *	2. reset the interrupt and error latches
703 	 *	3. reset the drive's IRQ.
704 	 *
705 	 * I think the order of these operations must be
706 	 * exactly as listed. Otherwise we the PCI-IDE
707 	 * controller can hang or we can miss the next interrupt
708 	 * edge.
709 	 *
710 	 */
711 	switch (state) {
712 	case S_DMA:
713 		ASSERT(ata_pktp->ap_pciide_dma == TRUE);
714 		/*
715 		 * Halt the DMA engine. When we reach this point
716 		 * we already know for certain that the device has
717 		 * an interrupt pending since the ata_get_status()
718 		 * function already checked the PCI-IDE interrupt
719 		 * status bit.
720 		 */
721 		ata_pciide_dma_stop(ata_ctlp);
722 		/*FALLTHRU*/
723 	case S_IDLE:
724 	case S_CMD:
725 	case S_CDB:
726 	case S_IN:
727 	case S_OUT:
728 		break;
729 	}
730 
731 
732 	/*
733 	 * Clear the PCI-IDE latches and the drive's IRQ
734 	 */
735 	status = ata_get_status_clear_intr(ata_ctlp, ata_pktp);
736 
737 	/*
738 	 * some non-compliant (i.e., NEC) drives don't
739 	 * set ATS_BSY within 400 nsec. and/or don't keep
740 	 * it asserted until they're actually non-busy.
741 	 * There's a small window between reading the alt_status
742 	 * and status registers where the drive might "bounce"
743 	 * the ATS_BSY bit.
744 	 */
745 	if (status & ATS_BSY)
746 		return (ATA_FSM_RC_BUSY);
747 
748 	/*
749 	 * get the interrupt reason code
750 	 */
751 	intr_reason = ddi_get8(io_hdl1, ata_ctlp->ac_count);
752 
753 	/*
754 	 * encode the status and interrupt reason bits
755 	 * into an event code which is used to index the
756 	 * FSM tables
757 	 */
758 	event = ATAPI_EVENT(status, intr_reason);
759 
760 	/*
761 	 * determine the action for this event
762 	 */
763 	action = atapi_PioAction[state][event];
764 
765 	/*
766 	 * determine the new state
767 	 */
768 	ata_drvp->ad_state = atapi_PioNextState[state][event];
769 
770 	switch (action) {
771 	default:
772 	case A_UNK:
773 		/*
774 		 * invalid state
775 		 */
776 /*
777  * ??? this shouldn't happen. ???
778  *	if there's an active command on
779  *	this device, the pkt timer should eventually clear the
780  *	device. I might try sending a DEVICE-RESET here to speed
781  *	up the error recovery except that DEVICE-RESET is kind of
782  *	complicated to implement correctly because if I send a
783  *	DEVICE-RESET to drive 1 it deselects itself.
784  */
785 		ADBG_WARN(("atapi_fsm_intr: Unsupported intr\n"));
786 		break;
787 
788 	case A_NADA:
789 		drv_usecwait(100);
790 		break;
791 
792 	case A_CDB:
793 		/*
794 		 * send out atapi pkt
795 		 */
796 		atapi_send_cdb(ata_ctlp, ata_pktp);
797 
798 		/*
799 		 * start the DMA engine if necessary and change
800 		 * the state variable to reflect not doing PIO
801 		 */
802 		if (ata_pktp->ap_pciide_dma) {
803 			atapi_start_dma(ata_ctlp, ata_drvp, ata_pktp);
804 			ata_drvp->ad_state = S_DMA;
805 		}
806 		break;
807 
808 	case A_IN:
809 		if (!(ata_pktp->ap_flags & AP_READ)) {
810 			/*
811 			 * maybe this was a spurious interrupt, just
812 			 * spin for a bit and see if the drive
813 			 * recovers
814 			 */
815 			atapi_fsm_error(ata_ctlp, state, event);
816 			drv_usecwait(100);
817 			break;
818 		}
819 		/*
820 		 * read in the data
821 		 */
822 		if (!ata_pktp->ap_pciide_dma) {
823 			atapi_pio_data_in(ata_ctlp, ata_pktp);
824 		}
825 		break;
826 
827 	case A_OUT:
828 		if (!(ata_pktp->ap_flags & AP_WRITE)) {
829 			/* spin for a bit and see if the drive recovers */
830 			atapi_fsm_error(ata_ctlp, state, event);
831 			drv_usecwait(100);
832 			break;
833 		}
834 		/*
835 		 * send out data
836 		 */
837 		if (!ata_pktp->ap_pciide_dma) {
838 			atapi_pio_data_out(ata_ctlp, ata_pktp);
839 		}
840 		break;
841 
842 	case A_IDLE:
843 		/*
844 		 * The DRQ bit deasserted before or between the data
845 		 * transfer phases.
846 		 */
847 		if (!ata_drvp->ad_bogus_drq) {
848 			ata_drvp->ad_bogus_drq = TRUE;
849 			atapi_fsm_error(ata_ctlp, state, event);
850 		}
851 		drv_usecwait(100);
852 		break;
853 
854 	case A_RE:
855 		/*
856 		 * If we get here, a command has completed!
857 		 *
858 		 * check status of completed command
859 		 */
860 		atapi_status(ata_ctlp, ata_pktp, status,
861 			(state == S_DMA) ? TRUE : FALSE);
862 
863 		return (ATA_FSM_RC_FINI);
864 
865 	case A_REX:
866 		/*
867 		 * some NEC drives don't report the right interrupt
868 		 * reason code for the status phase
869 		 */
870 		if (!ata_drvp->ad_nec_bad_status) {
871 			ata_drvp->ad_nec_bad_status = TRUE;
872 			atapi_fsm_error(ata_ctlp, state, event);
873 			drv_usecwait(100);
874 		}
875 		atapi_status(ata_ctlp, ata_pktp, status,
876 			(state == S_DMA) ? TRUE : FALSE);
877 		return (ATA_FSM_RC_FINI);
878 
879 	}
880 	return (ATA_FSM_RC_OKAY);
881 }
882