Home | History | Annotate | Download | only in ata
      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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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