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