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