11709Smlf /*
21709Smlf * CDDL HEADER START
31709Smlf *
41709Smlf * The contents of this file are subject to the terms of the
54852Smlf * Common Development and Distribution License (the "License").
61709Smlf * You may not use this file except in compliance with the License.
71709Smlf *
81709Smlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91709Smlf * or http://www.opensolaris.org/os/licensing.
101709Smlf * See the License for the specific language governing permissions
111709Smlf * and limitations under the License.
121709Smlf *
131709Smlf * When distributing Covered Code, include this CDDL HEADER in each
141709Smlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151709Smlf * If applicable, add the following below this CDDL HEADER, with the
161709Smlf * fields enclosed by brackets "[]" replaced with your own identifying
171709Smlf * information: Portions Copyright [yyyy] [name of copyright owner]
181709Smlf *
191709Smlf * CDDL HEADER END
201709Smlf */
211709Smlf
221709Smlf /*
23*7632SNick.Todd@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
241709Smlf * Use is subject to license terms.
251709Smlf */
261709Smlf
271709Smlf /*
281709Smlf * Finite State Machines for ATA controller and ATAPI devices
291709Smlf */
301709Smlf
311709Smlf #include <sys/types.h>
321709Smlf
331709Smlf #include "ata_common.h"
341709Smlf #include "atapi.h"
351709Smlf
361709Smlf /*
371709Smlf * Local functions
381709Smlf */
391709Smlf static int atapi_start_cmd(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
401709Smlf ata_pkt_t *ata_pktp);
411709Smlf static void atapi_send_cdb(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
421709Smlf static void atapi_start_dma(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
431709Smlf ata_pkt_t *ata_pktp);
441709Smlf static void atapi_pio_data_in(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
451709Smlf static void atapi_pio_data_out(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
461709Smlf static void atapi_status(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp,
471709Smlf uchar_t status, int dma_complete);
481709Smlf static void atapi_fsm_error(ata_ctl_t *ata_ctlp, uchar_t state,
491709Smlf uchar_t event);
501709Smlf
511709Smlf
521709Smlf
531709Smlf
541709Smlf static void
atapi_fsm_error(ata_ctl_t * ata_ctlp,uchar_t state,uchar_t event)551709Smlf atapi_fsm_error(
561709Smlf ata_ctl_t *ata_ctlp,
571709Smlf uchar_t state,
581709Smlf uchar_t event)
591709Smlf {
601709Smlf ADBG_ERROR(("atapi protocol error: 0x%p 0x%x 0x%x\n",
61*7632SNick.Todd@Sun.COM (void *)ata_ctlp->ac_data, state, event));
621709Smlf }
631709Smlf
641709Smlf
651709Smlf /*
661709Smlf *
671709Smlf * IO CoD DRQ
681709Smlf * -- --- ---
691709Smlf * 0 0 0 == 0 invalid
701709Smlf * 0 0 1 == 1 Data to device
711709Smlf * 0 1 0 == 2 Idle
721709Smlf * 0 1 1 == 3 Send ATAPI CDB to device
731709Smlf * 1 0 0 == 4 invalid
741709Smlf * 1 0 1 == 5 Data from device
751709Smlf * 1 1 0 == 6 Status ready
761709Smlf * 1 1 1 == 7 Future use
771709Smlf *
781709Smlf */
791709Smlf
801709Smlf /*
811709Smlf * Given the current state and the current event this
821709Smlf * table determines what action to take. Note, in the actual
831709Smlf * table I've left room for the invalid event codes: 0, 2, and 7.
841709Smlf *
851709Smlf * +-----------------------------------------------------
861709Smlf * | Current Event
871709Smlf * |
881709Smlf * State | dataout idle cdb datain status
891709Smlf * | 1 2 3 5 6
901709Smlf * |-----------------------------------------------------
911709Smlf * idle | sendcmd sendcmd sendcmd sendcmd sendcmd
921709Smlf * cmd | * * sendcdb * read-err-code
931709Smlf * cdb | xfer-out nada nada xfer-in read-err-code
941709Smlf * datain | * * * xfer-in read-err-code
951709Smlf * dataout | xfer-out * * * read-err-code
961709Smlf * DMA | * * * * read-err-code
971709Smlf *
981709Smlf */
991709Smlf
1001709Smlf uchar_t atapi_PioAction[ATAPI_NSTATES][ATAPI_NEVENTS] = {
1011709Smlf /* invalid dataout idle cdb invalid datain status future */
1021709Smlf { A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA, A_NADA }, /* Idle */
1031709Smlf { A_NADA, A_NADA, A_NADA, A_CDB, A_NADA, A_NADA, A_RE, A_NADA }, /* Cmd */
1041709Smlf { A_REX, A_OUT, A_NADA, A_NADA, A_IDLE, A_IN, A_RE, A_UNK }, /* Cdb */
1051709Smlf { A_REX, A_UNK, A_IDLE, A_UNK, A_IDLE, A_IN, A_RE, A_UNK }, /* DtaIn */
1061709Smlf { A_REX, A_OUT, A_IDLE, A_UNK, A_IDLE, A_UNK, A_RE, A_UNK }, /* DtaOut */
1071709Smlf { A_REX, A_UNK, A_UNK, A_UNK, A_UNK, A_UNK, A_RE, A_UNK } /* DmaAct */
1081709Smlf };
1091709Smlf
1101709Smlf /*
1111709Smlf *
1121709Smlf * Give the current state and the current event this table
1131709Smlf * determines the new state of the device.
1141709Smlf *
1151709Smlf * +----------------------------------------------
1161709Smlf * | Current Event
1171709Smlf * |
1181709Smlf * State | dataout idle cdb datain status
1191709Smlf * |----------------------------------------------
1201709Smlf * idle | cmd cmd cmd cmd cmd
1211709Smlf * cmd | * * cdb * *
1221709Smlf * cdb | dataout cdb cdb datain (idle)
1231709Smlf * datain | * * * datain (idle)
1241709Smlf * dataout | dataout * * * (idle)
1251709Smlf * DMA | DMA DMA DMA DMA (idle)
1261709Smlf *
1271709Smlf *
1281709Smlf * Note: the states enclosed in parens "(state)", are the accept states
1291709Smlf * for this FSM. A separate table is used to encode the done
1301709Smlf * states rather than extra state codes.
1311709Smlf *
1321709Smlf */
1331709Smlf
1341709Smlf uchar_t atapi_PioNextState[ATAPI_NSTATES][ATAPI_NEVENTS] = {
1351709Smlf /* invalid dataout idle cdb invalid datain status future */
1361709Smlf { S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE, S_IDLE}, /* idle */
1371709Smlf { S_CDB, S_CDB, S_CDB, S_CDB, S_CDB, S_CDB, S_IDLE, S_X }, /* cmd */
1381709Smlf { S_IDLE, S_OUT, S_CDB, S_CDB, S_CDB, S_IN, S_IDLE, S_X }, /* cdb */
1391709Smlf { S_IDLE, S_X, S_IN, S_X, S_IN, S_IN, S_IDLE, S_X }, /* datain */
1401709Smlf { S_IDLE, S_OUT, S_OUT, S_X, S_OUT, S_X, S_IDLE, S_X }, /* dataout */
1411709Smlf { S_IDLE, S_DMA, S_DMA, S_DMA, S_DMA, S_DMA, S_IDLE, S_DMA } /* dmaActv */
1421709Smlf };
1431709Smlf
1441709Smlf
1451709Smlf static int
atapi_start_cmd(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)1461709Smlf atapi_start_cmd(
1471709Smlf ata_ctl_t *ata_ctlp,
1481709Smlf ata_drv_t *ata_drvp,
1491709Smlf ata_pkt_t *ata_pktp)
1501709Smlf {
1511709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
1521709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
1531709Smlf
1541709Smlf /*
1551709Smlf * Bug 1256489:
1561709Smlf *
1571709Smlf * If AC_BSY_WAIT is set, wait for controller to be not busy,
1581709Smlf * before issuing a command. If AC_BSY_WAIT is not set,
1591709Smlf * skip the wait. This is important for laptops that do
1601709Smlf * suspend/resume but do not correctly wait for the busy bit to
1611709Smlf * drop after a resume.
1621709Smlf */
1631709Smlf
1641709Smlf if (ata_ctlp->ac_timing_flags & AC_BSY_WAIT) {
1651709Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2,
1661709Smlf 0, ATS_BSY, 5000000)) {
1671709Smlf ADBG_WARN(("atapi_start: BSY too long!\n"));
1681709Smlf ata_pktp->ap_flags |= AP_ERROR;
1691709Smlf return (ATA_FSM_RC_BUSY);
1701709Smlf }
1711709Smlf }
1721709Smlf
1731709Smlf /*
1741709Smlf * Select the drive
1751709Smlf */
1761709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_pktp->ap_hd);
1774852Smlf ata_nsecwait(400);
1781709Smlf
1791709Smlf /*
1801709Smlf * make certain the drive selected
1811709Smlf */
1821709Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, 5000000)) {
1831709Smlf ADBG_ERROR(("atapi_start_cmd: drive select failed\n"));
1841709Smlf return (ATA_FSM_RC_BUSY);
1851709Smlf }
1861709Smlf
1871709Smlf /*
1881709Smlf * Always make certain interrupts are enabled. It's been reported
1891709Smlf * (but not confirmed) that some notebook computers don't
1901709Smlf * clear the interrupt disable bit after being resumed. The
1911709Smlf * easiest way to fix this is to always clear the disable bit
1921709Smlf * before every command.
1931709Smlf */
1941709Smlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, ATDC_D3);
1951709Smlf
1961709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, ata_pktp->ap_lwcyl);
1971709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, ata_pktp->ap_hicyl);
1981709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, ata_pktp->ap_sec);
1991709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, ata_pktp->ap_count);
2001709Smlf
2011709Smlf if (ata_pktp->ap_pciide_dma) {
2021709Smlf
2031709Smlf ASSERT((ata_pktp->ap_flags & (AP_READ | AP_WRITE)) != 0);
2041709Smlf
2051709Smlf /*
2061709Smlf * DMA but no Overlap
2071709Smlf */
2081709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_feature, ATF_ATAPI_DMA);
2091709Smlf
2101709Smlf /*
2111709Smlf * copy the Scatter/Gather list to the controller's
2121709Smlf * Physical Region Descriptor Table
2131709Smlf */
2141709Smlf ata_pciide_dma_setup(ata_ctlp, ata_pktp->ap_sg_list,
2151709Smlf ata_pktp->ap_sg_cnt);
2161709Smlf } else {
2171709Smlf /*
2181709Smlf * no DMA and no Overlap
2191709Smlf */
2201709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_feature, 0);
2211709Smlf }
2221709Smlf
2231709Smlf /*
2241709Smlf * This next one sets the device in motion
2251709Smlf */
2261709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ata_pktp->ap_cmd);
2271709Smlf
2281709Smlf /* wait for the busy bit to settle */
2294852Smlf ata_nsecwait(400);
2301709Smlf
2311709Smlf if (!(ata_drvp->ad_flags & AD_NO_CDB_INTR)) {
2321709Smlf /*
2331709Smlf * the device will send me an interrupt when it's
2341709Smlf * ready for the packet
2351709Smlf */
2361709Smlf return (ATA_FSM_RC_OKAY);
2371709Smlf }
2381709Smlf
2391709Smlf /* else */
2401709Smlf
2411709Smlf /*
2421709Smlf * If we don't receive an interrupt requesting the scsi CDB,
2431709Smlf * we must poll for DRQ, and then send out the CDB.
2441709Smlf */
2451709Smlf
2461709Smlf /*
2471709Smlf * Wait for DRQ before sending the CDB. Bailout early
2481709Smlf * if an error occurs.
2491709Smlf *
2501709Smlf * I'm not certain what the correct timeout should be.
2511709Smlf */
2521709Smlf if (ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2,
2531709Smlf ATS_DRQ, ATS_BSY, /* okay */
2541709Smlf ATS_ERR, ATS_BSY, /* cmd failed */
2551709Smlf ATS_DF, ATS_BSY, /* cmd failed */
2561709Smlf 4000000)) {
2571709Smlf /* got good status */
2581709Smlf return (ATA_FSM_RC_INTR);
2591709Smlf }
2601709Smlf
2611709Smlf ADBG_WARN(("atapi_start_cmd: 0x%x status 0x%x error 0x%x\n",
2621709Smlf ata_pktp->ap_cmd,
2631709Smlf ddi_get8(io_hdl2, ata_ctlp->ac_altstatus),
2641709Smlf ddi_get8(io_hdl1, ata_ctlp->ac_error)));
2651709Smlf
2661709Smlf return (ATA_FSM_RC_INTR);
2671709Smlf }
2681709Smlf
2691709Smlf
2701709Smlf /*
2711709Smlf *
2721709Smlf * Send the SCSI CDB to the ATAPI device
2731709Smlf *
2741709Smlf */
2751709Smlf
2761709Smlf static void
atapi_send_cdb(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)2771709Smlf atapi_send_cdb(
2781709Smlf ata_ctl_t *ata_ctlp,
2791709Smlf ata_pkt_t *ata_pktp)
2801709Smlf {
2811709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
2821709Smlf int padding;
2831709Smlf
2841709Smlf ADBG_TRACE(("atapi_send_cdb entered\n"));
2851709Smlf
2861709Smlf /*
2871709Smlf * send the CDB to the drive
2881709Smlf */
2891709Smlf ddi_rep_put16(io_hdl1, (ushort_t *)ata_pktp->ap_cdbp, ata_ctlp->ac_data,
2901709Smlf ata_pktp->ap_cdb_len >> 1, DDI_DEV_NO_AUTOINCR);
2911709Smlf
2921709Smlf /*
2931709Smlf * pad to ad_cdb_len bytes
2941709Smlf */
2951709Smlf
2961709Smlf padding = ata_pktp->ap_cdb_pad;
2971709Smlf
2981709Smlf while (padding) {
2991709Smlf ddi_put16(io_hdl1, ata_ctlp->ac_data, 0);
3001709Smlf padding--;
3011709Smlf }
3021709Smlf
3031709Smlf /* wait for the busy bit to settle */
3044852Smlf ata_nsecwait(400);
3051709Smlf
3061709Smlf #ifdef ATA_DEBUG_XXX
3071709Smlf {
3081709Smlf uchar_t *cp = ata_pktp->ap_cdbp;
3091709Smlf
3101709Smlf ADBG_TRANSPORT(("\tatapi scsi cmd (%d bytes):\n ",
3111709Smlf ata_pktp->ap_cdb_len));
3121709Smlf ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
3131709Smlf cp[0], cp[1], cp[2], cp[3]));
3141709Smlf ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
3151709Smlf cp[4], cp[5], cp[6], cp[7]));
3161709Smlf ADBG_TRANSPORT(("\t\t 0x%x 0x%x 0x%x 0x%x\n",
3171709Smlf cp[8], cp[9], cp[10], cp[11]));
3181709Smlf }
3191709Smlf #endif
3201709Smlf
3211709Smlf ata_pktp->ap_flags |= AP_SENT_CMD;
3221709Smlf }
3231709Smlf
3241709Smlf
3251709Smlf
3261709Smlf /*
3271709Smlf * Start the DMA engine
3281709Smlf */
3291709Smlf
3301709Smlf /* ARGSUSED */
3311709Smlf static void
atapi_start_dma(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)3321709Smlf atapi_start_dma(
3331709Smlf ata_ctl_t *ata_ctlp,
3341709Smlf ata_drv_t *ata_drvp,
3351709Smlf ata_pkt_t *ata_pktp)
3361709Smlf {
3371709Smlf uchar_t rd_wr;
3381709Smlf
3391709Smlf /*
3401709Smlf * Determine the direction. This may look backwards
3411709Smlf * but the command bit programmed into the DMA engine
3421709Smlf * specifies the type of operation the engine performs
3431709Smlf * on the PCI bus (not the ATA bus). Therefore when
3441709Smlf * transferring data from the device to system memory, the
3451709Smlf * DMA engine performs PCI Write operations.
3461709Smlf */
3471709Smlf if (ata_pktp->ap_flags & AP_READ)
3481709Smlf rd_wr = PCIIDE_BMICX_RWCON_WRITE_TO_MEMORY;
3491709Smlf else
3501709Smlf rd_wr = PCIIDE_BMICX_RWCON_READ_FROM_MEMORY;
3511709Smlf
3521709Smlf /*
3531709Smlf * Start the DMA engine
3541709Smlf */
3551709Smlf ata_pciide_dma_start(ata_ctlp, rd_wr);
3561709Smlf }
3571709Smlf
3581709Smlf
3591709Smlf
3601709Smlf /*
3611709Smlf * Transfer the data from the device
3621709Smlf *
3631709Smlf * Note: the atapi_pio_data_in() and atapi_pio_data_out() functions
3641709Smlf * are complicated a lot by the requirement to handle an odd byte count.
3651709Smlf * The only device we've seen which does this is the Hitachi CDR-7730.
3661709Smlf * See bug ID 1214595. It's my understanding that Dell stopped shipping
3671709Smlf * that drive after discovering all the problems it caused, so it may
3681709Smlf * be impossible to find one for any sort of regression test.
3691709Smlf *
3701709Smlf * In the future, ATAPI tape drives will also probably support odd byte
3711709Smlf * counts so this code will be excersized more often.
3721709Smlf *
3731709Smlf */
3741709Smlf
3751709Smlf static void
atapi_pio_data_in(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)3761709Smlf atapi_pio_data_in(
3771709Smlf ata_ctl_t *ata_ctlp,
3781709Smlf ata_pkt_t *ata_pktp)
3791709Smlf {
3801709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
3811709Smlf int drive_bytes;
3821709Smlf int xfer_bytes;
3831709Smlf int xfer_words;
3841709Smlf
3851709Smlf ata_pktp->ap_flags |= AP_XFERRED_DATA;
3861709Smlf
3871709Smlf /*
3881709Smlf * Get the device's byte count for this transfer
3891709Smlf */
3901709Smlf drive_bytes = ((int)ddi_get8(io_hdl1, ata_ctlp->ac_hcyl) << 8)
3911709Smlf + ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
3921709Smlf
3931709Smlf /*
3941709Smlf * Determine actual number I'm going to transfer. My
3951709Smlf * buffer might have fewer bytes than what the device
3961709Smlf * expects or handles on each interrupt.
3971709Smlf */
3981709Smlf xfer_bytes = min(ata_pktp->ap_resid, drive_bytes);
3991709Smlf
4001709Smlf ASSERT(xfer_bytes >= 0);
4011709Smlf
4021709Smlf /*
4031709Smlf * Round down my transfer count to whole words so that
4041709Smlf * if the transfer count is odd it's still handled correctly.
4051709Smlf */
4061709Smlf xfer_words = xfer_bytes / 2;
4071709Smlf
4081709Smlf if (xfer_words) {
4091709Smlf int byte_count = xfer_words * 2;
4101709Smlf
4111709Smlf ddi_rep_get16(io_hdl1, (ushort_t *)ata_pktp->ap_v_addr,
4121709Smlf ata_ctlp->ac_data, xfer_words, DDI_DEV_NO_AUTOINCR);
4131709Smlf
4141709Smlf ata_pktp->ap_v_addr += byte_count;
4151709Smlf drive_bytes -= byte_count;
4161709Smlf }
4171709Smlf
4181709Smlf /*
4191709Smlf * Handle possible odd byte at end. Read a 16-bit
4201709Smlf * word but discard the high-order byte.
4211709Smlf */
4221709Smlf if (xfer_bytes & 1) {
4231709Smlf ushort_t tmp_word;
4241709Smlf
4251709Smlf tmp_word = ddi_get16(io_hdl1, ata_ctlp->ac_data);
4261709Smlf *ata_pktp->ap_v_addr++ = tmp_word & 0xff;
4271709Smlf drive_bytes -= 2;
4281709Smlf }
4291709Smlf
4301709Smlf ata_pktp->ap_resid -= xfer_bytes;
4311709Smlf
4321709Smlf ADBG_TRANSPORT(("atapi_pio_data_in: read 0x%x bytes\n", xfer_bytes));
4331709Smlf
4341709Smlf /*
4351709Smlf * Discard any unwanted data.
4361709Smlf */
4371709Smlf if (drive_bytes > 0) {
4381709Smlf ADBG_TRANSPORT(("atapi_pio_data_in: dump 0x%x bytes\n",
4391709Smlf drive_bytes));
4401709Smlf
4411709Smlf /* rounded up if the drive_bytes count is odd */
4421709Smlf for (; drive_bytes > 0; drive_bytes -= 2)
4431709Smlf (void) ddi_get16(io_hdl1, ata_ctlp->ac_data);
4441709Smlf }
4451709Smlf
4461709Smlf /* wait for the busy bit to settle */
4474852Smlf ata_nsecwait(400);
4481709Smlf }
4491709Smlf
4501709Smlf
4511709Smlf /*
4521709Smlf * Transfer the data to the device
4531709Smlf */
4541709Smlf
4551709Smlf static void
atapi_pio_data_out(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)4561709Smlf atapi_pio_data_out(
4571709Smlf ata_ctl_t *ata_ctlp,
4581709Smlf ata_pkt_t *ata_pktp)
4591709Smlf {
4601709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
4611709Smlf int drive_bytes;
4621709Smlf int xfer_bytes;
4631709Smlf int xfer_words;
4641709Smlf
4651709Smlf ata_pktp->ap_flags |= AP_XFERRED_DATA;
4661709Smlf
4671709Smlf /*
4681709Smlf * Get the device's byte count for this transfer
4691709Smlf */
4701709Smlf drive_bytes = ((int)ddi_get8(io_hdl1, ata_ctlp->ac_hcyl) << 8)
4711709Smlf + ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
4721709Smlf
4731709Smlf /*
4741709Smlf * Determine actual number I'm going to transfer. My
4751709Smlf * buffer might have fewer bytes than what the device
4761709Smlf * expects or handles on each interrupt.
4771709Smlf */
4781709Smlf xfer_bytes = min(ata_pktp->ap_resid, drive_bytes);
4791709Smlf
4801709Smlf /*
4811709Smlf * Round down my transfer count to whole words so that
4821709Smlf * if the transfer count is odd it's handled correctly.
4831709Smlf */
4841709Smlf xfer_words = xfer_bytes / 2;
4851709Smlf
4861709Smlf if (xfer_words) {
4871709Smlf int byte_count = xfer_words * 2;
4881709Smlf
4891709Smlf ddi_rep_put16(io_hdl1, (ushort_t *)ata_pktp->ap_v_addr,
4901709Smlf ata_ctlp->ac_data, xfer_words, DDI_DEV_NO_AUTOINCR);
4911709Smlf ata_pktp->ap_v_addr += byte_count;
4921709Smlf }
4931709Smlf
4941709Smlf /*
4951709Smlf * If odd byte count, transfer the last
4961709Smlf * byte. Use a tmp so that I don't run off
4971709Smlf * the end off the buffer and possibly page
4981709Smlf * fault.
4991709Smlf */
5001709Smlf if (xfer_bytes & 1) {
5011709Smlf ushort_t tmp_word;
5021709Smlf
5031709Smlf /* grab the last unsigned byte and widen it to 16-bits */
5041709Smlf tmp_word = *ata_pktp->ap_v_addr++;
5051709Smlf ddi_put16(io_hdl1, ata_ctlp->ac_data, tmp_word);
5061709Smlf }
5071709Smlf
5081709Smlf ata_pktp->ap_resid -= xfer_bytes;
5091709Smlf
5101709Smlf ADBG_TRANSPORT(("atapi_pio_data_out: wrote 0x%x bytes\n", xfer_bytes));
5111709Smlf
5121709Smlf /* wait for the busy bit to settle */
5134852Smlf ata_nsecwait(400);
5141709Smlf }
5151709Smlf
5161709Smlf
5171709Smlf /*
5181709Smlf *
5191709Smlf * check status of completed command
5201709Smlf *
5211709Smlf */
5221709Smlf static void
atapi_status(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp,uchar_t status,int dma_completion)5231709Smlf atapi_status(
5241709Smlf ata_ctl_t *ata_ctlp,
5251709Smlf ata_pkt_t *ata_pktp,
5261709Smlf uchar_t status,
5271709Smlf int dma_completion)
5281709Smlf {
5291709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
5301709Smlf
5311709Smlf ata_pktp->ap_flags |= AP_GOT_STATUS;
5321709Smlf
5331709Smlf if (status & (ATS_DF | ATS_ERR)) {
5341709Smlf ata_pktp->ap_flags |= AP_ERROR;
5351709Smlf }
5361709Smlf
5371709Smlf if (ata_pktp->ap_flags & AP_ERROR) {
5381709Smlf ata_pktp->ap_status = status;
5391709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
5401709Smlf }
5411709Smlf
5421709Smlf
5431709Smlf /*
5441709Smlf * If the DMA transfer failed leave the resid set to
5451709Smlf * the original byte count. The target driver has
5461709Smlf * to do a REQUEST SENSE to get the true residual
5471709Smlf * byte count. Otherwise, it all transferred so update
5481709Smlf * the flags and residual byte count.
5491709Smlf */
5501709Smlf if (dma_completion && !(ata_pktp->ap_flags & AP_TRAN_ERROR)) {
5511709Smlf ata_pktp->ap_flags |= AP_XFERRED_DATA;
5521709Smlf ata_pktp->ap_resid = 0;
5531709Smlf }
5541709Smlf }
5551709Smlf
5561709Smlf
5571709Smlf static void
atapi_device_reset(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)5581709Smlf atapi_device_reset(
5591709Smlf ata_ctl_t *ata_ctlp,
5601709Smlf ata_drv_t *ata_drvp)
5611709Smlf {
5621709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
5631709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
5641709Smlf
5651709Smlf /* select the drive */
5661709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
5674852Smlf ata_nsecwait(400);
5681709Smlf
5691709Smlf /* issue atapi DEVICE RESET */
5701709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ATC_DEVICE_RESET);
5711709Smlf
5721709Smlf /* wait for the busy bit to settle */
5734852Smlf ata_nsecwait(400);
5741709Smlf
5751709Smlf /*
5761709Smlf * Re-select the drive (this is probably only necessary
5771709Smlf * when resetting drive 1).
5781709Smlf */
5791709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
5804852Smlf ata_nsecwait(400);
5811709Smlf
5821709Smlf /* allow the drive the full 6 seconds to respond */
5831709Smlf /* LINTED */
5841709Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, 6 * 1000000)) {
5851709Smlf ADBG_WARN(("atapi_device_reset: still busy\n"));
5861709Smlf /*
5871709Smlf * It's not clear to me what to do at this point,
5881709Smlf * the drive might be dead or might eventually
5891709Smlf * recover. For now just ignore it and continue
5901709Smlf * to attempt to use the drive.
5911709Smlf */
5921709Smlf }
5931709Smlf }
5941709Smlf
5951709Smlf
5961709Smlf
5971709Smlf void
atapi_fsm_reset(ata_ctl_t * ata_ctlp)5981709Smlf atapi_fsm_reset(ata_ctl_t *ata_ctlp)
5991709Smlf {
6001709Smlf ata_drv_t *ata_drvp;
6011709Smlf int drive;
6021709Smlf
6031709Smlf /*
6041709Smlf * reset drive drive 0 and the drive 1
6051709Smlf */
6061709Smlf for (drive = 0; drive <= 1; drive++) {
6071709Smlf ata_drvp = CTL2DRV(ata_ctlp, drive, 0);
6081709Smlf if (ata_drvp && ATAPIDRV(ata_drvp)) {
6091709Smlf ata_drvp->ad_state = S_IDLE;
6101709Smlf atapi_device_reset(ata_ctlp, ata_drvp);
6111709Smlf }
6121709Smlf }
6131709Smlf }
6141709Smlf
6151709Smlf
6161709Smlf int
atapi_fsm_start(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)6171709Smlf atapi_fsm_start(
6181709Smlf ata_ctl_t *ata_ctlp,
6191709Smlf ata_drv_t *ata_drvp,
6201709Smlf ata_pkt_t *ata_pktp)
6211709Smlf {
6221709Smlf int rc;
6231709Smlf
6241709Smlf ADBG_TRACE(("atapi_start entered\n"));
6251709Smlf ADBG_TRANSPORT(("atapi_start: pkt = 0x%p\n", ata_pktp));
6261709Smlf
6271709Smlf /*
6281709Smlf * check for valid state
6291709Smlf */
6301709Smlf if (ata_drvp->ad_state != S_IDLE) {
6311709Smlf ADBG_ERROR(("atapi_fsm_start not idle 0x%x\n",
6321709Smlf ata_drvp->ad_state));
6331709Smlf return (ATA_FSM_RC_BUSY);
6341709Smlf } else {
6351709Smlf ata_drvp->ad_state = S_CMD;
6361709Smlf }
6371709Smlf
6381709Smlf rc = atapi_start_cmd(ata_ctlp, ata_drvp, ata_pktp);
6391709Smlf
6401709Smlf switch (rc) {
6411709Smlf case ATA_FSM_RC_OKAY:
6421709Smlf /*
6431709Smlf * The command started okay. Just return.
6441709Smlf */
6451709Smlf break;
6461709Smlf case ATA_FSM_RC_INTR:
6471709Smlf /*
6481709Smlf * Got Command Phase. The upper layer will send
6491709Smlf * the cdb by faking an interrupt.
6501709Smlf */
6511709Smlf break;
6521709Smlf case ATA_FSM_RC_FINI:
6531709Smlf /*
6541709Smlf * command completed immediately, stick on done q
6551709Smlf */
6561709Smlf break;
6571709Smlf case ATA_FSM_RC_BUSY:
6581709Smlf /*
6591709Smlf * The command wouldn't start, tell the upper layer to
6601709Smlf * stick this request on the done queue.
6611709Smlf */
6621709Smlf ata_drvp->ad_state = S_IDLE;
6631709Smlf return (ATA_FSM_RC_BUSY);
6641709Smlf }
6651709Smlf return (rc);
6661709Smlf }
6671709Smlf
6681709Smlf /*
6691709Smlf *
6701709Smlf * All interrupts on an ATAPI device come through here.
6711709Smlf * This function determines what to do next, based on
6721709Smlf * the current state of the request and the drive's current
6731709Smlf * status bits. See the FSM tables at the top of this file.
6741709Smlf *
6751709Smlf */
6761709Smlf
6771709Smlf int
atapi_fsm_intr(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)6781709Smlf atapi_fsm_intr(
6791709Smlf ata_ctl_t *ata_ctlp,
6801709Smlf ata_drv_t *ata_drvp,
6811709Smlf ata_pkt_t *ata_pktp)
6821709Smlf {
6831709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
6841709Smlf uchar_t status;
6851709Smlf uchar_t intr_reason;
6861709Smlf uchar_t state;
6871709Smlf uchar_t event;
6881709Smlf uchar_t action;
6891709Smlf
6901709Smlf
6911709Smlf /*
6921709Smlf * get the prior state
6931709Smlf */
6941709Smlf state = ata_drvp->ad_state;
6951709Smlf
6961709Smlf /*
6971709Smlf * If doing DMA, then:
6981709Smlf *
6991709Smlf * 1. halt the DMA engine
7001709Smlf * 2. reset the interrupt and error latches
7011709Smlf * 3. reset the drive's IRQ.
7021709Smlf *
7031709Smlf * I think the order of these operations must be
7041709Smlf * exactly as listed. Otherwise we the PCI-IDE
7051709Smlf * controller can hang or we can miss the next interrupt
7061709Smlf * edge.
7071709Smlf *
7081709Smlf */
7091709Smlf switch (state) {
7101709Smlf case S_DMA:
7111709Smlf ASSERT(ata_pktp->ap_pciide_dma == TRUE);
7121709Smlf /*
7131709Smlf * Halt the DMA engine. When we reach this point
7141709Smlf * we already know for certain that the device has
7151709Smlf * an interrupt pending since the ata_get_status()
7161709Smlf * function already checked the PCI-IDE interrupt
7171709Smlf * status bit.
7181709Smlf */
7191709Smlf ata_pciide_dma_stop(ata_ctlp);
7201709Smlf /*FALLTHRU*/
7211709Smlf case S_IDLE:
7221709Smlf case S_CMD:
7231709Smlf case S_CDB:
7241709Smlf case S_IN:
7251709Smlf case S_OUT:
7261709Smlf break;
7271709Smlf }
7281709Smlf
7291709Smlf
7301709Smlf /*
7311709Smlf * Clear the PCI-IDE latches and the drive's IRQ
7321709Smlf */
7331709Smlf status = ata_get_status_clear_intr(ata_ctlp, ata_pktp);
7341709Smlf
7351709Smlf /*
7361709Smlf * some non-compliant (i.e., NEC) drives don't
7371709Smlf * set ATS_BSY within 400 nsec. and/or don't keep
7381709Smlf * it asserted until they're actually non-busy.
7391709Smlf * There's a small window between reading the alt_status
7401709Smlf * and status registers where the drive might "bounce"
7411709Smlf * the ATS_BSY bit.
7421709Smlf */
7431709Smlf if (status & ATS_BSY)
7441709Smlf return (ATA_FSM_RC_BUSY);
7451709Smlf
7461709Smlf /*
7471709Smlf * get the interrupt reason code
7481709Smlf */
7491709Smlf intr_reason = ddi_get8(io_hdl1, ata_ctlp->ac_count);
7501709Smlf
7511709Smlf /*
7521709Smlf * encode the status and interrupt reason bits
7531709Smlf * into an event code which is used to index the
7541709Smlf * FSM tables
7551709Smlf */
7561709Smlf event = ATAPI_EVENT(status, intr_reason);
7571709Smlf
7581709Smlf /*
7591709Smlf * determine the action for this event
7601709Smlf */
7611709Smlf action = atapi_PioAction[state][event];
7621709Smlf
7631709Smlf /*
7641709Smlf * determine the new state
7651709Smlf */
7661709Smlf ata_drvp->ad_state = atapi_PioNextState[state][event];
7671709Smlf
7681709Smlf switch (action) {
7691709Smlf default:
7701709Smlf case A_UNK:
7711709Smlf /*
7721709Smlf * invalid state
7731709Smlf */
7741709Smlf /*
7751709Smlf * ??? this shouldn't happen. ???
7761709Smlf * if there's an active command on
7771709Smlf * this device, the pkt timer should eventually clear the
7781709Smlf * device. I might try sending a DEVICE-RESET here to speed
7791709Smlf * up the error recovery except that DEVICE-RESET is kind of
7801709Smlf * complicated to implement correctly because if I send a
7811709Smlf * DEVICE-RESET to drive 1 it deselects itself.
7821709Smlf */
7831709Smlf ADBG_WARN(("atapi_fsm_intr: Unsupported intr\n"));
7841709Smlf break;
7851709Smlf
7861709Smlf case A_NADA:
7871709Smlf drv_usecwait(100);
7881709Smlf break;
7891709Smlf
7901709Smlf case A_CDB:
7911709Smlf /*
7921709Smlf * send out atapi pkt
7931709Smlf */
7941709Smlf atapi_send_cdb(ata_ctlp, ata_pktp);
7951709Smlf
7961709Smlf /*
7971709Smlf * start the DMA engine if necessary and change
7981709Smlf * the state variable to reflect not doing PIO
7991709Smlf */
8001709Smlf if (ata_pktp->ap_pciide_dma) {
8011709Smlf atapi_start_dma(ata_ctlp, ata_drvp, ata_pktp);
8021709Smlf ata_drvp->ad_state = S_DMA;
8031709Smlf }
8041709Smlf break;
8051709Smlf
8061709Smlf case A_IN:
8071709Smlf if (!(ata_pktp->ap_flags & AP_READ)) {
8081709Smlf /*
8091709Smlf * maybe this was a spurious interrupt, just
8101709Smlf * spin for a bit and see if the drive
8111709Smlf * recovers
8121709Smlf */
8131709Smlf atapi_fsm_error(ata_ctlp, state, event);
8141709Smlf drv_usecwait(100);
8151709Smlf break;
8161709Smlf }
8171709Smlf /*
8181709Smlf * read in the data
8191709Smlf */
8201709Smlf if (!ata_pktp->ap_pciide_dma) {
8211709Smlf atapi_pio_data_in(ata_ctlp, ata_pktp);
8221709Smlf }
8231709Smlf break;
8241709Smlf
8251709Smlf case A_OUT:
8261709Smlf if (!(ata_pktp->ap_flags & AP_WRITE)) {
8271709Smlf /* spin for a bit and see if the drive recovers */
8281709Smlf atapi_fsm_error(ata_ctlp, state, event);
8291709Smlf drv_usecwait(100);
8301709Smlf break;
8311709Smlf }
8321709Smlf /*
8331709Smlf * send out data
8341709Smlf */
8351709Smlf if (!ata_pktp->ap_pciide_dma) {
8361709Smlf atapi_pio_data_out(ata_ctlp, ata_pktp);
8371709Smlf }
8381709Smlf break;
8391709Smlf
8401709Smlf case A_IDLE:
8411709Smlf /*
8421709Smlf * The DRQ bit deasserted before or between the data
8431709Smlf * transfer phases.
8441709Smlf */
8451709Smlf if (!ata_drvp->ad_bogus_drq) {
8461709Smlf ata_drvp->ad_bogus_drq = TRUE;
8471709Smlf atapi_fsm_error(ata_ctlp, state, event);
8481709Smlf }
8491709Smlf drv_usecwait(100);
8501709Smlf break;
8511709Smlf
8521709Smlf case A_RE:
8531709Smlf /*
8541709Smlf * If we get here, a command has completed!
8551709Smlf *
8561709Smlf * check status of completed command
8571709Smlf */
8581709Smlf atapi_status(ata_ctlp, ata_pktp, status,
8591709Smlf (state == S_DMA) ? TRUE : FALSE);
8601709Smlf
8611709Smlf return (ATA_FSM_RC_FINI);
8621709Smlf
8631709Smlf case A_REX:
8641709Smlf /*
8651709Smlf * some NEC drives don't report the right interrupt
8661709Smlf * reason code for the status phase
8671709Smlf */
8681709Smlf if (!ata_drvp->ad_nec_bad_status) {
8691709Smlf ata_drvp->ad_nec_bad_status = TRUE;
8701709Smlf atapi_fsm_error(ata_ctlp, state, event);
8711709Smlf drv_usecwait(100);
8721709Smlf }
8731709Smlf atapi_status(ata_ctlp, ata_pktp, status,
8741709Smlf (state == S_DMA) ? TRUE : FALSE);
8751709Smlf return (ATA_FSM_RC_FINI);
8761709Smlf
8771709Smlf }
8781709Smlf return (ATA_FSM_RC_OKAY);
8791709Smlf }
880