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