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